Commit b454cc6636d254fbf6049b73e9560aee76fb04a3

Authored by Maciej W. Rozycki
Committed by Ralf Baechle
1 parent 5986a2ec35

[TC] MIPS: TURBOchannel update to the driver model

This is a set of changes to convert support for the TURBOchannel bus to the
driver model.  It implements the usual set of calls similar to what other bus
drivers have: tc_register_driver(), tc_unregister_driver(), etc.  All the
platform-specific bits have been removed and headers from asm-mips/dec/ have
been merged into linux/tc.h, which should be included by drivers.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 8 changed files with 396 additions and 328 deletions Side-by-side Diff

... ... @@ -3287,6 +3287,11 @@
3287 3287 W: http://vtun.sourceforge.net/tun
3288 3288 S: Maintained
3289 3289  
  3290 +TURBOCHANNEL SUBSYSTEM
  3291 +P: Maciej W. Rozycki
  3292 +M: macro@linux-mips.org
  3293 +S: Maintained
  3294 +
3290 3295 U14-34F SCSI DRIVER
3291 3296 P: Dario Ballabio
3292 3297 M: ballabio_dario@emc.com
... ... @@ -4,7 +4,7 @@
4 4  
5 5 # Object file lists.
6 6  
7   -obj-$(CONFIG_TC) += tc.o
  7 +obj-$(CONFIG_TC) += tc.o tc-driver.o
8 8 obj-$(CONFIG_ZS) += zs.o
9 9 obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o
10 10  
drivers/tc/tc-driver.c
  1 +/*
  2 + * TURBOchannel driver services.
  3 + *
  4 + * Copyright (c) 2005 James Simmons
  5 + * Copyright (c) 2006 Maciej W. Rozycki
  6 + *
  7 + * Loosely based on drivers/dio/dio-driver.c and
  8 + * drivers/pci/pci-driver.c.
  9 + *
  10 + * This file is subject to the terms and conditions of the GNU
  11 + * General Public License. See the file "COPYING" in the main
  12 + * directory of this archive for more details.
  13 + */
  14 +
  15 +#include <linux/init.h>
  16 +#include <linux/module.h>
  17 +#include <linux/tc.h>
  18 +
  19 +/**
  20 + * tc_register_driver - register a new TC driver
  21 + * @drv: the driver structure to register
  22 + *
  23 + * Adds the driver structure to the list of registered drivers
  24 + * Returns a negative value on error, otherwise 0.
  25 + * If no error occurred, the driver remains registered even if
  26 + * no device was claimed during registration.
  27 + */
  28 +int tc_register_driver(struct tc_driver *tdrv)
  29 +{
  30 + return driver_register(&tdrv->driver);
  31 +}
  32 +EXPORT_SYMBOL(tc_register_driver);
  33 +
  34 +/**
  35 + * tc_unregister_driver - unregister a TC driver
  36 + * @drv: the driver structure to unregister
  37 + *
  38 + * Deletes the driver structure from the list of registered TC drivers,
  39 + * gives it a chance to clean up by calling its remove() function for
  40 + * each device it was responsible for, and marks those devices as
  41 + * driverless.
  42 + */
  43 +void tc_unregister_driver(struct tc_driver *tdrv)
  44 +{
  45 + driver_unregister(&tdrv->driver);
  46 +}
  47 +EXPORT_SYMBOL(tc_unregister_driver);
  48 +
  49 +/**
  50 + * tc_match_device - tell if a TC device structure has a matching
  51 + * TC device ID structure
  52 + * @tdrv: the TC driver to earch for matching TC device ID strings
  53 + * @tdev: the TC device structure to match against
  54 + *
  55 + * Used by a driver to check whether a TC device present in the
  56 + * system is in its list of supported devices. Returns the matching
  57 + * tc_device_id structure or %NULL if there is no match.
  58 + */
  59 +const struct tc_device_id *tc_match_device(struct tc_driver *tdrv,
  60 + struct tc_dev *tdev)
  61 +{
  62 + const struct tc_device_id *id = tdrv->id_table;
  63 +
  64 + if (id) {
  65 + while (id->name[0] || id->vendor[0]) {
  66 + if (strcmp(tdev->name, id->name) == 0 &&
  67 + strcmp(tdev->vendor, id->vendor) == 0)
  68 + return id;
  69 + id++;
  70 + }
  71 + }
  72 + return NULL;
  73 +}
  74 +EXPORT_SYMBOL(tc_match_device);
  75 +
  76 +/**
  77 + * tc_bus_match - Tell if a device structure has a matching
  78 + * TC device ID structure
  79 + * @dev: the device structure to match against
  80 + * @drv: the device driver to search for matching TC device ID strings
  81 + *
  82 + * Used by a driver to check whether a TC device present in the
  83 + * system is in its list of supported devices. Returns 1 if there
  84 + * is a match or 0 otherwise.
  85 + */
  86 +static int tc_bus_match(struct device *dev, struct device_driver *drv)
  87 +{
  88 + struct tc_dev *tdev = to_tc_dev(dev);
  89 + struct tc_driver *tdrv = to_tc_driver(drv);
  90 + const struct tc_device_id *id;
  91 +
  92 + id = tc_match_device(tdrv, tdev);
  93 + if (id)
  94 + return 1;
  95 +
  96 + return 0;
  97 +}
  98 +
  99 +struct bus_type tc_bus_type = {
  100 + .name = "tc",
  101 + .match = tc_bus_match,
  102 +};
  103 +EXPORT_SYMBOL(tc_bus_type);
  104 +
  105 +static int __init tc_driver_init(void)
  106 +{
  107 + return bus_register(&tc_bus_type);
  108 +}
  109 +
  110 +postcore_initcall(tc_driver_init);
