[SPARC]: sparc32 side of of_device layer IRQ resolution.

Happily, life is much simpler on 32-bit sparc systems.
The "intr" property, preferred over the "interrupts"
property is used-as. Some minor translations of this
value happen on sun4d systems.

The stage is now set to rewrite the sparc serial driver
probing to use the of_driver framework, and then to convert
all SBUS, EBUS, and ISA drivers in-kind so that we can nuke
all those special bus frameworks.

Signed-off-by: David S. Miller <davem@davemloft.net>

authored by David S. Miller and committed by David S. Miller 8f96cd1a 2b1e5978

+66 -8
+62 -7
arch/sparc/kernel/of_device.c
··· 129 return error; 130 } 131 132 #ifdef CONFIG_PCI 133 struct bus_type ebus_bus_type = { 134 .name = "ebus", ··· 523 struct device *parent) 524 { 525 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 526 - unsigned int *irq; 527 - int len; 528 529 if (!op) 530 return NULL; ··· 537 if (op->portid == -1) 538 op->portid = of_getintprop_default(dp, "portid", -1); 539 540 - irq = of_get_property(dp, "interrupts", &len); 541 - if (irq) 542 - op->irq = *irq; 543 - else 544 - op->irq = 0xffffffff; 545 546 build_device_resources(op, parent); 547
··· 129 return error; 130 } 131 132 + static int node_match(struct device *dev, void *data) 133 + { 134 + struct of_device *op = to_of_device(dev); 135 + struct device_node *dp = data; 136 + 137 + return (op->node == dp); 138 + } 139 + 140 + struct of_device *of_find_device_by_node(struct device_node *dp) 141 + { 142 + struct device *dev = bus_find_device(&of_bus_type, NULL, 143 + dp, node_match); 144 + 145 + if (dev) 146 + return to_of_device(dev); 147 + 148 + return NULL; 149 + } 150 + EXPORT_SYMBOL(of_find_device_by_node); 151 + 152 #ifdef CONFIG_PCI 153 struct bus_type ebus_bus_type = { 154 .name = "ebus", ··· 503 struct device *parent) 504 { 505 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 506 + struct linux_prom_irqs *intr; 507 + int len, i; 508 509 if (!op) 510 return NULL; ··· 517 if (op->portid == -1) 518 op->portid = of_getintprop_default(dp, "portid", -1); 519 520 + intr = of_get_property(dp, "intr", &len); 521 + if (intr) { 522 + op->num_irqs = len / sizeof(struct linux_prom_irqs); 523 + for (i = 0; i < op->num_irqs; i++) 524 + op->irqs[i] = intr[i].pri; 525 + } else { 526 + unsigned int *irq = of_get_property(dp, "interrupts", &len); 527 + 528 + if (irq) { 529 + op->num_irqs = len / sizeof(unsigned int); 530 + for (i = 0; i < op->num_irqs; i++) 531 + op->irqs[i] = irq[i]; 532 + } else { 533 + op->num_irqs = 0; 534 + } 535 + } 536 + if (sparc_cpu_model == sun4d) { 537 + static int pil_to_sbus[] = { 538 + 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, 539 + }; 540 + struct device_node *busp = dp->parent; 541 + struct linux_prom_registers *regs; 542 + int board = of_getintprop_default(busp, "board#", 0); 543 + int slot; 544 + 545 + regs = of_get_property(dp, "reg", NULL); 546 + slot = regs->which_io; 547 + 548 + for (i = 0; i < op->num_irqs; i++) { 549 + int this_irq = op->irqs[i]; 550 + int sbusl = pil_to_sbus[this_irq]; 551 + 552 + if (sbusl) 553 + this_irq = (((board + 1) << 5) + 554 + (sbusl << 2) + 555 + slot); 556 + 557 + op->irqs[i] = this_irq; 558 + } 559 + } 560 561 build_device_resources(op, parent); 562
+4 -1
include/asm-sparc/of_device.h
··· 21 struct device_node *node; 22 struct device dev; 23 struct resource resource[PROMREG_MAX]; 24 - unsigned int irq; 25 26 void *sysdata; 27 ··· 34 35 extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 36 extern void of_iounmap(void __iomem *base, unsigned long size); 37 38 extern const struct of_device_id *of_match_device( 39 const struct of_device_id *matches, const struct of_device *dev);
··· 21 struct device_node *node; 22 struct device dev; 23 struct resource resource[PROMREG_MAX]; 24 + unsigned int irqs[PROMINTR_MAX]; 25 + int num_irqs; 26 27 void *sysdata; 28 ··· 33 34 extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 35 extern void of_iounmap(void __iomem *base, unsigned long size); 36 + 37 + extern struct of_device *of_find_device_by_node(struct device_node *); 38 39 extern const struct of_device_id *of_match_device( 40 const struct of_device_id *matches, const struct of_device *dev);