1#include <linux/kernel.h> 2#include <linux/init.h> 3#include <linux/pci.h> 4#include <linux/slab.h> 5#include <asm/oplib.h> 6#include <asm/prom.h> 7#include <asm/of_device.h> 8#include <asm/isa.h> 9 10struct sparc_isa_bridge *isa_chain; 11 12static void __init fatal_err(const char *reason) 13{ 14 prom_printf("ISA: fatal error, %s.\n", reason); 15} 16 17static void __init report_dev(struct sparc_isa_device *isa_dev, int child) 18{ 19 if (child) 20 printk(" (%s)", isa_dev->prom_node->name); 21 else 22 printk(" [%s", isa_dev->prom_node->name); 23} 24 25static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev) 26{ 27 struct of_device *op = of_find_device_by_node(isa_dev->prom_node); 28 29 memcpy(&isa_dev->resource, &op->resource[0], sizeof(struct resource)); 30} 31 32static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev) 33{ 34 struct of_device *op = of_find_device_by_node(isa_dev->prom_node); 35 36 if (!op || !op->num_irqs) { 37 isa_dev->irq = PCI_IRQ_NONE; 38 } else { 39 isa_dev->irq = op->irqs[0]; 40 } 41} 42 43static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) 44{ 45 struct device_node *dp = parent_isa_dev->prom_node->child; 46 47 if (!dp) 48 return; 49 50 printk(" ->"); 51 while (dp) { 52 struct sparc_isa_device *isa_dev; 53 54 isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); 55 if (!isa_dev) { 56 fatal_err("cannot allocate child isa_dev"); 57 prom_halt(); 58 } 59 60 /* Link it in to parent. */ 61 isa_dev->next = parent_isa_dev->child; 62 parent_isa_dev->child = isa_dev; 63 64 isa_dev->bus = parent_isa_dev->bus; 65 isa_dev->prom_node = dp; 66 67 isa_dev_get_resource(isa_dev); 68 isa_dev_get_irq(isa_dev); 69 70 report_dev(isa_dev, 1); 71 72 dp = dp->sibling; 73 } 74} 75 76static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) 77{ 78 struct device_node *dp = isa_br->prom_node->child; 79 80 while (dp) { 81 struct sparc_isa_device *isa_dev; 82 83 isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); 84 if (!isa_dev) { 85 printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); 86 return; 87 } 88 89 isa_dev->ofdev.node = dp; 90 isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; 91 isa_dev->ofdev.dev.bus = &isa_bus_type; 92 sprintf(isa_dev->ofdev.dev.bus_id, "isa[%08x]", dp->node); 93 94 /* Register with core */ 95 if (of_device_register(&isa_dev->ofdev) != 0) { 96 printk(KERN_DEBUG "isa: device registration error for %s!\n", 97 dp->path_component_name); 98 kfree(isa_dev); 99 goto next_sibling; 100 } 101 102 /* Link it in. */ 103 isa_dev->next = NULL; 104 if (isa_br->devices == NULL) { 105 isa_br->devices = isa_dev; 106 } else { 107 struct sparc_isa_device *tmp = isa_br->devices; 108 109 while (tmp->next) 110 tmp = tmp->next; 111 112 tmp->next = isa_dev; 113 } 114 115 isa_dev->bus = isa_br; 116 isa_dev->prom_node = dp; 117 118 isa_dev_get_resource(isa_dev); 119 isa_dev_get_irq(isa_dev); 120 121 report_dev(isa_dev, 0); 122 123 isa_fill_children(isa_dev); 124 125 printk("]"); 126 127 next_sibling: 128 dp = dp->sibling; 129 } 130} 131 132void __init isa_init(void) 133{ 134 struct pci_dev *pdev; 135 unsigned short vendor, device; 136 int index = 0; 137 138 vendor = PCI_VENDOR_ID_AL; 139 device = PCI_DEVICE_ID_AL_M1533; 140 141 pdev = NULL; 142 while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) { 143 struct sparc_isa_bridge *isa_br; 144 struct device_node *dp; 145 146 dp = pci_device_to_OF_node(pdev); 147 148 isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL); 149 if (!isa_br) { 150 printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); 151 return; 152 } 153 154 isa_br->ofdev.node = dp; 155 isa_br->ofdev.dev.parent = &pdev->dev; 156 isa_br->ofdev.dev.bus = &isa_bus_type; 157 sprintf(isa_br->ofdev.dev.bus_id, "isa%d", index); 158 159 /* Register with core */ 160 if (of_device_register(&isa_br->ofdev) != 0) { 161 printk(KERN_DEBUG "isa: device registration error for %s!\n", 162 dp->path_component_name); 163 kfree(isa_br); 164 return; 165 } 166 167 /* Link it in. */ 168 isa_br->next = isa_chain; 169 isa_chain = isa_br; 170 171 isa_br->self = pdev; 172 isa_br->index = index++; 173 isa_br->prom_node = dp; 174 175 printk("isa%d:", isa_br->index); 176 177 isa_fill_devices(isa_br); 178 179 printk("\n"); 180 } 181} 182