1 1 /*
2   - * tc-init: We assume the TURBOchannel to be up and running so
3   - * just probe for Modules and fill in the global data structure
4   - * tc_bus.
  2 + * TURBOchannel bus services.
5 3 *
6   - * This file is subject to the terms and conditions of the GNU General Public
7   - * License. See the file "COPYING" in the main directory of this archive
8   - * for more details.
  4 + * Copyright (c) Harald Koerfgen, 1998
  5 + * Copyright (c) 2001, 2003, 2005, 2006 Maciej W. Rozycki
  6 + * Copyright (c) 2005 James Simmons
9 7 *
10   - * Copyright (c) Harald Koerfgen, 1998
11   - * Copyright (c) 2001, 2003, 2005 Maciej W. Rozycki
  8 + * This file is subject to the terms and conditions of the GNU
  9 + * General Public License. See the file "COPYING" in the main
  10 + * directory of this archive for more details.
12 11 */
  12 +#include <linux/compiler.h>
  13 +#include <linux/errno.h>
13 14 #include <linux/init.h>
  15 +#include <linux/ioport.h>
14 16 #include <linux/kernel.h>
  17 +#include <linux/list.h>
15 18 #include <linux/module.h>
16 19 #include <linux/string.h>
  20 +#include <linux/tc.h>
17 21 #include <linux/types.h>
18 22  
19   -#include <asm/addrspace.h>
20   -#include <asm/errno.h>
21 23 #include <asm/io.h>
22   -#include <asm/paccess.h>
23 24  
24   -#include <asm/dec/machtype.h>
25   -#include <asm/dec/prom.h>
26   -#include <asm/dec/tcinfo.h>
27   -#include <asm/dec/tcmodule.h>
28   -#include <asm/dec/interrupts.h>
  25 +static struct tc_bus tc_bus = {
  26 + .name = "TURBOchannel",
  27 +};
