diff options
| -rw-r--r-- | arch/sparc/kernel/of_device.c | 69 | ||||
| -rw-r--r-- | include/asm-sparc/of_device.h | 5 |
2 files changed, 66 insertions, 8 deletions
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 3ebe6cc71e71..bc956c530376 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c | |||
| @@ -129,6 +129,26 @@ static int of_device_resume(struct device * dev) | |||
| 129 | return error; | 129 | return error; |
| 130 | } | 130 | } |
| 131 | 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 | |||
| 132 | #ifdef CONFIG_PCI | 152 | #ifdef CONFIG_PCI |
| 133 | struct bus_type ebus_bus_type = { | 153 | struct bus_type ebus_bus_type = { |
| 134 | .name = "ebus", | 154 | .name = "ebus", |
| @@ -503,8 +523,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
| 503 | struct device *parent) | 523 | struct device *parent) |
| 504 | { | 524 | { |
| 505 | struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); | 525 | struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); |
| 506 | unsigned int *irq; | 526 | struct linux_prom_irqs *intr; |
| 507 | int len; | 527 | int len, i; |
| 508 | 528 | ||
| 509 | if (!op) | 529 | if (!op) |
| 510 | return NULL; | 530 | return NULL; |
| @@ -517,11 +537,46 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
| 517 | if (op->portid == -1) | 537 | if (op->portid == -1) |
| 518 | op->portid = of_getintprop_default(dp, "portid", -1); | 538 | op->portid = of_getintprop_default(dp, "portid", -1); |
| 519 | 539 | ||
| 520 | irq = of_get_property(dp, "interrupts", &len); | 540 | intr = of_get_property(dp, "intr", &len); |
| 521 | if (irq) | 541 | if (intr) { |
| 522 | op->irq = *irq; | 542 | op->num_irqs = len / sizeof(struct linux_prom_irqs); |
| 523 | else | 543 | for (i = 0; i < op->num_irqs; i++) |
| 524 | op->irq = 0xffffffff; | 544 | op->irqs[i] = intr[i].pri; |
| 545 | } else { | ||
| 546 | unsigned int *irq = of_get_property(dp, "interrupts", &len); | ||
| 547 | |||
| 548 | if (irq) { | ||
| 549 | op->num_irqs = len / sizeof(unsigned int); | ||
| 550 | for (i = 0; i < op->num_irqs; i++) | ||
| 551 | op->irqs[i] = irq[i]; | ||
| 552 | } else { | ||
| 553 | op->num_irqs = 0; | ||
| 554 | } | ||
| 555 | } | ||
| 556 | if (sparc_cpu_model == sun4d) { | ||
| 557 | static int pil_to_sbus[] = { | ||
| 558 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, | ||
| 559 | }; | ||
| 560 | struct device_node *busp = dp->parent; | ||
| 561 | struct linux_prom_registers *regs; | ||
| 562 | int board = of_getintprop_default(busp, "board#", 0); | ||
| 563 | int slot; | ||
| 564 | |||
| 565 | regs = of_get_property(dp, "reg", NULL); | ||
| 566 | slot = regs->which_io; | ||
| 567 | |||
| 568 | for (i = 0; i < op->num_irqs; i++) { | ||
| 569 | int this_irq = op->irqs[i]; | ||
| 570 | int sbusl = pil_to_sbus[this_irq]; | ||
| 571 | |||
| 572 | if (sbusl) | ||
| 573 | this_irq = (((board + 1) << 5) + | ||
| 574 | (sbusl << 2) + | ||
| 575 | slot); | ||
| 576 | |||
| 577 | op->irqs[i] = this_irq; | ||
| 578 | } | ||
| 579 | } | ||
| 525 | 580 | ||
| 526 | build_device_resources(op, parent); | 581 | build_device_resources(op, parent); |
| 527 | 582 | ||
diff --git a/include/asm-sparc/of_device.h b/include/asm-sparc/of_device.h index b5ca3145d48b..80ea31f6e17f 100644 --- a/include/asm-sparc/of_device.h +++ b/include/asm-sparc/of_device.h | |||
| @@ -21,7 +21,8 @@ struct of_device | |||
| 21 | struct device_node *node; | 21 | struct device_node *node; |
| 22 | struct device dev; | 22 | struct device dev; |
| 23 | struct resource resource[PROMREG_MAX]; | 23 | struct resource resource[PROMREG_MAX]; |
| 24 | unsigned int irq; | 24 | unsigned int irqs[PROMINTR_MAX]; |
| 25 | int num_irqs; | ||
| 25 | 26 | ||
| 26 | void *sysdata; | 27 | void *sysdata; |
| 27 | 28 | ||
| @@ -34,6 +35,8 @@ struct of_device | |||
| 34 | extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); | 35 | 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 | extern void of_iounmap(void __iomem *base, unsigned long size); |
| 36 | 37 | ||
| 38 | extern struct of_device *of_find_device_by_node(struct device_node *); | ||
| 39 | |||
| 37 | extern const struct of_device_id *of_match_device( | 40 | extern const struct of_device_id *of_match_device( |
| 38 | const struct of_device_id *matches, const struct of_device *dev); | 41 | const struct of_device_id *matches, const struct of_device *dev); |
| 39 | 42 | ||
