diff options
Diffstat (limited to 'arch/sparc64/kernel/isa.c')
| -rw-r--r-- | arch/sparc64/kernel/isa.c | 329 |
1 files changed, 0 insertions, 329 deletions
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c deleted file mode 100644 index 30862abee61..00000000000 --- a/arch/sparc64/kernel/isa.c +++ /dev/null @@ -1,329 +0,0 @@ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/slab.h> -#include <asm/oplib.h> -#include <asm/isa.h> - -struct sparc_isa_bridge *isa_chain; - -static void __init fatal_err(const char *reason) -{ - prom_printf("ISA: fatal error, %s.\n", reason); -} - -static void __init report_dev(struct sparc_isa_device *isa_dev, int child) -{ - if (child) - printk(" (%s)", isa_dev->prom_name); - else - printk(" [%s", isa_dev->prom_name); -} - -static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev, - struct linux_prom_registers *pregs, - int pregs_size) -{ - unsigned long base, len; - int prop_len; - - prop_len = prom_getproperty(isa_dev->prom_node, "reg", - (char *) pregs, pregs_size); - - if (prop_len <= 0) - return; - - /* Only the first one is interesting. */ - len = pregs[0].reg_size; - base = (((unsigned long)pregs[0].which_io << 32) | - (unsigned long)pregs[0].phys_addr); - base += isa_dev->bus->parent->io_space.start; - - isa_dev->resource.start = base; - isa_dev->resource.end = (base + len - 1UL); - isa_dev->resource.flags = IORESOURCE_IO; - isa_dev->resource.name = isa_dev->prom_name; - - request_resource(&isa_dev->bus->parent->io_space, - &isa_dev->resource); -} - -/* I can't believe they didn't put a real INO in the isa device - * interrupts property. The whole point of the OBP properties - * is to shield the kernel from IRQ routing details. - * - * The P1275 standard for ISA devices seems to also have been - * totally ignored. - * - * On later systems, an interrupt-map and interrupt-map-mask scheme - * akin to EBUS is used. - */ -static struct { - int obp_irq; - int pci_ino; -} grover_irq_table[] = { - { 1, 0x00 }, /* dma, unknown ino at this point */ - { 2, 0x27 }, /* floppy */ - { 3, 0x22 }, /* parallel */ - { 4, 0x2b }, /* serial */ - { 5, 0x25 }, /* acpi power management */ - - { 0, 0x00 } /* end of table */ -}; - -static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev, - struct sparc_isa_bridge *isa_br, - int *interrupt, - struct linux_prom_registers *pregs) -{ - unsigned int hi, lo, irq; - int i; - - hi = pregs->which_io & isa_br->isa_intmask.phys_hi; - lo = pregs->phys_addr & isa_br->isa_intmask.phys_lo; - irq = *interrupt & isa_br->isa_intmask.interrupt; - for (i = 0; i < isa_br->num_isa_intmap; i++) { - if ((isa_br->isa_intmap[i].phys_hi == hi) && - (isa_br->isa_intmap[i].phys_lo == lo) && - (isa_br->isa_intmap[i].interrupt == irq)) { - *interrupt = isa_br->isa_intmap[i].cinterrupt; - return 0; - } - } - return -1; -} - -static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, - struct linux_prom_registers *pregs) -{ - int irq_prop; - - irq_prop = prom_getintdefault(isa_dev->prom_node, - "interrupts", -1); - if (irq_prop <= 0) { - goto no_irq; - } else { - struct pci_controller_info *pcic; - struct pci_pbm_info *pbm; - int i; - - if (isa_dev->bus->num_isa_intmap) { - if (!isa_dev_get_irq_using_imap(isa_dev, - isa_dev->bus, - &irq_prop, - pregs)) - goto route_irq; - } - - for (i = 0; grover_irq_table[i].obp_irq != 0; i++) { - if (grover_irq_table[i].obp_irq == irq_prop) { - int ino = grover_irq_table[i].pci_ino; - - if (ino == 0) - goto no_irq; - - irq_prop = ino; - goto route_irq; - } - } - goto no_irq; - -route_irq: - pbm = isa_dev->bus->parent; - pcic = pbm->parent; - isa_dev->irq = pcic->irq_build(pbm, NULL, irq_prop); - return; - } - -no_irq: - isa_dev->irq = PCI_IRQ_NONE; -} - -static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) -{ - int node = prom_getchild(parent_isa_dev->prom_node); - - if (node == 0) - return; - - printk(" ->"); - while (node != 0) { - struct linux_prom_registers regs[PROMREG_MAX]; - struct sparc_isa_device *isa_dev; - int prop_len; - - isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); - if (!isa_dev) { - fatal_err("cannot allocate child isa_dev"); - prom_halt(); - } - - memset(isa_dev, 0, sizeof(*isa_dev)); - - /* Link it in to parent. */ - isa_dev->next = parent_isa_dev->child; - parent_isa_dev->child = isa_dev; - - isa_dev->bus = parent_isa_dev->bus; - isa_dev->prom_node = node; - prop_len = prom_getproperty(node, "name", - (char *) isa_dev->prom_name, - sizeof(isa_dev->prom_name)); - if (prop_len <= 0) { - fatal_err("cannot get child isa_dev OBP node name"); - prom_halt(); - } - - prop_len = prom_getproperty(node, "compatible", - (char *) isa_dev->compatible, - sizeof(isa_dev->compatible)); - - /* Not having this is OK. */ - if (prop_len <= 0) - isa_dev->compatible[0] = '\0'; - - isa_dev_get_resource(isa_dev, regs, sizeof(regs)); - isa_dev_get_irq(isa_dev, regs); - - report_dev(isa_dev, 1); - - node = prom_getsibling(node); - } -} - -static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) -{ - int node = prom_getchild(isa_br->prom_node); - - while (node != 0) { - struct linux_prom_registers regs[PROMREG_MAX]; - struct sparc_isa_device *isa_dev; - int prop_len; - - isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); - if (!isa_dev) { - fatal_err("cannot allocate isa_dev"); - prom_halt(); - } - - memset(isa_dev, 0, sizeof(*isa_dev)); - - /* Link it in. */ - isa_dev->next = NULL; - if (isa_br->devices == NULL) { - isa_br->devices = isa_dev; - } else { - struct sparc_isa_device *tmp = isa_br->devices; - - while (tmp->next) - tmp = tmp->next; - - tmp->next = isa_dev; - } - - isa_dev->bus = isa_br; - isa_dev->prom_node = node; - prop_len = prom_getproperty(node, "name", - (char *) isa_dev->prom_name, - sizeof(isa_dev->prom_name)); - if (prop_len <= 0) { - fatal_err("cannot get isa_dev OBP node name"); - prom_halt(); - } - - prop_len = prom_getproperty(node, "compatible", - (char *) isa_dev->compatible, - sizeof(isa_dev->compatible)); - - /* Not having this is OK. */ - if (prop_len <= 0) - isa_dev->compatible[0] = '\0'; - - isa_dev_get_resource(isa_dev, regs, sizeof(regs)); - isa_dev_get_irq(isa_dev, regs); - - report_dev(isa_dev, 0); - - isa_fill_children(isa_dev); - - printk("]"); - - node = prom_getsibling(node); - } -} - -void __init isa_init(void) -{ - struct pci_dev *pdev; - unsigned short vendor, device; - int index = 0; - - vendor = PCI_VENDOR_ID_AL; - device = PCI_DEVICE_ID_AL_M1533; - - pdev = NULL; - while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) { - struct pcidev_cookie *pdev_cookie; - struct pci_pbm_info *pbm; - struct sparc_isa_bridge *isa_br; - int prop_len; - - pdev_cookie = pdev->sysdata; - if (!pdev_cookie) { - printk("ISA: Warning, ISA bridge ignored due to " - "lack of OBP data.\n"); - continue; - } - pbm = pdev_cookie->pbm; - - isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); - if (!isa_br) { - fatal_err("cannot allocate sparc_isa_bridge"); - prom_halt(); - } - - memset(isa_br, 0, sizeof(*isa_br)); - - /* Link it in. */ - isa_br->next = isa_chain; - isa_chain = isa_br; - - isa_br->parent = pbm; - isa_br->self = pdev; - isa_br->index = index++; - isa_br->prom_node = pdev_cookie->prom_node; - strncpy(isa_br->prom_name, pdev_cookie->prom_name, - sizeof(isa_br->prom_name)); - - prop_len = prom_getproperty(isa_br->prom_node, - "ranges", - (char *) isa_br->isa_ranges, - sizeof(isa_br->isa_ranges)); - if (prop_len <= 0) - isa_br->num_isa_ranges = 0; - else - isa_br->num_isa_ranges = - (prop_len / sizeof(struct linux_prom_isa_ranges)); - - prop_len = prom_getproperty(isa_br->prom_node, - "interrupt-map", - (char *) isa_br->isa_intmap, - sizeof(isa_br->isa_intmap)); - if (prop_len <= 0) - isa_br->num_isa_intmap = 0; - else - isa_br->num_isa_intmap = - (prop_len / sizeof(struct linux_prom_isa_intmap)); - - prop_len = prom_getproperty(isa_br->prom_node, - "interrupt-map-mask", - (char *) &(isa_br->isa_intmask), - sizeof(isa_br->isa_intmask)); - - printk("isa%d:", isa_br->index); - - isa_fill_devices(isa_br); - - printk("\n"); - } -} |
