1 #include <linux/kernel.h>
2 #include <linux/init.h>
4 #include <linux/slab.h>
8 struct sparc_isa_bridge *isa_chain;
10 static void __init fatal_err(const char *reason)
12 prom_printf("ISA: fatal error, %s.\n", reason);
15 static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
18 printk(" (%s)", isa_dev->prom_name);
20 printk(" [%s", isa_dev->prom_name);
23 static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
24 struct linux_prom_registers *pregs,
27 unsigned long base, len;
30 prop_len = prom_getproperty(isa_dev->prom_node, "reg",
31 (char *) pregs, pregs_size);
36 /* Only the first one is interesting. */
37 len = pregs[0].reg_size;
38 base = (((unsigned long)pregs[0].which_io << 32) |
39 (unsigned long)pregs[0].phys_addr);
40 base += isa_dev->bus->parent->io_space.start;
42 isa_dev->resource.start = base;
43 isa_dev->resource.end = (base + len - 1UL);
44 isa_dev->resource.flags = IORESOURCE_IO;
45 isa_dev->resource.name = isa_dev->prom_name;
47 request_resource(&isa_dev->bus->parent->io_space,
51 /* I can't believe they didn't put a real INO in the isa device
52 * interrupts property. The whole point of the OBP properties
53 * is to shield the kernel from IRQ routing details.
55 * The P1275 standard for ISA devices seems to also have been
58 * On later systems, an interrupt-map and interrupt-map-mask scheme
59 * akin to EBUS is used.
64 } grover_irq_table[] = {
65 { 1, 0x00 }, /* dma, unknown ino at this point */
66 { 2, 0x27 }, /* floppy */
67 { 3, 0x22 }, /* parallel */
68 { 4, 0x2b }, /* serial */
69 { 5, 0x25 }, /* acpi power management */
71 { 0, 0x00 } /* end of table */
74 static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev,
75 struct sparc_isa_bridge *isa_br,
77 struct linux_prom_registers *pregs)
79 unsigned int hi, lo, irq;
82 hi = pregs->which_io & isa_br->isa_intmask.phys_hi;
83 lo = pregs->phys_addr & isa_br->isa_intmask.phys_lo;
84 irq = *interrupt & isa_br->isa_intmask.interrupt;
85 for (i = 0; i < isa_br->num_isa_intmap; i++) {
86 if ((isa_br->isa_intmap[i].phys_hi == hi) &&
87 (isa_br->isa_intmap[i].phys_lo == lo) &&
88 (isa_br->isa_intmap[i].interrupt == irq)) {
89 *interrupt = isa_br->isa_intmap[i].cinterrupt;
96 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
97 struct linux_prom_registers *pregs)
101 irq_prop = prom_getintdefault(isa_dev->prom_node,
106 struct pci_controller_info *pcic;
107 struct pci_pbm_info *pbm;
110 if (isa_dev->bus->num_isa_intmap) {
111 if (!isa_dev_get_irq_using_imap(isa_dev,
118 for (i = 0; grover_irq_table[i].obp_irq != 0; i++) {
119 if (grover_irq_table[i].obp_irq == irq_prop) {
120 int ino = grover_irq_table[i].pci_ino;
132 pbm = isa_dev->bus->parent;
134 isa_dev->irq = pcic->irq_build(pbm, NULL, irq_prop);
139 isa_dev->irq = PCI_IRQ_NONE;
142 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
144 int node = prom_getchild(parent_isa_dev->prom_node);
151 struct linux_prom_registers regs[PROMREG_MAX];
152 struct sparc_isa_device *isa_dev;
155 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
157 fatal_err("cannot allocate child isa_dev");
161 memset(isa_dev, 0, sizeof(*isa_dev));
163 /* Link it in to parent. */
164 isa_dev->next = parent_isa_dev->child;
165 parent_isa_dev->child = isa_dev;
167 isa_dev->bus = parent_isa_dev->bus;
168 isa_dev->prom_node = node;
169 prop_len = prom_getproperty(node, "name",
170 (char *) isa_dev->prom_name,
171 sizeof(isa_dev->prom_name));
173 fatal_err("cannot get child isa_dev OBP node name");
177 prop_len = prom_getproperty(node, "compatible",
178 (char *) isa_dev->compatible,
179 sizeof(isa_dev->compatible));
181 /* Not having this is OK. */
183 isa_dev->compatible[0] = '\0';
185 isa_dev_get_resource(isa_dev, regs, sizeof(regs));
186 isa_dev_get_irq(isa_dev, regs);
188 report_dev(isa_dev, 1);
190 node = prom_getsibling(node);
194 static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
196 int node = prom_getchild(isa_br->prom_node);
199 struct linux_prom_registers regs[PROMREG_MAX];
200 struct sparc_isa_device *isa_dev;
203 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
205 fatal_err("cannot allocate isa_dev");
209 memset(isa_dev, 0, sizeof(*isa_dev));
212 isa_dev->next = NULL;
213 if (isa_br->devices == NULL) {
214 isa_br->devices = isa_dev;
216 struct sparc_isa_device *tmp = isa_br->devices;
224 isa_dev->bus = isa_br;
225 isa_dev->prom_node = node;
226 prop_len = prom_getproperty(node, "name",
227 (char *) isa_dev->prom_name,
228 sizeof(isa_dev->prom_name));
230 fatal_err("cannot get isa_dev OBP node name");
234 prop_len = prom_getproperty(node, "compatible",
235 (char *) isa_dev->compatible,
236 sizeof(isa_dev->compatible));
238 /* Not having this is OK. */
240 isa_dev->compatible[0] = '\0';
242 isa_dev_get_resource(isa_dev, regs, sizeof(regs));
243 isa_dev_get_irq(isa_dev, regs);
245 report_dev(isa_dev, 0);
247 isa_fill_children(isa_dev);
251 node = prom_getsibling(node);
255 void __init isa_init(void)
257 struct pci_dev *pdev;
258 unsigned short vendor, device;
261 vendor = PCI_VENDOR_ID_AL;
262 device = PCI_DEVICE_ID_AL_M1533;
265 while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) {
266 struct pcidev_cookie *pdev_cookie;
267 struct pci_pbm_info *pbm;
268 struct sparc_isa_bridge *isa_br;
271 pdev_cookie = pdev->sysdata;
273 printk("ISA: Warning, ISA bridge ignored due to "
274 "lack of OBP data.\n");
277 pbm = pdev_cookie->pbm;
279 isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
281 fatal_err("cannot allocate sparc_isa_bridge");
285 memset(isa_br, 0, sizeof(*isa_br));
288 isa_br->next = isa_chain;
291 isa_br->parent = pbm;
293 isa_br->index = index++;
294 isa_br->prom_node = pdev_cookie->prom_node;
295 strncpy(isa_br->prom_name, pdev_cookie->prom_name,
296 sizeof(isa_br->prom_name));
298 prop_len = prom_getproperty(isa_br->prom_node,
300 (char *) isa_br->isa_ranges,
301 sizeof(isa_br->isa_ranges));
303 isa_br->num_isa_ranges = 0;
305 isa_br->num_isa_ranges =
306 (prop_len / sizeof(struct linux_prom_isa_ranges));
308 prop_len = prom_getproperty(isa_br->prom_node,
310 (char *) isa_br->isa_intmap,
311 sizeof(isa_br->isa_intmap));
313 isa_br->num_isa_intmap = 0;
315 isa_br->num_isa_intmap =
316 (prop_len / sizeof(struct linux_prom_isa_intmap));
318 prop_len = prom_getproperty(isa_br->prom_node,
319 "interrupt-map-mask",
320 (char *) &(isa_br->isa_intmask),
321 sizeof(isa_br->isa_intmask));
323 printk("isa%d:", isa_br->index);
325 isa_fill_devices(isa_br);