From 1636f8ac2b08410df4766449f7c86b912443cd99 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:09:58 -0600 Subject: sparc/of: Move of_device fields into struct pdev_archdata This patch moves SPARC architecture specific data members out of struct of_device and into the pdev_archdata structure. The reason for this change is to unify the struct of_device definition amongst all the architectures. It also remvoes the .sysdata, .slot, .portid and .clock_freq properties because they aren't actually used by anything. A subsequent patch will replace struct of_device entirely with struct platform_device and the of_platform support code will share common routines with the platform bus (but the bus instances themselves can remain separate). This patch also adds 'struct resources *resource' and num_resources to match the fields defined in struct platform_device. After this change, 'struct platform_device' can be used as a drop-in replacement for 'struct of_platform'. This change is in preparation for merging the of_platform_bus_type with the platform_bus_type. Signed-off-by: Grant Likely Acked-by: David S. Miller Cc: Stephen Rothwell --- arch/sparc/include/asm/device.h | 5 +++++ arch/sparc/include/asm/floppy_64.h | 4 ++-- arch/sparc/include/asm/of_device.h | 11 +++-------- arch/sparc/include/asm/parport.h | 4 ++-- arch/sparc/kernel/of_device_32.c | 28 ++++++++++++---------------- arch/sparc/kernel/of_device_64.c | 24 ++++++++++-------------- arch/sparc/kernel/of_device_common.c | 4 ++-- arch/sparc/kernel/pci.c | 2 +- arch/sparc/kernel/pci_psycho.c | 8 ++++---- arch/sparc/kernel/pci_sabre.c | 8 ++++---- arch/sparc/kernel/pci_schizo.c | 20 ++++++++++---------- arch/sparc/kernel/power.c | 2 +- 12 files changed, 56 insertions(+), 64 deletions(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index d4c452147412..f9740d065fe7 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -6,6 +6,8 @@ #ifndef _ASM_SPARC_DEVICE_H #define _ASM_SPARC_DEVICE_H +#include + struct device_node; struct of_device; @@ -18,6 +20,9 @@ struct dev_archdata { }; struct pdev_archdata { + struct resource resource[PROMREG_MAX]; + unsigned int irqs[PROMINTR_MAX]; + int num_irqs; }; #endif /* _ASM_SPARC_DEVICE_H */ diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 8fac3ab22f36..4f5bde638f72 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -567,7 +567,7 @@ static unsigned long __init sun_floppy_init(void) } if (op) { floppy_op = op; - FLOPPY_IRQ = op->irqs[0]; + FLOPPY_IRQ = op->archdata.irqs[0]; } else { struct device_node *ebus_dp; void __iomem *auxio_reg; @@ -593,7 +593,7 @@ static unsigned long __init sun_floppy_init(void) if (state_prop && !strncmp(state_prop, "disabled", 8)) return 0; - FLOPPY_IRQ = op->irqs[0]; + FLOPPY_IRQ = op->archdata.irqs[0]; /* Make sure the high density bit is set, some systems * (most notably Ultra5/Ultra10) come up with it clear. diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index f320246a0586..6d1844a547b4 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -15,15 +15,10 @@ struct of_device { struct device dev; - struct resource resource[PROMREG_MAX]; - unsigned int irqs[PROMINTR_MAX]; - int num_irqs; + u32 num_resources; + struct resource *resource; - void *sysdata; - - int slot; - int portid; - int clock_freq; + struct pdev_archdata archdata; }; extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index c333b8d0949b..0c34a8792fc7 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -116,7 +116,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id parent = op->dev.of_node->parent; if (!strcmp(parent->name, "dma")) { p = parport_pc_probe_port(base, base + 0x400, - op->irqs[0], PARPORT_DMA_NOFIFO, + op->archdata.irqs[0], PARPORT_DMA_NOFIFO, op->dev.parent->parent, 0); if (!p) return -ENOMEM; @@ -166,7 +166,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id 0, PTR_LPT_REG_DIR); p = parport_pc_probe_port(base, base + 0x400, - op->irqs[0], + op->archdata.irqs[0], slot, op->dev.parent, 0); diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 47e63f1e719c..331de91ad2bc 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -267,6 +267,8 @@ static void __init build_device_resources(struct of_device *op, /* Conver to num-entries. */ num_reg /= na + ns; + op->resource = op->archdata.resource; + op->num_resources = num_reg; for (index = 0; index < num_reg; index++) { struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; @@ -349,27 +351,21 @@ static struct of_device * __init scan_one_device(struct device_node *dp, op->dev.of_node = dp; - op->clock_freq = of_getintprop_default(dp, "clock-frequency", - (25*1000*1000)); - op->portid = of_getintprop_default(dp, "upa-portid", -1); - if (op->portid == -1) - op->portid = of_getintprop_default(dp, "portid", -1); - intr = of_get_property(dp, "intr", &len); if (intr) { - op->num_irqs = len / sizeof(struct linux_prom_irqs); - for (i = 0; i < op->num_irqs; i++) - op->irqs[i] = intr[i].pri; + op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); + for (i = 0; i < op->archdata.num_irqs; i++) + op->archdata.irqs[i] = intr[i].pri; } else { const unsigned int *irq = of_get_property(dp, "interrupts", &len); if (irq) { - op->num_irqs = len / sizeof(unsigned int); - for (i = 0; i < op->num_irqs; i++) - op->irqs[i] = irq[i]; + op->archdata.num_irqs = len / sizeof(unsigned int); + for (i = 0; i < op->archdata.num_irqs; i++) + op->archdata.irqs[i] = irq[i]; } else { - op->num_irqs = 0; + op->archdata.num_irqs = 0; } } if (sparc_cpu_model == sun4d) { @@ -411,8 +407,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp, goto build_resources; } - for (i = 0; i < op->num_irqs; i++) { - int this_irq = op->irqs[i]; + for (i = 0; i < op->archdata.num_irqs; i++) { + int this_irq = op->archdata.irqs[i]; int sbusl = pil_to_sbus[this_irq]; if (sbusl) @@ -420,7 +416,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, (sbusl << 2) + slot); - op->irqs[i] = this_irq; + op->archdata.irqs[i] = this_irq; } } diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 1dae8079f728..5e8cbb942d3d 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -344,6 +344,8 @@ static void __init build_device_resources(struct of_device *op, num_reg = PROMREG_MAX; } + op->resource = op->archdata.resource; + op->num_resources = num_reg; for (index = 0; index < num_reg; index++) { struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; @@ -644,31 +646,25 @@ static struct of_device * __init scan_one_device(struct device_node *dp, op->dev.of_node = dp; - op->clock_freq = of_getintprop_default(dp, "clock-frequency", - (25*1000*1000)); - op->portid = of_getintprop_default(dp, "upa-portid", -1); - if (op->portid == -1) - op->portid = of_getintprop_default(dp, "portid", -1); - irq = of_get_property(dp, "interrupts", &len); if (irq) { - op->num_irqs = len / 4; + op->archdata.num_irqs = len / 4; /* Prevent overrunning the op->irqs[] array. */ - if (op->num_irqs > PROMINTR_MAX) { + if (op->archdata.num_irqs > PROMINTR_MAX) { printk(KERN_WARNING "%s: Too many irqs (%d), " "limiting to %d.\n", - dp->full_name, op->num_irqs, PROMINTR_MAX); - op->num_irqs = PROMINTR_MAX; + dp->full_name, op->archdata.num_irqs, PROMINTR_MAX); + op->archdata.num_irqs = PROMINTR_MAX; } - memcpy(op->irqs, irq, op->num_irqs * 4); + memcpy(op->archdata.irqs, irq, op->archdata.num_irqs * 4); } else { - op->num_irqs = 0; + op->archdata.num_irqs = 0; } build_device_resources(op, parent); - for (i = 0; i < op->num_irqs; i++) - op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); + for (i = 0; i < op->archdata.num_irqs; i++) + op->archdata.irqs[i] = build_one_device_irq(op, parent, op->archdata.irqs[i]); op->dev.parent = parent; op->dev.bus = &of_platform_bus_type; diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 10c6c36a6e75..016c947d4cae 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -35,10 +35,10 @@ unsigned int irq_of_parse_and_map(struct device_node *node, int index) { struct of_device *op = of_find_device_by_node(node); - if (!op || index >= op->num_irqs) + if (!op || index >= op->archdata.num_irqs) return 0; - return op->irqs[index]; + return op->archdata.irqs[index]; } EXPORT_SYMBOL(irq_of_parse_and_map); diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 8a8363adb8bd..1523290db0a1 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -340,7 +340,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->hdr_type = PCI_HEADER_TYPE_NORMAL; dev->rom_base_reg = PCI_ROM_ADDRESS; - dev->irq = sd->op->irqs[0]; + dev->irq = sd->op->archdata.irqs[0]; if (dev->irq == 0xffffffff) dev->irq = PCI_IRQ_NONE; } diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 558a70512824..93011e6e7ddc 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -302,23 +302,23 @@ static void psycho_register_error_handlers(struct pci_pbm_info *pbm) * 5: POWER MANAGEMENT */ - if (op->num_irqs < 6) + if (op->archdata.num_irqs < 6) return; /* We really mean to ignore the return result here. Two * PCI controller share the same interrupt numbers and * drive the same front-end hardware. */ - err = request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED, + err = request_irq(op->archdata.irqs[1], psycho_ue_intr, IRQF_SHARED, "PSYCHO_UE", pbm); - err = request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED, + err = request_irq(op->archdata.irqs[2], psycho_ce_intr, IRQF_SHARED, "PSYCHO_CE", pbm); /* This one, however, ought not to fail. We can just warn * about it since the system can still operate properly even * if this fails. */ - err = request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED, + err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, IRQF_SHARED, "PSYCHO_PCIERR", pbm); if (err) printk(KERN_WARNING "%s: Could not register PCIERR, " diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 6dad8e3b7506..99c6dba7d4fd 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -329,7 +329,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm) * 2: CE ERR * 3: POWER FAIL */ - if (op->num_irqs < 4) + if (op->archdata.num_irqs < 4) return; /* We clear the error bits in the appropriate AFSR before @@ -341,7 +341,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm) SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE), base + SABRE_UE_AFSR); - err = request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm); + err = request_irq(op->archdata.irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm); if (err) printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n", pbm->name, err); @@ -351,11 +351,11 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm) base + SABRE_CE_AFSR); - err = request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm); + err = request_irq(op->archdata.irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm); if (err) printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n", pbm->name, err); - err = request_irq(op->irqs[0], psycho_pcierr_intr, 0, + err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, 0, "SABRE_PCIERR", pbm); if (err) printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n", diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 97a1ae2e1c02..9041dae7aaca 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -857,14 +857,14 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) */ if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { - err = request_irq(op->irqs[1], schizo_ue_intr, 0, + err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0, "TOMATILLO_UE", pbm); if (err) printk(KERN_WARNING "%s: Could not register UE, " "err=%d\n", pbm->name, err); } if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { - err = request_irq(op->irqs[2], schizo_ce_intr, 0, + err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0, "TOMATILLO_CE", pbm); if (err) printk(KERN_WARNING "%s: Could not register CE, " @@ -872,10 +872,10 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) } err = 0; if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, + err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0, "TOMATILLO_PCIERR", pbm); } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, + err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0, "TOMATILLO_PCIERR", pbm); } if (err) @@ -883,7 +883,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) "err=%d\n", pbm->name, err); if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { - err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, + err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0, "TOMATILLO_SERR", pbm); if (err) printk(KERN_WARNING "%s: Could not register SERR, " @@ -952,14 +952,14 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm) */ if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { - err = request_irq(op->irqs[1], schizo_ue_intr, 0, + err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0, "SCHIZO_UE", pbm); if (err) printk(KERN_WARNING "%s: Could not register UE, " "err=%d\n", pbm->name, err); } if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { - err = request_irq(op->irqs[2], schizo_ce_intr, 0, + err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0, "SCHIZO_CE", pbm); if (err) printk(KERN_WARNING "%s: Could not register CE, " @@ -967,10 +967,10 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm) } err = 0; if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, + err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0, "SCHIZO_PCIERR", pbm); } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, + err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0, "SCHIZO_PCIERR", pbm); } if (err) @@ -978,7 +978,7 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm) "err=%d\n", pbm->name, err); if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { - err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, + err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0, "SCHIZO_SERR", pbm); if (err) printk(KERN_WARNING "%s: Could not register SERR, " diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index 168d4cb63f5b..1cfee577f6b5 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -36,7 +36,7 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node * static int __devinit power_probe(struct of_device *op, const struct of_device_id *match) { struct resource *res = &op->resource[0]; - unsigned int irq= op->irqs[0]; + unsigned int irq = op->archdata.irqs[0]; power_reg = of_ioremap(res, 0, 0x4, "power"); -- cgit v1.2.3 From b505ff5e7291cca6379549297e3852ce3622d550 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:09:59 -0600 Subject: of: kill struct of_device Now that the device tree node pointer has been moved out of struct of_device and into the common struct device, there isn't anything unique about of_device anymore. In fact, there isn't much need for a separate of_bus when all busses have access to OF style probing. arch/powerpc and arch/microblaze are moving away from using the of_bus and using the regular platform bus instead for mmio devices. This patch makes of_device the same as platform_device as a stepping stone in migrating of_platform_drivers over to the platform bus. Signed-off-by: Grant Likely Acked-by: David S. Miller Cc: Michal Simek Cc: Benjamin Herrenschmidt Cc: Stephen Rothwell --- arch/microblaze/include/asm/of_device.h | 10 ---------- arch/powerpc/include/asm/of_device.h | 11 ----------- arch/powerpc/include/asm/smu.h | 4 ++-- arch/sparc/include/asm/device.h | 4 ++-- arch/sparc/include/asm/of_device.h | 14 -------------- 5 files changed, 4 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index 73cb98040982..0a5f3f914b42 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -15,16 +15,6 @@ #include #include -/* - * The of_device is a kind of "base class" that is a superset of - * struct device for use by devices attached to an OF node and - * probed using OF properties. - */ -struct of_device { - struct device dev; /* Generic device interface */ - struct pdev_archdata archdata; -}; - extern ssize_t of_device_get_modalias(struct of_device *ofdev, char *str, ssize_t len); diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index 444e97e2982e..cb36632f953c 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -5,17 +5,6 @@ #include #include -/* - * The of_device is a kind of "base class" that is a superset of - * struct device for use by devices attached to an OF node and - * probed using OF properties. - */ -struct of_device -{ - struct device dev; /* Generic device interface */ - struct pdev_archdata archdata; -}; - extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index 7ae2753da565..e3bdada8c542 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h @@ -457,8 +457,8 @@ extern void smu_poll(void); */ extern int smu_init(void); extern int smu_present(void); -struct of_device; -extern struct of_device *smu_get_ofdev(void); +struct platform_device; +extern struct platform_device *smu_get_ofdev(void); /* diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index f9740d065fe7..fb220e482039 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -9,13 +9,13 @@ #include struct device_node; -struct of_device; +struct platform_device; struct dev_archdata { void *iommu; void *stc; void *host_controller; - struct of_device *op; + struct platform_device *op; int numa_node; }; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index 6d1844a547b4..22b9828fe693 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -7,20 +7,6 @@ #include #include -/* - * The of_device is a kind of "base class" that is a superset of - * struct device for use by devices attached to an OF node and - * probed using OF properties. - */ -struct of_device -{ - struct device dev; - u32 num_resources; - struct resource *resource; - - struct pdev_archdata archdata; -}; - extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); -- cgit v1.2.3 From e3873444990dd6f8a095d1f72b5ad45192f8c506 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:09:59 -0600 Subject: of/irq: Move irq_of_parse_and_map() to common code Merge common code between PowerPC and Microblaze. SPARC implements irq_of_parse_and_map(), but the implementation is different, so it does not use this code. Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt Cc: Michal Simek Cc: "David S. Miller" Cc: Stephen Rothwell Cc: Jeremy Kerr --- arch/microblaze/include/asm/irq.h | 24 ------------------------ arch/microblaze/include/asm/prom.h | 26 +------------------------- arch/microblaze/kernel/irq.c | 14 ++------------ arch/powerpc/include/asm/irq.h | 28 ---------------------------- arch/powerpc/include/asm/prom.h | 27 +-------------------------- arch/powerpc/kernel/irq.c | 14 ++------------ arch/sparc/include/asm/prom.h | 1 - 7 files changed, 6 insertions(+), 128 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h index 31a35c33df63..ec5583d6111c 100644 --- a/arch/microblaze/include/asm/irq.h +++ b/arch/microblaze/include/asm/irq.h @@ -27,17 +27,6 @@ extern unsigned int nr_irq; struct pt_regs; extern void do_IRQ(struct pt_regs *regs); -/** - * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space - * @device: Device node of the device whose interrupt is to be mapped - * @index: Index of the interrupt to map - * - * This function is a wrapper that chains of_irq_map_one() and - * irq_create_of_mapping() to make things easier to callers - */ -struct device_node; -extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); - /** FIXME - not implement * irq_dispose_mapping - Unmap an interrupt * @virq: linux virq number of the interrupt to unmap @@ -62,17 +51,4 @@ struct irq_host; extern unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq); -/** - * irq_create_of_mapping - Map a hardware interrupt into linux virq space - * @controller: Device node of the interrupt controller - * @inspec: Interrupt specifier from the device-tree - * @intsize: Size of the interrupt specifier from the device-tree - * - * This function is identical to irq_create_mapping except that it takes - * as input informations straight from the device-tree (typically the results - * of the of_irq_map_*() functions. - */ -extern unsigned int irq_create_of_mapping(struct device_node *controller, - u32 *intspec, unsigned int intsize); - #endif /* _ASM_MICROBLAZE_IRQ_H */ diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index e7d67a329bd7..e9fb2eb0035d 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -20,6 +20,7 @@ #ifndef __ASSEMBLY__ #include +#include #include #include #include @@ -92,18 +93,6 @@ extern const void *of_get_mac_address(struct device_node *np); * OF interrupt mapping */ -/* This structure is returned when an interrupt is mapped. The controller - * field needs to be put() after use - */ - -#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ - -struct of_irq { - struct device_node *controller; /* Interrupt controller node */ - u32 size; /* Specifier size */ - u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ -}; - /** * of_irq_map_init - Initialize the irq remapper * @flags: flags defining workarounds to enable @@ -138,19 +127,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, const u32 *addr, struct of_irq *out_irq); -/** - * of_irq_map_one - Resolve an interrupt for a device - * @device: the device whose interrupt is to be resolved - * @index: index of the interrupt to resolve - * @out_irq: structure of_irq filled by this function - * - * This function resolves an interrupt, walking the tree, for a given - * device-tree node. It's the high level pendant to of_irq_map_raw(). - * It also implements the workarounds for OldWolrd Macs. - */ -extern int of_irq_map_one(struct device_node *device, int index, - struct of_irq *out_irq); - /** * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 8f120aca123d..dd32b09b4a3c 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c @@ -17,20 +17,10 @@ #include #include #include +#include #include -unsigned int irq_of_parse_and_map(struct device_node *dev, int index) -{ - struct of_irq oirq; - - if (of_irq_map_one(dev, index, &oirq)) - return NO_IRQ; - - return oirq.specifier[0]; -} -EXPORT_SYMBOL_GPL(irq_of_parse_and_map); - static u32 concurrent_irq; void __irq_entry do_IRQ(struct pt_regs *regs) @@ -104,7 +94,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) EXPORT_SYMBOL_GPL(irq_create_mapping); unsigned int irq_create_of_mapping(struct device_node *controller, - u32 *intspec, unsigned int intsize) + const u32 *intspec, unsigned int intsize) { return intspec[0]; } diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e054baef1845..4e3051595b2b 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host, */ extern void irq_free_virt(unsigned int virq, unsigned int count); - -/* -- OF helpers -- */ - -/** - * irq_create_of_mapping - Map a hardware interrupt into linux virq space - * @controller: Device node of the interrupt controller - * @inspec: Interrupt specifier from the device-tree - * @intsize: Size of the interrupt specifier from the device-tree - * - * This function is identical to irq_create_mapping except that it takes - * as input informations straight from the device-tree (typically the results - * of the of_irq_map_*() functions. - */ -extern unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize); - -/** - * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space - * @device: Device node of the device whose interrupt is to be mapped - * @index: Index of the interrupt to map - * - * This function is a wrapper that chains of_irq_map_one() and - * irq_create_of_mapping() to make things easier to callers - */ -extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); - -/* -- End OF helpers -- */ - /** * irq_early_init - Init irq remapping subsystem */ diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index ddd408a93b5a..47d41b67c94d 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include @@ -108,18 +109,6 @@ extern const void *of_get_mac_address(struct device_node *np); * OF interrupt mapping */ -/* This structure is returned when an interrupt is mapped. The controller - * field needs to be put() after use - */ - -#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ - -struct of_irq { - struct device_node *controller; /* Interrupt controller node */ - u32 size; /* Specifier size */ - u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ -}; - /** * of_irq_map_init - Initialize the irq remapper * @flags: flags defining workarounds to enable @@ -154,20 +143,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, const u32 *addr, struct of_irq *out_irq); - -/** - * of_irq_map_one - Resolve an interrupt for a device - * @device: the device whose interrupt is to be resolved - * @index: index of the interrupt to resolve - * @out_irq: structure of_irq filled by this function - * - * This function resolves an interrupt, walking the tree, for a given - * device-tree node. It's the high level pendant to of_irq_map_raw(). - * It also implements the workarounds for OldWolrd Macs. - */ -extern int of_irq_map_one(struct device_node *device, int index, - struct of_irq *out_irq); - /** * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 30817d9b20cb..2676ef288bf5 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #include @@ -813,18 +815,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller, } EXPORT_SYMBOL_GPL(irq_create_of_mapping); -unsigned int irq_of_parse_and_map(struct device_node *dev, int index) -{ - struct of_irq oirq; - - if (of_irq_map_one(dev, index, &oirq)) - return NO_IRQ; - - return irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); -} -EXPORT_SYMBOL_GPL(irq_of_parse_and_map); - void irq_dispose_mapping(unsigned int virq) { struct irq_host *host; diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index f845828ca4c6..ac695742df85 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -56,7 +56,6 @@ extern void of_fill_in_cpu_data(void); * register them in the of_device objects, whereas powerpc computes them * on request. */ -extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); static inline void irq_dispose_mapping(unsigned int virq) { } -- cgit v1.2.3 From b6295c8b85fe83e5679b7b8bebe4df85deebebfc Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:10:00 -0600 Subject: of/microblaze: strip out of_irq_workarounds code Microblaze doesn't have any legacy workaround in the device tree irq mapping data. All of the of_irq_workarounds stuff can be dropped Signed-off-by: Grant Likely Cc: Michal Simek Cc: Stephen Rothwell --- arch/microblaze/include/asm/prom.h | 10 --------- arch/microblaze/kernel/prom_parse.c | 41 ------------------------------------- 2 files changed, 51 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index e9fb2eb0035d..4f34bc5baa83 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -93,19 +93,9 @@ extern const void *of_get_mac_address(struct device_node *np); * OF interrupt mapping */ -/** - * of_irq_map_init - Initialize the irq remapper - * @flags: flags defining workarounds to enable - * - * Some machines have bugs in the device-tree which require certain workarounds - * to be applied. Call this before any interrupt mapping attempts to enable - * those workarounds. - */ #define OF_IMAP_OLDWORLD_MAC 0x00000001 #define OF_IMAP_NO_PHANDLE 0x00000002 -extern void of_irq_map_init(unsigned int flags); - /** * of_irq_map_raw - Low level interrupt tree parsing * @parent: the device interrupt parent diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index bf7e6c27e318..cba05812ab46 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -676,47 +676,6 @@ static struct device_node *of_irq_find_parent(struct device_node *child) return p; } -/* This doesn't need to be called if you don't have any special workaround - * flags to pass - */ -void of_irq_map_init(unsigned int flags) -{ - of_irq_workarounds = flags; - - /* OldWorld, don't bother looking at other things */ - if (flags & OF_IMAP_OLDWORLD_MAC) - return; - - /* If we don't have phandles, let's try to locate a default interrupt - * controller (happens when booting with BootX). We do a first match - * here, hopefully, that only ever happens on machines with one - * controller. - */ - if (flags & OF_IMAP_NO_PHANDLE) { - struct device_node *np; - - for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) { - if (of_get_property(np, "interrupt-controller", NULL) - == NULL) - continue; - /* Skip /chosen/interrupt-controller */ - if (strcmp(np->name, "chosen") == 0) - continue; - /* It seems like at least one person on this planet - * wants to use BootX on a machine with an AppleKiwi - * controller which happens to pretend to be an - * interrupt controller too. - */ - if (strcmp(np->name, "AppleKiwi") == 0) - continue; - /* I think we found one ! */ - of_irq_dflt_pic = np; - break; - } - } - -} - int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, const u32 *addr, struct of_irq *out_irq) { -- cgit v1.2.3 From b83da291b4c73eaddc20e2edb614123a6d681b3b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 18 Jun 2010 11:10:01 -0600 Subject: of/powerpc: Move Powermac irq quirk code into powermac pic driver code The code that figures out what is wrong with the powermac irq device tree data belongs with the rest of the powermac irq code. This patch moves it out of prom_parse.c and into powermac/pic.c so that it is only compiled in when actually needed. Signed-off-by: Grant Likely Cc: Benjamin Herrenschmidt Cc: Stephen Rothwell --- arch/powerpc/include/asm/prom.h | 24 ++++++---- arch/powerpc/kernel/prom_parse.c | 85 ----------------------------------- arch/powerpc/platforms/powermac/pic.c | 72 ++++++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 100 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 47d41b67c94d..4486765db6e7 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -109,18 +109,24 @@ extern const void *of_get_mac_address(struct device_node *np); * OF interrupt mapping */ -/** - * of_irq_map_init - Initialize the irq remapper - * @flags: flags defining workarounds to enable - * - * Some machines have bugs in the device-tree which require certain workarounds - * to be applied. Call this before any interrupt mapping attempts to enable - * those workarounds. - */ #define OF_IMAP_OLDWORLD_MAC 0x00000001 #define OF_IMAP_NO_PHANDLE 0x00000002 -extern void of_irq_map_init(unsigned int flags); +#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) +/* Workarounds only needed for 32bit powermac machines */ +extern unsigned int of_irq_workarounds; +extern struct device_node *of_irq_dflt_pic; +extern int of_irq_map_oldworld(struct device_node *device, int index, + struct of_irq *out_irq); +#else +#define of_irq_workarounds (0) +#define of_irq_dflt_pic (NULL) +static inline int of_irq_map_oldworld(struct device_node *device, int index, + struct of_irq *out_irq) +{ + return -EINVAL; +} +#endif /** * of_irq_map_raw - Low level interrupt tree parsing diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 8362620c9e6f..dfa6de6572bb 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -682,9 +682,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, * Interrupt remapper */ -static unsigned int of_irq_workarounds; -static struct device_node *of_irq_dflt_pic; - static struct device_node *of_irq_find_parent(struct device_node *child) { struct device_node *p; @@ -710,44 +707,6 @@ static struct device_node *of_irq_find_parent(struct device_node *child) return p; } -/* This doesn't need to be called if you don't have any special workaround - * flags to pass - */ -void of_irq_map_init(unsigned int flags) -{ - of_irq_workarounds = flags; - - /* OldWorld, don't bother looking at other things */ - if (flags & OF_IMAP_OLDWORLD_MAC) - return; - - /* If we don't have phandles, let's try to locate a default interrupt - * controller (happens when booting with BootX). We do a first match - * here, hopefully, that only ever happens on machines with one - * controller. - */ - if (flags & OF_IMAP_NO_PHANDLE) { - struct device_node *np; - - for_each_node_with_property(np, "interrupt-controller") { - /* Skip /chosen/interrupt-controller */ - if (strcmp(np->name, "chosen") == 0) - continue; - /* It seems like at least one person on this planet wants - * to use BootX on a machine with an AppleKiwi controller - * which happens to pretend to be an interrupt - * controller too. - */ - if (strcmp(np->name, "AppleKiwi") == 0) - continue; - /* I think we found one ! */ - of_irq_dflt_pic = np; - break; - } - } - -} - int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, const u32 *addr, struct of_irq *out_irq) { @@ -922,50 +881,6 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, } EXPORT_SYMBOL_GPL(of_irq_map_raw); -#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) -static int of_irq_map_oldworld(struct device_node *device, int index, - struct of_irq *out_irq) -{ - const u32 *ints = NULL; - int intlen; - - /* - * Old machines just have a list of interrupt numbers - * and no interrupt-controller nodes. We also have dodgy - * cases where the APPL,interrupts property is completely - * missing behind pci-pci bridges and we have to get it - * from the parent (the bridge itself, as apple just wired - * everything together on these) - */ - while (device) { - ints = of_get_property(device, "AAPL,interrupts", &intlen); - if (ints != NULL) - break; - device = device->parent; - if (device && strcmp(device->type, "pci") != 0) - break; - } - if (ints == NULL) - return -EINVAL; - intlen /= sizeof(u32); - - if (index >= intlen) - return -EINVAL; - - out_irq->controller = NULL; - out_irq->specifier[0] = ints[index]; - out_irq->size = 1; - - return 0; -} -#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */ -static int of_irq_map_oldworld(struct device_node *device, int index, - struct of_irq *out_irq) -{ - return -EINVAL; -} -#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */ - int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) { struct device_node *p; diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 630a533d0e59..890d5f72b198 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -46,6 +46,10 @@ struct pmac_irq_hw { unsigned int level; }; +/* Workaround flags for 32bit powermac machines */ +unsigned int of_irq_workarounds; +struct device_node *of_irq_dflt_pic; + /* Default addresses */ static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; @@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void) setup_irq(irq_create_mapping(NULL, 20), &xmon_action); #endif } + +int of_irq_map_oldworld(struct device_node *device, int index, + struct of_irq *out_irq) +{ + const u32 *ints = NULL; + int intlen; + + /* + * Old machines just have a list of interrupt numbers + * and no interrupt-controller nodes. We also have dodgy + * cases where the APPL,interrupts property is completely + * missing behind pci-pci bridges and we have to get it + * from the parent (the bridge itself, as apple just wired + * everything together on these) + */ + while (device) { + ints = of_get_property(device, "AAPL,interrupts", &intlen); + if (ints != NULL) + break; + device = device->parent; + if (device && strcmp(device->type, "pci") != 0) + break; + } + if (ints == NULL) + return -EINVAL; + intlen /= sizeof(u32); + + if (index >= intlen) + return -EINVAL; + + out_irq->controller = NULL; + out_irq->specifier[0] = ints[index]; + out_irq->size = 1; + + return 0; +} #endif /* CONFIG_PPC32 */ static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) @@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void) void __init pmac_pic_init(void) { - unsigned int flags = 0; - /* We configure the OF parsing based on our oldworld vs. newworld * platform type and wether we were booted by BootX. */ #ifdef CONFIG_PPC32 if (!pmac_newworld) - flags |= OF_IMAP_OLDWORLD_MAC; + of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC; if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL) - flags |= OF_IMAP_NO_PHANDLE; -#endif /* CONFIG_PPC_32 */ + of_irq_workarounds |= OF_IMAP_NO_PHANDLE; - of_irq_map_init(flags); + /* If we don't have phandles on a newworld, then try to locate a + * default interrupt controller (happens when booting with BootX). + * We do a first match here, hopefully, that only ever happens on + * machines with one controller. + */ + if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) { + struct device_node *np; + + for_each_node_with_property(np, "interrupt-controller") { + /* Skip /chosen/interrupt-controller */ + if (strcmp(np->name, "chosen") == 0) + continue; + /* It seems like at least one person wants + * to use BootX on a machine with an AppleKiwi + * controller which happens to pretend to be an + * interrupt controller too. */ + if (strcmp(np->name, "AppleKiwi") == 0) + continue; + /* I think we found one ! */ + of_irq_dflt_pic = np; + break; + } + } +#endif /* CONFIG_PPC32 */ /* We first try to detect Apple's new Core99 chipset, since mac-io * is quite different on those machines and contains an IBM MPIC2. -- cgit v1.2.3 From 7dc2e1134a22dc242175d5321c0c9e97d16eb87b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:06 -0600 Subject: of/irq: merge irq mapping code Merge common irq mapping code between PowerPC and Microblaze. This patch merges of_irq_find_parent(), of_irq_map_raw() and of_irq_map_one(). The functions are dependent on one another, so all three are merged in a single patch. Other than cosmetic difference (ie. DBG() vs. pr_debug()), the implementations are identical. of_irq_to_resource() is also merged, but in this case the implementations are different. This patch drops the microblaze version and uses the powerpc implementation unchanged. The microblaze version essentially open-coded irq_of_parse_and_map() which it does not need to do. Therefore the powerpc version is safe to adopt. Signed-off-by: Grant Likely CC: Michal Simek CC: Benjamin Herrenschmidt CC: Stephen Rothwell --- arch/microblaze/include/asm/prom.h | 31 ---- arch/microblaze/kernel/prom_parse.c | 290 ------------------------------------ arch/powerpc/include/asm/prom.h | 47 ------ arch/powerpc/kernel/prom_parse.c | 266 --------------------------------- 4 files changed, 634 deletions(-) (limited to 'arch') diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 4f34bc5baa83..5fbdfe76fe76 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -89,34 +89,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); /* Get the MAC address */ extern const void *of_get_mac_address(struct device_node *np); -/* - * OF interrupt mapping - */ - -#define OF_IMAP_OLDWORLD_MAC 0x00000001 -#define OF_IMAP_NO_PHANDLE 0x00000002 - -/** - * of_irq_map_raw - Low level interrupt tree parsing - * @parent: the device interrupt parent - * @intspec: interrupt specifier ("interrupts" property of the device) - * @ointsize: size of the passed in interrupt specifier - * @addr: address specifier (start of "reg" property of the device) - * @out_irq: structure of_irq filled by this function - * - * Returns 0 on success and a negative number on error - * - * This function is a low-level interrupt tree walking function. It - * can be used to do a partial walk with synthetized reg and interrupts - * properties, for example when resolving PCI interrupts when no device - * node exist for the parent. - * - */ - -extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, - u32 ointsize, const u32 *addr, - struct of_irq *out_irq); - /** * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved @@ -131,9 +103,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -extern int of_irq_to_resource(struct device_node *dev, int index, - struct resource *r); - /** * of_iomap - Maps the memory mapped IO for a given device_node * @device: the device whose io range will be mapped diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index cba05812ab46..e28968fa34c1 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -644,267 +644,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, *size = of_read_number(dma_window, cells); } -/* - * Interrupt remapper - */ - -static unsigned int of_irq_workarounds; -static struct device_node *of_irq_dflt_pic; - -static struct device_node *of_irq_find_parent(struct device_node *child) -{ - struct device_node *p; - const phandle *parp; - - if (!of_node_get(child)) - return NULL; - - do { - parp = of_get_property(child, "interrupt-parent", NULL); - if (parp == NULL) - p = of_get_parent(child); - else { - if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) - p = of_node_get(of_irq_dflt_pic); - else - p = of_find_node_by_phandle(*parp); - } - of_node_put(child); - child = p; - } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); - - return p; -} - -int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, - const u32 *addr, struct of_irq *out_irq) -{ - struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; - const u32 *tmp, *imap, *imask; - u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; - int imaplen, match, i; - - pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...]," - "ointsize=%d\n", - parent->full_name, intspec[0], intspec[1], ointsize); - - ipar = of_node_get(parent); - - /* First get the #interrupt-cells property of the current cursor - * that tells us how to interpret the passed-in intspec. If there - * is none, we are nice and just walk up the tree - */ - do { - tmp = of_get_property(ipar, "#interrupt-cells", NULL); - if (tmp != NULL) { - intsize = *tmp; - break; - } - tnode = ipar; - ipar = of_irq_find_parent(ipar); - of_node_put(tnode); - } while (ipar); - if (ipar == NULL) { - pr_debug(" -> no parent found !\n"); - goto fail; - } - - pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", - ipar->full_name, intsize); - - if (ointsize != intsize) - return -EINVAL; - - /* Look for this #address-cells. We have to implement the old linux - * trick of looking for the parent here as some device-trees rely on it - */ - old = of_node_get(ipar); - do { - tmp = of_get_property(old, "#address-cells", NULL); - tnode = of_get_parent(old); - of_node_put(old); - old = tnode; - } while (old && tmp == NULL); - of_node_put(old); - old = NULL; - addrsize = (tmp == NULL) ? 2 : *tmp; - - pr_debug(" -> addrsize=%d\n", addrsize); - - /* Now start the actual "proper" walk of the interrupt tree */ - while (ipar != NULL) { - /* Now check if cursor is an interrupt-controller and if it is - * then we are done - */ - if (of_get_property(ipar, "interrupt-controller", NULL) != - NULL) { - pr_debug(" -> got it !\n"); - memcpy(out_irq->specifier, intspec, - intsize * sizeof(u32)); - out_irq->size = intsize; - out_irq->controller = ipar; - of_node_put(old); - return 0; - } - - /* Now look for an interrupt-map */ - imap = of_get_property(ipar, "interrupt-map", &imaplen); - /* No interrupt map, check for an interrupt parent */ - if (imap == NULL) { - pr_debug(" -> no map, getting parent\n"); - newpar = of_irq_find_parent(ipar); - goto skiplevel; - } - imaplen /= sizeof(u32); - - /* Look for a mask */ - imask = of_get_property(ipar, "interrupt-map-mask", NULL); - - /* If we were passed no "reg" property and we attempt to parse - * an interrupt-map, then #address-cells must be 0. - * Fail if it's not. - */ - if (addr == NULL && addrsize != 0) { - pr_debug(" -> no reg passed in when needed !\n"); - goto fail; - } - - /* Parse interrupt-map */ - match = 0; - while (imaplen > (addrsize + intsize + 1) && !match) { - /* Compare specifiers */ - match = 1; - for (i = 0; i < addrsize && match; ++i) { - u32 mask = imask ? imask[i] : 0xffffffffu; - match = ((addr[i] ^ imap[i]) & mask) == 0; - } - for (; i < (addrsize + intsize) && match; ++i) { - u32 mask = imask ? imask[i] : 0xffffffffu; - match = - ((intspec[i-addrsize] ^ imap[i]) - & mask) == 0; - } - imap += addrsize + intsize; - imaplen -= addrsize + intsize; - - pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); - - /* Get the interrupt parent */ - if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) - newpar = of_node_get(of_irq_dflt_pic); - else - newpar = - of_find_node_by_phandle((phandle)*imap); - imap++; - --imaplen; - - /* Check if not found */ - if (newpar == NULL) { - pr_debug(" -> imap parent not found !\n"); - goto fail; - } - - /* Get #interrupt-cells and #address-cells of new - * parent - */ - tmp = of_get_property(newpar, "#interrupt-cells", NULL); - if (tmp == NULL) { - pr_debug(" -> parent lacks " - "#interrupt-cells!\n"); - goto fail; - } - newintsize = *tmp; - tmp = of_get_property(newpar, "#address-cells", NULL); - newaddrsize = (tmp == NULL) ? 0 : *tmp; - - pr_debug(" -> newintsize=%d, newaddrsize=%d\n", - newintsize, newaddrsize); - - /* Check for malformed properties */ - if (imaplen < (newaddrsize + newintsize)) - goto fail; - - imap += newaddrsize + newintsize; - imaplen -= newaddrsize + newintsize; - - pr_debug(" -> imaplen=%d\n", imaplen); - } - if (!match) - goto fail; - - of_node_put(old); - old = of_node_get(newpar); - addrsize = newaddrsize; - intsize = newintsize; - intspec = imap - intsize; - addr = intspec - addrsize; - -skiplevel: - /* Iterate again with new parent */ - pr_debug(" -> new parent: %s\n", - newpar ? newpar->full_name : "<>"); - of_node_put(ipar); - ipar = newpar; - newpar = NULL; - } -fail: - of_node_put(ipar); - of_node_put(old); - of_node_put(newpar); - - return -EINVAL; -} -EXPORT_SYMBOL_GPL(of_irq_map_raw); - -int of_irq_map_one(struct device_node *device, - int index, struct of_irq *out_irq) -{ - struct device_node *p; - const u32 *intspec, *tmp, *addr; - u32 intsize, intlen; - int res; - - pr_debug("of_irq_map_one: dev=%s, index=%d\n", - device->full_name, index); - - /* Get the interrupts property */ - intspec = of_get_property(device, "interrupts", (int *) &intlen); - if (intspec == NULL) - return -EINVAL; - intlen /= sizeof(u32); - - pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen); - - /* Get the reg property (if any) */ - addr = of_get_property(device, "reg", NULL); - - /* Look for the interrupt parent. */ - p = of_irq_find_parent(device); - if (p == NULL) - return -EINVAL; - - /* Get size of interrupt specifier */ - tmp = of_get_property(p, "#interrupt-cells", NULL); - if (tmp == NULL) { - of_node_put(p); - return -EINVAL; - } - intsize = *tmp; - - pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); - - /* Check index */ - if ((index + 1) * intsize > intlen) - return -EINVAL; - - /* Get new specifier and map it */ - res = of_irq_map_raw(p, intspec + index * intsize, intsize, - addr, out_irq); - of_node_put(p); - return res; -} -EXPORT_SYMBOL_GPL(of_irq_map_one); - /** * Search the device tree for the best MAC address to use. 'mac-address' is * checked first, because that is supposed to contain to "most recent" MAC @@ -943,35 +682,6 @@ const void *of_get_mac_address(struct device_node *np) } EXPORT_SYMBOL(of_get_mac_address); -int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) -{ - struct of_irq out_irq; - int irq; - int res; - - res = of_irq_map_one(dev, index, &out_irq); - - /* Get irq for the device */ - if (res) { - pr_debug("IRQ not found... code = %d", res); - return NO_IRQ; - } - /* Assuming single interrupt controller... */ - irq = out_irq.specifier[0]; - - pr_debug("IRQ found = %d", irq); - - /* Only dereference the resource if both the - * resource and the irq are valid. */ - if (r && irq != NO_IRQ) { - r->start = r->end = irq; - r->flags = IORESOURCE_IRQ; - } - - return irq; -} -EXPORT_SYMBOL_GPL(of_irq_to_resource); - void __iomem *of_iomap(struct device_node *np, int index) { struct resource res; diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 4486765db6e7..10d5ee556702 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -105,50 +105,6 @@ struct device_node *of_find_next_cache_node(struct device_node *np); /* Get the MAC address */ extern const void *of_get_mac_address(struct device_node *np); -/* - * OF interrupt mapping - */ - -#define OF_IMAP_OLDWORLD_MAC 0x00000001 -#define OF_IMAP_NO_PHANDLE 0x00000002 - -#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) -/* Workarounds only needed for 32bit powermac machines */ -extern unsigned int of_irq_workarounds; -extern struct device_node *of_irq_dflt_pic; -extern int of_irq_map_oldworld(struct device_node *device, int index, - struct of_irq *out_irq); -#else -#define of_irq_workarounds (0) -#define of_irq_dflt_pic (NULL) -static inline int of_irq_map_oldworld(struct device_node *device, int index, - struct of_irq *out_irq) -{ - return -EINVAL; -} -#endif - -/** - * of_irq_map_raw - Low level interrupt tree parsing - * @parent: the device interrupt parent - * @intspec: interrupt specifier ("interrupts" property of the device) - * @ointsize: size of the passed in interrupt specifier - * @addr: address specifier (start of "reg" property of the device) - * @out_irq: structure of_irq filled by this function - * - * Returns 0 on success and a negative number on error - * - * This function is a low-level interrupt tree walking function. It - * can be used to do a partial walk with synthetized reg and interrupts - * properties, for example when resolving PCI interrupts when no device - * node exist for the parent. - * - */ - -extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, - u32 ointsize, const u32 *addr, - struct of_irq *out_irq); - /** * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved @@ -163,9 +119,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -extern int of_irq_to_resource(struct device_node *dev, int index, - struct resource *r); - /** * of_iomap - Maps the memory mapped IO for a given device_node * @device: the device whose io range will be mapped diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index dfa6de6572bb..d61a5c5fe690 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -678,257 +678,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, *size = of_read_number(dma_window, cells); } -/* - * Interrupt remapper - */ - -static struct device_node *of_irq_find_parent(struct device_node *child) -{ - struct device_node *p; - const phandle *parp; - - if (!of_node_get(child)) - return NULL; - - do { - parp = of_get_property(child, "interrupt-parent", NULL); - if (parp == NULL) - p = of_get_parent(child); - else { - if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) - p = of_node_get(of_irq_dflt_pic); - else - p = of_find_node_by_phandle(*parp); - } - of_node_put(child); - child = p; - } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); - - return p; -} - -int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, - const u32 *addr, struct of_irq *out_irq) -{ - struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; - const u32 *tmp, *imap, *imask; - u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; - int imaplen, match, i; - - DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", - parent->full_name, intspec[0], intspec[1], ointsize); - - ipar = of_node_get(parent); - - /* First get the #interrupt-cells property of the current cursor - * that tells us how to interpret the passed-in intspec. If there - * is none, we are nice and just walk up the tree - */ - do { - tmp = of_get_property(ipar, "#interrupt-cells", NULL); - if (tmp != NULL) { - intsize = *tmp; - break; - } - tnode = ipar; - ipar = of_irq_find_parent(ipar); - of_node_put(tnode); - } while (ipar); - if (ipar == NULL) { - DBG(" -> no parent found !\n"); - goto fail; - } - - DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); - - if (ointsize != intsize) - return -EINVAL; - - /* Look for this #address-cells. We have to implement the old linux - * trick of looking for the parent here as some device-trees rely on it - */ - old = of_node_get(ipar); - do { - tmp = of_get_property(old, "#address-cells", NULL); - tnode = of_get_parent(old); - of_node_put(old); - old = tnode; - } while(old && tmp == NULL); - of_node_put(old); - old = NULL; - addrsize = (tmp == NULL) ? 2 : *tmp; - - DBG(" -> addrsize=%d\n", addrsize); - - /* Now start the actual "proper" walk of the interrupt tree */ - while (ipar != NULL) { - /* Now check if cursor is an interrupt-controller and if it is - * then we are done - */ - if (of_get_property(ipar, "interrupt-controller", NULL) != - NULL) { - DBG(" -> got it !\n"); - memcpy(out_irq->specifier, intspec, - intsize * sizeof(u32)); - out_irq->size = intsize; - out_irq->controller = ipar; - of_node_put(old); - return 0; - } - - /* Now look for an interrupt-map */ - imap = of_get_property(ipar, "interrupt-map", &imaplen); - /* No interrupt map, check for an interrupt parent */ - if (imap == NULL) { - DBG(" -> no map, getting parent\n"); - newpar = of_irq_find_parent(ipar); - goto skiplevel; - } - imaplen /= sizeof(u32); - - /* Look for a mask */ - imask = of_get_property(ipar, "interrupt-map-mask", NULL); - - /* If we were passed no "reg" property and we attempt to parse - * an interrupt-map, then #address-cells must be 0. - * Fail if it's not. - */ - if (addr == NULL && addrsize != 0) { - DBG(" -> no reg passed in when needed !\n"); - goto fail; - } - - /* Parse interrupt-map */ - match = 0; - while (imaplen > (addrsize + intsize + 1) && !match) { - /* Compare specifiers */ - match = 1; - for (i = 0; i < addrsize && match; ++i) { - u32 mask = imask ? imask[i] : 0xffffffffu; - match = ((addr[i] ^ imap[i]) & mask) == 0; - } - for (; i < (addrsize + intsize) && match; ++i) { - u32 mask = imask ? imask[i] : 0xffffffffu; - match = - ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; - } - imap += addrsize + intsize; - imaplen -= addrsize + intsize; - - DBG(" -> match=%d (imaplen=%d)\n", match, imaplen); - - /* Get the interrupt parent */ - if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) - newpar = of_node_get(of_irq_dflt_pic); - else - newpar = of_find_node_by_phandle((phandle)*imap); - imap++; - --imaplen; - - /* Check if not found */ - if (newpar == NULL) { - DBG(" -> imap parent not found !\n"); - goto fail; - } - - /* Get #interrupt-cells and #address-cells of new - * parent - */ - tmp = of_get_property(newpar, "#interrupt-cells", NULL); - if (tmp == NULL) { - DBG(" -> parent lacks #interrupt-cells !\n"); - goto fail; - } - newintsize = *tmp; - tmp = of_get_property(newpar, "#address-cells", NULL); - newaddrsize = (tmp == NULL) ? 0 : *tmp; - - DBG(" -> newintsize=%d, newaddrsize=%d\n", - newintsize, newaddrsize); - - /* Check for malformed properties */ - if (imaplen < (newaddrsize + newintsize)) - goto fail; - - imap += newaddrsize + newintsize; - imaplen -= newaddrsize + newintsize; - - DBG(" -> imaplen=%d\n", imaplen); - } - if (!match) - goto fail; - - of_node_put(old); - old = of_node_get(newpar); - addrsize = newaddrsize; - intsize = newintsize; - intspec = imap - intsize; - addr = intspec - addrsize; - - skiplevel: - /* Iterate again with new parent */ - DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>"); - of_node_put(ipar); - ipar = newpar; - newpar = NULL; - } - fail: - of_node_put(ipar); - of_node_put(old); - of_node_put(newpar); - - return -EINVAL; -} -EXPORT_SYMBOL_GPL(of_irq_map_raw); - -int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) -{ - struct device_node *p; - const u32 *intspec, *tmp, *addr; - u32 intsize, intlen; - int res = -EINVAL; - - DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); - - /* OldWorld mac stuff is "special", handle out of line */ - if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) - return of_irq_map_oldworld(device, index, out_irq); - - /* Get the interrupts property */ - intspec = of_get_property(device, "interrupts", &intlen); - if (intspec == NULL) - return -EINVAL; - intlen /= sizeof(u32); - - /* Get the reg property (if any) */ - addr = of_get_property(device, "reg", NULL); - - /* Look for the interrupt parent. */ - p = of_irq_find_parent(device); - if (p == NULL) - return -EINVAL; - - /* Get size of interrupt specifier */ - tmp = of_get_property(p, "#interrupt-cells", NULL); - if (tmp == NULL) - goto out; - intsize = *tmp; - - DBG(" intsize=%d intlen=%d\n", intsize, intlen); - - /* Check index */ - if ((index + 1) * intsize > intlen) - goto out; - - /* Get new specifier and map it */ - res = of_irq_map_raw(p, intspec + index * intsize, intsize, - addr, out_irq); -out: - of_node_put(p); - return res; -} -EXPORT_SYMBOL_GPL(of_irq_map_one); - /** * Search the device tree for the best MAC address to use. 'mac-address' is * checked first, because that is supposed to contain to "most recent" MAC @@ -967,21 +716,6 @@ const void *of_get_mac_address(struct device_node *np) } EXPORT_SYMBOL(of_get_mac_address); -int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) -{ - int irq = irq_of_parse_and_map(dev, index); - - /* Only dereference the resource if both the - * resource and the irq are valid. */ - if (r && irq != NO_IRQ) { - r->start = r->end = irq; - r->flags = IORESOURCE_IRQ; - } - - return irq; -} -EXPORT_SYMBOL_GPL(of_irq_to_resource); - void __iomem *of_iomap(struct device_node *np, int index) { struct resource res; -- cgit v1.2.3 From 6b884a8d50a6eea2fb3dad7befe748f67193073b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:09 -0600 Subject: of/address: merge of_iomap() Merge common code between Microblaze and PowerPC. This patch creates new of_address.h and address.c files to containing address translation and mapping routines. First routine to be moved it of_io