1// SPDX-License-Identifier: GPL-2.0-only
2/**
3 * tpci200.c
4 *
5 * driver for the TEWS TPCI-200 device
6 *
7 * Copyright (C) 2009-2012 CERN (www.cern.ch)
8 * Author: Nicolas Serafini, EIC2 SA
9 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
10 */
11
12#include <linux/module.h>
13#include <linux/slab.h>
14#include "tpci200.h"
15
16static const u16 tpci200_status_timeout[] = {
17	TPCI200_A_TIMEOUT,
18	TPCI200_B_TIMEOUT,
19	TPCI200_C_TIMEOUT,
20	TPCI200_D_TIMEOUT,
21};
22
23static const u16 tpci200_status_error[] = {
24	TPCI200_A_ERROR,
25	TPCI200_B_ERROR,
26	TPCI200_C_ERROR,
27	TPCI200_D_ERROR,
28};
29
30static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
31	[IPACK_IO_SPACE]    = TPCI200_IO_SPACE_SIZE,
32	[IPACK_ID_SPACE]    = TPCI200_ID_SPACE_SIZE,
33	[IPACK_INT_SPACE]   = TPCI200_INT_SPACE_SIZE,
34	[IPACK_MEM8_SPACE]  = TPCI200_MEM8_SPACE_SIZE,
35	[IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
36};
37
38static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
39	[IPACK_IO_SPACE]    = TPCI200_IO_SPACE_INTERVAL,
40	[IPACK_ID_SPACE]    = TPCI200_ID_SPACE_INTERVAL,
41	[IPACK_INT_SPACE]   = TPCI200_INT_SPACE_INTERVAL,
42	[IPACK_MEM8_SPACE]  = TPCI200_MEM8_SPACE_INTERVAL,
43	[IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
44};
45
46static struct tpci200_board *check_slot(struct ipack_device *dev)
47{
48	struct tpci200_board *tpci200;
49
50	if (dev == NULL)
51		return NULL;
52
53
54	tpci200 = dev_get_drvdata(dev->bus->parent);
55
56	if (tpci200 == NULL) {
57		dev_info(&dev->dev, "carrier board not found\n");
58		return NULL;
59	}
60
61	if (dev->slot >= TPCI200_NB_SLOT) {
62		dev_info(&dev->dev,
63			 "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
64			 dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
65		return NULL;
66	}
67
68	return tpci200;
69}
70
71static void tpci200_clear_mask(struct tpci200_board *tpci200,
72			       __le16 __iomem *addr, u16 mask)
73{
74	unsigned long flags;
75	spin_lock_irqsave(&tpci200->regs_lock, flags);
76	iowrite16(ioread16(addr) & (~mask), addr);
77	spin_unlock_irqrestore(&tpci200->regs_lock, flags);
78}
79
80static void tpci200_set_mask(struct tpci200_board *tpci200,
81			     __le16 __iomem *addr, u16 mask)
82{
83	unsigned long flags;
84	spin_lock_irqsave(&tpci200->regs_lock, flags);
85	iowrite16(ioread16(addr) | mask, addr);
86	spin_unlock_irqrestore(&tpci200->regs_lock, flags);
87}
88
89static void tpci200_unregister(struct tpci200_board *tpci200)
90{
91	free_irq(tpci200->info->pdev->irq, (void *) tpci200);
92
93	pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
94
95	pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
96	pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
97	pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
98	pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
99
100	pci_disable_device(tpci200->info->pdev);
101}
102
103static void tpci200_enable_irq(struct tpci200_board *tpci200,
104			       int islot)
105{
106	tpci200_set_mask(tpci200,
107			&tpci200->info->interface_regs->control[islot],
108			TPCI200_INT0_EN | TPCI200_INT1_EN);
109}
110
111static void tpci200_disable_irq(struct tpci200_board *tpci200,
112				int islot)
113{
114	tpci200_clear_mask(tpci200,
115			&tpci200->info->interface_regs->control[islot],
116			TPCI200_INT0_EN | TPCI200_INT1_EN);
117}
118
119static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
120{
121	irqreturn_t ret;
122
123	if (!slot_irq)
124		return -ENODEV;
125	ret = slot_irq->handler(slot_irq->arg);
126
127	return ret;
128}
129
130static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
131{
132	struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
133	struct slot_irq *slot_irq;
134	irqreturn_t ret;
135	u16 status_reg;
136	int i;
137
138	/* Read status register */
139	status_reg = ioread16(&tpci200->info->interface_regs->status);
140
141	/* Did we cause the interrupt? */
142	if (!(status_reg & TPCI200_SLOT_INT_MASK))
143		return IRQ_NONE;
144
145	/* callback to the IRQ handler for the corresponding slot */
146	rcu_read_lock();
147	for (i = 0; i < TPCI200_NB_SLOT; i++) {
148		if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
149			continue;
150		slot_irq = rcu_dereference(tpci200->slots[i].irq);
151		ret = tpci200_slot_irq(slot_irq);
152		if (ret == -ENODEV) {
153			dev_info(&tpci200->info->pdev->dev,
154				 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
155				 tpci200->number, i);
156			tpci200_disable_irq(tpci200, i);
157		}
158	}
159	rcu_read_unlock();
160
161	return IRQ_HANDLED;
162}
163
164static int tpci200_free_irq(struct ipack_device *dev)
165{
166	struct slot_irq *slot_irq;
167	struct tpci200_board *tpci200;
168
169	tpci200 = check_slot(dev);
170	if (tpci200 == NULL)
171		return -EINVAL;
172
173	if (mutex_lock_interruptible(&tpci200->mutex))
174		return -ERESTARTSYS;
175
176	if (tpci200->slots[dev->slot].irq == NULL) {
177		mutex_unlock(&tpci200->mutex);
178		return -EINVAL;
179	}
180
181	tpci200_disable_irq(tpci200, dev->slot);
182	slot_irq = tpci200->slots[dev->slot].irq;
183	/* uninstall handler */
184	RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
185	synchronize_rcu();
186	kfree(slot_irq);
187	mutex_unlock(&tpci200->mutex);
188	return 0;
189}
190
191static int tpci200_request_irq(struct ipack_device *dev,
192			       irqreturn_t (*handler)(void *), void *arg)
193{
194	int res = 0;
195	struct slot_irq *slot_irq;
196	struct tpci200_board *tpci200;
197
198	tpci200 = check_slot(dev);
199	if (tpci200 == NULL)
200		return -EINVAL;
201
202	if (mutex_lock_interruptible(&tpci200->mutex))
203		return -ERESTARTSYS;
204
205	if (tpci200->slots[dev->slot].irq != NULL) {
206		dev_err(&dev->dev,
207			"Slot [%d:%d] IRQ already registered !\n",
208			dev->bus->bus_nr,
209			dev->slot);
210		res = -EINVAL;
211		goto out_unlock;
212	}
213
214	slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
215	if (slot_irq == NULL) {
216		dev_err(&dev->dev,
217			"Slot [%d:%d] unable to allocate memory for IRQ !\n",
218			dev->bus->bus_nr, dev->slot);
219		res = -ENOMEM;
220		goto out_unlock;
221	}
222
223	/*
224	 * WARNING: Setup Interrupt Vector in the IndustryPack device
225	 * before an IRQ request.
226	 * Read the User Manual of your IndustryPack device to know
227	 * where to write the vector in memory.
228	 */
229	slot_irq->handler = handler;
230	slot_irq->arg = arg;
231	slot_irq->holder = dev;
232
233	rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
234	tpci200_enable_irq(tpci200, dev->slot);
235
236out_unlock:
237	mutex_unlock(&tpci200->mutex);
238	return res;
239}
240
241static int tpci200_register(struct tpci200_board *tpci200)
242{
243	int i;
244	int res;
245	phys_addr_t ioidint_base;
246	unsigned short slot_ctrl;
247
248	if (pci_enable_device(tpci200->info->pdev) < 0)
249		return -ENODEV;
250
251	/* Request IP interface register (Bar 2) */
252	res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
253				 "Carrier IP interface registers");
254	if (res) {
255		dev_err(&tpci200->info->pdev->dev,
256			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
257			tpci200->info->pdev->bus->number,
258			tpci200->info->pdev->devfn);
259		goto err_disable_device;
260	}
261
262	/* Request IO ID INT space (Bar 3) */
263	res = pci_request_region(tpci200->info->pdev,
264				 TPCI200_IO_ID_INT_SPACES_BAR,
265				 "Carrier IO ID INT space");
266	if (res) {
267		dev_err(&tpci200->info->pdev->dev,
268			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
269			tpci200->info->pdev->bus->number,
270			tpci200->info->pdev->devfn);
271		goto err_ip_interface_bar;
272	}
273
274	/* Request MEM8 space (Bar 5) */
275	res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
276				 "Carrier MEM8 space");
277	if (res) {
278		dev_err(&tpci200->info->pdev->dev,
279			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
280			tpci200->info->pdev->bus->number,
281			tpci200->info->pdev->devfn);
282		goto err_io_id_int_spaces_bar;
283	}
284
285	/* Request MEM16 space (Bar 4) */
286	res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
287				 "Carrier MEM16 space");
288	if (res) {
289		dev_err(&tpci200->info->pdev->dev,
290			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
291			tpci200->info->pdev->bus->number,
292			tpci200->info->pdev->devfn);
293		goto err_mem8_space_bar;
294	}
295
296	/* Map internal tpci200 driver user space */
297	tpci200->info->interface_regs =
298		ioremap(pci_resource_start(tpci200->info->pdev,
299					   TPCI200_IP_INTERFACE_BAR),
300			TPCI200_IFACE_SIZE);
301	if (!tpci200->info->interface_regs) {
302		dev_err(&tpci200->info->pdev->dev,
303			"(bn 0x%X, sn 0x%X) failed to map driver user space!",
304			tpci200->info->pdev->bus->number,
305			tpci200->info->pdev->devfn);
306		res = -ENOMEM;
307		goto err_mem16_space_bar;
308	}
309
310	/* Initialize lock that protects interface_regs */
311	spin_lock_init(&tpci200->regs_lock);
312
313	ioidint_base = pci_resource_start(tpci200->info->pdev,
314					  TPCI200_IO_ID_INT_SPACES_BAR);
315	tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
316	tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
317	tpci200->mod_mem[IPACK_INT_SPACE] =
318		ioidint_base + TPCI200_INT_SPACE_OFF;
319	tpci200->mod_mem[IPACK_MEM8_SPACE] =
320		pci_resource_start(tpci200->info->pdev,
321				   TPCI200_MEM8_SPACE_BAR);
322	tpci200->mod_mem[IPACK_MEM16_SPACE] =
323		pci_resource_start(tpci200->info->pdev,
324				   TPCI200_MEM16_SPACE_BAR);
325
326	/* Set the default parameters of the slot
327	 * INT0 disabled, level sensitive
328	 * INT1 disabled, level sensitive
329	 * error interrupt disabled
330	 * timeout interrupt disabled
331	 * recover time disabled
332	 * clock rate 8 MHz
333	 */
334	slot_ctrl = 0;
335	for (i = 0; i < TPCI200_NB_SLOT; i++)
336		writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
337
338	res = request_irq(tpci200->info->pdev->irq,
339			  tpci200_interrupt, IRQF_SHARED,
340			  KBUILD_MODNAME, (void *) tpci200);
341	if (res) {
342		dev_err(&tpci200->info->pdev->dev,
343			"(bn 0x%X, sn 0x%X) unable to register IRQ !",
344			tpci200->info->pdev->bus->number,
345			tpci200->info->pdev->devfn);
346		goto err_interface_regs;
347	}
348
349	return 0;
350
351err_interface_regs:
352	pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
353err_mem16_space_bar:
354	pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
355err_mem8_space_bar:
356	pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
357err_io_id_int_spaces_bar:
358	pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
359err_ip_interface_bar:
360	pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
361err_disable_device:
362	pci_disable_device(tpci200->info->pdev);
363	return res;
364}
365
366static int tpci200_get_clockrate(struct ipack_device *dev)
367{
368	struct tpci200_board *tpci200 = check_slot(dev);
369	__le16 __iomem *addr;
370
371	if (!tpci200)
372		return -ENODEV;
373
374	addr = &tpci200->info->interface_regs->control[dev->slot];
375	return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8;
376}
377
378static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
379{
380	struct tpci200_board *tpci200 = check_slot(dev);
381	__le16 __iomem *addr;
382
383	if (!tpci200)
384		return -ENODEV;
385
386	addr = &tpci200->info->interface_regs->control[dev->slot];
387
388	switch (mherz) {
389	case 8:
390		tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
391		break;
392	case 32:
393		tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
394		break;
395	default:
396		return -EINVAL;
397	}
398	return 0;
399}
400
401static int tpci200_get_error(struct ipack_device *dev)
402{
403	struct tpci200_board *tpci200 = check_slot(dev);
404	__le16 __iomem *addr;
405	u16 mask;
406
407	if (!tpci200)
408		return -ENODEV;
409
410	addr = &tpci200->info->interface_regs->status;
411	mask = tpci200_status_error[dev->slot];
412	return (ioread16(addr) & mask) ? 1 : 0;
413}
414
415static int tpci200_get_timeout(struct ipack_device *dev)
416{
417	struct tpci200_board *tpci200 = check_slot(dev);
418	__le16 __iomem *addr;
419	u16 mask;
420
421	if (!tpci200)
422		return -ENODEV;
423
424	addr = &tpci200->info->interface_regs->status;
425	mask = tpci200_status_timeout[dev->slot];
426
427	return (ioread16(addr) & mask) ? 1 : 0;
428}
429
430static int tpci200_reset_timeout(struct ipack_device *dev)
431{
432	struct tpci200_board *tpci200 = check_slot(dev);
433	__le16 __iomem *addr;
434	u16 mask;
435
436	if (!tpci200)
437		return -ENODEV;
438
439	addr = &tpci200->info->interface_regs->status;
440	mask = tpci200_status_timeout[dev->slot];
441
442	iowrite16(mask, addr);
443	return 0;
444}
445
446static void tpci200_uninstall(struct tpci200_board *tpci200)
447{
448	tpci200_unregister(tpci200);
449	kfree(tpci200->slots);
450}
451
452static const struct ipack_bus_ops tpci200_bus_ops = {
453	.request_irq = tpci200_request_irq,
454	.free_irq = tpci200_free_irq,
455	.get_clockrate = tpci200_get_clockrate,
456	.set_clockrate = tpci200_set_clockrate,
457	.get_error     = tpci200_get_error,
458	.get_timeout   = tpci200_get_timeout,
459	.reset_timeout = tpci200_reset_timeout,
460};
461
462static int tpci200_install(struct tpci200_board *tpci200)
463{
464	int res;
465
466	tpci200->slots = kcalloc(TPCI200_NB_SLOT, sizeof(struct tpci200_slot),
467				 GFP_KERNEL);
468	if (tpci200->slots == NULL)
469		return -ENOMEM;
470
471	res = tpci200_register(tpci200);
472	if (res) {
473		kfree(tpci200->slots);
474		tpci200->slots = NULL;
475		return res;
476	}
477
478	mutex_init(&tpci200->mutex);
479	return 0;
480}
481
482static void tpci200_release_device(struct ipack_device *dev)
483{
484	kfree(dev);
485}
486
487static int tpci200_create_device(struct tpci200_board *tpci200, int i)
488{
489	int ret;
490	enum ipack_space space;
491	struct ipack_device *dev =
492		kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
493	if (!dev)
494		return -ENOMEM;
495	dev->slot = i;
496	dev->bus = tpci200->info->ipack_bus;
497	dev->release = tpci200_release_device;
498
499	for (space = 0; space < IPACK_SPACE_COUNT; space++) {
500		dev->region[space].start =
501			tpci200->mod_mem[space]
502			+ tpci200_space_interval[space] * i;
503		dev->region[space].size = tpci200_space_size[space];
504	}
505
506	ret = ipack_device_init(dev);
507	if (ret < 0) {
508		ipack_put_device(dev);
509		return ret;
510	}
511
512	ret = ipack_device_add(dev);
513	if (ret < 0)
514		ipack_put_device(dev);
515
516	return ret;
517}
518
519static int tpci200_pci_probe(struct pci_dev *pdev,
520			     const struct pci_device_id *id)
521{
522	int ret, i;
523	struct tpci200_board *tpci200;
524	u32 reg32;
525
526	tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
527	if (!tpci200)
528		return -ENOMEM;
529
530	tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
531	if (!tpci200->info) {
532		ret = -ENOMEM;
533		goto err_tpci200;
534	}
535
536	pci_dev_get(pdev);
537
538	/* Obtain a mapping of the carrier's PCI configuration registers */
539	ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
540				 KBUILD_MODNAME " Configuration Memory");
541	if (ret) {
542		dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
543		ret = -EBUSY;
544		goto err_tpci200_info;
545	}
546	tpci200->info->cfg_regs = ioremap(
547			pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
548			pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
549	if (!tpci200->info->cfg_regs) {
550		dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
551		ret = -EFAULT;
552		goto err_request_region;
553	}
554
555	/* Disable byte swapping for 16 bit IP module access. This will ensure
556	 * that the Industrypack big endian byte order is preserved by the
557	 * carrier. */
558	reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
559	reg32 |= 1 << LAS_BIT_BIGENDIAN;
560	iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
561
562	reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
563	reg32 |= 1 << LAS_BIT_BIGENDIAN;
564	iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
565
566	/* Save struct pci_dev pointer */
567	tpci200->info->pdev = pdev;
568	tpci200->info->id_table = (struct pci_device_id *)id;
569
570	/* register the device and initialize it */
571	ret = tpci200_install(tpci200);
572	if (ret) {
573		dev_err(&pdev->dev, "error during tpci200 install\n");
574		ret = -ENODEV;
575		goto err_cfg_regs;
576	}
577
578	/* Register the carrier in the industry pack bus driver */
579	tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
580						      TPCI200_NB_SLOT,
581						      &tpci200_bus_ops,
582						      THIS_MODULE);
583	if (!tpci200->info->ipack_bus) {
584		dev_err(&pdev->dev,
585			"error registering the carrier on ipack driver\n");
586		ret = -EFAULT;
587		goto err_tpci200_install;
588	}
589
590	/* save the bus number given by ipack to logging purpose */
591	tpci200->number = tpci200->info->ipack_bus->bus_nr;
592	dev_set_drvdata(&pdev->dev, tpci200);
593
594	for (i = 0; i < TPCI200_NB_SLOT; i++)
595		tpci200_create_device(tpci200, i);
596	return 0;
597
598err_tpci200_install:
599	tpci200_uninstall(tpci200);
600err_cfg_regs:
601	pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
602err_request_region:
603	pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
604err_tpci200_info:
605	kfree(tpci200->info);
606	pci_dev_put(pdev);
607err_tpci200:
608	kfree(tpci200);
609	return ret;
610}
611
612static void __tpci200_pci_remove(struct tpci200_board *tpci200)
613{
614	ipack_bus_unregister(tpci200->info->ipack_bus);
615	tpci200_uninstall(tpci200);
616
617	pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
618
619	pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
620
621	pci_dev_put(tpci200->info->pdev);
622
623	kfree(tpci200->info);
624	kfree(tpci200);
625}
626
627static void tpci200_pci_remove(struct pci_dev *dev)
628{
629	struct tpci200_board *tpci200 = pci_get_drvdata(dev);
630
631	__tpci200_pci_remove(tpci200);
632}
633
634static const struct pci_device_id tpci200_idtable[] = {
635	{ TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
636	  TPCI200_SUBDEVICE_ID },
637	{ 0, },
638};
639
640MODULE_DEVICE_TABLE(pci, tpci200_idtable);
641
642static struct pci_driver tpci200_pci_drv = {
643	.name = "tpci200",
644	.id_table = tpci200_idtable,
645	.probe = tpci200_pci_probe,
646	.remove = tpci200_pci_remove,
647};
648
649module_pci_driver(tpci200_pci_drv);
650
651MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
652MODULE_LICENSE("GPL");
653