[SPARC64]: Fix typo in isa_dev_get_irq_using_imap().
[pandora-kernel.git] / arch / sparc64 / kernel / isa.c
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/isa.h>
7
8 struct sparc_isa_bridge *isa_chain;
9
10 static void __init fatal_err(const char *reason)
11 {
12         prom_printf("ISA: fatal error, %s.\n", reason);
13 }
14
15 static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
16 {
17         if (child)
18                 printk(" (%s)", isa_dev->prom_node->name);
19         else
20                 printk(" [%s", isa_dev->prom_node->name);
21 }
22
23 static struct linux_prom_registers * __init
24 isa_dev_get_resource(struct sparc_isa_device *isa_dev)
25 {
26         struct linux_prom_registers *pregs;
27         unsigned long base, len;
28         int prop_len;
29
30         pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
31
32         /* Only the first one is interesting. */
33         len = pregs[0].reg_size;
34         base = (((unsigned long)pregs[0].which_io << 32) |
35                 (unsigned long)pregs[0].phys_addr);
36         base += isa_dev->bus->parent->io_space.start;
37
38         isa_dev->resource.start = base;
39         isa_dev->resource.end   = (base + len - 1UL);
40         isa_dev->resource.flags = IORESOURCE_IO;
41         isa_dev->resource.name  = isa_dev->prom_node->name;
42
43         request_resource(&isa_dev->bus->parent->io_space,
44                          &isa_dev->resource);
45
46         return pregs;
47 }
48
49 /* I can't believe they didn't put a real INO in the isa device
50  * interrupts property.  The whole point of the OBP properties
51  * is to shield the kernel from IRQ routing details.
52  *
53  * The P1275 standard for ISA devices seems to also have been
54  * totally ignored.
55  *
56  * On later systems, an interrupt-map and interrupt-map-mask scheme
57  * akin to EBUS is used.
58  */
59 static struct {
60         int     obp_irq;
61         int     pci_ino;
62 } grover_irq_table[] = {
63         { 1, 0x00 },    /* dma, unknown ino at this point */
64         { 2, 0x27 },    /* floppy */
65         { 3, 0x22 },    /* parallel */
66         { 4, 0x2b },    /* serial */
67         { 5, 0x25 },    /* acpi power management */
68
69         { 0, 0x00 }     /* end of table */
70 };
71
72 static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev,
73                                              struct sparc_isa_bridge *isa_br,
74                                              int *interrupt,
75                                              struct linux_prom_registers *reg)
76 {
77         struct linux_prom_ebus_intmap *imap;
78         struct linux_prom_ebus_intmask *imask;
79         unsigned int hi, lo, irq;
80         int i, len, n_imap;
81
82         imap = of_get_property(isa_br->prom_node, "interrupt-map", &len);
83         if (!imap)
84                 return 0;
85         n_imap = len / sizeof(imap[0]);
86
87         imask = of_get_property(isa_br->prom_node, "interrupt-map-mask", NULL);
88         if (!imask)
89                 return 0;
90
91         hi = reg->which_io & imask->phys_hi;
92         lo = reg->phys_addr & imask->phys_lo;
93         irq = *interrupt & imask->interrupt;
94         for (i = 0; i < n_imap; i++) {
95                 if ((imap[i].phys_hi == hi) &&
96                     (imap[i].phys_lo == lo) &&
97                     (imap[i].interrupt == irq)) {
98                         *interrupt = imap[i].cinterrupt;
99                         return 0;
100                 }
101         }
102         return -1;
103 }
104
105 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
106                                    struct linux_prom_registers *pregs)
107 {
108         int irq_prop;
109
110         irq_prop = of_getintprop_default(isa_dev->prom_node,
111                                          "interrupts", -1);
112         if (irq_prop <= 0) {
113                 goto no_irq;
114         } else {
115                 struct pci_controller_info *pcic;
116                 struct pci_pbm_info *pbm;
117                 int i;
118
119                 if (of_find_property(isa_dev->bus->prom_node,
120                                      "interrupt-map", NULL)) {
121                         if (!isa_dev_get_irq_using_imap(isa_dev,
122                                                         isa_dev->bus,
123                                                         &irq_prop,
124                                                         pregs))
125                                 goto route_irq;
126                 }
127
128                 for (i = 0; grover_irq_table[i].obp_irq != 0; i++) {
129                         if (grover_irq_table[i].obp_irq == irq_prop) {
130                                 int ino = grover_irq_table[i].pci_ino;
131
132                                 if (ino == 0)
133                                         goto no_irq;
134  
135                                 irq_prop = ino;
136                                 goto route_irq;
137                         }
138                 }
139                 goto no_irq;
140
141 route_irq:
142                 pbm = isa_dev->bus->parent;
143                 pcic = pbm->parent;
144                 isa_dev->irq = pcic->irq_build(pbm, NULL, irq_prop);
145                 return;
146         }
147
148 no_irq:
149         isa_dev->irq = PCI_IRQ_NONE;
150 }
151
152 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
153 {
154         struct device_node *dp = parent_isa_dev->prom_node->child;
155
156         if (!dp)
157                 return;
158
159         printk(" ->");
160         while (dp) {
161                 struct linux_prom_registers *regs;
162                 struct sparc_isa_device *isa_dev;
163
164                 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
165                 if (!isa_dev) {
166                         fatal_err("cannot allocate child isa_dev");
167                         prom_halt();
168                 }
169
170                 memset(isa_dev, 0, sizeof(*isa_dev));
171
172                 /* Link it in to parent. */
173                 isa_dev->next = parent_isa_dev->child;
174                 parent_isa_dev->child = isa_dev;
175
176                 isa_dev->bus = parent_isa_dev->bus;
177                 isa_dev->prom_node = dp;
178
179                 regs = isa_dev_get_resource(isa_dev);
180                 isa_dev_get_irq(isa_dev, regs);
181
182                 report_dev(isa_dev, 1);
183
184                 dp = dp->sibling;
185         }
186 }
187
188 static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
189 {
190         struct device_node *dp = isa_br->prom_node->child;
191
192         while (dp) {
193                 struct linux_prom_registers *regs;
194                 struct sparc_isa_device *isa_dev;
195
196                 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
197                 if (!isa_dev) {
198                         printk(KERN_DEBUG "ISA: cannot allocate isa_dev");
199                         return;
200                 }
201
202                 memset(isa_dev, 0, sizeof(*isa_dev));
203
204                 isa_dev->ofdev.node = dp;
205                 isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
206                 isa_dev->ofdev.dev.bus = &isa_bus_type;
207                 strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name);
208
209                 /* Register with core */
210                 if (of_device_register(&isa_dev->ofdev) != 0) {
211                         printk(KERN_DEBUG "isa: device registration error for %s!\n",
212                                isa_dev->ofdev.dev.bus_id);
213                         kfree(isa_dev);
214                         goto next_sibling;
215                 }
216
217                 /* Link it in. */
218                 isa_dev->next = NULL;
219                 if (isa_br->devices == NULL) {
220                         isa_br->devices = isa_dev;
221                 } else {
222                         struct sparc_isa_device *tmp = isa_br->devices;
223
224                         while (tmp->next)
225                                 tmp = tmp->next;
226
227                         tmp->next = isa_dev;
228                 }
229
230                 isa_dev->bus = isa_br;
231                 isa_dev->prom_node = dp;
232
233                 regs = isa_dev_get_resource(isa_dev);
234                 isa_dev_get_irq(isa_dev, regs);
235
236                 report_dev(isa_dev, 0);
237
238                 isa_fill_children(isa_dev);
239
240                 printk("]");
241
242         next_sibling:
243                 dp = dp->sibling;
244         }
245 }
246
247 void __init isa_init(void)
248 {
249         struct pci_dev *pdev;
250         unsigned short vendor, device;
251         int index = 0;
252
253         vendor = PCI_VENDOR_ID_AL;
254         device = PCI_DEVICE_ID_AL_M1533;
255
256         pdev = NULL;
257         while ((pdev = pci_get_device(vendor, device, pdev)) != NULL) {
258                 struct pcidev_cookie *pdev_cookie;
259                 struct pci_pbm_info *pbm;
260                 struct sparc_isa_bridge *isa_br;
261                 struct device_node *dp;
262
263                 pdev_cookie = pdev->sysdata;
264                 if (!pdev_cookie) {
265                         printk("ISA: Warning, ISA bridge ignored due to "
266                                "lack of OBP data.\n");
267                         continue;
268                 }
269                 pbm = pdev_cookie->pbm;
270                 dp = pdev_cookie->prom_node;
271
272                 isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
273                 if (!isa_br) {
274                         printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge");
275                         return;
276                 }
277
278                 memset(isa_br, 0, sizeof(*isa_br));
279
280                 isa_br->ofdev.node = dp;
281                 isa_br->ofdev.dev.parent = &pdev->dev;
282                 isa_br->ofdev.dev.bus = &isa_bus_type;
283                 strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name);
284
285                 /* Register with core */
286                 if (of_device_register(&isa_br->ofdev) != 0) {
287                         printk(KERN_DEBUG "isa: device registration error for %s!\n",
288                                isa_br->ofdev.dev.bus_id);
289                         kfree(isa_br);
290                         return;
291                 }
292
293                 /* Link it in. */
294                 isa_br->next = isa_chain;
295                 isa_chain = isa_br;
296
297                 isa_br->parent = pbm;
298                 isa_br->self = pdev;
299                 isa_br->index = index++;
300                 isa_br->prom_node = pdev_cookie->prom_node;
301
302                 printk("isa%d:", isa_br->index);
303
304                 isa_fill_devices(isa_br);
305
306                 printk("\n");
307         }
308 }