29 28  
30   -MODULE_LICENSE("GPL");
31   -slot_info tc_bus[MAX_SLOT];
32   -static int num_tcslots;
33   -static tcinfo *info;
34   -
35 29 /*
36   - * Interface to the world. Read comment in include/asm-mips/tc.h.
  30 + * Probing for TURBOchannel modules.
37 31 */
38   -
39   -int search_tc_card(const char *name)
  32 +static void __init tc_bus_add_devices(struct tc_bus *tbus)
40 33 {
41   - int slot;
42   - slot_info *sip;
43   -
44   - for (slot = 0; slot < num_tcslots; slot++) {
45   - sip = &tc_bus[slot];
46   - if ((sip->flags & FREE) &&
47   - (strncmp(sip->name, name, strlen(name)) == 0)) {
48   - return slot;
49   - }
50   - }
51   -
52   - return -ENODEV;
53   -}
54   -
55   -void claim_tc_card(int slot)
56   -{
57   - if (tc_bus[slot].flags & IN_USE) {
58   - printk("claim_tc_card: attempting to claim a card already in use\n");
59   - return;
60   - }
61   - tc_bus[slot].flags &= ~FREE;
62   - tc_bus[slot].flags |= IN_USE;
63   -}
64   -
65   -void release_tc_card(int slot)
66   -{
67   - if (tc_bus[slot].flags & FREE) {
68   - printk("release_tc_card: "
69   - "attempting to release a card already free\n");
70   - return;
71   - }
72   - tc_bus[slot].flags &= ~IN_USE;
73   - tc_bus[slot].flags |= FREE;
74   -}
75   -
76   -unsigned long get_tc_base_addr(int slot)
77   -{
78   - return tc_bus[slot].base_addr;
79   -}
80   -
81   -unsigned long get_tc_irq_nr(int slot)
82   -{
83   - return tc_bus[slot].interrupt;
84   -}
85   -
86   -unsigned long get_tc_speed(void)
87   -{
88   - return 100000 * (10000 / (unsigned long)info->clk_period);
89   -}
90   -
91   -/*
92   - * Probing for TURBOchannel modules
93   - */
94   -static void __init tc_probe(unsigned long startaddr, unsigned long size,
95   - int slots)
96   -{
97   - unsigned long slotaddr;
  34 + resource_size_t slotsize = tbus->info.slot_size << 20;
  35 + resource_size_t extslotsize = tbus->ext_slot_size;
  36 + resource_size_t slotaddr;
  37 + resource_size_t extslotaddr;
  38 + resource_size_t devsize;
  39 + void __iomem *module;
  40 + struct tc_dev *tdev;
98 41 int i, slot, err;
99   - long offset;
100 42 u8 pattern[4];
101   - volatile u8 *module;
  43 + long offset;
102 44  
103   - for (slot = 0; slot < slots; slot++) {
104   - slotaddr = startaddr + slot * size;
105   - module = ioremap_nocache(slotaddr, size);
  45 + for (slot = 0; slot < tbus->num_tcslots; slot++) {
  46 + slotaddr = tbus->slot_base + slot * slotsize;
  47 + extslotaddr = tbus->ext_slot_base + slot * extslotsize;
  48 + module = ioremap_nocache(slotaddr, slotsize);
106 49 BUG_ON(!module);
107 50  
108   - offset = OLDCARD;
  51 + offset = TC_OLDCARD;
109 52  
110 53 err = 0;
111   - err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
112   - err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
113   - err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
114   - err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
115   - if (err) {
116   - iounmap(module);
117   - continue;
118   - }
  54 + err |= tc_preadb(pattern + 0, module + offset + TC_PATTERN0);
  55 + err |= tc_preadb(pattern + 1, module + offset + TC_PATTERN1);
  56 + err |= tc_preadb(pattern + 2, module + offset + TC_PATTERN2);
  57 + err |= tc_preadb(pattern + 3, module + offset + TC_PATTERN3);
  58 + if (err)
  59 + goto out_err;
119 60  
120 61 if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
121 62 pattern[2] != 0xaa || pattern[3] != 0xff) {
122   - offset = NEWCARD;
  63 + offset = TC_NEWCARD;
123 64  
124 65 err = 0;
125   - err |= get_dbe(pattern[0], module + TC_PATTERN0);
126   - err |= get_dbe(pattern[1], module + TC_PATTERN1);
127   - err |= get_dbe(pattern[2], module + TC_PATTERN2);
128   - err |= get_dbe(pattern[3], module + TC_PATTERN3);
129   - if (err) {
130   - iounmap(module);
131   - continue;
132   - }
  66 + err |= tc_preadb(pattern + 0,
  67 + module + offset + TC_PATTERN0);
  68 + err |= tc_preadb(pattern + 1,
  69 + module + offset + TC_PATTERN1);
  70 + err |= tc_preadb(pattern + 2,
  71 + module + offset + TC_PATTERN2);
  72 + err |= tc_preadb(pattern + 3,
  73 + module + offset + TC_PATTERN3);
  74 + if (err)
  75 + goto out_err;
133 76 }
134 77  
135 78 if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
136   - pattern[2] != 0xaa || pattern[3] != 0xff) {
137   - iounmap(module);
138   - continue;
  79 + pattern[2] != 0xaa || pattern[3] != 0xff)
  80 + goto out_err;
  81 +
  82 + /* Found a board, allocate it an entry in the list */
  83 + tdev = kzalloc(sizeof(*tdev), GFP_KERNEL);
  84 + if (!tdev) {
  85 + printk(KERN_ERR "tc%x: unable to allocate tc_dev\n",
  86 + slot);
  87 + goto out_err;
139 88 }
  89 + sprintf(tdev->dev.bus_id, "tc%x", slot);
  90 + tdev->bus = tbus;
  91 + tdev->dev.parent = &tbus->dev;
  92 + tdev->dev.bus = &tc_bus_type;
  93 + tdev->slot = slot;
140 94  
141   - tc_bus[slot].base_addr = slotaddr;
142 95 for (i = 0; i < 8; i++) {
143   - tc_bus[slot].firmware[i] =
144   - module[TC_FIRM_VER + offset + 4 * i];
145   - tc_bus[slot].vendor[i] =
146   - module[TC_VENDOR + offset + 4 * i];
147   - tc_bus[slot].name[i] =
148   - module[TC_MODULE + offset + 4 * i];
  96 + tdev->firmware[i] =
  97 + readb(module + offset + TC_FIRM_VER + 4 * i);
  98 + tdev->vendor[i] =
  99 + readb(module + offset + TC_VENDOR + 4 * i);
  100 + tdev->name[i] =
  101 + readb(module + offset + TC_MODULE + 4 * i);
149 102 }
150   - tc_bus[slot].firmware[8] = 0;
151   - tc_bus[slot].vendor[8] = 0;
152   - tc_bus[slot].name[8] = 0;
153   - /*
154   - * Looks unneccesary, but we may change
155   - * TC? in the future
156   - */
157   - switch (slot) {
158   - case 0:
159   - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
160   - break;
161   - case 1:
162   - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
163   - break;
164   - case 2:
165   - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
166   - break;
167   - /*
168   - * Yuck! DS5000/200 onboard devices
169   - */
170   - case 5:
171   - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
172   - break;
173   - case 6:
174   - tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
175   - break;
176   - default:
177   - tc_bus[slot].interrupt = -1;
178   - break;
  103 + tdev->firmware[8] = 0;
  104 + tdev->vendor[8] = 0;
  105 + tdev->name[8] = 0;
  106 +
  107 + pr_info("%s: %s %s %s\n", tdev->dev.bus_id, tdev->vendor,
  108 + tdev->name, tdev->firmware);
  109 +
  110 + devsize = readb(module + offset + TC_SLOT_SIZE);
  111 + devsize <<= 22;
  112 + if (devsize <= slotsize) {
  113 + tdev->resource.start = slotaddr;
  114 + tdev->resource.end = slotaddr + devsize - 1;
  115 + } else if (devsize <= extslotsize) {
  116 + tdev->resource.start = extslotaddr;
  117 + tdev->resource.end = extslotaddr + devsize - 1;
  118 + } else {
  119 + printk(KERN_ERR "%s: Cannot provide slot space "
  120 + "(%dMiB required, up to %dMiB supported)\n",
  121 + tdev->dev.bus_id, devsize >> 20,
  122 + max(slotsize, extslotsize) >> 20);
  123 + kfree(tdev);
  124 + goto out_err;
179 125 }
  126 + tdev->resource.name = tdev->name;
  127 + tdev->resource.flags = IORESOURCE_MEM;
180 128  
  129 + tc_device_get_irq(tdev);
  130 +
  131 + device_register(&tdev->dev);
  132 + list_add_tail(&tdev->node, &tbus->devices);
  133 +
  134 +out_err:
181 135 iounmap(module);
182 136 }
183 137 }
184 138  
185 139 /*
186   - * the main entry
  140 + * The main entry.
187 141 */
188 142 static int __init tc_init(void)
189 143 {
190   - int tc_clock;
191   - int i;
192   - unsigned long slot0addr;
193   - unsigned long slot_size;
194   -
195   - if (!TURBOCHANNEL)
  144 + /* Initialize the TURBOchannel bus */
  145 + if (tc_bus_get_info(&tc_bus))
196 146 return 0;
197 147  
198   - for (i = 0; i < MAX_SLOT; i++) {
199   - tc_bus[i].base_addr = 0;
200   - tc_bus[i].name[0] = 0;
201   - tc_bus[i].vendor[0] = 0;
202   - tc_bus[i].firmware[0] = 0;
203   - tc_bus[i].interrupt = -1;
204   - tc_bus[i].flags = FREE;
205   - }
  148 + INIT_LIST_HEAD(&tc_bus.devices);
  149 + strcpy(tc_bus.dev.bus_id, "tc");
  150 + device_register(&tc_bus.dev);
206 151  
207   - info = rex_gettcinfo();
208   - slot0addr = CPHYSADDR((long)rex_slot_address(0));
  152 + if (tc_bus.info.slot_size) {
  153 + unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000;
209 154  
210   - switch (mips_machtype) {
211   - case MACH_DS5000_200:
212   - num_tcslots = 7;
213   - break;
214   - case MACH_DS5000_1XX:
215   - case MACH_DS5000_2X0:
216   - case MACH_DS5900:
217   - num_tcslots = 3;
218   - break;
219   - case MACH_DS5000_XX:
220   - default:
221   - num_tcslots = 2;
222   - break;
223   - }
  155 + pr_info("tc: TURBOchannel rev. %d at %d.%d MHz "
  156 + "(with%s parity)\n", tc_bus.info.revision,
  157 + tc_clock / 10, tc_clock % 10,
  158 + tc_bus.info.parity ? "" : "out");
224 159  
225   - tc_clock = 10000 / info->clk_period;
226   -
227   - if (info->slot_size && slot0addr) {
228   - pr_info("TURBOchannel rev. %d at %d.%d MHz (with%s parity)\n",
229   - info->revision, tc_clock / 10, tc_clock % 10,
230   - info->parity ? "" : "out");
231   -
232   - slot_size = info->slot_size << 20;
233   -
234   - tc_probe(slot0addr, slot_size, num_tcslots);
235   -
236   - for (i = 0; i < num_tcslots; i++) {
237   - if (!tc_bus[i].base_addr)
238   - continue;
239   - pr_info(" slot %d: %s %s %s\n", i, tc_bus[i].vendor,
240   - tc_bus[i].name, tc_bus[i].firmware);
  160 + tc_bus.resource[0].start = tc_bus.slot_base;
  161 + tc_bus.resource[0].end = tc_bus.slot_base +
  162 + (tc_bus.info.slot_size << 20) *
  163 + tc_bus.num_tcslots;
  164 + tc_bus.resource[0].name = tc_bus.name;
  165 + tc_bus.resource[0].flags = IORESOURCE_MEM;
  166 + if (request_resource(&iomem_resource,
  167 + &tc_bus.resource[0]) < 0) {
  168 + printk(KERN_ERR "tc: Cannot reserve resource\n");
  169 + return 0;
241 170 }
  171 + if (tc_bus.ext_slot_size) {
  172 + tc_bus.resource[1].start = tc_bus.ext_slot_base;
  173 + tc_bus.resource[1].end = tc_bus.ext_slot_base +
  174 + tc_bus.ext_slot_size *
  175 + tc_bus.num_tcslots;
  176 + tc_bus.resource[1].name = tc_bus.name;
  177 + tc_bus.resource[1].flags = IORESOURCE_MEM;
  178 + if (request_resource(&iomem_resource,
  179 + &tc_bus.resource[1]) < 0) {
  180 + printk(KERN_ERR
  181 + "tc: Cannot reserve resource\n");
  182 + release_resource(&tc_bus.resource[0]);
  183 + return 0;
  184 + }
  185 + }
  186 +
  187 + tc_bus_add_devices(&tc_bus);
242 188 }
243 189  
244 190 return 0;
245 191 }
246 192  
247 193 subsys_initcall(tc_init);
248   -
249   -EXPORT_SYMBOL(search_tc_card);
250   -EXPORT_SYMBOL(claim_tc_card);
251   -EXPORT_SYMBOL(release_tc_card);
252   -EXPORT_SYMBOL(get_tc_base_addr);
253   -EXPORT_SYMBOL(get_tc_irq_nr);
254   -EXPORT_SYMBOL(get_tc_speed);
include/asm-mips/dec/tc.h
1   -/*
2   - * Interface to the TURBOchannel related routines
3   - *
4   - * This file is subject to the terms and conditions of the GNU General Public
5   - * License. See the file "COPYING" in the main directory of this archive
6   - * for more details.
7   - *
8   - * Copyright (c) 1998 Harald Koerfgen
9   - */
10   -#ifndef __ASM_DEC_TC_H
11   -#define __ASM_DEC_TC_H
12   -
13   -/*
14   - * Search for a TURBOchannel Option Module
15   - * with a certain name. Returns slot number
16   - * of the first card not in use or -ENODEV
17   - * if none found.
18   - */
19   -extern int search_tc_card(const char *);
20   -/*
21   - * Marks the card in slot as used
22   - */
23   -extern void claim_tc_card(int);
24   -/*
25   - * Marks the card in slot as free
26   - */
27   -extern void release_tc_card(int);
28   -/*
29   - * Return base address of card in slot
30   - */
31   -extern unsigned long get_tc_base_addr(int);
32   -/*
33   - * Return interrupt number of slot
34   - */
35   -extern unsigned long get_tc_irq_nr(int);
36   -/*
37   - * Return TURBOchannel clock frequency in Hz
38   - */
39   -extern unsigned long get_tc_speed(void);
40   -
41   -#endif /* __ASM_DEC_TC_H */
include/asm-mips/dec/tcinfo.h
1   -/*
2   - * Various TURBOchannel related stuff
3   - *
4   - * This file is subject to the terms and conditions of the GNU General Public
5   - * License. See the file "COPYING" in the main directory of this archive
6   - * for more details.
7   - *
8   - * Information obtained through the get_tcinfo prom call
9   - * created from:
10   - *
11   - * TURBOchannel Firmware Specification
12   - *
13   - * EK-TCAAD-FS-004
14   - * from Digital Equipment Corporation
15   - *
16   - * Copyright (c) 1998 Harald Koerfgen
17   - */
18   -
19   -typedef struct {
20   - int revision;
21   - int clk_period;
22   - int slot_size;
23   - int io_timeout;
24   - int dma_range;
25   - int max_dma_burst;
26   - int parity;
27   - int reserved[4];
28   -} tcinfo;
29   -
30   -#define MAX_SLOT 7
31   -
32   -typedef struct {
33   - unsigned long base_addr;
34   - unsigned char name[9];
35   - unsigned char vendor[9];
36   - unsigned char firmware[9];
37   - int interrupt;
38   - int flags;
39   -} slot_info;
40   -
41   -/*
42   - * Values for flags
43   - */
44   -#define FREE 1<<0
45   -#define IN_USE 1<<1
include/asm-mips/dec/tcmodule.h
1   -/*
2   - * This file is subject to the terms and conditions of the GNU General Public
3   - * License. See the file "COPYING" in the main directory of this archive
4   - * for more details.
5   - *
6   - * Offsets for the ROM header locations for
7   - * TURBOchannel cards
8   - *
9   - * created from:
10   - *
11   - * TURBOchannel Firmware Specification
12   - *
13   - * EK-TCAAD-FS-004
14   - * from Digital Equipment Corporation
15   - *
16   - * Jan.1998 Harald Koerfgen
17   - */
18   -#ifndef __ASM_DEC_TCMODULE_H
19   -#define __ASM_DEC_TCMODULE_H
20   -
21   -#define OLDCARD 0x3c0000
22   -#define NEWCARD 0x000000
23   -
24   -#define TC_ROM_WIDTH 0x3e0
25   -#define TC_ROM_STRIDE 0x3e4
26   -#define TC_ROM_SIZE 0x3e8
27   -#define TC_SLOT_SIZE 0x3ec
28   -#define TC_PATTERN0 0x3f0
29   -#define TC_PATTERN1 0x3f4
30   -#define TC_PATTERN2 0x3f8
31   -#define TC_PATTERN3 0x3fc
32   -#define TC_FIRM_VER 0x400
33   -#define TC_VENDOR 0x420
34   -#define TC_MODULE 0x440
35   -#define TC_FIRM_TYPE 0x460
36   -#define TC_FLAGS 0x470
37   -#define TC_ROM_OBJECTS 0x480
38   -
39   -#endif /* __ASM_DEC_TCMODULE_H */
  1 +/*
  2 + * Interface to the TURBOchannel related routines.
  3 + *
  4 + * Copyright (c) 1998 Harald Koerfgen
  5 + * Copyright (c) 2005 James Simmons
  6 + * Copyright (c) 2006 Maciej W. Rozycki
  7 + *
  8 + * Based on:
  9 + *
  10 + * "TURBOchannel Firmware Specification", EK-TCAAD-FS-004
  11 + *
  12 + * from Digital Equipment Corporation.
  13 + *
  14 + * This file is subject to the terms and conditions of the GNU
  15 + * General Public License. See the file "COPYING" in the main
  16 + * directory of this archive for more details.
  17 + */
  18 +#ifndef _LINUX_TC_H
  19 +#define _LINUX_TC_H
  20 +
  21 +#include <linux/compiler.h>
  22 +#include <linux/device.h>
  23 +#include <linux/ioport.h>
  24 +#include <linux/types.h>
  25 +
  26 +/*
  27 + * Offsets for the ROM header locations for TURBOchannel cards.
  28 + */
  29 +#define TC_OLDCARD 0x3c0000
  30 +#define TC_NEWCARD 0x000000
  31 +
  32 +#define TC_ROM_WIDTH 0x3e0
  33 +#define TC_ROM_STRIDE 0x3e4
  34 +#define TC_ROM_SIZE 0x3e8
  35 +#define TC_SLOT_SIZE 0x3ec
  36 +#define TC_PATTERN0 0x3f0
  37 +#define TC_PATTERN1 0x3f4
  38 +#define TC_PATTERN2 0x3f8
  39 +#define TC_PATTERN3 0x3fc
  40 +#define TC_FIRM_VER 0x400
  41 +#define TC_VENDOR 0x420
  42 +#define TC_MODULE 0x440
  43 +#define TC_FIRM_TYPE 0x460
  44 +#define TC_FLAGS 0x470
  45 +#define TC_ROM_OBJECTS 0x480
  46 +
  47 +/*
  48 + * Information obtained through the get_tcinfo() PROM call.
  49 + */
  50 +struct tcinfo {
  51 + s32 revision; /* Hardware revision level. */
  52 + s32 clk_period; /* Clock period in nanoseconds. */
  53 + s32 slot_size; /* Slot size in megabytes. */
  54 + s32 io_timeout; /* I/O timeout in cycles. */
  55 + s32 dma_range; /* DMA address range in megabytes. */
  56 + s32 max_dma_burst; /* Maximum DMA burst length. */
  57 + s32 parity; /* System module supports TC parity. */
  58 + s32 reserved[4];
  59 +};
  60 +
  61 +/*
  62 + * TURBOchannel bus.
  63 + */
  64 +struct tc_bus {
  65 + struct list_head devices; /* List of devices on this bus. */
  66 + struct resource resource[2]; /* Address space routed to this bus. */
  67 +
  68 + struct device dev;
  69 + char name[13];
  70 + resource_size_t slot_base;
  71 + resource_size_t ext_slot_base;
  72 + resource_size_t ext_slot_size;
  73 + int num_tcslots;
  74 + struct tcinfo info;
  75 +};
  76 +
  77 +/*
  78 + * TURBOchannel device.
  79 + */
  80 +struct tc_dev {
  81 + struct list_head node; /* Node in list of all TC devices. */
  82 + struct tc_bus *bus; /* Bus this device is on. */
  83 + struct tc_driver *driver; /* Which driver has allocated this
  84 + device. */
  85 + struct device dev; /* Generic device interface. */
  86 + struct resource resource; /* Address space of this device. */
  87 + char vendor[9];
  88 + char name[9];
  89 + char firmware[9];
  90 + int interrupt;
  91 + int slot;
  92 +};
  93 +
  94 +#define to_tc_dev(n) container_of(n, struct tc_dev, dev)
  95 +
  96 +struct tc_device_id {
  97 + char vendor[9];
  98 + char name[9];
  99 +};
  100 +
  101 +/*
  102 + * TURBOchannel driver.
  103 + */
  104 +struct tc_driver {
  105 + struct list_head node;
  106 + const struct tc_device_id *id_table;
  107 + struct device_driver driver;
  108 +};
  109 +
  110 +#define to_tc_driver(drv) container_of(drv, struct tc_driver, driver)
  111 +
  112 +/*
  113 + * Return TURBOchannel clock frequency in Hz.
  114 + */
  115 +static inline unsigned long tc_get_speed(struct tc_bus *tbus)
  116 +{
  117 + return 100000 * (10000 / (unsigned long)tbus->info.clk_period);
  118 +}
  119 +
  120 +#ifdef CONFIG_TC
  121 +
  122 +extern struct bus_type tc_bus_type;
  123 +
  124 +extern int tc_register_driver(struct tc_driver *tdrv);
  125 +extern void tc_unregister_driver(struct tc_driver *tdrv);
  126 +
  127 +#else /* !CONFIG_TC */
  128 +
  129 +static inline int tc_register_driver(struct tc_driver *tdrv) { return 0; }
  130 +static inline void tc_unregister_driver(struct tc_driver *tdrv) { }
  131 +
  132 +#endif /* CONFIG_TC */
  133 +
  134 +/*
  135 + * These have to be provided by the architecture.
  136 + */
  137 +extern int tc_preadb(u8 *valp, void __iomem *addr);
  138 +extern int tc_bus_get_info(struct tc_bus *tbus);
  139 +extern void tc_device_get_irq(struct tc_dev *tdev);
  140 +
  141 +#endif /* _LINUX_TC_H */