aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ipack
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-16 11:14:18 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-16 11:14:18 -0500
commit05e5027efc9c0bb6d1d04cde279afbafca0a7929 (patch)
tree733b0291db6cc6c13844b97e3c7bf593b6711d66 /drivers/ipack
parent76859725ad31ac480d55bf176e5bbe0f9ab6e6cb (diff)
Staging: ipack: move out of staging
The ipack subsystem is cleaned up enough to now move out of the staging tree, and into drivers/ipack. Cc: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Cc: Jens Taprogge <jens.taprogge@taprogge.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/ipack')
-rw-r--r--drivers/ipack/Kconfig24
-rw-r--r--drivers/ipack/Makefile6
-rw-r--r--drivers/ipack/carriers/Kconfig7
-rw-r--r--drivers/ipack/carriers/Makefile1
-rw-r--r--drivers/ipack/carriers/tpci200.c627
-rw-r--r--drivers/ipack/carriers/tpci200.h168
-rw-r--r--drivers/ipack/devices/Kconfig6
-rw-r--r--drivers/ipack/devices/Makefile1
-rw-r--r--drivers/ipack/devices/ipoctal.c751
-rw-r--r--drivers/ipack/devices/ipoctal.h42
-rw-r--r--drivers/ipack/devices/scc2698.h228
-rw-r--r--drivers/ipack/ipack.c481
-rw-r--r--drivers/ipack/ipack.h215
-rw-r--r--drivers/ipack/ipack_ids.h32
14 files changed, 2589 insertions, 0 deletions
diff --git a/drivers/ipack/Kconfig b/drivers/ipack/Kconfig
new file mode 100644
index 000000000000..3949e5589560
--- /dev/null
+++ b/drivers/ipack/Kconfig
@@ -0,0 +1,24 @@
1#
2# IPACK configuration.
3#
4
5menuconfig IPACK_BUS
6 tristate "IndustryPack bus support"
7 depends on HAS_IOMEM
8 ---help---
9 This option provides support for the IndustryPack framework. There
10 are IndustryPack carrier boards, which interface another bus (such as
11 PCI) to an IndustryPack bus, and IndustryPack modules, that are
12 hosted on these buses. While IndustryPack modules can provide a
13 large variety of functionality, they are most often found in
14 industrial control applications.
15
16 Say N if unsure.
17
18if IPACK_BUS
19
20source "drivers/ipack/carriers/Kconfig"
21
22source "drivers/ipack/devices/Kconfig"
23
24endif # IPACK
diff --git a/drivers/ipack/Makefile b/drivers/ipack/Makefile
new file mode 100644
index 000000000000..6f14ade0f8f3
--- /dev/null
+++ b/drivers/ipack/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the IPACK bridge device drivers.
3#
4obj-$(CONFIG_IPACK_BUS) += ipack.o
5obj-y += devices/
6obj-y += carriers/
diff --git a/drivers/ipack/carriers/Kconfig b/drivers/ipack/carriers/Kconfig
new file mode 100644
index 000000000000..922ff5c35acc
--- /dev/null
+++ b/drivers/ipack/carriers/Kconfig
@@ -0,0 +1,7 @@
1config BOARD_TPCI200
2 tristate "Support for the TEWS TPCI-200 IndustryPack carrier board"
3 depends on IPACK_BUS
4 depends on PCI
5 help
6 This driver adds support for the TEWS TPCI200 IndustryPack carrier board.
7 default n
diff --git a/drivers/ipack/carriers/Makefile b/drivers/ipack/carriers/Makefile
new file mode 100644
index 000000000000..d8b76459300f
--- /dev/null
+++ b/drivers/ipack/carriers/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_BOARD_TPCI200) += tpci200.o
diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c
new file mode 100644
index 000000000000..c1a19b274c23
--- /dev/null
+++ b/drivers/ipack/carriers/tpci200.c
@@ -0,0 +1,627 @@
1/**
2 * tpci200.c
3 *
4 * driver for the TEWS TPCI-200 device
5 *
6 * Copyright (C) 2009-2012 CERN (www.cern.ch)
7 * Author: Nicolas Serafini, EIC2 SA
8 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; version 2 of the License.
13 */
14
15#include <linux/module.h>
16#include <linux/slab.h>
17#include "tpci200.h"
18
19static const u16 tpci200_status_timeout[] = {
20 TPCI200_A_TIMEOUT,
21 TPCI200_B_TIMEOUT,
22 TPCI200_C_TIMEOUT,
23 TPCI200_D_TIMEOUT,
24};
25
26static const u16 tpci200_status_error[] = {
27 TPCI200_A_ERROR,
28 TPCI200_B_ERROR,
29 TPCI200_C_ERROR,
30 TPCI200_D_ERROR,
31};
32
33static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
34 [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
35 [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
36 [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
37 [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
38 [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
39};
40
41static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
42 [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
43 [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
44 [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
45 [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
46 [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
47};
48
49static struct tpci200_board *check_slot(struct ipack_device *dev)
50{
51 struct tpci200_board *tpci200;
52
53 if (dev == NULL)
54 return NULL;
55
56
57 tpci200 = dev_get_drvdata(dev->bus->parent);
58
59 if (tpci200 == NULL) {
60 dev_info(&dev->dev, "carrier board not found\n");
61 return NULL;
62 }
63
64 if (dev->slot >= TPCI200_NB_SLOT) {
65 dev_info(&dev->dev,
66 "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
67 dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
68 return NULL;
69 }
70
71 return tpci200;
72}
73
74static void tpci200_clear_mask(struct tpci200_board *tpci200,
75 __le16 __iomem *addr, u16 mask)
76{
77 unsigned long flags;
78 spin_lock_irqsave(&tpci200->regs_lock, flags);
79 iowrite16(ioread16(addr) & (~mask), addr);
80 spin_unlock_irqrestore(&tpci200->regs_lock, flags);
81}
82
83static void tpci200_set_mask(struct tpci200_board *tpci200,
84 __le16 __iomem *addr, u16 mask)
85{
86 unsigned long flags;
87 spin_lock_irqsave(&tpci200->regs_lock, flags);
88 iowrite16(ioread16(addr) | mask, addr);
89 spin_unlock_irqrestore(&tpci200->regs_lock, flags);
90}
91
92static void tpci200_unregister(struct tpci200_board *tpci200)
93{
94 free_irq(tpci200->info->pdev->irq, (void *) tpci200);
95
96 pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
97 pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
98
99 pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
100 pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
101 pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
102 pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
103 pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
104
105 pci_disable_device(tpci200->info->pdev);
106 pci_dev_put(tpci200->info->pdev);
107}
108
109static void tpci200_enable_irq(struct tpci200_board *tpci200,
110 int islot)
111{
112 tpci200_set_mask(tpci200,
113 &tpci200->info->interface_regs->control[islot],
114 TPCI200_INT0_EN | TPCI200_INT1_EN);
115}
116
117static void tpci200_disable_irq(struct tpci200_board *tpci200,
118 int islot)
119{
120 tpci200_clear_mask(tpci200,
121 &tpci200->info->interface_regs->control[islot],
122 TPCI200_INT0_EN | TPCI200_INT1_EN);
123}
124
125static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
126{
127 irqreturn_t ret;
128
129 if (!slot_irq)
130 return -ENODEV;
131 ret = slot_irq->handler(slot_irq->arg);
132
133 return ret;
134}
135
136static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
137{
138 struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
139 struct slot_irq *slot_irq;
140 irqreturn_t ret;
141 u16 status_reg;
142 int i;
143
144 /* Read status register */
145 status_reg = ioread16(&tpci200->info->interface_regs->status);
146
147 /* Did we cause the interrupt? */
148 if (!(status_reg & TPCI200_SLOT_INT_MASK))
149 return IRQ_NONE;
150
151 /* callback to the IRQ handler for the corresponding slot */
152 rcu_read_lock();
153 for (i = 0; i < TPCI200_NB_SLOT; i++) {
154 if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
155 continue;
156 slot_irq = rcu_dereference(tpci200->slots[i].irq);
157 ret = tpci200_slot_irq(slot_irq);
158 if (ret == -ENODEV) {
159 dev_info(&tpci200->info->pdev->dev,
160 "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
161 tpci200->number, i);
162 tpci200_disable_irq(tpci200, i);
163 }
164 }
165 rcu_read_unlock();
166
167 return IRQ_HANDLED;
168}
169
170static int tpci200_free_irq(struct ipack_device *dev)
171{
172 struct slot_irq *slot_irq;
173 struct tpci200_board *tpci200;
174
175 tpci200 = check_slot(dev);
176 if (tpci200 == NULL)
177 return -EINVAL;
178
179 if (mutex_lock_interruptible(&tpci200->mutex))
180 return -ERESTARTSYS;
181
182 if (tpci200->slots[dev->slot].irq == NULL) {
183 mutex_unlock(&tpci200->mutex);
184 return -EINVAL;
185 }
186
187 tpci200_disable_irq(tpci200, dev->slot);
188 slot_irq = tpci200->slots[dev->slot].irq;
189 /* uninstall handler */
190 RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
191 synchronize_rcu();
192 kfree(slot_irq);
193 mutex_unlock(&tpci200->mutex);
194 return 0;
195}
196
197static int tpci200_request_irq(struct ipack_device *dev,
198 irqreturn_t (*handler)(void *), void *arg)
199{
200 int res = 0;
201 struct slot_irq *slot_irq;
202 struct tpci200_board *tpci200;
203
204 tpci200 = check_slot(dev);
205 if (tpci200 == NULL)
206 return -EINVAL;
207
208 if (mutex_lock_interruptible(&tpci200->mutex))
209 return -ERESTARTSYS;
210
211 if (tpci200->slots[dev->slot].irq != NULL) {
212 dev_err(&dev->dev,
213 "Slot [%d:%d] IRQ already registered !\n",
214 dev->bus->bus_nr,
215 dev->slot);
216 res = -EINVAL;
217 goto out_unlock;
218 }
219
220 slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
221 if (slot_irq == NULL) {
222 dev_err(&dev->dev,
223 "Slot [%d:%d] unable to allocate memory for IRQ !\n",
224 dev->bus->bus_nr, dev->slot);
225 res = -ENOMEM;
226 goto out_unlock;
227 }
228
229 /*
230 * WARNING: Setup Interrupt Vector in the IndustryPack device
231 * before an IRQ request.
232 * Read the User Manual of your IndustryPack device to know
233 * where to write the vector in memory.
234 */
235 slot_irq->handler = handler;
236 slot_irq->arg = arg;
237 slot_irq->holder = dev;
238
239 rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
240 tpci200_enable_irq(tpci200, dev->slot);
241
242out_unlock:
243 mutex_unlock(&tpci200->mutex);
244 return res;
245}
246
247static int tpci200_register(struct tpci200_board *tpci200)
248{
249 int i;
250 int res;
251 phys_addr_t ioidint_base;
252 unsigned short slot_ctrl;
253
254 if (pci_enable_device(tpci200->info->pdev) < 0)
255 return -ENODEV;
256
257 /* Request IP interface register (Bar 2) */
258 res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
259 "Carrier IP interface registers");
260 if (res) {
261 dev_err(&tpci200->info->pdev->dev,
262 "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
263 tpci200->info->pdev->bus->number,
264 tpci200->info->pdev->devfn);
265 goto out_disable_pci;
266 }
267
268 /* Request IO ID INT space (Bar 3) */
269 res = pci_request_region(tpci200->info->pdev,
270 TPCI200_IO_ID_INT_SPACES_BAR,
271 "Carrier IO ID INT space");
272 if (res) {
273 dev_err(&tpci200->info->pdev->dev,
274 "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
275 tpci200->info->pdev->bus->number,
276 tpci200->info->pdev->devfn);
277 goto out_release_ip_space;
278 }
279
280 /* Request MEM8 space (Bar 5) */
281 res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
282 "Carrier MEM8 space");
283 if (res) {
284 dev_err(&tpci200->info->pdev->dev,
285 "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
286 tpci200->info->pdev->bus->number,
287 tpci200->info->pdev->devfn);
288 goto out_release_ioid_int_space;
289 }
290
291 /* Request MEM16 space (Bar 4) */
292 res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
293 "Carrier MEM16 space");
294 if (res) {
295 dev_err(&tpci200->info->pdev->dev,
296 "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
297 tpci200->info->pdev->bus->number,
298 tpci200->info->pdev->devfn);
299 goto out_release_mem8_space;
300 }
301
302 /* Map internal tpci200 driver user space */
303 tpci200->info->interface_regs =
304 ioremap_nocache(pci_resource_start(tpci200->info->pdev,
305 TPCI200_IP_INTERFACE_BAR),
306 TPCI200_IFACE_SIZE);
307
308 /* Initialize lock that protects interface_regs */
309 spin_lock_init(&tpci200->regs_lock);
310
311 ioidint_base = pci_resource_start(tpci200->info->pdev,
312 TPCI200_IO_ID_INT_SPACES_BAR);
313 tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
314 tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
315 tpci200->mod_mem[IPACK_INT_SPACE] =
316 ioidint_base + TPCI200_INT_SPACE_OFF;
317 tpci200->mod_mem[IPACK_MEM8_SPACE] =
318 pci_resource_start(tpci200->info->pdev,
319 TPCI200_MEM8_SPACE_BAR);
320 tpci200->mod_mem[IPACK_MEM16_SPACE] =
321 pci_resource_start(tpci200->info->pdev,
322 TPCI200_MEM16_SPACE_BAR);
323
324 /* Set the default parameters of the slot
325 * INT0 disabled, level sensitive
326 * INT1 disabled, level sensitive
327 * error interrupt disabled
328 * timeout interrupt disabled
329 * recover time disabled
330 * clock rate 8 MHz
331 */
332 slot_ctrl = 0;
333 for (i = 0; i < TPCI200_NB_SLOT; i++)
334 writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
335
336 res = request_irq(tpci200->info->pdev->irq,
337 tpci200_interrupt, IRQF_SHARED,
338 KBUILD_MODNAME, (void *) tpci200);
339 if (res) {
340 dev_err(&tpci200->info->pdev->dev,
341 "(bn 0x%X, sn 0x%X) unable to register IRQ !",
342 tpci200->info->pdev->bus->number,
343 tpci200->info->pdev->devfn);
344 goto out_release_ioid_int_space;
345 }
346
347 return 0;
348
349out_release_mem8_space:
350 pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
351out_release_ioid_int_space:
352 pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
353out_release_ip_space:
354 pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
355out_disable_pci:
356 pci_disable_device(tpci200->info->pdev);
357 return res;
358}
359
360static int tpci200_get_clockrate(struct ipack_device *dev)
361{
362 struct tpci200_board *tpci200 = check_slot(dev);
363 __le16 __iomem *addr;
364
365 if (!tpci200)
366 return -ENODEV;
367
368 addr = &tpci200->info->interface_regs->control[dev->slot];
369 return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8;
370}
371
372static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
373{
374 struct tpci200_board *tpci200 = check_slot(dev);
375 __le16 __iomem *addr;
376
377 if (!tpci200)
378 return -ENODEV;
379
380 addr = &tpci200->info->interface_regs->control[dev->slot];
381
382 switch (mherz) {
383 case 8:
384 tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
385 break;
386 case 32:
387 tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
388 break;
389 default:
390 return -EINVAL;
391 }
392 return 0;
393}
394
395static int tpci200_get_error(struct ipack_device *dev)
396{
397 struct tpci200_board *tpci200 = check_slot(dev);
398 __le16 __iomem *addr;
399 u16 mask;
400
401 if (!tpci200)
402 return -ENODEV;
403
404 addr = &tpci200->info->interface_regs->status;
405 mask = tpci200_status_error[dev->slot];
406 return (ioread16(addr) & mask) ? 1 : 0;
407}
408
409static int tpci200_get_timeout(struct ipack_device *dev)
410{
411 struct tpci200_board *tpci200 = check_slot(dev);
412 __le16 __iomem *addr;
413 u16 mask;
414
415 if (!tpci200)
416 return -ENODEV;
417
418 addr = &tpci200->info->interface_regs->status;
419 mask = tpci200_status_timeout[dev->slot];
420
421 return (ioread16(addr) & mask) ? 1 : 0;
422}
423
424static int tpci200_reset_timeout(struct ipack_device *dev)
425{
426 struct tpci200_board *tpci200 = check_slot(dev);
427 __le16 __iomem *addr;
428 u16 mask;
429
430 if (!tpci200)
431 return -ENODEV;
432
433 addr = &tpci200->info->interface_regs->status;
434 mask = tpci200_status_timeout[dev->slot];
435
436 iowrite16(mask, addr);
437 return 0;
438}
439
440static void tpci200_uninstall(struct tpci200_board *tpci200)
441{
442 tpci200_unregister(tpci200);
443 kfree(tpci200->slots);
444}
445
446static const struct ipack_bus_ops tpci200_bus_ops = {
447 .request_irq = tpci200_request_irq,
448 .free_irq = tpci200_free_irq,
449 .get_clockrate = tpci200_get_clockrate,
450 .set_clockrate = tpci200_set_clockrate,
451 .get_error = tpci200_get_error,
452 .get_timeout = tpci200_get_timeout,
453 .reset_timeout = tpci200_reset_timeout,
454};
455
456static int tpci200_install(struct tpci200_board *tpci200)
457{
458 int res;
459
460 tpci200->slots = kzalloc(
461 TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL);
462 if (tpci200->slots == NULL)
463 return -ENOMEM;
464
465 res = tpci200_register(tpci200);
466 if (res) {
467 kfree(tpci200->slots);
468 tpci200->slots = NULL;
469 return res;
470 }
471
472 mutex_init(&tpci200->mutex);
473 return 0;
474}
475
476static void tpci200_release_device(struct ipack_device *dev)
477{
478 kfree(dev);
479}
480
481static int tpci200_create_device(struct tpci200_board *tpci200, int i)
482{
483 enum ipack_space space;
484 struct ipack_device *dev =
485 kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
486 if (!dev)
487 return -ENOMEM;
488 dev->slot = i;
489 dev->bus = tpci200->info->ipack_bus;
490 dev->release = tpci200_release_device;
491
492 for (space = 0; space < IPACK_SPACE_COUNT; space++) {
493 dev->region[space].start =
494 tpci200->mod_mem[space]
495 + tpci200_space_interval[space] * i;
496 dev->region[space].size = tpci200_space_size[space];
497 }
498 return ipack_device_register(dev);
499}
500
501static int tpci200_pci_probe(struct pci_dev *pdev,
502 const struct pci_device_id *id)
503{
504 int ret, i;
505 struct tpci200_board *tpci200;
506 u32 reg32;
507
508 tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
509 if (!tpci200)
510 return -ENOMEM;
511
512 tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
513 if (!tpci200->info) {
514 ret = -ENOMEM;
515 goto out_err_info;
516 }
517
518 pci_dev_get(pdev);
519
520 /* Obtain a mapping of the carrier's PCI configuration registers */
521 ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
522 KBUILD_MODNAME " Configuration Memory");
523 if (ret) {
524 dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
525 ret = -EBUSY;
526 goto out_err_pci_request;
527 }
528 tpci200->info->cfg_regs = ioremap_nocache(
529 pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
530 pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
531 if (!tpci200->info->cfg_regs) {
532 dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
533 ret = -EFAULT;
534 goto out_err_ioremap;
535 }
536
537 /* Disable byte swapping for 16 bit IP module access. This will ensure
538 * that the Industrypack big endian byte order is preserved by the
539 * carrier. */
540 reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
541 reg32 |= 1 << LAS_BIT_BIGENDIAN;
542 iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
543
544 reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
545 reg32 |= 1 << LAS_BIT_BIGENDIAN;
546 iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
547
548 /* Save struct pci_dev pointer */
549 tpci200->info->pdev = pdev;
550 tpci200->info->id_table = (struct pci_device_id *)id;
551
552 /* register the device and initialize it */
553 ret = tpci200_install(tpci200);
554 if (ret) {
555 dev_err(&pdev->dev, "error during tpci200 install\n");
556 ret = -ENODEV;
557 goto out_err_install;
558 }
559
560 /* Register the carrier in the industry pack bus driver */
561 tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
562 TPCI200_NB_SLOT,
563 &tpci200_bus_ops);
564 if (!tpci200->info->ipack_bus) {
565 dev_err(&pdev->dev,
566 "error registering the carrier on ipack driver\n");
567 ret = -EFAULT;
568 goto out_err_bus_register;
569 }
570
571 /* save the bus number given by ipack to logging purpose */
572 tpci200->number = tpci200->info->ipack_bus->bus_nr;
573 dev_set_drvdata(&pdev->dev, tpci200);
574
575 for (i = 0; i < TPCI200_NB_SLOT; i++)
576 tpci200_create_device(tpci200, i);
577 return 0;
578
579out_err_bus_register:
580 tpci200_uninstall(tpci200);
581out_err_install:
582 iounmap(tpci200->info->cfg_regs);
583out_err_ioremap:
584 pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
585out_err_pci_request:
586 pci_dev_put(pdev);
587 kfree(tpci200->info);
588out_err_info:
589 kfree(tpci200);
590 return ret;
591}
592
593static void __tpci200_pci_remove(struct tpci200_board *tpci200)
594{
595 ipack_bus_unregister(tpci200->info->ipack_bus);
596 tpci200_uninstall(tpci200);
597
598 kfree(tpci200->info);
599 kfree(tpci200);
600}
601
602static void __devexit tpci200_pci_remove(struct pci_dev *dev)
603{
604 struct tpci200_board *tpci200 = pci_get_drvdata(dev);
605
606 __tpci200_pci_remove(tpci200);
607}
608
609static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = {
610 { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
611 TPCI200_SUBDEVICE_ID },
612 { 0, },
613};
614
615MODULE_DEVICE_TABLE(pci, tpci200_idtable);
616
617static struct pci_driver tpci200_pci_drv = {
618 .name = "tpci200",
619 .id_table = tpci200_idtable,
620 .probe = tpci200_pci_probe,
621 .remove = __devexit_p(tpci200_pci_remove),
622};
623
624module_pci_driver(tpci200_pci_drv);
625
626MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
627MODULE_LICENSE("GPL");
diff --git a/drivers/ipack/carriers/tpci200.h b/drivers/ipack/carriers/tpci200.h
new file mode 100644
index 000000000000..8d9be277b34d
--- /dev/null
+++ b/drivers/ipack/carriers/tpci200.h
@@ -0,0 +1,168 @@
1/**
2 * tpci200.h
3 *
4 * driver for the carrier TEWS TPCI-200
5 *
6 * Copyright (C) 2009-2012 CERN (www.cern.ch)
7 * Author: Nicolas Serafini, EIC2 SA
8 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; version 2 of the License.
13 */
14
15#ifndef _TPCI200_H_
16#define _TPCI200_H_
17
18#include <linux/limits.h>
19#include <linux/pci.h>
20#include <linux/spinlock.h>
21#include <linux/swab.h>
22#include <linux/io.h>
23
24#include "../ipack.h"
25
26#define TPCI200_NB_SLOT 0x4
27#define TPCI200_NB_BAR 0x6
28
29#define TPCI200_VENDOR_ID 0x1498
30#define TPCI200_DEVICE_ID 0x30C8
31#define TPCI200_SUBVENDOR_ID 0x1498
32#define TPCI200_SUBDEVICE_ID 0x300A
33
34#define TPCI200_CFG_MEM_BAR 0
35#define TPCI200_IP_INTERFACE_BAR 2
36#define TPCI200_IO_ID_INT_SPACES_BAR 3
37#define TPCI200_MEM16_SPACE_BAR 4
38#define TPCI200_MEM8_SPACE_BAR 5
39
40struct tpci200_regs {
41 __le16 revision;
42 /* writes to control should occur with the mutex held to protect
43 * read-modify-write operations */
44 __le16 control[4];
45 __le16 reset;
46 __le16 status;
47 u8 reserved[242];
48} __packed;
49
50#define TPCI200_IFACE_SIZE 0x100
51
52#define TPCI200_IO_SPACE_OFF 0x0000
53#define TPCI200_IO_SPACE_INTERVAL 0x0100
54#define TPCI200_IO_SPACE_SIZE 0x0080
55#define TPCI200_ID_SPACE_OFF 0x0080
56#define TPCI200_ID_SPACE_INTERVAL 0x0100
57#define TPCI200_ID_SPACE_SIZE 0x0040
58#define TPCI200_INT_SPACE_OFF 0x00C0
59#define TPCI200_INT_SPACE_INTERVAL 0x0100
60#define TPCI200_INT_SPACE_SIZE 0x0040
61#define TPCI200_IOIDINT_SIZE 0x0400
62
63#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000
64#define TPCI200_MEM8_SPACE_SIZE 0x00400000
65#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000
66#define TPCI200_MEM16_SPACE_SIZE 0x00800000
67
68/* control field in tpci200_regs */
69#define TPCI200_INT0_EN 0x0040
70#define TPCI200_INT1_EN 0x0080
71#define TPCI200_INT0_EDGE 0x0010
72#define TPCI200_INT1_EDGE 0x0020
73#define TPCI200_ERR_INT_EN 0x0008
74#define TPCI200_TIME_INT_EN 0x0004
75#define TPCI200_RECOVER_EN 0x0002
76#define TPCI200_CLK32 0x0001
77
78/* reset field in tpci200_regs */
79#define TPCI200_A_RESET 0x0001
80#define TPCI200_B_RESET 0x0002
81#define TPCI200_C_RESET 0x0004
82#define TPCI200_D_RESET 0x0008
83
84/* status field in tpci200_regs */
85#define TPCI200_A_TIMEOUT 0x1000
86#define TPCI200_B_TIMEOUT 0x2000
87#define TPCI200_C_TIMEOUT 0x4000
88#define TPCI200_D_TIMEOUT 0x8000
89
90#define TPCI200_A_ERROR 0x0100
91#define TPCI200_B_ERROR 0x0200
92#define TPCI200_C_ERROR 0x0400
93#define TPCI200_D_ERROR 0x0800
94
95#define TPCI200_A_INT0 0x0001
96#define TPCI200_A_INT1 0x0002
97#define TPCI200_B_INT0 0x0004
98#define TPCI200_B_INT1 0x0008
99#define TPCI200_C_INT0 0x0010
100#define TPCI200_C_INT1 0x0020
101#define TPCI200_D_INT0 0x0040
102#define TPCI200_D_INT1 0x0080
103
104#define TPCI200_SLOT_INT_MASK 0x00FF
105
106/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */
107#define LAS1_DESC 0x2C
108#define LAS2_DESC 0x30
109
110/* Bits in the LAS?_DESC registers */
111#define LAS_BIT_BIGENDIAN 24
112
113#define VME_IOID_SPACE "IOID"
114#define VME_MEM_SPACE "MEM"
115
116/**
117 * struct slot_irq - slot IRQ definition.
118 * @vector Vector number
119 * @handler Handler called when IRQ arrives
120 * @arg Handler argument
121 *
122 */
123struct slot_irq {
124 struct ipack_device *holder;
125 int vector;
126 irqreturn_t (*handler)(void *);
127 void *arg;
128};
129
130/**
131 * struct tpci200_slot - data specific to the tpci200 slot.
132 * @slot_id Slot identification gived to external interface
133 * @irq Slot IRQ infos
134 * @io_phys IO physical base address register of the slot
135 * @id_phys ID physical base address register of the slot
136 * @int_phys INT physical base address register of the slot
137 * @mem_phys MEM physical base address register of the slot
138 *
139 */
140struct tpci200_slot {
141 struct slot_irq *irq;
142};
143
144/**
145 * struct tpci200_infos - informations specific of the TPCI200 tpci200.
146 * @pci_dev PCI device
147 * @interface_regs Pointer to IP interface space (Bar 2)
148 * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3)
149 * @mem8_space Pointer to MEM space (Bar 4)
150 *
151 */
152struct tpci200_infos {
153 struct pci_dev *pdev;
154 struct pci_device_id *id_table;
155 struct tpci200_regs __iomem *interface_regs;
156 void __iomem *cfg_regs;
157 struct ipack_bus_device *ipack_bus;
158};
159struct tpci200_board {
160 unsigned int number;
161 struct mutex mutex;
162 spinlock_t regs_lock;
163 struct tpci200_slot *slots;
164 struct tpci200_infos *info;
165 phys_addr_t mod_mem[IPACK_SPACE_COUNT];
166};
167
168#endif /* _TPCI200_H_ */
diff --git a/drivers/ipack/devices/Kconfig b/drivers/ipack/devices/Kconfig
new file mode 100644
index 000000000000..0b82fdc198c0
--- /dev/null
+++ b/drivers/ipack/devices/Kconfig
@@ -0,0 +1,6 @@
1config SERIAL_IPOCTAL
2 tristate "IndustryPack IP-OCTAL uart support"
3 depends on IPACK_BUS
4 help
5 This driver supports the IPOCTAL serial port device for the IndustryPack bus.
6 default n
diff --git a/drivers/ipack/devices/Makefile b/drivers/ipack/devices/Makefile
new file mode 100644
index 000000000000..6de18bda4a9a
--- /dev/null
+++ b/drivers/ipack/devices/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SERIAL_IPOCTAL) += ipoctal.o
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
new file mode 100644
index 000000000000..783f120338d1
--- /dev/null
+++ b/drivers/ipack/devices/ipoctal.c
@@ -0,0 +1,751 @@
1/**
2 * ipoctal.c
3 *
4 * driver for the GE IP-OCTAL boards
5 *
6 * Copyright (C) 2009-2012 CERN (www.cern.ch)
7 * Author: Nicolas Serafini, EIC2 SA
8 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; version 2 of the License.
13 */
14
15#include <linux/device.h>
16#include <linux/module.h>
17#include <linux/interrupt.h>
18#include <linux/sched.h>
19#include <linux/tty.h>
20#include <linux/serial.h>
21#include <linux/tty_flip.h>
22#include <linux/slab.h>
23#include <linux/atomic.h>
24#include <linux/io.h>
25#include "../ipack.h"
26#include "ipoctal.h"
27#include "scc2698.h"
28
29#define IP_OCTAL_ID_SPACE_VECTOR 0x41
30#define IP_OCTAL_NB_BLOCKS 4
31
32static const struct tty_operations ipoctal_fops;
33
34struct ipoctal_channel {
35 struct ipoctal_stats stats;
36 unsigned int nb_bytes;
37 wait_queue_head_t queue;
38 spinlock_t lock;
39 unsigned int pointer_read;
40 unsigned int pointer_write;
41 atomic_t open;
42 struct tty_port tty_port;
43 union scc2698_channel __iomem *regs;
44 union scc2698_block __iomem *block_regs;
45 unsigned int board_id;
46 unsigned char *board_write;
47 u8 isr_rx_rdy_mask;
48 u8 isr_tx_rdy_mask;
49};
50
51struct ipoctal {
52 struct ipack_device *dev;
53 unsigned int board_id;
54 struct ipoctal_channel channel[NR_CHANNELS];
55 unsigned char write;
56 struct tty_driver *tty_drv;
57 u8 __iomem *mem8_space;
58 u8 __iomem *int_space;
59};
60
61static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
62{
63 struct ipoctal_channel *channel;
64
65 channel = dev_get_drvdata(tty->dev);
66
67 iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
68 return 0;
69}
70
71static int ipoctal_open(struct tty_struct *tty, struct file *file)
72{
73 int res;
74 struct ipoctal_channel *channel;
75
76 channel = dev_get_drvdata(tty->dev);
77
78 if (atomic_read(&channel->open))
79 return -EBUSY;
80
81 tty->driver_data = channel;
82
83 res = tty_port_open(&channel->tty_port, tty, file);
84 if (res)
85 return res;
86
87 atomic_inc(&channel->open);
88 return 0;
89}
90
91static void ipoctal_reset_stats(struct ipoctal_stats *stats)
92{
93 stats->tx = 0;
94 stats->rx = 0;
95 stats->rcv_break = 0;
96 stats->framing_err = 0;
97 stats->overrun_err = 0;
98 stats->parity_err = 0;
99}
100
101static void ipoctal_free_channel(struct ipoctal_channel *channel)
102{
103 ipoctal_reset_stats(&channel->stats);
104 channel->pointer_read = 0;
105 channel->pointer_write = 0;
106 channel->nb_bytes = 0;
107}
108
109static void ipoctal_close(struct tty_struct *tty, struct file *filp)
110{
111 struct ipoctal_channel *channel = tty->driver_data;
112
113 tty_port_close(&channel->tty_port, tty, filp);
114
115 if (atomic_dec_and_test(&channel->open))
116 ipoctal_free_channel(channel);
117}
118
119static int ipoctal_get_icount(struct tty_struct *tty,
120 struct serial_icounter_struct *icount)
121{
122 struct ipoctal_channel *channel = tty->driver_data;
123
124 icount->cts = 0;
125 icount->dsr = 0;
126 icount->rng = 0;
127 icount->dcd = 0;
128 icount->rx = channel->stats.rx;
129 icount->tx = channel->stats.tx;
130 icount->frame = channel->stats.framing_err;
131 icount->parity = channel->stats.parity_err;
132 icount->brk = channel->stats.rcv_break;
133 return 0;
134}
135
136static void ipoctal_irq_rx(struct ipoctal_channel *channel,
137 struct tty_struct *tty, u8 sr)
138{
139 unsigned char value;
140 unsigned char flag = TTY_NORMAL;
141 u8 isr;
142
143 do {
144 value = ioread8(&channel->regs->r.rhr);
145 /* Error: count statistics */
146 if (sr & SR_ERROR) {
147 iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
148
149 if (sr & SR_OVERRUN_ERROR) {
150 channel->stats.overrun_err++;
151 /* Overrun doesn't affect the current character*/
152 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
153 }
154 if (sr & SR_PARITY_ERROR) {
155 channel->stats.parity_err++;
156 flag = TTY_PARITY;
157 }
158 if (sr & SR_FRAMING_ERROR) {
159 channel->stats.framing_err++;
160 flag = TTY_FRAME;
161 }
162 if (sr & SR_RECEIVED_BREAK) {
163 iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr);
164 channel->stats.rcv_break++;
165 flag = TTY_BREAK;
166 }
167 }
168 tty_insert_flip_char(tty, value, flag);
169
170 /* Check if there are more characters in RX FIFO
171 * If there are more, the isr register for this channel
172 * has enabled the RxRDY|FFULL bit.
173 */
174 isr = ioread8(&channel->block_regs->r.isr);
175 sr = ioread8(&channel->regs->r.sr);
176 } while (isr & channel->isr_rx_rdy_mask);
177
178 tty_flip_buffer_push(tty);
179}
180
181static void ipoctal_irq_tx(struct ipoctal_channel *channel)
182{
183 unsigned char value;
184 unsigned int *pointer_write = &channel->pointer_write;
185
186 if (channel->nb_bytes <= 0) {
187 channel->nb_bytes = 0;
188 return;
189 }
190
191 value = channel->tty_port.xmit_buf[*pointer_write];
192 iowrite8(value, &channel->regs->w.thr);
193 channel->stats.tx++;
194 (*pointer_write)++;
195 *pointer_write = *pointer_write % PAGE_SIZE;
196 channel->nb_bytes--;
197
198 if ((channel->nb_bytes == 0) &&
199 (waitqueue_active(&channel->queue))) {
200
201 if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
202 *channel->board_write = 1;
203 wake_up_interruptible(&channel->queue);
204 }
205 }
206}
207
208static void ipoctal_irq_channel(struct ipoctal_channel *channel)
209{
210 u8 isr, sr;
211 struct tty_struct *tty;
212
213 /* If there is no client, skip the check */
214 if (!atomic_read(&channel->open))
215 return;
216
217 tty = tty_port_tty_get(&channel->tty_port);
218 if (!tty)
219 return;
220 /* The HW is organized in pair of channels. See which register we need
221 * to read from */
222 isr = ioread8(&channel->block_regs->r.isr);
223 sr = ioread8(&channel->regs->r.sr);
224
225 /* In case of RS-485, change from TX to RX when finishing TX.
226 * Half-duplex. */
227 if ((channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
228 (sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) {
229 iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
230 iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
231 iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
232 *channel->board_write = 1;
233 wake_up_interruptible(&channel->queue);
234 }
235
236 /* RX data */
237 if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY))
238 ipoctal_irq_rx(channel, tty, sr);
239
240 /* TX of each character */
241 if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
242 ipoctal_irq_tx(channel);
243
244 tty_flip_buffer_push(tty);
245 tty_kref_put(tty);
246}
247
248static irqreturn_t ipoctal_irq_handler(void *arg)
249{
250 unsigned int i;
251 struct ipoctal *ipoctal = (struct ipoctal *) arg;
252
253 /* Check all channels */
254 for (i = 0; i < NR_CHANNELS; i++)
255 ipoctal_irq_channel(&ipoctal->channel[i]);
256
257 /* Clear the IPack device interrupt */
258 readw(ipoctal->int_space + ACK_INT_REQ0);
259 readw(ipoctal->int_space + ACK_INT_REQ1);
260
261 return IRQ_HANDLED;
262}
263
264static const struct tty_port_operations ipoctal_tty_port_ops = {
265 .dtr_rts = NULL,
266 .activate = ipoctal_port_activate,
267};
268
269static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
270 unsigned int slot)
271{
272 int res;
273 int i;
274 struct tty_driver *tty;
275 char name[20];
276 struct ipoctal_channel *channel;
277 struct ipack_region *region;
278 void __iomem *addr;
279 union scc2698_channel __iomem *chan_regs;
280 union scc2698_block __iomem *block_regs;
281
282 ipoctal->board_id = ipoctal->dev->id_device;
283
284 region = &ipoctal->dev->region[IPACK_IO_SPACE];
285 addr = devm_ioremap_nocache(&ipoctal->dev->dev,
286 region->start, region->size);
287 if (!addr) {
288 dev_err(&ipoctal->dev->dev,
289 "Unable to map slot [%d:%d] IO space!\n",
290 bus_nr, slot);
291 return -EADDRNOTAVAIL;
292 }
293 /* Save the virtual address to access the registers easily */
294 chan_regs =
295 (union scc2698_channel __iomem *) addr;
296 block_regs =
297 (union scc2698_block __iomem *) addr;
298
299 region = &ipoctal->dev->region[IPACK_INT_SPACE];
300 ipoctal->int_space =
301 devm_ioremap_nocache(&ipoctal->dev->dev,
302 region->start, region->size);
303 if (!ipoctal->int_space) {
304 dev_err(&ipoctal->dev->dev,
305 "Unable to map slot [%d:%d] INT space!\n",
306 bus_nr, slot);
307 return -EADDRNOTAVAIL;
308 }
309
310 region = &ipoctal->dev->region[IPACK_MEM8_SPACE];
311 ipoctal->mem8_space =
312 devm_ioremap_nocache(&ipoctal->dev->dev,
313 region->start, 0x8000);
314 if (!addr) {
315 dev_err(&ipoctal->dev->dev,
316 "Unable to map slot [%d:%d] MEM8 space!\n",
317 bus_nr, slot);
318 return -EADDRNOTAVAIL;
319 }
320
321
322 /* Disable RX and TX before touching anything */
323 for (i = 0; i < NR_CHANNELS ; i++) {
324 struct ipoctal_channel *channel = &ipoctal->channel[i];
325 channel->regs = chan_regs + i;
326 channel->block_regs = block_regs + (i >> 1);
327 channel->board_write = &ipoctal->write;
328 channel->board_id = ipoctal->board_id;
329 if (i & 1) {
330 channel->isr_tx_rdy_mask = ISR_TxRDY_B;
331 channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B;
332 } else {
333 channel->isr_tx_rdy_mask = ISR_TxRDY_A;
334 channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A;
335 }
336
337 iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
338 iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
339 iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
340 iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY,
341 &channel->regs->w.mr); /* mr1 */
342 iowrite8(0, &channel->regs->w.mr); /* mr2 */
343 iowrite8(TX_CLK_9600 | RX_CLK_9600, &channel->regs->w.csr);
344 }
345
346 for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
347 iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr);
348 iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN,
349 &block_regs[i].w.opcr);
350 iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A |
351 IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B,
352 &block_regs[i].w.imr);
353 }
354
355 /*
356 * IP-OCTAL has different addresses to copy its IRQ vector.
357 * Depending of the carrier these addresses are accesible or not.
358 * More info in the datasheet.
359 */
360 ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
361 ipoctal_irq_handler, ipoctal);
362 /* Dummy write */
363 iowrite8(1, ipoctal->mem8_space + 1);
364
365 /* Register the TTY device */
366
367 /* Each IP-OCTAL channel is a TTY port */
368 tty = alloc_tty_driver(NR_CHANNELS);
369
370 if (!tty)
371 return -ENOMEM;
372
373 /* Fill struct tty_driver with ipoctal data */
374 tty->owner = THIS_MODULE;
375 tty->driver_name = KBUILD_MODNAME;
376 sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot);
377 tty->name = name;
378 tty->major = 0;
379
380 tty->minor_start = 0;
381 tty->type = TTY_DRIVER_TYPE_SERIAL;
382 tty->subtype = SERIAL_TYPE_NORMAL;
383 tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
384 tty->init_termios = tty_std_termios;
385 tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
386 tty->init_termios.c_ispeed = 9600;
387 tty->init_termios.c_ospeed = 9600;
388
389 tty_set_operations(tty, &ipoctal_fops);
390 res = tty_register_driver(tty);
391 if (res) {
392 dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
393 put_tty_driver(tty);
394 return res;
395 }
396
397 /* Save struct tty_driver for use it when uninstalling the device */
398 ipoctal->tty_drv = tty;
399
400 for (i = 0; i < NR_CHANNELS; i++) {
401 struct device *tty_dev;
402
403 channel = &ipoctal->channel[i];
404 tty_port_init(&channel->tty_port);
405 tty_port_alloc_xmit_buf(&channel->tty_port);
406 channel->tty_port.ops = &ipoctal_tty_port_ops;
407
408 ipoctal_reset_stats(&channel->stats);
409 channel->nb_bytes = 0;
410 init_waitqueue_head(&channel->queue);
411
412 spin_lock_init(&channel->lock);
413 channel->pointer_read = 0;
414 channel->pointer_write = 0;
415 tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL);
416 if (IS_ERR(tty_dev)) {
417 dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
418 continue;
419 }
420 dev_set_drvdata(tty_dev, channel);
421
422 /*
423 * Enable again the RX. TX will be enabled when
424 * there is something to send
425 */
426 iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
427 }
428
429 return 0;
430}
431
432static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
433 const unsigned char *buf,
434 int count)
435{
436 unsigned long flags;
437 int i;
438 unsigned int *pointer_read = &channel->pointer_read;
439
440 /* Copy the bytes from the user buffer to the internal one */
441 for (i = 0; i < count; i++) {
442 if (i <= (PAGE_SIZE - channel->nb_bytes)) {
443 spin_lock_irqsave(&channel->lock, flags);
444 channel->tty_port.xmit_buf[*pointer_read] = buf[i];
445 *pointer_read = (*pointer_read + 1) % PAGE_SIZE;
446 channel->nb_bytes++;
447 spin_unlock_irqrestore(&channel->lock, flags);
448 } else {
449 break;
450 }
451 }
452 return i;
453}
454
455static int ipoctal_write_tty(struct tty_struct *tty,
456 const unsigned char *buf, int count)
457{
458 struct ipoctal_channel *channel = tty->driver_data;
459 unsigned int char_copied;
460
461 char_copied = ipoctal_copy_write_buffer(channel, buf, count);
462
463 /* As the IP-OCTAL 485 only supports half duplex, do it manually */
464 if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
465 iowrite8(CR_DISABLE_RX, &channel->regs->w.cr);
466 iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr);
467 }
468
469 /*
470 * Send a packet and then disable TX to avoid failure after several send
471 * operations
472 */
473 iowrite8(CR_ENABLE_TX, &channel->regs->w.cr);
474 wait_event_interruptible(channel->queue, *channel->board_write);
475 iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
476
477 *channel->board_write = 0;
478 return char_copied;
479}
480
481static int ipoctal_write_room(struct tty_struct *tty)
482{
483 struct ipoctal_channel *channel = tty->driver_data;
484
485 return PAGE_SIZE - channel->nb_bytes;
486}
487
488static int ipoctal_chars_in_buffer(struct tty_struct *tty)
489{
490 struct ipoctal_channel *channel = tty->driver_data;
491
492 return channel->nb_bytes;
493}
494
495static void ipoctal_set_termios(struct tty_struct *tty,
496 struct ktermios *old_termios)
497{
498 unsigned int cflag;
499 unsigned char mr1 = 0;
500 unsigned char mr2 = 0;
501 unsigned char csr = 0;
502 struct ipoctal_channel *channel = tty->driver_data;
503 speed_t baud;
504
505 cflag = tty->termios.c_cflag;
506
507 /* Disable and reset everything before change the setup */
508 iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
509 iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
510 iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
511 iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
512 iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr);
513
514 /* Set Bits per chars */
515 switch (cflag & CSIZE) {
516 case CS6:
517 mr1 |= MR1_CHRL_6_BITS;
518 break;
519 case CS7:
520 mr1 |= MR1_CHRL_7_BITS;
521 break;
522 case CS8:
523 default:
524 mr1 |= MR1_CHRL_8_BITS;
525 /* By default, select CS8 */
526 tty->termios.c_cflag = (cflag & ~CSIZE) | CS8;
527 break;
528 }
529
530 /* Set Parity */
531 if (cflag & PARENB)
532 if (cflag & PARODD)
533 mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD;
534 else
535 mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN;
536 else
537 mr1 |= MR1_PARITY_OFF;
538
539 /* Mark or space parity is not supported */
540 tty->termios.c_cflag &= ~CMSPAR;
541
542 /* Set stop bits */
543 if (cflag & CSTOPB)
544 mr2 |= MR2_STOP_BITS_LENGTH_2;
545 else
546 mr2 |= MR2_STOP_BITS_LENGTH_1;
547
548 /* Set the flow control */
549 switch (channel->board_id) {
550 case IPACK1_DEVICE_ID_SBS_OCTAL_232:
551 if (cflag & CRTSCTS) {
552 mr1 |= MR1_RxRTS_CONTROL_ON;
553 mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON;
554 } else {
555 mr1 |= MR1_RxRTS_CONTROL_OFF;
556 mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
557 }
558 break;
559 case IPACK1_DEVICE_ID_SBS_OCTAL_422:
560 mr1 |= MR1_RxRTS_CONTROL_OFF;
561 mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
562 break;
563 case IPACK1_DEVICE_ID_SBS_OCTAL_485:
564 mr1 |= MR1_RxRTS_CONTROL_OFF;
565 mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF;
566 break;
567 default:
568 return;
569 break;
570 }
571
572 baud = tty_get_baud_rate(tty);
573 tty_termios_encode_baud_rate(&tty->termios, baud, baud);
574
575 /* Set baud rate */
576 switch (baud) {
577 case 75:
578 csr |= TX_CLK_75 | RX_CLK_75;
579 break;
580 case 110:
581 csr |= TX_CLK_110 | RX_CLK_110;
582 break;
583 case 150:
584 csr |= TX_CLK_150 | RX_CLK_150;
585 break;
586 case 300:
587 csr |= TX_CLK_300 | RX_CLK_300;
588 break;
589 case 600:
590 csr |= TX_CLK_600 | RX_CLK_600;
591 break;
592 case 1200:
593 csr |= TX_CLK_1200 | RX_CLK_1200;
594 break;
595 case 1800:
596 csr |= TX_CLK_1800 | RX_CLK_1800;
597 break;
598 case 2000:
599 csr |= TX_CLK_2000 | RX_CLK_2000;
600 break;
601 case 2400:
602 csr |= TX_CLK_2400 | RX_CLK_2400;
603 break;
604 case 4800:
605 csr |= TX_CLK_4800 | RX_CLK_4800;
606 break;
607 case 9600:
608 csr |= TX_CLK_9600 | RX_CLK_9600;
609 break;
610 case 19200:
611 csr |= TX_CLK_19200 | RX_CLK_19200;
612 break;
613 case 38400:
614 default:
615 csr |= TX_CLK_38400 | RX_CLK_38400;
616 /* In case of default, we establish 38400 bps */
617 tty_termios_encode_baud_rate(&tty->termios, 38400, 38400);
618 break;
619 }
620
621 mr1 |= MR1_ERROR_CHAR;
622 mr1 |= MR1_RxINT_RxRDY;
623
624 /* Write the control registers */
625 iowrite8(mr1, &channel->regs->w.mr);
626 iowrite8(mr2, &channel->regs->w.mr);
627 iowrite8(csr, &channel->regs->w.csr);
628
629 /* Enable again the RX */
630 iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
631}
632
633static void ipoctal_hangup(struct tty_struct *tty)
634{
635 unsigned long flags;
636 struct ipoctal_channel *channel = tty->driver_data;
637
638 if (channel == NULL)
639 return;
640
641 spin_lock_irqsave(&channel->lock, flags);
642 channel->nb_bytes = 0;
643 channel->pointer_read = 0;
644 channel->pointer_write = 0;
645 spin_unlock_irqrestore(&channel->lock, flags);
646
647 tty_port_hangup(&channel->tty_port);
648
649 iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
650 iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
651 iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
652 iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
653 iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr);
654
655 clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
656 wake_up_interruptible(&channel->tty_port.open_wait);
657}
658
659static const struct tty_operations ipoctal_fops = {
660 .ioctl = NULL,
661 .open = ipoctal_open,
662 .close = ipoctal_close,
663 .write = ipoctal_write_tty,
664 .set_termios = ipoctal_set_termios,
665 .write_room = ipoctal_write_room,
666 .chars_in_buffer = ipoctal_chars_in_buffer,
667 .get_icount = ipoctal_get_icount,
668 .hangup = ipoctal_hangup,
669};
670
671static int ipoctal_probe(struct ipack_device *dev)
672{
673 int res;
674 struct ipoctal *ipoctal;
675
676 ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL);
677 if (ipoctal == NULL)
678 return -ENOMEM;
679
680 ipoctal->dev = dev;
681 res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot);
682 if (res)
683 goto out_uninst;
684
685 dev_set_drvdata(&dev->dev, ipoctal);
686 return 0;
687
688out_uninst:
689 kfree(ipoctal);
690 return res;
691}
692
693static void __ipoctal_remove(struct ipoctal *ipoctal)
694{
695 int i;
696
697 ipoctal->dev->bus->ops->free_irq(ipoctal->dev);
698
699 for (i = 0; i < NR_CHANNELS; i++) {
700 struct ipoctal_channel *channel = &ipoctal->channel[i];
701 tty_unregister_device(ipoctal->tty_drv, i);
702 tty_port_free_xmit_buf(&channel->tty_port);
703 }
704
705 tty_unregister_driver(ipoctal->tty_drv);
706 put_tty_driver(ipoctal->tty_drv);
707 kfree(ipoctal);
708}
709
710static void ipoctal_remove(struct ipack_device *idev)
711{
712 __ipoctal_remove(dev_get_drvdata(&idev->dev));
713}
714
715static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
716 { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
717 IPACK1_DEVICE_ID_SBS_OCTAL_232) },
718 { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
719 IPACK1_DEVICE_ID_SBS_OCTAL_422) },
720 { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
721 IPACK1_DEVICE_ID_SBS_OCTAL_485) },
722 { 0, },
723};
724
725MODULE_DEVICE_TABLE(ipack, ipoctal_ids);
726
727static const struct ipack_driver_ops ipoctal_drv_ops = {
728 .probe = ipoctal_probe,
729 .remove = ipoctal_remove,
730};
731
732static struct ipack_driver driver = {
733 .ops = &ipoctal_drv_ops,
734 .id_table = ipoctal_ids,
735};
736
737static int __init ipoctal_init(void)
738{
739 return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME);
740}
741
742static void __exit ipoctal_exit(void)
743{
744 ipack_driver_unregister(&driver);
745}
746
747MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver");
748MODULE_LICENSE("GPL");
749
750module_init(ipoctal_init);
751module_exit(ipoctal_exit);
diff --git a/drivers/ipack/devices/ipoctal.h b/drivers/ipack/devices/ipoctal.h
new file mode 100644
index 000000000000..28f1c4233154
--- /dev/null
+++ b/drivers/ipack/devices/ipoctal.h
@@ -0,0 +1,42 @@
1/**
2 * ipoctal.h
3 *
4 * driver for the IPOCTAL boards
5
6 * Copyright (C) 2009-2012 CERN (www.cern.ch)
7 * Author: Nicolas Serafini, EIC2 SA
8 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; version 2 of the License.
13 */
14
15#ifndef _IPOCTAL_H
16#define _IPOCTAL_H_
17
18#define NR_CHANNELS 8
19#define IPOCTAL_MAX_BOARDS 16
20#define MAX_DEVICES (NR_CHANNELS * IPOCTAL_MAX_BOARDS)
21#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
22
23/**
24 * struct ipoctal_stats -- Stats since last reset
25 *
26 * @tx: Number of transmitted bytes
27 * @rx: Number of received bytes
28 * @overrun: Number of overrun errors
29 * @parity_err: Number of parity errors
30 * @framing_err: Number of framing errors
31 * @rcv_break: Number of break received
32 */
33struct ipoctal_stats {
34 unsigned long tx;
35 unsigned long rx;
36 unsigned long overrun_err;
37 unsigned long parity_err;
38 unsigned long framing_err;
39 unsigned long rcv_break;
40};
41
42#endif /* _IPOCTAL_H_ */
diff --git a/drivers/ipack/devices/scc2698.h b/drivers/ipack/devices/scc2698.h
new file mode 100644
index 000000000000..2ad6acd513fa
--- /dev/null
+++ b/drivers/ipack/devices/scc2698.h
@@ -0,0 +1,228 @@
1/*
2 * scc2698.h
3 *
4 * driver for the IPOCTAL boards
5 *
6 * Copyright (C) 2009-2012 CERN (www.cern.ch)
7 * Author: Nicolas Serafini, EIC2 SA
8 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; version 2 of the License.
13 */
14
15#ifndef SCC2698_H_
16#define SCC2698_H_
17
18/*
19 * union scc2698_channel - Channel access to scc2698 IO
20 *
21 * dn value are only spacer.
22 *
23 */
24union scc2698_channel {
25 struct {
26 u8 d0, mr; /* Mode register 1/2*/
27 u8 d1, sr; /* Status register */
28 u8 d2, r1; /* reserved */
29 u8 d3, rhr; /* Receive holding register (R) */
30 u8 junk[8]; /* other crap for block control */
31 } __packed r; /* Read access */
32 struct {
33 u8 d0, mr; /* Mode register 1/2 */
34 u8 d1, csr; /* Clock select register */
35 u8 d2, cr; /* Command register */
36 u8 d3, thr; /* Transmit holding register */
37 u8 junk[8]; /* other crap for block control */
38 } __packed w; /* Write access */
39};
40
41/*
42 * union scc2698_block - Block access to scc2698 IO
43 *
44 * The scc2698 contain 4 block.
45 * Each block containt two channel a and b.
46 * dn value are only spacer.
47 *
48 */
49union scc2698_block {
50 struct {
51 u8 d0, mra; /* Mode register 1/2 (a) */
52 u8 d1, sra; /* Status register (a) */
53 u8 d2, r1; /* reserved */
54 u8 d3, rhra; /* Receive holding register (a) */
55 u8 d4, ipcr; /* Input port change register of block */
56 u8 d5, isr; /* Interrupt status register of block */
57 u8 d6, ctur; /* Counter timer upper register of block */
58 u8 d7, ctlr; /* Counter timer lower register of block */
59 u8 d8, mrb; /* Mode register 1/2 (b) */
60 u8 d9, srb; /* Status register (b) */
61 u8 da, r2; /* reserved */
62 u8 db, rhrb; /* Receive holding register (b) */
63 u8 dc, r3; /* reserved */
64 u8 dd, ip; /* Input port register of block */
65 u8 de, ctg; /* Start counter timer of block */
66 u8 df, cts; /* Stop counter timer of block */
67 } __packed r; /* Read access */
68 struct {
69 u8 d0, mra; /* Mode register 1/2 (a) */
70 u8 d1, csra; /* Clock select register (a) */
71 u8 d2, cra; /* Command register (a) */
72 u8 d3, thra; /* Transmit holding register (a) */
73 u8 d4, acr; /* Auxiliary control register of block */
74 u8 d5, imr; /* Interrupt mask register of block */
75 u8 d6, ctu; /* Counter timer upper register of block */
76 u8 d7, ctl; /* Counter timer lower register of block */
77 u8 d8, mrb; /* Mode register 1/2 (b) */
78 u8 d9, csrb; /* Clock select register (a) */
79 u8 da, crb; /* Command register (b) */
80 u8 db, thrb; /* Transmit holding register (b) */
81 u8 dc, r1; /* reserved */
82 u8 dd, opcr; /* Output port configuration register of block */
83 u8 de, r2; /* reserved */
84 u8 df, r3; /* reserved */
85 } __packed w; /* Write access */
86};
87
88#define MR1_CHRL_5_BITS (0x0 << 0)
89#define MR1_CHRL_6_BITS (0x1 << 0)
90#define MR1_CHRL_7_BITS (0x2 << 0)
91#define MR1_CHRL_8_BITS (0x3 << 0)
92#define MR1_PARITY_EVEN (0x1 << 2)
93#define MR1_PARITY_ODD (0x0 << 2)
94#define MR1_PARITY_ON (0x0 << 3)
95#define MR1_PARITY_FORCE (0x1 << 3)
96#define MR1_PARITY_OFF (0x2 << 3)
97#define MR1_PARITY_SPECIAL (0x3 << 3)
98#define MR1_ERROR_CHAR (0x0 << 5)
99#define MR1_ERROR_BLOCK (0x1 << 5)
100#define MR1_RxINT_RxRDY (0x0 << 6)
101#define MR1_RxINT_FFULL (0x1 << 6)
102#define MR1_RxRTS_CONTROL_ON (0x1 << 7)
103#define MR1_RxRTS_CONTROL_OFF (0x0 << 7)
104
105#define MR2_STOP_BITS_LENGTH_1 (0x7 << 0)
106#define MR2_STOP_BITS_LENGTH_2 (0xF << 0)
107#define MR2_CTS_ENABLE_TX_ON (0x1 << 4)
108#define MR2_CTS_ENABLE_TX_OFF (0x0 << 4)
109#define MR2_TxRTS_CONTROL_ON (0x1 << 5)
110#define MR2_TxRTS_CONTROL_OFF (0x0 << 5)
111#define MR2_CH_MODE_NORMAL (0x0 << 6)
112#define MR2_CH_MODE_ECHO (0x1 << 6)
113#define MR2_CH_MODE_LOCAL (0x2 << 6)
114#define MR2_CH_MODE_REMOTE (0x3 << 6)
115
116#define CR_ENABLE_RX (0x1 << 0)
117#define CR_DISABLE_RX (0x1 << 1)
118#define CR_ENABLE_TX (0x1 << 2)
119#define CR_DISABLE_TX (0x1 << 3)
120#define CR_CMD_RESET_MR (0x1 << 4)
121#define CR_CMD_RESET_RX (0x2 << 4)
122#define CR_CMD_RESET_TX (0x3 << 4)
123#define CR_CMD_RESET_ERR_STATUS (0x4 << 4)
124#define CR_CMD_RESET_BREAK_CHANGE (0x5 << 4)
125#define CR_CMD_START_BREAK (0x6 << 4)
126#define CR_CMD_STOP_BREAK (0x7 << 4)
127#define CR_CMD_ASSERT_RTSN (0x8 << 4)
128#define CR_CMD_NEGATE_RTSN (0x9 << 4)
129#define CR_CMD_SET_TIMEOUT_MODE (0xA << 4)
130#define CR_CMD_DISABLE_TIMEOUT_MODE (0xC << 4)
131
132#define SR_RX_READY (0x1 << 0)
133#define SR_FIFO_FULL (0x1 << 1)
134#define SR_TX_READY (0x1 << 2)
135#define SR_TX_EMPTY (0x1 << 3)
136#define SR_OVERRUN_ERROR (0x1 << 4)
137#define SR_PARITY_ERROR (0x1 << 5)
138#define SR_FRAMING_ERROR (0x1 << 6)
139#define SR_RECEIVED_BREAK (0x1 << 7)
140
141#define SR_ERROR (0xF0)
142
143#define ACR_DELTA_IP0_IRQ_EN (0x1 << 0)
144#define ACR_DELTA_IP1_IRQ_EN (0x1 << 1)
145#define ACR_DELTA_IP2_IRQ_EN (0x1 << 2)
146#define ACR_DELTA_IP3_IRQ_EN (0x1 << 3)
147#define ACR_CT_Mask (0x7 << 4)
148#define ACR_CExt (0x0 << 4)
149#define ACR_CTxCA (0x1 << 4)
150#define ACR_CTxCB (0x2 << 4)
151#define ACR_CClk16 (0x3 << 4)
152#define ACR_TExt (0x4 << 4)
153#define ACR_TExt16 (0x5 << 4)
154#define ACR_TClk (0x6 << 4)
155#define ACR_TClk16 (0x7 << 4)
156#define ACR_BRG_SET1 (0x0 << 7)
157#define ACR_BRG_SET2 (0x1 << 7)
158
159#define TX_CLK_75 (0x0 << 0)
160#define TX_CLK_110 (0x1 << 0)
161#define TX_CLK_38400 (0x2 << 0)
162#define TX_CLK_150 (0x3 << 0)
163#define TX_CLK_300 (0x4 << 0)
164#define TX_CLK_600 (0x5 << 0)
165#define TX_CLK_1200 (0x6 << 0)
166#define TX_CLK_2000 (0x7 << 0)
167#define TX_CLK_2400 (0x8 << 0)
168#define TX_CLK_4800 (0x9 << 0)
169#define TX_CLK_1800 (0xA << 0)
170#define TX_CLK_9600 (0xB << 0)
171#define TX_CLK_19200 (0xC << 0)
172#define RX_CLK_75 (0x0 << 4)
173#define RX_CLK_110 (0x1 << 4)
174#define RX_CLK_38400 (0x2 << 4)
175#define RX_CLK_150 (0x3 << 4)
176#define RX_CLK_300 (0x4 << 4)
177#define RX_CLK_600 (0x5 << 4)
178#define RX_CLK_1200 (0x6 << 4)
179#define RX_CLK_2000 (0x7 << 4)
180#define RX_CLK_2400 (0x8 << 4)
181#define RX_CLK_4800 (0x9 << 4)
182#define RX_CLK_1800 (0xA << 4)
183#define RX_CLK_9600 (0xB << 4)
184#define RX_CLK_19200 (0xC << 4)
185
186#define OPCR_MPOa_RTSN (0x0 << 0)
187#define OPCR_MPOa_C_TO (0x1 << 0)
188#define OPCR_MPOa_TxC1X (0x2 << 0)
189#define OPCR_MPOa_TxC16X (0x3 << 0)
190#define OPCR_MPOa_RxC1X (0x4 << 0)
191#define OPCR_MPOa_RxC16X (0x5 << 0)
192#define OPCR_MPOa_TxRDY (0x6 << 0)
193#define OPCR_MPOa_RxRDY_FF (0x7 << 0)
194
195#define OPCR_MPOb_RTSN (0x0 << 4)
196#define OPCR_MPOb_C_TO (0x1 << 4)
197#define OPCR_MPOb_TxC1X (0x2 << 4)
198#define OPCR_MPOb_TxC16X (0x3 << 4)
199#define OPCR_MPOb_RxC1X (0x4 << 4)
200#define OPCR_MPOb_RxC16X (0x5 << 4)
201#define OPCR_MPOb_TxRDY (0x6 << 4)
202#define OPCR_MPOb_RxRDY_FF (0x7 << 4)
203
204#define OPCR_MPP_INPUT (0x0 << 7)
205#define OPCR_MPP_OUTPUT (0x1 << 7)
206
207#define IMR_TxRDY_A (0x1 << 0)
208#define IMR_RxRDY_FFULL_A (0x1 << 1)
209#define IMR_DELTA_BREAK_A (0x1 << 2)
210#define IMR_COUNTER_READY (0x1 << 3)
211#define IMR_TxRDY_B (0x1 << 4)
212#define IMR_RxRDY_FFULL_B (0x1 << 5)
213#define IMR_DELTA_BREAK_B (0x1 << 6)
214#define IMR_INPUT_PORT_CHANGE (0x1 << 7)
215
216#define ISR_TxRDY_A (0x1 << 0)
217#define ISR_RxRDY_FFULL_A (0x1 << 1)
218#define ISR_DELTA_BREAK_A (0x1 << 2)
219#define ISR_COUNTER_READY (0x1 << 3)
220#define ISR_TxRDY_B (0x1 << 4)
221#define ISR_RxRDY_FFULL_B (0x1 << 5)
222#define ISR_DELTA_BREAK_B (0x1 << 6)
223#define ISR_INPUT_PORT_CHANGE (0x1 << 7)
224
225#define ACK_INT_REQ0 0
226#define ACK_INT_REQ1 2
227
228#endif /* SCC2698_H_ */
diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c
new file mode 100644
index 000000000000..6d5079de52b9
--- /dev/null
+++ b/drivers/ipack/ipack.c
@@ -0,0 +1,481 @@
1/*
2 * Industry-pack bus support functions.
3 *
4 * Copyright (C) 2011-2012 CERN (www.cern.ch)
5 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; version 2 of the License.
10 */
11
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <linux/idr.h>
15#include <linux/io.h>
16#include "ipack.h"
17
18#define to_ipack_dev(device) container_of(device, struct ipack_device, dev)
19#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver)
20
21static DEFINE_IDA(ipack_ida);
22
23static void ipack_device_release(struct device *dev)
24{
25 struct ipack_device *device = to_ipack_dev(dev);
26 kfree(device->id);
27 device->release(device);
28}
29
30static inline const struct ipack_device_id *
31ipack_match_one_device(const struct ipack_device_id *id,
32 const struct ipack_device *device)
33{
34 if ((id->format == IPACK_ANY_FORMAT ||
35 id->format == device->id_format) &&
36 (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) &&
37 (id->device == IPACK_ANY_ID || id->device == device->id_device))
38 return id;
39 return NULL;
40}
41
42static const struct ipack_device_id *
43ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev)
44{
45 if (ids) {
46 while (ids->vendor || ids->device) {
47 if (ipack_match_one_device(ids, idev))
48 return ids;
49 ids++;
50 }
51 }
52 return NULL;
53}
54
55static int ipack_bus_match(struct device *dev, struct device_driver *drv)
56{
57 struct ipack_device *idev = to_ipack_dev(dev);
58 struct ipack_driver *idrv = to_ipack_driver(drv);
59 const struct ipack_device_id *found_id;
60
61 found_id = ipack_match_id(idrv->id_table, idev);
62 return found_id ? 1 : 0;
63}
64
65static int ipack_bus_probe(struct device *device)
66{
67 struct ipack_device *dev = to_ipack_dev(device);
68 struct ipack_driver *drv = to_ipack_driver(device->driver);
69
70 if (!drv->ops->probe)
71 return -EINVAL;
72
73 return drv->ops->probe(dev);
74}
75
76static int ipack_bus_remove(struct device *device)
77{
78 struct ipack_device *dev = to_ipack_dev(device);
79 struct ipack_driver *drv = to_ipack_driver(device->driver);
80
81 if (!drv->ops->remove)
82 return -EINVAL;
83
84 drv->ops->remove(dev);
85 return 0;
86}
87
88static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
89{
90 struct ipack_device *idev;
91
92 if (!dev)
93 return -ENODEV;
94
95 idev = to_ipack_dev(dev);
96
97 if (add_uevent_var(env,
98 "MODALIAS=ipack:f%02Xv%08Xd%08X", idev->id_format,
99 idev->id_vendor, idev->id_device))
100 return -ENOMEM;
101
102 return 0;
103}
104
105#define ipack_device_attr(field, format_string) \
106static ssize_t \
107field##_show(struct device *dev, struct device_attribute *attr, \
108 char *buf) \
109{ \
110 struct ipack_device *idev = to_ipack_dev(dev); \
111 return sprintf(buf, format_string, idev->field); \
112}
113
114static ssize_t id_show(struct device *dev,
115 struct device_attribute *attr, char *buf)
116{
117 unsigned int i, c, l, s;
118 struct ipack_device *idev = to_ipack_dev(dev);
119
120
121 switch (idev->id_format) {
122 case IPACK_ID_VERSION_1:
123 l = 0x7; s = 1; break;
124 case IPACK_ID_VERSION_2:
125 l = 0xf; s = 2; break;
126 default:
127 return -EIO;
128 }
129 c = 0;
130 for (i = 0; i < idev->id_avail; i++) {
131 if (i > 0) {
132 if ((i & l) == 0)
133 buf[c++] = '\n';
134 else if ((i & s) == 0)
135 buf[c++] = ' ';
136 }
137 sprintf(&buf[c], "%02x", idev->id[i]);
138 c += 2;
139 }
140 buf[c++] = '\n';
141 return c;
142}
143
144static ssize_t
145id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
146{
147 struct ipack_device *idev = to_ipack_dev(dev);
148 switch (idev->id_format) {
149 case IPACK_ID_VERSION_1:
150 return sprintf(buf, "0x%02x\n", idev->id_vendor);
151 case IPACK_ID_VERSION_2:
152 return sprintf(buf, "0x%06x\n", idev->id_vendor);
153 default:
154 return -EIO;
155 }
156}
157
158static ssize_t
159id_device_show(struct device *dev, struct device_attribute *attr, char *buf)
160{
161 struct ipack_device *idev = to_ipack_dev(dev);
162 switch (idev->id_format) {
163 case IPACK_ID_VERSION_1:
164 return sprintf(buf, "0x%02x\n", idev->id_device);
165 case IPACK_ID_VERSION_2:
166 return sprintf(buf, "0x%04x\n", idev->id_device);
167 default:
168 return -EIO;
169 }
170}
171
172static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
173 char *buf)
174{
175 struct ipack_device *idev = to_ipack_dev(dev);
176
177 return sprintf(buf, "ipac:f%02Xv%08Xd%08X", idev->id_format,
178 idev->id_vendor, idev->id_device);
179}
180
181ipack_device_attr(id_format, "0x%hhu\n");
182
183static struct device_attribute ipack_dev_attrs[] = {
184 __ATTR_RO(id),
185 __ATTR_RO(id_device),
186 __ATTR_RO(id_format),
187 __ATTR_RO(id_vendor),
188 __ATTR_RO(modalias),
189};
190
191static struct bus_type ipack_bus_type = {
192 .name = "ipack",
193 .probe = ipack_bus_probe,
194 .match = ipack_bus_match,
195 .remove = ipack_bus_remove,
196 .dev_attrs = ipack_dev_attrs,
197 .uevent = ipack_uevent,
198};
199
200struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
201 const struct ipack_bus_ops *ops)
202{
203 int bus_nr;
204 struct ipack_bus_device *bus;
205
206 bus = kzalloc(sizeof(struct ipack_bus_device), GFP_KERNEL);
207 if (!bus)
208 return NULL;
209
210 bus_nr = ida_simple_get(&ipack_ida, 0, 0, GFP_KERNEL);
211 if (bus_nr < 0) {
212 kfree(bus);
213 return NULL;
214 }
215
216 bus->bus_nr = bus_nr;
217 bus->parent = parent;
218 bus->slots = slots;
219 bus->ops = ops;
220 return bus;
221}
222EXPORT_SYMBOL_GPL(ipack_bus_register);
223
224static int ipack_unregister_bus_member(struct device *dev, void *data)
225{
226 struct ipack_device *idev = to_ipack_dev(dev);
227 struct ipack_bus_device *bus = data;
228
229 if (idev->bus == bus)
230 ipack_device_unregister(idev);
231
232 return 1;
233}
234
235int ipack_bus_unregister(struct ipack_bus_device *bus)
236{
237 bus_for_each_dev(&ipack_bus_type, NULL, bus,
238 ipack_unregister_bus_member);
239 ida_simple_remove(&ipack_ida, bus->bus_nr);
240 kfree(bus);
241 return 0;
242}
243EXPORT_SYMBOL_GPL(ipack_bus_unregister);
244
245int ipack_driver_register(struct ipack_driver *edrv, struct module *owner,
246 const char *name)
247{
248 edrv->driver.owner = owner;
249 edrv->driver.name = name;
250 edrv->driver.bus = &ipack_bus_type;
251 return driver_register(&edrv->driver);
252}
253EXPORT_SYMBOL_GPL(ipack_driver_register);
254
255void ipack_driver_unregister(struct ipack_driver *edrv)
256{
257 driver_unregister(&edrv->driver);
258}
259EXPORT_SYMBOL_GPL(ipack_driver_unregister);
260
261static u16 ipack_crc_byte(u16 crc, u8 c)
262{
263 int i;
264
265 crc ^= c << 8;
266 for (i = 0; i < 8; i++)
267 crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
268 return crc;
269}
270
271/*
272 * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the
273 * opposite bit ordering.
274 */
275static u8 ipack_calc_crc1(struct ipack_device *dev)
276{
277 u8 c;
278 u16 crc;
279 unsigned int i;
280
281 crc = 0xffff;
282 for (i = 0; i < dev->id_avail; i++) {
283 c = (i != 11) ? dev->id[i] : 0;
284 crc = ipack_crc_byte(crc, c);
285 }
286 crc = ~crc;
287 return crc & 0xff;
288}
289
290static u16 ipack_calc_crc2(struct ipack_device *dev)
291{
292 u8 c;
293 u16 crc;
294 unsigned int i;
295
296 crc = 0xffff;
297 for (i = 0; i < dev->id_avail; i++) {
298 c = ((i != 0x18) && (i != 0x19)) ? dev->id[i] : 0;
299 crc = ipack_crc_byte(crc, c);
300 }
301 crc = ~crc;
302 return crc;
303}
304
305static void ipack_parse_id1(struct ipack_device *dev)
306{
307 u8 *id = dev->id;
308 u8 crc;
309
310 dev->id_vendor = id[4];
311 dev->id_device = id[5];
312 dev->speed_8mhz = 1;
313 dev->speed_32mhz = (id[7] == 'H');
314 crc = ipack_calc_crc1(dev);
315 dev->id_crc_correct = (crc == id[11]);
316 if (!dev->id_crc_correct) {
317 dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n",
318 id[11], crc);
319 }
320}
321
322static void ipack_parse_id2(struct ipack_device *dev)
323{
324 __be16 *id = (__be16 *) dev->id;
325 u16 flags, crc;
326
327 dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16)
328 + be16_to_cpu(id[4]);
329 dev->id_device = be16_to_cpu(id[5]);
330 flags = be16_to_cpu(id[10]);
331 dev->speed_8mhz = !!(flags & 2);
332 dev->speed_32mhz = !!(flags & 4);
333 crc = ipack_calc_crc2(dev);
334 dev->id_crc_correct = (crc == be16_to_cpu(id[12]));
335 if (!dev->id_crc_correct) {
336 dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n",
337 id[11], crc);
338 }
339}
340
341static int ipack_device_read_id(struct ipack_device *dev)
342{
343 u8 __iomem *idmem;
344 int i;
345 int ret = 0;
346
347 idmem = ioremap(dev->region[IPACK_ID_SPACE].start,
348 dev->region[IPACK_ID_SPACE].size);
349 if (!idmem) {
350 dev_err(&dev->dev, "error mapping memory\n");
351 return -ENOMEM;
352 }
353
354 /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH"
355 * we are dealing with a IndustryPack format 1 device. If we detect
356 * "VITA4 " (16 bit big endian formatted) we are dealing with a
357 * IndustryPack format 2 device */
358 if ((ioread8(idmem + 1) == 'I') &&
359 (ioread8(idmem + 3) == 'P') &&
360 (ioread8(idmem + 5) == 'A') &&
361 ((ioread8(idmem + 7) == 'C') ||
362 (ioread8(idmem + 7) == 'H'))) {
363 dev->id_format = IPACK_ID_VERSION_1;
364 dev->id_avail = ioread8(idmem + 0x15);
365 if ((dev->id_avail < 0x0c) || (dev->id_avail > 0x40)) {
366 dev_warn(&dev->dev, "invalid id size");
367 dev->id_avail = 0x0c;
368 }
369 } else if ((ioread8(idmem + 0) == 'I') &&
370 (ioread8(idmem + 1) == 'V') &&
371 (ioread8(idmem + 2) == 'A') &&
372 (ioread8(idmem + 3) == 'T') &&
373 (ioread8(idmem + 4) == ' ') &&
374 (ioread8(idmem + 5) == '4')) {
375 dev->id_format = IPACK_ID_VERSION_2;
376 dev->id_avail = ioread16be(idmem + 0x16);
377 if ((dev->id_avail < 0x1a) || (dev->id_avail > 0x40)) {
378 dev_warn(&dev->dev, "invalid id size");
379 dev->id_avail = 0x1a;
380 }
381 } else {
382 dev->id_format = IPACK_ID_VERSION_INVALID;
383 dev->id_avail = 0;
384 }
385
386 if (!dev->id_avail) {
387 ret = -ENODEV;
388 goto out;
389 }
390
391 /* Obtain the amount of memory required to store a copy of the complete
392 * ID ROM contents */
393 dev->id = kmalloc(dev->id_avail, GFP_KERNEL);
394 if (!dev->id) {
395 dev_err(&dev->dev, "dev->id alloc failed.\n");
396 ret = -ENOMEM;
397 goto out;
398 }
399 for (i = 0; i < dev->id_avail; i++) {
400 if (dev->id_format == IPACK_ID_VERSION_1)
401 dev->id[i] = ioread8(idmem + (i << 1) + 1);
402 else
403 dev->id[i] = ioread8(idmem + i);
404 }
405
406 /* now we can finally work with the copy */
407 switch (dev->id_format) {
408 case IPACK_ID_VERSION_1:
409 ipack_parse_id1(dev);
410 break;
411 case IPACK_ID_VERSION_2:
412 ipack_parse_id2(dev);
413 break;
414 }
415
416out:
417 iounmap(idmem);
418
419 return ret;
420}
421
422int ipack_device_register(struct ipack_device *dev)
423{
424 int ret;
425
426 dev->dev.bus = &ipack_bus_type;
427 dev->dev.release = ipack_device_release;
428 dev->dev.parent = dev->bus->parent;
429 dev_set_name(&dev->dev,
430 "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot);
431
432 if (dev->bus->ops->set_clockrate(dev, 8))
433 dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n");
434 if (dev->bus->ops->reset_timeout(dev))
435 dev_warn(&dev->dev, "failed to reset potential timeout.");
436
437 ret = ipack_device_read_id(dev);
438 if (ret < 0) {
439 dev_err(&dev->dev, "error reading device id section.\n");
440 return ret;
441 }
442
443 /* if the device supports 32 MHz operation, use it. */
444 if (dev->speed_32mhz) {
445 ret = dev->bus->ops->set_clockrate(dev, 32);
446 if (ret < 0)
447 dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n");
448 }
449
450 ret = device_register(&dev->dev);
451 if (ret < 0)
452 kfree(dev->id);
453
454 return ret;
455}
456EXPORT_SYMBOL_GPL(ipack_device_register);
457
458void ipack_device_unregister(struct ipack_device *dev)
459{
460 device_unregister(&dev->dev);
461}
462EXPORT_SYMBOL_GPL(ipack_device_unregister);
463
464static int __init ipack_init(void)
465{
466 ida_init(&ipack_ida);
467 return bus_register(&ipack_bus_type);
468}
469
470static void __exit ipack_exit(void)
471{
472 bus_unregister(&ipack_bus_type);
473 ida_destroy(&ipack_ida);
474}
475
476module_init(ipack_init);
477module_exit(ipack_exit);
478
479MODULE_AUTHOR("Samuel Iglesias Gonsalvez <siglesias@igalia.com>");
480MODULE_LICENSE("GPL");
481MODULE_DESCRIPTION("Industry-pack bus core");
diff --git a/drivers/ipack/ipack.h b/drivers/ipack/ipack.h
new file mode 100644
index 000000000000..6760bfaf0ac4
--- /dev/null
+++ b/drivers/ipack/ipack.h
@@ -0,0 +1,215 @@
1/*
2 * Industry-pack bus.
3 *
4 * Copyright (C) 2011-2012 CERN (www.cern.ch)
5 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; version 2 of the License.
10 */
11
12#include <linux/mod_devicetable.h>
13#include <linux/device.h>
14#include <linux/interrupt.h>
15
16#include "ipack_ids.h"
17
18#define IPACK_IDPROM_OFFSET_I 0x01
19#define IPACK_IDPROM_OFFSET_P 0x03
20#define IPACK_IDPROM_OFFSET_A 0x05
21#define IPACK_IDPROM_OFFSET_C 0x07
22#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09
23#define IPACK_IDPROM_OFFSET_MODEL 0x0B
24#define IPACK_IDPROM_OFFSET_REVISION 0x0D
25#define IPACK_IDPROM_OFFSET_RESERVED 0x0F
26#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11
27#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13
28#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15
29#define IPACK_IDPROM_OFFSET_CRC 0x17
30
31struct ipack_bus_ops;
32struct ipack_driver;
33
34enum ipack_space {
35 IPACK_IO_SPACE = 0,
36 IPACK_ID_SPACE,
37 IPACK_INT_SPACE,
38 IPACK_MEM8_SPACE,
39 IPACK_MEM16_SPACE,
40 /* Dummy for counting the number of entries. Must remain the last
41 * entry */
42 IPACK_SPACE_COUNT,
43};
44
45/**
46 */
47struct ipack_region {
48 phys_addr_t start;
49 size_t size;
50};
51
52/**
53 * struct ipack_device
54 *
55 * @slot: Slot where the device is plugged in the carrier board
56 * @bus: ipack_bus_device where the device is plugged to.
57 * @id_space: Virtual address to ID space.
58 * @io_space: Virtual address to IO space.
59 * @mem_space: Virtual address to MEM space.
60 * @dev: device in kernel representation.
61 *
62 * Warning: Direct access to mapped memory is possible but the endianness
63 * is not the same with PCI carrier or VME carrier. The endianness is managed
64 * by the carrier board throught bus->ops.
65 */
66struct ipack_device {
67 unsigned int slot;
68 struct ipack_bus_device *bus;
69 struct device dev;
70 void (*release) (struct ipack_device *dev);
71 struct ipack_region region[IPACK_SPACE_COUNT];
72 u8 *id;
73 size_t id_avail;
74 u32 id_vendor;
75 u32 id_device;
76 u8 id_format;
77 unsigned int id_crc_correct:1;
78 unsigned int speed_8mhz:1;
79 unsigned int speed_32mhz:1;
80};
81
82/**
83 * struct ipack_driver_ops -- Callbacks to IPack device driver
84 *
85 * @probe: Probe function
86 * @remove: Prepare imminent removal of the device. Services provided by the
87 * device should be revoked.
88 */
89
90struct ipack_driver_ops {
91 int (*probe) (struct ipack_device *dev);
92 void (*remove) (struct ipack_device *dev);
93};
94
95/**
96 * struct ipack_driver -- Specific data to each ipack device driver
97 *
98 * @driver: Device driver kernel representation
99 * @ops: Callbacks provided by the IPack device driver
100 */
101struct ipack_driver {
102 struct device_driver driver;
103 const struct ipack_device_id *id_table;
104 const struct ipack_driver_ops *ops;
105};
106
107/**
108 * struct ipack_bus_ops - available operations on a bridge module
109 *
110 * @map_space: map IP address space
111 * @unmap_space: unmap IP address space
112 * @request_irq: request IRQ
113 * @free_irq: free IRQ
114 * @get_clockrate: Returns the clockrate the carrier is currently
115 * communicating with the device at.
116 * @set_clockrate: Sets the clock-rate for carrier / module communication.
117 * Should return -EINVAL if the requested speed is not supported.
118 * @get_error: Returns the error state for the slot the device is attached
119 * to.
120 * @get_timeout: Returns 1 if the communication with the device has
121 * previously timed out.
122 * @reset_timeout: Resets the state returned by get_timeout.
123 */
124struct ipack_bus_ops {
125 int (*request_irq) (struct ipack_device *dev,
126 irqreturn_t (*handler)(void *), void *arg);
127 int (*free_irq) (struct ipack_device *dev);
128 int (*get_clockrate) (struct ipack_device *dev);
129 int (*set_clockrate) (struct ipack_device *dev, int mherz);
130 int (*get_error) (struct ipack_device *dev);
131 int (*get_timeout) (struct ipack_device *dev);
132 int (*reset_timeout) (struct ipack_device *dev);
133};
134
135/**
136 * struct ipack_bus_device
137 *
138 * @dev: pointer to carrier device
139 * @slots: number of slots available
140 * @bus_nr: ipack bus number
141 * @ops: bus operations for the mezzanine drivers
142 */
143struct ipack_bus_device {
144 struct device *parent;
145 int slots;
146 int bus_nr;
147 const struct ipack_bus_ops *ops;
148};
149
150/**
151 * ipack_bus_register -- register a new ipack bus
152 *
153 * @parent: pointer to the parent device, if any.
154 * @slots: number of slots available in the bus device.
155 * @ops: bus operations for the mezzanine drivers.
156 *
157 * The carrier board device should call this function to register itself as
158 * available bus device in ipack.
159 */
160struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots,
161 const struct ipack_bus_ops *ops);
162
163/**
164 * ipack_bus_unregister -- unregister an ipack bus
165 */
166int ipack_bus_unregister(struct ipack_bus_device *bus);
167
168/**
169 * ipack_driver_register -- Register a new ipack device driver
170 *
171 * Called by a ipack driver to register itself as a driver
172 * that can manage ipack devices.
173 */
174int ipack_driver_register(struct ipack_driver *edrv, struct module *owner,
175 const char *name);
176void ipack_driver_unregister(struct ipack_driver *edrv);
177
178/**
179 * ipack_device_register -- register an IPack device with the kernel
180 * @dev: the new device to register.
181 *
182 * Register a new IPack device ("module" in IndustryPack jargon). The call
183 * is done by the carrier driver. The carrier should populate the fields
184 * bus and slot as well as the region array of @dev prior to calling this
185 * function. The rest of the fields will be allocated and populated
186 * during registration.
187 *
188 * Return zero on success or error code on failure.
189 */
190int ipack_device_register(struct ipack_device *dev);
191void ipack_device_unregister(struct ipack_device *dev);
192
193/**
194 * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table
195 * @_table: device table name
196 *
197 * This macro is used to create a struct ipack_device_id array (a device table)
198 * in a generic manner.
199 */
200#define DEFINE_IPACK_DEVICE_TABLE(_table) \
201 const struct ipack_device_id _table[] __devinitconst
202
203/**
204 * IPACK_DEVICE - macro used to describe a specific IndustryPack device
205 * @_format: the format version (currently either 1 or 2, 8 bit value)
206 * @vend: the 8 or 24 bit IndustryPack Vendor ID
207 * @dev: the 8 or 16 bit IndustryPack Device ID
208 *
209 * This macro is used to create a struct ipack_device_id that matches a specific
210 * device.
211 */
212#define IPACK_DEVICE(_format, vend, dev) \
213 .format = (_format), \
214 .vendor = (vend), \
215 .device = (dev)
diff --git a/drivers/ipack/ipack_ids.h b/drivers/ipack/ipack_ids.h
new file mode 100644
index 000000000000..8153fee3f2f7
--- /dev/null
+++ b/drivers/ipack/ipack_ids.h
@@ -0,0 +1,32 @@
1/*
2 * IndustryPack Fromat, Vendor and Device IDs.
3 */
4
5/* ID section format versions */
6#define IPACK_ID_VERSION_INVALID 0x00
7#define IPACK_ID_VERSION_1 0x01
8#define IPACK_ID_VERSION_2 0x02
9
10/* Vendors and devices. Sort key: vendor first, device next. */
11#define IPACK1_VENDOR_ID_RESERVED1 0x00
12#define IPACK1_VENDOR_ID_RESERVED2 0xFF
13#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01
14#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02
15#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03
16#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04
17#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05
18#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06
19#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07
20#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08
21#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09
22#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A
23#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B
24#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C
25#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D
26#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E
27#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F
28
29#define IPACK1_VENDOR_ID_SBS 0xF0
30#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22
31#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A
32#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48