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 diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index d4c4521..f9740d0 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 8fac3ab..4f5bde6 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 f320246..6d1844a 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 c333b8d..0c34a87 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 47e63f1..331de91 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 1dae807..5e8cbb9 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 10c6c36..016c947 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 8a8363a..1523290 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 558a705..93011e6 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 6dad8e3..99c6dba 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 97a1ae2..9041dae 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 168d4cb..1cfee57 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"); diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index da8f176..38df87b 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2657,7 +2657,7 @@ static int __devinit fore200e_sba_probe(struct of_device *op, fore200e->bus = bus; fore200e->bus_dev = op; - fore200e->irq = op->irqs[0]; + fore200e->irq = op->archdata.irqs[0]; fore200e->phys_base = op->resource[0].start; sprintf(fore200e->name, "%s-%d", bus->model_name, index); diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 04e32f2..c7d50ff4 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -58,9 +58,9 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev if (!strcmp(dp->name, OBP_PS2KBD_NAME1) || !strcmp(dp->name, OBP_PS2KBD_NAME2)) { struct of_device *kbd = of_find_device_by_node(dp); - unsigned int irq = kbd->irqs[0]; + unsigned int irq = kbd->archdata.irqs[0]; if (irq == 0xffffffff) - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; i8042_kbd_irq = irq; kbd_iobase = of_ioremap(&kbd->resource[0], 0, 8, "kbd"); @@ -68,9 +68,9 @@ static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_dev } else if (!strcmp(dp->name, OBP_PS2MS_NAME1) || !strcmp(dp->name, OBP_PS2MS_NAME2)) { struct of_device *ms = of_find_device_by_node(dp); - unsigned int irq = ms->irqs[0]; + unsigned int irq = ms->archdata.irqs[0]; if (irq == 0xffffffff) - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; i8042_aux_irq = irq; } diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 1a57c3d..370d3c1 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1079,7 +1079,7 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic mp->dev = dev; dev->watchdog_timeo = 5*HZ; - dev->irq = op->irqs[0]; + dev->irq = op->archdata.irqs[0]; dev->netdev_ops = &myri_ops; /* Register interrupt handler now. */ diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 63e8e38..5dd50b6 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9119,12 +9119,12 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map) if (!int_prop) return -ENODEV; - for (i = 0; i < op->num_irqs; i++) { + for (i = 0; i < op->archdata.num_irqs; i++) { ldg_num_map[i] = int_prop[i]; - np->ldg[i].irq = op->irqs[i]; + np->ldg[i].irq = op->archdata.irqs[i]; } - np->num_ldg = op->num_irqs; + np->num_ldg = op->archdata.num_irqs; return 0; #else diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 367e96f..0b10d24 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1201,7 +1201,7 @@ static int __devinit bigmac_ether_init(struct of_device *op, dev->watchdog_timeo = 5*HZ; /* Finish net device registration. */ - dev->irq = bp->bigmac_op->irqs[0]; + dev->irq = bp->bigmac_op->archdata.irqs[0]; dev->dma = 0; if (register_netdev(dev)) { diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 3d9650b..0a63ebe 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2561,7 +2561,7 @@ static int __init quattro_sbus_register_irqs(void) if (skip) continue; - err = request_irq(op->irqs[0], + err = request_irq(op->archdata.irqs[0], quattro_sbus_interrupt, IRQF_SHARED, "Quattro", qp); @@ -2590,7 +2590,7 @@ static void quattro_sbus_free_irqs(void) if (skip) continue; - free_irq(op->irqs[0], qp); + free_irq(op->archdata.irqs[0], qp); } } #endif /* CONFIG_SBUS */ @@ -2790,7 +2790,7 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) /* Happy Meal can do it all... */ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; - dev->irq = op->irqs[0]; + dev->irq = op->archdata.irqs[0]; #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) /* Hook up SBUS register/descriptor accessors. */ diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 7d9c33d..c6bfdad 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1474,7 +1474,7 @@ no_link_test: dev->ethtool_ops = &sparc_lance_ethtool_ops; dev->netdev_ops = &sparc_lance_ops; - dev->irq = op->irqs[0]; + dev->irq = op->archdata.irqs[0]; /* We cannot sleep if the chip is busy during a * multicast list update event, because such events diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 72b579c..4465174 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -803,7 +803,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child) qec_init_once(qecp, op); - if (request_irq(op->irqs[0], qec_interrupt, + if (request_irq(op->archdata.irqs[0], qec_interrupt, IRQF_SHARED, "qec", (void *) qecp)) { printk(KERN_ERR "qec: Can't register irq.\n"); goto fail; @@ -901,7 +901,7 @@ static int __devinit qec_ether_init(struct of_device *op) SET_NETDEV_DEV(dev, &op->dev); dev->watchdog_timeo = 5*HZ; - dev->irq = op->irqs[0]; + dev->irq = op->archdata.irqs[0]; dev->dma = 0; dev->ethtool_ops = &qe_ethtool_ops; dev->netdev_ops = &qec_ops; @@ -999,7 +999,7 @@ static void __exit qec_exit(void) struct sunqec *next = root_qec_dev->next_module; struct of_device *op = root_qec_dev->op; - free_irq(op->irqs[0], (void *) root_qec_dev); + free_irq(op->archdata.irqs[0], (void *) root_qec_dev); of_iounmap(&op->resource[0], root_qec_dev->gregs, GLOB_REG_SIZE); kfree(root_qec_dev); diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 9a5b4b8..3cdfe96 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -295,7 +295,7 @@ static int __devinit bpp_probe(struct of_device *op, const struct of_device_id * void __iomem *base; struct parport *p; - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; base = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), "sunbpp"); diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 8bfdd63..40d7a1f 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -317,7 +317,7 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int inde bp->waiting = 0; init_waitqueue_head(&bp->wq); - if (request_irq(op->irqs[0], bbc_i2c_interrupt, + if (request_irq(op->archdata.irqs[0], bbc_i2c_interrupt, IRQF_SHARED, "bbc_i2c", bp)) goto fail; @@ -373,7 +373,7 @@ static int __devinit bbc_i2c_probe(struct of_device *op, err = bbc_envctrl_init(bp); if (err) { - free_irq(op->irqs[0], bp); + free_irq(op->archdata.irqs[0], bp); if (bp->i2c_bussel_reg) of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1); if (bp->i2c_control_regs) @@ -392,7 +392,7 @@ static int __devexit bbc_i2c_remove(struct of_device *op) bbc_envctrl_cleanup(bp); - free_irq(op->irqs[0], bp); + free_irq(op->archdata.irqs[0], bp); if (bp->i2c_bussel_reg) of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 5f25366..b8b40e9 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -367,7 +367,7 @@ static int __devinit uctrl_probe(struct of_device *op, goto out_free; } - p->irq = op->irqs[0]; + p->irq = op->archdata.irqs[0]; err = request_irq(p->irq, uctrl_interrupt, 0, "uctrl", p); if (err) { printk(KERN_ERR "uctrl: Unable to register irq.\n"); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index ca5c15c..3f5b541 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -729,7 +729,7 @@ static int __devinit qpti_register_irq(struct qlogicpti *qpti) { struct of_device *op = qpti->op; - qpti->qhost->irq = qpti->irq = op->irqs[0]; + qpti->qhost->irq = qpti->irq = op->archdata.irqs[0]; /* We used to try various overly-clever things to * reduce the interrupt processing overhead on @@ -1302,7 +1302,7 @@ static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_devic /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. */ - if (op->irqs[0] == 0) + if (op->archdata.irqs[0] == 0) return -ENODEV; host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti)); diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 386dd9d..ddc221a 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -116,7 +116,7 @@ static int __devinit esp_sbus_register_irq(struct esp *esp) struct Scsi_Host *host = esp->host; struct of_device *op = esp->dev; - host->irq = op->irqs[0]; + host->irq = op->archdata.irqs[0]; return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); } diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 890f917..36e2448 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -525,7 +525,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m unsigned long minor; int err; - if (op->irqs[0] == 0xffffffff) + if (op->archdata.irqs[0] == 0xffffffff) return -ENODEV; port = kzalloc(sizeof(struct uart_port), GFP_KERNEL); @@ -557,7 +557,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m port->membase = (unsigned char __iomem *) __pa(port); - port->irq = op->irqs[0]; + port->irq = op->archdata.irqs[0]; port->dev = &op->dev; diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 5e81bc6..0a7dd68 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -969,7 +969,7 @@ static int __devinit sunsab_init_one(struct uart_sunsab_port *up, return -ENOMEM; up->regs = (union sab82532_async_regs __iomem *) up->port.membase; - up->port.irq = op->irqs[0]; + up->port.irq = op->archdata.irqs[0]; up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; up->port.iotype = UPIO_MEM; diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 234459c..56d891a 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1443,7 +1443,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m return -ENOMEM; } - up->port.irq = op->irqs[0]; + up->port.irq = op->archdata.irqs[0]; up->port.dev = &op->dev; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index f9a24f4..fcbe20d 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1426,7 +1426,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m rp = sunzilog_chip_regs[inst]; if (zilog_irq == -1) - zilog_irq = op->irqs[0]; + zilog_irq = op->archdata.irqs[0]; up = &sunzilog_port_table[inst * 2]; @@ -1434,7 +1434,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m up[0].port.mapbase = op->resource[0].start + 0x00; up[0].port.membase = (void __iomem *) &rp->channelA; up[0].port.iotype = UPIO_MEM; - up[0].port.irq = op->irqs[0]; + up[0].port.irq = op->archdata.irqs[0]; up[0].port.uartclk = ZS_CLOCK; up[0].port.fifosize = 1; up[0].port.ops = &sunzilog_pops; @@ -1451,7 +1451,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m up[1].port.mapbase = op->resource[0].start + 0x04; up[1].port.membase = (void __iomem *) &rp->channelB; up[1].port.iotype = UPIO_MEM; - up[1].port.irq = op->irqs[0]; + up[1].port.irq = op->archdata.irqs[0]; up[1].port.uartclk = ZS_CLOCK; up[1].port.fifosize = 1; up[1].port.ops = &sunzilog_pops; @@ -1492,12 +1492,12 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m "is a %s\n", dev_name(&op->dev), (unsigned long long) up[0].port.mapbase, - op->irqs[0], sunzilog_type(&up[0].port)); + op->archdata.irqs[0], sunzilog_type(&up[0].port)); printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " "is a %s\n", dev_name(&op->dev), (unsigned long long) up[1].port.mapbase, - op->irqs[0], sunzilog_type(&up[1].port)); + op->archdata.irqs[0], sunzilog_type(&up[1].port)); kbm_inst++; } diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index d62b9ce..8c03fd7 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -545,7 +545,7 @@ static int __devinit cpwd_probe(struct of_device *op, goto out; } - p->irq = op->irqs[0]; + p->irq = op->archdata.irqs[0]; spin_lock_init(&p->lock); diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 71221fd..43c63d4 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1010,7 +1010,7 @@ static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_de struct snd_amd7930 *amd; int err, irq; - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; if (dev_num >= SNDRV_CARDS) return -ENODEV; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index fb4c6f2..f7f05c2 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1832,14 +1832,14 @@ static int __devinit snd_cs4231_sbus_create(struct snd_card *card, chip->c_dma.request = sbus_dma_request; chip->c_dma.address = sbus_dma_addr; - if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, + if (request_irq(op->archdata.irqs[0], snd_cs4231_sbus_interrupt, IRQF_SHARED, "cs4231", chip)) { snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", - dev, op->irqs[0]); + dev, op->archdata.irqs[0]); snd_cs4231_sbus_free(chip); return -EBUSY; } - chip->irq[0] = op->irqs[0]; + chip->irq[0] = op->archdata.irqs[0]; if (snd_cs4231_probe(chip) < 0) { snd_cs4231_sbus_free(chip); @@ -1870,7 +1870,7 @@ static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_dev card->shortname, rp->flags & 0xffL, (unsigned long long)rp->start, - op->irqs[0]); + op->archdata.irqs[0]); err = snd_cs4231_sbus_create(card, op, dev); if (err < 0) { @@ -1979,12 +1979,12 @@ static int __devinit snd_cs4231_ebus_create(struct snd_card *card, chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; chip->c_dma.ebus_info.client_cookie = chip; - chip->c_dma.ebus_info.irq = op->irqs[0]; + chip->c_dma.ebus_info.irq = op->archdata.irqs[0]; strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; chip->p_dma.ebus_info.client_cookie = chip; - chip->p_dma.ebus_info.irq = op->irqs[1]; + chip->p_dma.ebus_info.irq = op->archdata.irqs[1]; chip->p_dma.prepare = _ebus_dma_prepare; chip->p_dma.enable = _ebus_dma_enable; @@ -2060,7 +2060,7 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev sprintf(card->longname, "%s at 0x%llx, irq %d", card->shortname, op->resource[0].start, - op->irqs[0]); + op->archdata.irqs[0]); err = snd_cs4231_ebus_create(card, op, dev); if (err < 0) { diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 1557bf1..491ce71 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2608,7 +2608,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id return -ENOENT; } - irq = op->irqs[0]; + irq = op->archdata.irqs[0]; if (irq <= 0) { printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); return -ENODEV; -- cgit v0.10.2 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 diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index 73cb980..0a5f3f91 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 444e97e..cb36632 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 7ae2753..e3bdada 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 f9740d0..fb220e4 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 6d1844a..22b9828 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); diff --git a/drivers/net/niu.h b/drivers/net/niu.h index d671546..a41fa8e 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -3236,7 +3236,7 @@ struct niu_phy_ops { int (*link_status)(struct niu *np, int *); }; -struct of_device; +struct platform_device; struct niu { void __iomem *regs; struct net_device *dev; @@ -3297,7 +3297,7 @@ struct niu { struct niu_vpd vpd; u32 eeprom_len; - struct of_device *op; + struct platform_device *op; void __iomem *vir_regs_1; void __iomem *vir_regs_2; }; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 11651fa..a3ae590 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -3,9 +3,26 @@ #ifdef CONFIG_OF_DEVICE #include +#include #include #include + +/* + * The of_device *was* a kind of "base class" that was a superset of + * struct device for use by devices attached to an OF node and probed + * using OF properties. However, the important bit of OF-style + * probing, namely the device node pointer, has been moved into the + * common struct device when CONFIG_OF is set to make OF-style probing + * available to all bus types. So now, just make of_device and + * platform_device equivalent so that current of_platform bus users + * can be transparently migrated over to using the platform bus. + * + * This line will go away once all references to of_device are removed + * from the kernel. + */ +#define of_device platform_device + #include #define to_of_device(d) container_of(d, struct of_device, dev) -- cgit v0.10.2 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 diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h index 31a35c3..ec5583d 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 e7d67a3..e9fb2eb 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 @@ -139,19 +128,6 @@ extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, 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 * @out_irq: structure of_irq filled by this function diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 8f120ac..dd32b09 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 e054bae..4e30515 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 ddd408a..47d41b6 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 30817d9..2676ef2 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 f845828..ac69574 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) { } diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 7cecc8f..b87495e 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -6,6 +6,10 @@ config OF_DYNAMIC def_bool y depends on OF && PPC_OF +config OF_IRQ + def_bool y + depends on OF && !SPARC + config OF_DEVICE def_bool y depends on OF && (SPARC || PPC_OF || MICROBLAZE) diff --git a/drivers/of/Makefile b/drivers/of/Makefile index f232cc9..3631a5e 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,5 +1,6 @@ obj-y = base.o obj-$(CONFIG_OF_FLATTREE) += fdt.o +obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o diff --git a/drivers/of/irq.c b/drivers/of/irq.c new file mode 100644 index 0000000..9b3397c --- /dev/null +++ b/drivers/of/irq.c @@ -0,0 +1,45 @@ +/* + * Derived from arch/i386/kernel/irq.c + * Copyright (C) 1992 Linus Torvalds + * Adapted from arch/i386 by Gary Thomas + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Updated and modified by Cort Dougan + * Copyright (C) 1996-2001 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras + * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This file contains the code used to make IRQ descriptions in the + * device tree to actual irq numbers on an interrupt controller + * driver. + */ + +#include +#include +#include +#include +#include + +/** + * 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 + */ +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); diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 42a6715..1fce00e 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index 5fed7e3..d504f1d 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -9,6 +9,7 @@ #include #include #include +#include #include /** diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h new file mode 100644 index 0000000..0e37c05 --- /dev/null +++ b/include/linux/of_irq.h @@ -0,0 +1,41 @@ +#ifndef __OF_IRQ_H +#define __OF_IRQ_H + +#if defined(CONFIG_OF) +struct of_irq; +#include +#include + +/* + * irq_of_parse_and_map() is used ba all OF enabled platforms; but SPARC + * implements it differently. However, the prototype is the same for all, + * so declare it here regardless of the CONFIG_OF_IRQ setting. + */ +extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); + +#if defined(CONFIG_OF_IRQ) +/** + * of_irq - container for device_node/irq_specifier pair for an irq controller + * @controller: pointer to interrupt controller device tree node + * @size: size of interrupt specifier + * @specifier: array of cells @size long specifing the specific interrupt + * + * 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 */ +}; + +extern int of_irq_map_one(struct device_node *device, int index, + struct of_irq *out_irq); +extern unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, + unsigned int intsize); + +#endif /* CONFIG_OF_IRQ */ +#endif /* CONFIG_OF */ +#endif /* __OF_IRQ_H */ -- cgit v0.10.2 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 diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index e9fb2eb..4f34bc5 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 bf7e6c2..cba0581 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 v0.10.2 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 diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 47d41b6..4486765 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 8362620..dfa6de6 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 630a533..890d5f7 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 v0.10.2 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 diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 4f34bc5..5fbdfe7 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 cba0581..e28968f 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 4486765..10d5ee5 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 dfa6de6..d61a5c5 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; diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 9b3397c..598454f 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -43,3 +43,304 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) oirq.size); } EXPORT_SYMBOL_GPL(irq_of_parse_and_map); + +/** + * of_irq_find_parent - Given a device node, find its interrupt parent node + * @child: pointer to device node + * + * Returns a pointer to the interrupt parent node, or NULL if the interrupt + * parent could not be determined. + */ +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; +} + +/** + * 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. + */ +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); + +/** + * 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(). + */ +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; + + pr_debug("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); + + 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) + goto out; + intsize = *tmp; + + pr_debug(" 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); + +/** + * of_irq_to_resource - Decode a node's IRQ and return it as a resource + * @dev: pointer to device tree node + * @index: zero-based index of the irq + * @r: pointer to resource structure to return result into. + */ +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); diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 0e37c05..5929781 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -4,6 +4,8 @@ #if defined(CONFIG_OF) struct of_irq; #include +#include +#include #include /* @@ -30,11 +32,38 @@ struct of_irq { u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ }; +/* + * Workarounds only applied to 32bit powermac machines + */ +#define OF_IMAP_OLDWORLD_MAC 0x00000001 +#define OF_IMAP_NO_PHANDLE 0x00000002 + +#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC) +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 /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ +#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 /* CONFIG_PPC32 && CONFIG_PPC_PMAC */ + + +extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, + u32 ointsize, const u32 *addr, + struct of_irq *out_irq); extern int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq); extern unsigned int irq_create_of_mapping(struct device_node *controller, const u32 *intspec, unsigned int intsize); +extern int of_irq_to_resource(struct device_node *dev, int index, + struct resource *r); #endif /* CONFIG_OF_IRQ */ #endif /* CONFIG_OF */ -- cgit v0.10.2 From a7c194b007ec40a130207e9ace9cecf598fc6ac5 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 8 Jun 2010 07:48:08 -0600 Subject: of/irq: little endian fixes Fix some endian issues in the irq mapping OF code. Signed-off-by: Rob Herring Signed-off-by: Grant Likely CC: Michal Simek CC: Wolfram Sang CC: Stephen Rothwell CC: Benjamin Herrenschmidt diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 598454f..623eb66 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -95,7 +95,7 @@ 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; + const __be32 *tmp, *imap, *imask; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i; @@ -111,7 +111,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, do { tmp = of_get_property(ipar, "#interrupt-cells", NULL); if (tmp != NULL) { - intsize = *tmp; + intsize = be32_to_cpu(*tmp); break; } tnode = ipar; @@ -140,7 +140,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, } while (old && tmp == NULL); of_node_put(old); old = NULL; - addrsize = (tmp == NULL) ? 2 : *tmp; + addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp); pr_debug(" -> addrsize=%d\n", addrsize); @@ -152,8 +152,9 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, if (of_get_property(ipar, "interrupt-controller", NULL) != NULL) { pr_debug(" -> got it !\n"); - memcpy(out_irq->specifier, intspec, - intsize * sizeof(u32)); + for (i = 0; i < intsize; i++) + out_irq->specifier[i] = + of_read_number(intspec +i, 1); out_irq->size = intsize; out_irq->controller = ipar; of_node_put(old); @@ -223,9 +224,9 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, pr_debug(" -> parent lacks #interrupt-cells!\n"); goto fail; } - newintsize = *tmp; + newintsize = be32_to_cpu(*tmp); tmp = of_get_property(newpar, "#address-cells", NULL); - newaddrsize = (tmp == NULL) ? 0 : *tmp; + newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp); pr_debug(" -> newintsize=%d, newaddrsize=%d\n", newintsize, newaddrsize); @@ -307,7 +308,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq tmp = of_get_property(p, "#interrupt-cells", NULL); if (tmp == NULL) goto out; - intsize = *tmp; + intsize = be32_to_cpu(*tmp); pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); -- cgit v0.10.2 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_iomap() Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt CC: Michal Simek CC: Stephen Rothwell diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 5fbdfe7..6411c3b 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 @@ -103,15 +104,6 @@ extern const void *of_get_mac_address(struct device_node *np); struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -/** - * of_iomap - Maps the memory mapped IO for a given device_node - * @device: the device whose io range will be mapped - * @index: index of the io range - * - * Returns a pointer to the mapped memory - */ -extern void __iomem *of_iomap(struct device_node *device, int index); - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index e28968f..1159ba5 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -681,14 +681,3 @@ const void *of_get_mac_address(struct device_node *np) return NULL; } EXPORT_SYMBOL(of_get_mac_address); - -void __iomem *of_iomap(struct device_node *np, int index) -{ - struct resource res; - - if (of_address_to_resource(np, index, &res)) - return NULL; - - return ioremap(res.start, 1 + res.end - res.start); -} -EXPORT_SYMBOL(of_iomap); diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 10d5ee5..0abe379 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 @@ -119,14 +120,5 @@ extern const void *of_get_mac_address(struct device_node *np); struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -/** - * of_iomap - Maps the memory mapped IO for a given device_node - * @device: the device whose io range will be mapped - * @index: index of the io range - * - * Returns a pointer to the mapped memory - */ -extern void __iomem *of_iomap(struct device_node *device, int index); - #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index d61a5c5..1d5d4f6 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -715,14 +715,3 @@ const void *of_get_mac_address(struct device_node *np) return NULL; } EXPORT_SYMBOL(of_get_mac_address); - -void __iomem *of_iomap(struct device_node *np, int index) -{ - struct resource res; - - if (of_address_to_resource(np, index, &res)) - return NULL; - - return ioremap(res.start, 1 + res.end - res.start); -} -EXPORT_SYMBOL(of_iomap); diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index b87495e..097f42a 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -6,6 +6,10 @@ config OF_DYNAMIC def_bool y depends on OF && PPC_OF +config OF_ADDRESS + def_bool y + depends on OF && !SPARC + config OF_IRQ def_bool y depends on OF && !SPARC diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 3631a5e..0052c40 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,5 +1,6 @@ obj-y = base.o obj-$(CONFIG_OF_FLATTREE) += fdt.o +obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o diff --git a/drivers/of/address.c b/drivers/of/address.c new file mode 100644 index 0000000..258528d --- /dev/null +++ b/drivers/of/address.c @@ -0,0 +1,22 @@ + +#include +#include +#include + +/** + * of_iomap - Maps the memory mapped IO for a given device_node + * @device: the device whose io range will be mapped + * @index: index of the io range + * + * Returns a pointer to the mapped memory + */ +void __iomem *of_iomap(struct device_node *np, int index) +{ + struct resource res; + + if (of_address_to_resource(np, index, &res)) + return NULL; + + return ioremap(res.start, 1 + res.end - res.start); +} +EXPORT_SYMBOL(of_iomap); diff --git a/include/linux/of_address.h b/include/linux/of_address.h new file mode 100644 index 0000000..570831d --- /dev/null +++ b/include/linux/of_address.h @@ -0,0 +1,9 @@ +#ifndef __OF_ADDRESS_H +#define __OF_ADDRESS_H +#include +#include + +extern void __iomem *of_iomap(struct device_node *device, int index); + +#endif /* __OF_ADDRESS_H */ + -- cgit v0.10.2 From 1f5bef30cf6c66f097ea5dfc580a41924df888d1 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:09 -0600 Subject: of/address: merge of_address_to_resource() Merge common code between PowerPC and Microblaze. This patch also moves the prototype of pci_address_to_pio() out of pci-bridge.h and into prom.h because the only user of pci_address_to_pio() is of_address_to_resource(). Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt CC: Michal Simek CC: Stephen Rothwell diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 0c77cda..0c68764 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -172,13 +172,8 @@ static inline int pci_has_flag(int flag) extern struct list_head hose_list; -extern unsigned long pci_address_to_pio(phys_addr_t address); extern int pcibios_vaddr_is_ioport(void __iomem *address); #else -static inline unsigned long pci_address_to_pio(phys_addr_t address) -{ - return (unsigned long)-1; -} static inline int pcibios_vaddr_is_ioport(void __iomem *address) { return 0; diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 6411c3b..4e94c07 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -65,17 +65,18 @@ extern const u32 *of_get_address(struct device_node *dev, int index, extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags); -/* Get an address as a resource. Note that if your address is - * a PIO address, the conversion will fail if the physical address - * can't be internally converted to an IO token with - * pci_address_to_pio(), that is because it's either called to early - * or it can't be matched to any host bridge IO space - */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); +#ifdef CONFIG_PCI +extern unsigned long pci_address_to_pio(phys_addr_t address); +#else +static inline unsigned long pci_address_to_pio(phys_addr_t address) +{ + return (unsigned long)-1; +} +#endif /* CONFIG_PCI */ + /* Parse the ibm,dma-window property of an OF node into the busno, phys and * size parameters. */ diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 1159ba5..2f9cdd2 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -17,9 +18,6 @@ (ns) > 0) static struct of_bus *of_match_bus(struct device_node *np); -static int __of_address_to_resource(struct device_node *dev, - const u32 *addrp, u64 size, unsigned int flags, - struct resource *r); /* Debug utility */ #ifdef DEBUG @@ -576,48 +574,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, - struct resource *r) -{ - u64 taddr; - - if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) - return -EINVAL; - taddr = of_translate_address(dev, addrp); - if (taddr == OF_BAD_ADDR) - return -EINVAL; - memset(r, 0, sizeof(struct resource)); - if (flags & IORESOURCE_IO) { - unsigned long port; - port = -1; /* pci_address_to_pio(taddr); */ - if (port == (unsigned long)-1) - return -EINVAL; - r->start = port; - r->end = port + size - 1; - } else { - r->start = taddr; - r->end = taddr + size - 1; - } - r->flags = flags; - r->name = dev->name; - return 0; -} - -int of_address_to_resource(struct device_node *dev, int index, - struct resource *r) -{ - const u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_address(dev, index, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_address_to_resource); - void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) { diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 76e1f31..51e9e6f 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -303,13 +303,8 @@ extern void pcibios_free_controller(struct pci_controller *phb); extern void pcibios_setup_phb_resources(struct pci_controller *hose); #ifdef CONFIG_PCI -extern unsigned long pci_address_to_pio(phys_addr_t address); extern int pcibios_vaddr_is_ioport(void __iomem *address); #else -static inline unsigned long pci_address_to_pio(phys_addr_t address) -{ - return (unsigned long)-1; -} static inline int pcibios_vaddr_is_ioport(void __iomem *address) { return 0; diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 0abe379..ceace96 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -70,14 +70,6 @@ static inline const u32 *of_get_pci_address(struct device_node *dev, } #endif /* CONFIG_PCI */ -/* Get an address as a resource. Note that if your address is - * a PIO address, the conversion will fail if the physical address - * can't be internally converted to an IO token with - * pci_address_to_pio(), that is because it's either called to early - * or it can't be matched to any host bridge IO space - */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); #ifdef CONFIG_PCI extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); @@ -89,6 +81,15 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar, } #endif /* CONFIG_PCI */ +#ifdef CONFIG_PCI +extern unsigned long pci_address_to_pio(phys_addr_t address); +#else +static inline unsigned long pci_address_to_pio(phys_addr_t address) +{ + return (unsigned long)-1; +} +#endif /* CONFIG_PCI */ + /* Parse the ibm,dma-window property of an OF node into the busno, phys and * size parameters. */ diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 1d5d4f6..1dac535 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -27,10 +28,6 @@ (ns) > 0) static struct of_bus *of_match_bus(struct device_node *np); -static int __of_address_to_resource(struct device_node *dev, - const u32 *addrp, u64 size, unsigned int flags, - struct resource *r); - /* Debug utility */ #ifdef DEBUG @@ -610,48 +607,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, - struct resource *r) -{ - u64 taddr; - - if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) - return -EINVAL; - taddr = of_translate_address(dev, addrp); - if (taddr == OF_BAD_ADDR) - return -EINVAL; - memset(r, 0, sizeof(struct resource)); - if (flags & IORESOURCE_IO) { - unsigned long port; - port = pci_address_to_pio(taddr); - if (port == (unsigned long)-1) - return -EINVAL; - r->start = port; - r->end = port + size - 1; - } else { - r->start = taddr; - r->end = taddr + size - 1; - } - r->flags = flags; - r->name = dev->name; - return 0; -} - -int of_address_to_resource(struct device_node *dev, int index, - struct resource *r) -{ - const u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_address(dev, index, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_address_to_resource); - void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) { diff --git a/drivers/of/address.c b/drivers/of/address.c index 258528d..c381955 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -3,6 +3,57 @@ #include #include +int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, + struct resource *r) +{ + u64 taddr; + + if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) + return -EINVAL; + taddr = of_translate_address(dev, addrp); + if (taddr == OF_BAD_ADDR) + return -EINVAL; + memset(r, 0, sizeof(struct resource)); + if (flags & IORESOURCE_IO) { + unsigned long port; + port = pci_address_to_pio(taddr); + if (port == (unsigned long)-1) + return -EINVAL; + r->start = port; + r->end = port + size - 1; + } else { + r->start = taddr; + r->end = taddr + size - 1; + } + r->flags = flags; + r->name = dev->name; + return 0; +} + +/** + * of_address_to_resource - Translate device tree address and return as resource + * + * Note that if your address is a PIO address, the conversion will fail if + * the physical address can't be internally converted to an IO token with + * pci_address_to_pio(), that is because it's either called to early or it + * can't be matched to any host bridge IO space + */ +int of_address_to_resource(struct device_node *dev, int index, + struct resource *r) +{ + const u32 *addrp; + u64 size; + unsigned int flags; + + addrp = of_get_address(dev, index, &size, &flags); + if (addrp == NULL) + return -EINVAL; + return __of_address_to_resource(dev, addrp, size, flags, r); +} +EXPORT_SYMBOL_GPL(of_address_to_resource); + + /** * of_iomap - Maps the memory mapped IO for a given device_node * @device: the device whose io range will be mapped diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 570831d..474b794 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -3,6 +3,11 @@ #include #include +extern int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, + struct resource *r); +extern int of_address_to_resource(struct device_node *dev, int index, + struct resource *r); extern void __iomem *of_iomap(struct device_node *device, int index); #endif /* __OF_ADDRESS_H */ -- cgit v0.10.2 From dbbdee94734bf6f1db7af42008a53655e77cab8f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:10 -0600 Subject: of/address: Merge all of the bus translation code Microblaze and PowerPC share a large chunk of code for translating OF device tree data into usable addresses. Differences between the two consist of cosmetic differences, and the addition of dma-ranges support code to powerpc but not microblaze. This patch moves the powerpc version into common code and applies many of the cosmetic (non-functional) changes from the microblaze version. Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt CC: Michal Simek CC: Wolfram Sang CC: Stephen Rothwell diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 4e94c07..cb9c3dd 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -52,10 +52,6 @@ extern void pci_create_OF_bus_map(void); * OF address retreival & translation */ -/* Translate an OF address block into a CPU physical address - */ -extern u64 of_translate_address(struct device_node *np, const u32 *addr); - /* Extract an address from a device, returns the region size and * the address space flags too. The PCI version uses a BAR number * instead of an absolute index diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 2f9cdd2..d33ba17 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -10,213 +10,7 @@ #include #include -#define PRu64 "%llx" - -/* Max address size we deal with */ -#define OF_MAX_ADDR_CELLS 4 -#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ - (ns) > 0) - -static struct of_bus *of_match_bus(struct device_node *np); - -/* Debug utility */ -#ifdef DEBUG -static void of_dump_addr(const char *s, const u32 *addr, int na) -{ - printk(KERN_INFO "%s", s); - while (na--) - printk(KERN_INFO " %08x", *(addr++)); - printk(KERN_INFO "\n"); -} -#else -static void of_dump_addr(const char *s, const u32 *addr, int na) { } -#endif - -/* Callbacks for bus specific translators */ -struct of_bus { - const char *name; - const char *addresses; - int (*match)(struct device_node *parent); - void (*count_cells)(struct device_node *child, - int *addrc, int *sizec); - u64 (*map)(u32 *addr, const u32 *range, - int na, int ns, int pna); - int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(const u32 *addr); -}; - -/* - * Default translator (generic bus) - */ - -static void of_bus_default_count_cells(struct device_node *dev, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = of_n_addr_cells(dev); - if (sizec) - *sizec = of_n_size_cells(dev); -} - -static u64 of_bus_default_map(u32 *addr, const u32 *range, - int na, int ns, int pna) -{ - u64 cp, s, da; - - cp = of_read_number(range, na); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr, na); - - pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", - cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_default_translate(u32 *addr, u64 offset, int na) -{ - u64 a = of_read_number(addr, na); - memset(addr, 0, na * 4); - a += offset; - if (na > 1) - addr[na - 2] = a >> 32; - addr[na - 1] = a & 0xffffffffu; - - return 0; -} - -static unsigned int of_bus_default_get_flags(const u32 *addr) -{ - return IORESOURCE_MEM; -} - #ifdef CONFIG_PCI -/* - * PCI bus specific translator - */ - -static int of_bus_pci_match(struct device_node *np) -{ - /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ - return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); -} - -static void of_bus_pci_count_cells(struct device_node *np, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 3; - if (sizec) - *sizec = 2; -} - -static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x03000000) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_number(range + 1, na - 1); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr + 1, na - 1); - - pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_pci_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); -} - -static unsigned int of_bus_pci_get_flags(const u32 *addr) -{ - unsigned int flags = 0; - u32 w = addr[0]; - - switch ((w >> 24) & 0x03) { - case 0x01: - flags |= IORESOURCE_IO; - break; - case 0x02: /* 32 bits */ - case 0x03: /* 64 bits */ - flags |= IORESOURCE_MEM; - break; - } - if (w & 0x40000000) - flags |= IORESOURCE_PREFETCH; - return flags; -} - -const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, - unsigned int *flags) -{ - const u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - if (strcmp(bus->name, "pci")) { - of_node_put(parent); - return NULL; - } - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = of_get_property(dev, bus->addresses, &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { - if (size) - *size = of_read_number(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_pci_address); - -int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r) -{ - const u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_pci_address(dev, bar, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_pci_address_to_resource); - -static u8 of_irq_pci_swizzle(u8 slot, u8 pin) -{ - return (((pin - 1) + slot) % 4) + 1; -} - int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) { struct device_node *dn, *ppnode; @@ -291,289 +85,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) EXPORT_SYMBOL_GPL(of_irq_map_pci); #endif /* CONFIG_PCI */ -/* - * ISA bus specific translator - */ - -static int of_bus_isa_match(struct device_node *np) -{ - return !strcmp(np->name, "isa"); -} - -static void of_bus_isa_count_cells(struct device_node *child, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 2; - if (sizec) - *sizec = 1; -} - -static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x00000001) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_number(range + 1, na - 1); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr + 1, na - 1); - - pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_isa_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); -} - -static unsigned int of_bus_isa_get_flags(const u32 *addr) -{ - unsigned int flags = 0; - u32 w = addr[0]; - - if (w & 1) - flags |= IORESOURCE_IO; - else - flags |= IORESOURCE_MEM; - return flags; -} - -/* - * Array of bus specific translators - */ - -static struct of_bus of_busses[] = { -#ifdef CONFIG_PCI - /* PCI */ - { - .name = "pci", - .addresses = "assigned-addresses", - .match = of_bus_pci_match, - .count_cells = of_bus_pci_count_cells, - .map = of_bus_pci_map, - .translate = of_bus_pci_translate, - .get_flags = of_bus_pci_get_flags, - }, -#endif /* CONFIG_PCI */ - /* ISA */ - { - .name = "isa", - .addresses = "reg", - .match = of_bus_isa_match, - .count_cells = of_bus_isa_count_cells, - .map = of_bus_isa_map, - .translate = of_bus_isa_translate, - .get_flags = of_bus_isa_get_flags, - }, - /* Default */ - { - .name = "default", - .addresses = "reg", - .match = NULL, - .count_cells = of_bus_default_count_cells, - .map = of_bus_default_map, - .translate = of_bus_default_translate, - .get_flags = of_bus_default_get_flags, - }, -}; - -static struct of_bus *of_match_bus(struct device_node *np) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(of_busses); i++) - if (!of_busses[i].match || of_busses[i].match(np)) - return &of_busses[i]; - BUG(); - return NULL; -} - -static int of_translate_one(struct device_node *parent, struct of_bus *bus, - struct of_bus *pbus, u32 *addr, - int na, int ns, int pna) -{ - const u32 *ranges; - unsigned int rlen; - int rone; - u64 offset = OF_BAD_ADDR; - - /* Normally, an absence of a "ranges" property means we are - * crossing a non-translatable boundary, and thus the addresses - * below the current not cannot be converted to CPU physical ones. - * Unfortunately, while this is very clear in the spec, it's not - * what Apple understood, and they do have things like /uni-n or - * /ht nodes with no "ranges" property and a lot of perfectly - * useable mapped devices below them. Thus we treat the absence of - * "ranges" as equivalent to an empty "ranges" property which means - * a 1:1 translation at that level. It's up to the caller not to try - * to translate addresses that aren't supposed to be translated in - * the first place. --BenH. - */ - ranges = of_get_property(parent, "ranges", (int *) &rlen); - if (ranges == NULL || rlen == 0) { - offset = of_read_number(addr, na); - memset(addr, 0, pna * 4); - pr_debug("OF: no ranges, 1:1 translation\n"); - goto finish; - } - - pr_debug("OF: walking ranges...\n"); - - /* Now walk through the ranges */ - rlen /= 4; - rone = na + pna + ns; - for (; rlen >= rone; rlen -= rone, ranges += rone) { - offset = bus->map(addr, ranges, na, ns, pna); - if (offset != OF_BAD_ADDR) - break; - } - if (offset == OF_BAD_ADDR) { - pr_debug("OF: not found !\n"); - return 1; - } - memcpy(addr, ranges + na, 4 * pna); - - finish: - of_dump_addr("OF: parent translation for:", addr, pna); - pr_debug("OF: with offset: "PRu64"\n", offset); - - /* Translate it into parent bus space */ - return pbus->translate(addr, offset, pna); -} - -/* - * Translate an address from the device-tree into a CPU physical address, - * this walks up the tree and applies the various bus mappings on the - * way. - * - * Note: We consider that crossing any level with #size-cells == 0 to mean - * that translation is impossible (that is we are not dealing with a value - * that can be mapped to a cpu physical address). This is not really specified - * that way, but this is traditionally the way IBM at least do things - */ -u64 of_translate_address(struct device_node *dev, const u32 *in_addr) -{ - struct device_node *parent = NULL; - struct of_bus *bus, *pbus; - u32 addr[OF_MAX_ADDR_CELLS]; - int na, ns, pna, pns; - u64 result = OF_BAD_ADDR; - - pr_debug("OF: ** translation for device %s **\n", dev->full_name); - - /* Increase refcount at current level */ - of_node_get(dev); - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - goto bail; - bus = of_match_bus(parent); - - /* Cound address cells & copy address locally */ - bus->count_cells(dev, &na, &ns); - if (!OF_CHECK_COUNTS(na, ns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - dev->full_name); - goto bail; - } - memcpy(addr, in_addr, na * 4); - - pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", - bus->name, na, ns, parent->full_name); - of_dump_addr("OF: translating address:", addr, na); - - /* Translate */ - for (;;) { - /* Switch to parent bus */ - of_node_put(dev); - dev = parent; - parent = of_get_parent(dev); - - /* If root, we have finished */ - if (parent == NULL) { - pr_debug("OF: reached root node\n"); - result = of_read_number(addr, na); - break; - } - - /* Get new parent bus and counts */ - pbus = of_match_bus(parent); - pbus->count_cells(dev, &pna, &pns); - if (!OF_CHECK_COUNTS(pna, pns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - dev->full_name); - break; - } - - pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", - pbus->name, pna, pns, parent->full_name); - - /* Apply bus translation */ - if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) - break; - - /* Complete the move up one level */ - na = pna; - ns = pns; - bus = pbus; - - of_dump_addr("OF: one level translation:", addr, na); - } - bail: - of_node_put(parent); - of_node_put(dev); - - return result; -} -EXPORT_SYMBOL(of_translate_address); - -const u32 *of_get_address(struct device_node *dev, int index, u64 *size, - unsigned int *flags) -{ - const u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = of_get_property(dev, bus->addresses, (int *) &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if (i == index) { - if (size) - *size = of_read_number(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_address); - void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) { diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index ceace96..f864722 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -45,10 +45,6 @@ extern void pci_create_OF_bus_map(void); * OF address retreival & translation */ -/* Translate an OF address block into a CPU physical address - */ -extern u64 of_translate_address(struct device_node *np, const u32 *addr); - /* Translate a DMA address from device space to CPU space */ extern u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr); diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 1dac535..88334af 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -10,225 +10,7 @@ #include #include -#ifdef DEBUG -#define DBG(fmt...) do { printk(fmt); } while(0) -#else -#define DBG(fmt...) do { } while(0) -#endif - -#ifdef CONFIG_PPC64 -#define PRu64 "%lx" -#else -#define PRu64 "%llx" -#endif - -/* Max address size we deal with */ -#define OF_MAX_ADDR_CELLS 4 -#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ - (ns) > 0) - -static struct of_bus *of_match_bus(struct device_node *np); - -/* Debug utility */ -#ifdef DEBUG -static void of_dump_addr(const char *s, const u32 *addr, int na) -{ - printk("%s", s); - while(na--) - printk(" %08x", *(addr++)); - printk("\n"); -} -#else -static void of_dump_addr(const char *s, const u32 *addr, int na) { } -#endif - - -/* Callbacks for bus specific translators */ -struct of_bus { - const char *name; - const char *addresses; - int (*match)(struct device_node *parent); - void (*count_cells)(struct device_node *child, - int *addrc, int *sizec); - u64 (*map)(u32 *addr, const u32 *range, - int na, int ns, int pna); - int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(const u32 *addr); -}; - - -/* - * Default translator (generic bus) - */ - -static void of_bus_default_count_cells(struct device_node *dev, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = of_n_addr_cells(dev); - if (sizec) - *sizec = of_n_size_cells(dev); -} - -static u64 of_bus_default_map(u32 *addr, const u32 *range, - int na, int ns, int pna) -{ - u64 cp, s, da; - - cp = of_read_number(range, na); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr, na); - - DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", - cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_default_translate(u32 *addr, u64 offset, int na) -{ - u64 a = of_read_number(addr, na); - memset(addr, 0, na * 4); - a += offset; - if (na > 1) - addr[na - 2] = a >> 32; - addr[na - 1] = a & 0xffffffffu; - - return 0; -} - -static unsigned int of_bus_default_get_flags(const u32 *addr) -{ - return IORESOURCE_MEM; -} - - #ifdef CONFIG_PCI -/* - * PCI bus specific translator - */ - -static int of_bus_pci_match(struct device_node *np) -{ - /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ - return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); -} - -static void of_bus_pci_count_cells(struct device_node *np, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 3; - if (sizec) - *sizec = 2; -} - -static unsigned int of_bus_pci_get_flags(const u32 *addr) -{ - unsigned int flags = 0; - u32 w = addr[0]; - - switch((w >> 24) & 0x03) { - case 0x01: - flags |= IORESOURCE_IO; - break; - case 0x02: /* 32 bits */ - case 0x03: /* 64 bits */ - flags |= IORESOURCE_MEM; - break; - } - if (w & 0x40000000) - flags |= IORESOURCE_PREFETCH; - return flags; -} - -static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - unsigned int af, rf; - - af = of_bus_pci_get_flags(addr); - rf = of_bus_pci_get_flags(range); - - /* Check address type match */ - if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO)) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_number(range + 1, na - 1); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr + 1, na - 1); - - DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_pci_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); -} - -const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, - unsigned int *flags) -{ - const u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - if (strcmp(bus->name, "pci")) { - of_node_put(parent); - return NULL; - } - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = of_get_property(dev, bus->addresses, &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { - if (size) - *size = of_read_number(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_pci_address); - -int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r) -{ - const u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_pci_address(dev, bar, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_pci_address_to_resource); - int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) { struct device_node *dn, *ppnode; @@ -310,303 +92,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) EXPORT_SYMBOL_GPL(of_irq_map_pci); #endif /* CONFIG_PCI */ -/* - * ISA bus specific translator - */ - -static int of_bus_isa_match(struct device_node *np) -{ - return !strcmp(np->name, "isa"); -} - -static void of_bus_isa_count_cells(struct device_node *child, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 2; - if (sizec) - *sizec = 1; -} - -static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x00000001) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_number(range + 1, na - 1); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr + 1, na - 1); - - DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_isa_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); -} - -static unsigned int of_bus_isa_get_flags(const u32 *addr) -{ - unsigned int flags = 0; - u32 w = addr[0]; - - if (w & 1) - flags |= IORESOURCE_IO; - else - flags |= IORESOURCE_MEM; - return flags; -} - - -/* - * Array of bus specific translators - */ - -static struct of_bus of_busses[] = { -#ifdef CONFIG_PCI - /* PCI */ - { - .name = "pci", - .addresses = "assigned-addresses", - .match = of_bus_pci_match, - .count_cells = of_bus_pci_count_cells, - .map = of_bus_pci_map, - .translate = of_bus_pci_translate, - .get_flags = of_bus_pci_get_flags, - }, -#endif /* CONFIG_PCI */ - /* ISA */ - { - .name = "isa", - .addresses = "reg", - .match = of_bus_isa_match, - .count_cells = of_bus_isa_count_cells, - .map = of_bus_isa_map, - .translate = of_bus_isa_translate, - .get_flags = of_bus_isa_get_flags, - }, - /* Default */ - { - .name = "default", - .addresses = "reg", - .match = NULL, - .count_cells = of_bus_default_count_cells, - .map = of_bus_default_map, - .translate = of_bus_default_translate, - .get_flags = of_bus_default_get_flags, - }, -}; - -static struct of_bus *of_match_bus(struct device_node *np) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(of_busses); i ++) - if (!of_busses[i].match || of_busses[i].match(np)) - return &of_busses[i]; - BUG(); - return NULL; -} - -static int of_translate_one(struct device_node *parent, struct of_bus *bus, - struct of_bus *pbus, u32 *addr, - int na, int ns, int pna, const char *rprop) -{ - const u32 *ranges; - unsigned int rlen; - int rone; - u64 offset = OF_BAD_ADDR; - - /* Normally, an absence of a "ranges" property means we are - * crossing a non-translatable boundary, and thus the addresses - * below the current not cannot be converted to CPU physical ones. - * Unfortunately, while this is very clear in the spec, it's not - * what Apple understood, and they do have things like /uni-n or - * /ht nodes with no "ranges" property and a lot of perfectly - * useable mapped devices below them. Thus we treat the absence of - * "ranges" as equivalent to an empty "ranges" property which means - * a 1:1 translation at that level. It's up to the caller not to try - * to translate addresses that aren't supposed to be translated in - * the first place. --BenH. - */ - ranges = of_get_property(parent, rprop, &rlen); - if (ranges == NULL || rlen == 0) { - offset = of_read_number(addr, na); - memset(addr, 0, pna * 4); - DBG("OF: no ranges, 1:1 translation\n"); - goto finish; - } - - DBG("OF: walking ranges...\n"); - - /* Now walk through the ranges */ - rlen /= 4; - rone = na + pna + ns; - for (; rlen >= rone; rlen -= rone, ranges += rone) { - offset = bus->map(addr, ranges, na, ns, pna); - if (offset != OF_BAD_ADDR) - break; - } - if (offset == OF_BAD_ADDR) { - DBG("OF: not found !\n"); - return 1; - } - memcpy(addr, ranges + na, 4 * pna); - - finish: - of_dump_addr("OF: parent translation for:", addr, pna); - DBG("OF: with offset: "PRu64"\n", offset); - - /* Translate it into parent bus space */ - return pbus->translate(addr, offset, pna); -} - - -/* - * Translate an address from the device-tree into a CPU physical address, - * this walks up the tree and applies the various bus mappings on the - * way. - * - * Note: We consider that crossing any level with #size-cells == 0 to mean - * that translation is impossible (that is we are not dealing with a value - * that can be mapped to a cpu physical address). This is not really specified - * that way, but this is traditionally the way IBM at least do things - */ -u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, - const char *rprop) -{ - struct device_node *parent = NULL; - struct of_bus *bus, *pbus; - u32 addr[OF_MAX_ADDR_CELLS]; - int na, ns, pna, pns; - u64 result = OF_BAD_ADDR; - - DBG("OF: ** translation for device %s **\n", dev->full_name); - - /* Increase refcount at current level */ - of_node_get(dev); - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - goto bail; - bus = of_match_bus(parent); - - /* Cound address cells & copy address locally */ - bus->count_cells(dev, &na, &ns); - if (!OF_CHECK_COUNTS(na, ns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - dev->full_name); - goto bail; - } - memcpy(addr, in_addr, na * 4); - - DBG("OF: bus is %s (na=%d, ns=%d) on %s\n", - bus->name, na, ns, parent->full_name); - of_dump_addr("OF: translating address:", addr, na); - - /* Translate */ - for (;;) { - /* Switch to parent bus */ - of_node_put(dev); - dev = parent; - parent = of_get_parent(dev); - - /* If root, we have finished */ - if (parent == NULL) { - DBG("OF: reached root node\n"); - result = of_read_number(addr, na); - break; - } - - /* Get new parent bus and counts */ - pbus = of_match_bus(parent); - pbus->count_cells(dev, &pna, &pns); - if (!OF_CHECK_COUNTS(pna, pns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - dev->full_name); - break; - } - - DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n", - pbus->name, pna, pns, parent->full_name); - - /* Apply bus translation */ - if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) - break; - - /* Complete the move up one level */ - na = pna; - ns = pns; - bus = pbus; - - of_dump_addr("OF: one level translation:", addr, na); - } - bail: - of_node_put(parent); - of_node_put(dev); - - return result; -} - -u64 of_translate_address(struct device_node *dev, const u32 *in_addr) -{ - return __of_translate_address(dev, in_addr, "ranges"); -} -EXPORT_SYMBOL(of_translate_address); - -u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) -{ - return __of_translate_address(dev, in_addr, "dma-ranges"); -} -EXPORT_SYMBOL(of_translate_dma_address); - -const u32 *of_get_address(struct device_node *dev, int index, u64 *size, - unsigned int *flags) -{ - const u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = of_get_property(dev, bus->addresses, &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if (i == index) { - if (size) - *size = of_read_number(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_address); - void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) { diff --git a/drivers/of/address.c b/drivers/of/address.c index c381955..2a905d5 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -1,11 +1,522 @@ #include #include +#include #include +#include +#include -int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, - struct resource *r) +/* Max address size we deal with */ +#define OF_MAX_ADDR_CELLS 4 +#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ + (ns) > 0) + +static struct of_bus *of_match_bus(struct device_node *np); +static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, + struct resource *r); + +/* Debug utility */ +#ifdef DEBUG +static void of_dump_addr(const char *s, const u32 *addr, int na) +{ + printk(KERN_DEBUG "%s", s); + while (na--) + printk(" %08x", *(addr++)); + printk("\n"); +} +#else +static void of_dump_addr(const char *s, const u32 *addr, int na) { } +#endif + +/* Callbacks for bus specific translators */ +struct of_bus { + const char *name; + const char *addresses; + int (*match)(struct device_node *parent); + void (*count_cells)(struct device_node *child, + int *addrc, int *sizec); + u64 (*map)(u32 *addr, const u32 *range, + int na, int ns, int pna); + int (*translate)(u32 *addr, u64 offset, int na); + unsigned int (*get_flags)(const u32 *addr); +}; + +/* + * Default translator (generic bus) + */ + +static void of_bus_default_count_cells(struct device_node *dev, + int *addrc, int *sizec) +{ + if (addrc) + *addrc = of_n_addr_cells(dev); + if (sizec) + *sizec = of_n_size_cells(dev); +} + +static u64 of_bus_default_map(u32 *addr, const u32 *range, + int na, int ns, int pna) +{ + u64 cp, s, da; + + cp = of_read_number(range, na); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr, na); + + pr_debug("OF: default map, cp=%llx, s=%llx, da=%llx\n", + (unsigned long long)cp, (unsigned long long)s, + (unsigned long long)da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_default_translate(u32 *addr, u64 offset, int na) +{ + u64 a = of_read_number(addr, na); + memset(addr, 0, na * 4); + a += offset; + if (na > 1) + addr[na - 2] = a >> 32; + addr[na - 1] = a & 0xffffffffu; + + return 0; +} + +static unsigned int of_bus_default_get_flags(const u32 *addr) +{ + return IORESOURCE_MEM; +} + +#ifdef CONFIG_PCI +/* + * PCI bus specific translator + */ + +static int of_bus_pci_match(struct device_node *np) +{ + /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ + return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); +} + +static void of_bus_pci_count_cells(struct device_node *np, + int *addrc, int *sizec) +{ + if (addrc) + *addrc = 3; + if (sizec) + *sizec = 2; +} + +static unsigned int of_bus_pci_get_flags(const u32 *addr) +{ + unsigned int flags = 0; + u32 w = addr[0]; + + switch((w >> 24) & 0x03) { + case 0x01: + flags |= IORESOURCE_IO; + break; + case 0x02: /* 32 bits */ + case 0x03: /* 64 bits */ + flags |= IORESOURCE_MEM; + break; + } + if (w & 0x40000000) + flags |= IORESOURCE_PREFETCH; + return flags; +} + +static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) +{ + u64 cp, s, da; + unsigned int af, rf; + + af = of_bus_pci_get_flags(addr); + rf = of_bus_pci_get_flags(range); + + /* Check address type match */ + if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO)) + return OF_BAD_ADDR; + + /* Read address values, skipping high cell */ + cp = of_read_number(range + 1, na - 1); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr + 1, na - 1); + + pr_debug("OF: PCI map, cp=%llx, s=%llx, da=%llx\n", + (unsigned long long)cp, (unsigned long long)s, + (unsigned long long)da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_pci_translate(u32 *addr, u64 offset, int na) +{ + return of_bus_default_translate(addr + 1, offset, na - 1); +} + +const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, + unsigned int *flags) +{ + const u32 *prop; + unsigned int psize; + struct device_node *parent; + struct of_bus *bus; + int onesize, i, na, ns; + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + return NULL; + bus = of_match_bus(parent); + if (strcmp(bus->name, "pci")) { + of_node_put(parent); + return NULL; + } + bus->count_cells(dev, &na, &ns); + of_node_put(parent); + if (!OF_CHECK_COUNTS(na, ns)) + return NULL; + + /* Get "reg" or "assigned-addresses" property */ + prop = of_get_property(dev, bus->addresses, &psize); + if (prop == NULL) + return NULL; + psize /= 4; + + onesize = na + ns; + for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) + if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { + if (size) + *size = of_read_number(prop + na, ns); + if (flags) + *flags = bus->get_flags(prop); + return prop; + } + return NULL; +} +EXPORT_SYMBOL(of_get_pci_address); + +int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r) +{ + const u32 *addrp; + u64 size; + unsigned int flags; + + addrp = of_get_pci_address(dev, bar, &size, &flags); + if (addrp == NULL) + return -EINVAL; + return __of_address_to_resource(dev, addrp, size, flags, r); +} +EXPORT_SYMBOL_GPL(of_pci_address_to_resource); +#endif /* CONFIG_PCI */ + +/* + * ISA bus specific translator + */ + +static int of_bus_isa_match(struct device_node *np) +{ + return !strcmp(np->name, "isa"); +} + +static void of_bus_isa_count_cells(struct device_node *child, + int *addrc, int *sizec) +{ + if (addrc) + *addrc = 2; + if (sizec) + *sizec = 1; +} + +static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) +{ + u64 cp, s, da; + + /* Check address type match */ + if ((addr[0] ^ range[0]) & 0x00000001) + return OF_BAD_ADDR; + + /* Read address values, skipping high cell */ + cp = of_read_number(range + 1, na - 1); + s = of_read_number(range + na + pna, ns); + da = of_read_number(addr + 1, na - 1); + + pr_debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n", + (unsigned long long)cp, (unsigned long long)s, + (unsigned long long)da); + + if (da < cp || da >= (cp + s)) + return OF_BAD_ADDR; + return da - cp; +} + +static int of_bus_isa_translate(u32 *addr, u64 offset, int na) +{ + return of_bus_default_translate(addr + 1, offset, na - 1); +} + +static unsigned int of_bus_isa_get_flags(const u32 *addr) +{ + unsigned int flags = 0; + u32 w = addr[0]; + + if (w & 1) + flags |= IORESOURCE_IO; + else + flags |= IORESOURCE_MEM; + return flags; +} + +/* + * Array of bus specific translators + */ + +static struct of_bus of_busses[] = { +#ifdef CONFIG_PCI + /* PCI */ + { + .name = "pci", + .addresses = "assigned-addresses", + .match = of_bus_pci_match, + .count_cells = of_bus_pci_count_cells, + .map = of_bus_pci_map, + .translate = of_bus_pci_translate, + .get_flags = of_bus_pci_get_flags, + }, +#endif /* CONFIG_PCI */ + /* ISA */ + { + .name = "isa", + .addresses = "reg", + .match = of_bus_isa_match, + .count_cells = of_bus_isa_count_cells, + .map = of_bus_isa_map, + .translate = of_bus_isa_translate, + .get_flags = of_bus_isa_get_flags, + }, + /* Default */ + { + .name = "default", + .addresses = "reg", + .match = NULL, + .count_cells = of_bus_default_count_cells, + .map = of_bus_default_map, + .translate = of_bus_default_translate, + .get_flags = of_bus_default_get_flags, + }, +}; + +static struct of_bus *of_match_bus(struct device_node *np) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(of_busses); i++) + if (!of_busses[i].match || of_busses[i].match(np)) + return &of_busses[i]; + BUG(); + return NULL; +} + +static int of_translate_one(struct device_node *parent, struct of_bus *bus, + struct of_bus *pbus, u32 *addr, + int na, int ns, int pna, const char *rprop) +{ + const u32 *ranges; + unsigned int rlen; + int rone; + u64 offset = OF_BAD_ADDR; + + /* Normally, an absence of a "ranges" property means we are + * crossing a non-translatable boundary, and thus the addresses + * below the current not cannot be converted to CPU physical ones. + * Unfortunately, while this is very clear in the spec, it's not + * what Apple understood, and they do have things like /uni-n or + * /ht nodes with no "ranges" property and a lot of perfectly + * useable mapped devices below them. Thus we treat the absence of + * "ranges" as equivalent to an empty "ranges" property which means + * a 1:1 translation at that level. It's up to the caller not to try + * to translate addresses that aren't supposed to be translated in + * the first place. --BenH. + */ + ranges = of_get_property(parent, rprop, &rlen); + if (ranges == NULL || rlen == 0) { + offset = of_read_number(addr, na); + memset(addr, 0, pna * 4); + pr_debug("OF: no ranges, 1:1 translation\n"); + goto finish; + } + + pr_debug("OF: walking ranges...\n"); + + /* Now walk through the ranges */ + rlen /= 4; + rone = na + pna + ns; + for (; rlen >= rone; rlen -= rone, ranges += rone) { + offset = bus->map(addr, ranges, na, ns, pna); + if (offset != OF_BAD_ADDR) + break; + } + if (offset == OF_BAD_ADDR) { + pr_debug("OF: not found !\n"); + return 1; + } + memcpy(addr, ranges + na, 4 * pna); + + finish: + of_dump_addr("OF: parent translation for:", addr, pna); + pr_debug("OF: with offset: %llx\n", (unsigned long long)offset); + + /* Translate it into parent bus space */ + return pbus->translate(addr, offset, pna); +} + +/* + * Translate an address from the device-tree into a CPU physical address, + * this walks up the tree and applies the various bus mappings on the + * way. + * + * Note: We consider that crossing any level with #size-cells == 0 to mean + * that translation is impossible (that is we are not dealing with a value + * that can be mapped to a cpu physical address). This is not really specified + * that way, but this is traditionally the way IBM at least do things + */ +u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, + const char *rprop) +{ + struct device_node *parent = NULL; + struct of_bus *bus, *pbus; + u32 addr[OF_MAX_ADDR_CELLS]; + int na, ns, pna, pns; + u64 result = OF_BAD_ADDR; + + pr_debug("OF: ** translation for device %s **\n", dev->full_name); + + /* Increase refcount at current level */ + of_node_get(dev); + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + goto bail; + bus = of_match_bus(parent); + + /* Cound address cells & copy address locally */ + bus->count_cells(dev, &na, &ns); + if (!OF_CHECK_COUNTS(na, ns)) { + printk(KERN_ERR "prom_parse: Bad cell count for %s\n", + dev->full_name); + goto bail; + } + memcpy(addr, in_addr, na * 4); + + pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", + bus->name, na, ns, parent->full_name); + of_dump_addr("OF: translating address:", addr, na); + + /* Translate */ + for (;;) { + /* Switch to parent bus */ + of_node_put(dev); + dev = parent; + parent = of_get_parent(dev); + + /* If root, we have finished */ + if (parent == NULL) { + pr_debug("OF: reached root node\n"); + result = of_read_number(addr, na); + break; + } + + /* Get new parent bus and counts */ + pbus = of_match_bus(parent); + pbus->count_cells(dev, &pna, &pns); + if (!OF_CHECK_COUNTS(pna, pns)) { + printk(KERN_ERR "prom_parse: Bad cell count for %s\n", + dev->full_name); + break; + } + + pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", + pbus->name, pna, pns, parent->full_name); + + /* Apply bus translation */ + if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) + break; + + /* Complete the move up one level */ + na = pna; + ns = pns; + bus = pbus; + + of_dump_addr("OF: one level translation:", addr, na); + } + bail: + of_node_put(parent); + of_node_put(dev); + + return result; +} + +u64 of_translate_address(struct device_node *dev, const u32 *in_addr) +{ + return __of_translate_address(dev, in_addr, "ranges"); +} +EXPORT_SYMBOL(of_translate_address); + +u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) +{ + return __of_translate_address(dev, in_addr, "dma-ranges"); +} +EXPORT_SYMBOL(of_translate_dma_address); + +const u32 *of_get_address(struct device_node *dev, int index, u64 *size, + unsigned int *flags) +{ + const u32 *prop; + unsigned int psize; + struct device_node *parent; + struct of_bus *bus; + int onesize, i, na, ns; + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + return NULL; + bus = of_match_bus(parent); + bus->count_cells(dev, &na, &ns); + of_node_put(parent); + if (!OF_CHECK_COUNTS(na, ns)) + return NULL; + + /* Get "reg" or "assigned-addresses" property */ + prop = of_get_property(dev, bus->addresses, &psize); + if (prop == NULL) + return NULL; + psize /= 4; + + onesize = na + ns; + for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) + if (i == index) { + if (size) + *size = of_read_number(prop + na, ns); + if (flags) + *flags = bus->get_flags(prop); + return prop; + } + return NULL; +} +EXPORT_SYMBOL(of_get_address); + +static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, + u64 size, unsigned int flags, + struct resource *r) { u64 taddr; diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 474b794..cc567df 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -3,9 +3,7 @@ #include #include -extern int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, - struct resource *r); +extern u64 of_translate_address(struct device_node *np, const u32 *addr); extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); extern void __iomem *of_iomap(struct device_node *device, int index); -- cgit v0.10.2 From 154063a9c03d31228b6f9366d2ffc2b7c4961698 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:11 -0600 Subject: of/address: little-endian fixes Fix some endian issues in the OF address translation code. Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt CC: Michal Simek CC: Stephen Rothwell diff --git a/drivers/of/address.c b/drivers/of/address.c index 2a905d5..0b04137 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -22,7 +22,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na) { printk(KERN_DEBUG "%s", s); while (na--) - printk(" %08x", *(addr++)); + printk(" %08x", be32_to_cpu(*(addr++))); printk("\n"); } #else @@ -79,8 +79,8 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) memset(addr, 0, na * 4); a += offset; if (na > 1) - addr[na - 2] = a >> 32; - addr[na - 1] = a & 0xffffffffu; + addr[na - 2] = cpu_to_be32(a >> 32); + addr[na - 1] = cpu_to_be32(a & 0xffffffffu); return 0; } @@ -190,14 +190,16 @@ const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, psize /= 4; onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { + for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) { + u32 val = be32_to_cpu(prop[0]); + if ((val & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { if (size) *size = of_read_number(prop + na, ns); if (flags) *flags = bus->get_flags(prop); return prop; } + } return NULL; } EXPORT_SYMBOL(of_get_pci_address); -- cgit v0.10.2 From 3930f294d081c9e2a65f137a7d5fb6c161e4aa94 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:11 -0600 Subject: of/address: restrict 'no-ranges' kludge to powerpc Certain Apple machines don't use the ranges property correctly, but the workaround should not be applied on other architectures. This patch disables the workaround for non-powerpc architectures. Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt CC: Stephen Rothwell diff --git a/drivers/of/address.c b/drivers/of/address.c index 0b04137..5c220c3 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -346,12 +346,21 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * a 1:1 translation at that level. It's up to the caller not to try * to translate addresses that aren't supposed to be translated in * the first place. --BenH. + * + * As far as we know, this damage only exists on Apple machines, so + * This code is only enabled on powerpc. --gcl */ ranges = of_get_property(parent, rprop, &rlen); +#if !defined(CONFIG_PPC) + if (ranges == NULL) { + pr_err("OF: no ranges; cannot translate\n"); + return 1; + } +#endif /* !defined(CONFIG_PPC) */ if (ranges == NULL || rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); - pr_debug("OF: no ranges, 1:1 translation\n"); + pr_debug("OF: empty ranges; 1:1 translation\n"); goto finish; } -- cgit v0.10.2 From d3571c3acfabb6f3a93b517b75d9b30eb7e8692e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:12 -0600 Subject: of: Use full node name in resource structures Resource names appear in human readable output, so when extracting IRQ and address resources from a device tree node, use the full node name to give proper context in places like /proc/iomem. Signed-off-by: Grant Likely CC: Michal Simek CC: Stephen Rothwell CC: Benjamin Herrenschmidt CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org diff --git a/drivers/of/address.c b/drivers/of/address.c index 5c220c3..fcadb72 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -549,7 +549,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, r->end = taddr + size - 1; } r->flags = flags; - r->name = dev->name; + r->name = dev->full_name; return 0; } diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 623eb66..6cfb307 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -340,6 +340,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) if (r && irq != NO_IRQ) { r->start = r->end = irq; r->flags = IORESOURCE_IRQ; + r->name = dev->full_name; } return irq; -- cgit v0.10.2 From dd27dcda37f0b1a3b674760fb411abc5c8fe309c Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:12 -0600 Subject: of/device: merge of_device_uevent Merge common code between powerpc and microblaze Signed-off-by: Grant Likely CC: Michal Simek CC: Wolfram Sang CC: Stephen Rothwell CC: Benjamin Herrenschmidt CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index 0a5f3f91..58e627d 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -22,9 +22,6 @@ extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -extern int of_device_uevent(struct device *dev, - struct kobj_uevent_env *env); - extern void of_device_make_bus_id(struct of_device *dev); /* This is just here during the transition */ diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index b372787..3a367d7 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -62,51 +62,3 @@ struct of_device *of_device_alloc(struct device_node *np, return dev; } EXPORT_SYMBOL(of_device_alloc); - -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct of_device *ofdev; - const char *compat; - int seen = 0, cplen, sl; - - if (!dev) - return -ENODEV; - - ofdev = to_of_device(dev); - - if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) - return -ENOMEM; - - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) - return -ENOMEM; - - /* Since the compatible field can contain pretty much anything - * it's not really legal to split it out with commas. We split it - * up using a number of environment variables instead. */ - - compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); - while (compat && *compat && cplen > 0) { - if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) - return -ENOMEM; - - sl = strlen(compat) + 1; - compat += sl; - cplen -= sl; - seen++; - } - - if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) - return -ENOMEM; - - /* modalias is trickier, we add it in 2 steps */ - if (add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], - sizeof(env->buf) - env->buflen); - if (sl >= (sizeof(env->buf) - env->buflen)) - return -ENOMEM; - env->buflen += sl; - - return 0; -} -EXPORT_SYMBOL(of_device_uevent); diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index cb36632..5d5103c 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -9,8 +9,5 @@ extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -extern int of_device_uevent(struct device *dev, - struct kobj_uevent_env *env); - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index df78e02..db91a9d 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -82,52 +82,3 @@ struct of_device *of_device_alloc(struct device_node *np, return dev; } EXPORT_SYMBOL(of_device_alloc); - -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct of_device *ofdev; - const char *compat; - int seen = 0, cplen, sl; - - if (!dev) - return -ENODEV; - - ofdev = to_of_device(dev); - - if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) - return -ENOMEM; - - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) - return -ENOMEM; - - /* Since the compatible field can contain pretty much anything - * it's not really legal to split it out with commas. We split it - * up using a number of environment variables instead. */ - - compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); - while (compat && *compat && cplen > 0) { - if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) - return -ENOMEM; - - sl = strlen (compat) + 1; - compat += sl; - cplen -= sl; - seen++; - } - - if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) - return -ENOMEM; - - /* modalias is trickier, we add it in 2 steps */ - if (add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], - sizeof(env->buf) - env->buflen); - if (sl >= (sizeof(env->buf) - env->buflen)) - return -ENOMEM; - env->buflen += sl; - - return 0; -} -EXPORT_SYMBOL(of_device_uevent); -EXPORT_SYMBOL(of_device_get_modalias); diff --git a/drivers/of/device.c b/drivers/of/device.c index 7d18f8e..275cc9c 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -170,3 +170,51 @@ ssize_t of_device_get_modalias(struct of_device *ofdev, return tsize; } + +/** + * of_device_uevent - Display OF related uevent information + */ +int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + const char *compat; + int seen = 0, cplen, sl; + + if ((!dev) || (!dev->of_node)) + return -ENODEV; + + if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name)) + return -ENOMEM; + + if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type)) + return -ENOMEM; + + /* Since the compatible field can contain pretty much anything + * it's not really legal to split it out with commas. We split it + * up using a number of environment variables instead. */ + + compat = of_get_property(dev->of_node, "compatible", &cplen); + while (compat && *compat && cplen > 0) { + if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) + return -ENOMEM; + + sl = strlen(compat) + 1; + compat += sl; + cplen -= sl; + seen++; + } + + if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) + return -ENOMEM; + + /* modalias is trickier, we add it in 2 steps */ + if (add_uevent_var(env, "MODALIAS=")) + return -ENOMEM; + + sl = of_device_get_modalias(to_of_device(dev), &env->buf[env->buflen-1], + sizeof(env->buf) - env->buflen); + if (sl >= (sizeof(env->buf) - env->buflen)) + return -ENOMEM; + env->buflen += sl; + + return 0; +} diff --git a/include/linux/of_device.h b/include/linux/of_device.h index a3ae590..da83e73 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -44,6 +44,10 @@ static inline void of_device_free(struct of_device *dev) extern ssize_t of_device_get_modalias(struct of_device *ofdev, char *str, ssize_t len); + +extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); + + #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ -- cgit v0.10.2 From 34a1c1e8c700f7cd849deb21193718a172722f8d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:13 -0600 Subject: of: Modify of_device_get_modalias to be passed struct device Now that the of_node pointer is part of struct device, of_device_get_modalias could be used on any struct device that has the device node pointer set. This patch changes of_device_get_modalias to accept a struct device instead of a struct of_device. Signed-off-by: Grant Likely CC: Michal Simek CC: Benjamin Herrenschmidt CC: Wolfram Sang CC: Stephen Rothwell CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index 58e627d..c9be534 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -15,9 +15,6 @@ #include #include -extern ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len); - extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 6999ce5..6024038 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -41,10 +41,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev = to_of_device(dev); - int len; - - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); + int len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; diff --git a/drivers/of/device.c b/drivers/of/device.c index 275cc9c..c2a98f5 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -68,10 +68,7 @@ static ssize_t name_show(struct device *dev, static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev = to_of_device(dev); - ssize_t len = 0; - - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); + ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; return len+1; @@ -123,19 +120,18 @@ void of_device_unregister(struct of_device *ofdev) } EXPORT_SYMBOL(of_device_unregister); -ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len) +ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) { const char *compat; int cplen, i; ssize_t tsize, csize, repend; /* Name & Type */ - csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name, - ofdev->dev.of_node->type); + csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, + dev->of_node->type); /* Get compatible property if any */ - compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); + compat = of_get_property(dev->of_node, "compatible", &cplen); if (!compat) return csize; @@ -210,7 +206,7 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; - sl = of_device_get_modalias(to_of_device(dev), &env->buf[env->buflen-1], + sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], sizeof(env->buf) - env->buflen); if (sl >= (sizeof(env->buf) - env->buflen)) return -ENOMEM; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index da83e73..238e92e 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -42,7 +42,7 @@ static inline void of_device_free(struct of_device *dev) of_release_dev(&dev->dev); } -extern ssize_t of_device_get_modalias(struct of_device *ofdev, +extern ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len); extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); -- cgit v0.10.2 From 5fd200f3b351183b5489cef69961c60af9cead2f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:13 -0600 Subject: of/device: Merge of_platform_bus_probe() Merge common code between PowerPC and microblaze. This patch merges the code that scans the tree and registers devices. The functions merged are of_platform_bus_probe(), of_platform_bus_create(), and of_platform_device_create(). This patch also move the of_default_bus_ids[] table out of a Microblaze header file and makes it non-static. The device ids table isn't merged because powerpc and microblaze use different default data. Signed-off-by: Grant Likely CC: Michal Simek CC: Grant Likely CC: Benjamin Herrenschmidt CC: Stephen Rothwell CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h index 3749127..625003f 100644 --- a/arch/microblaze/include/asm/of_platform.h +++ b/arch/microblaze/include/asm/of_platform.h @@ -14,39 +14,6 @@ /* This is just here during the transition */ #include -/* - * The list of OF IDs below is used for matching bus types in the - * system whose devices are to be exposed as of_platform_devices. - * - * This is the default list valid for most platforms. This file provides - * functions who can take an explicit list if necessary though - * - * The search is always performed recursively looking for children of - * the provided device_node and recursively if such a children matches - * a bus type in the list - */ - -static const struct of_device_id of_default_bus_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .type = "plb5", }, - { .type = "plb4", }, - { .type = "opb", }, - { .type = "simple", }, - {}, -}; - -/* Platform devices and busses creation */ -extern struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent); -/* pseudo "matches" value to not do deep probe */ -#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) - -extern int of_platform_bus_probe(struct device_node *root, - const struct of_device_id *matches, - struct device *parent); - extern struct of_device *of_find_device_by_phandle(phandle ph); extern void of_instantiate_rtc(void); diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index ccf6f42..a07abdd 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -37,132 +37,27 @@ static int __init of_bus_driver_init(void) } postcore_initcall(of_bus_driver_init); -struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = of_device_alloc(np, bus_id, parent); - if (!dev) - return NULL; - - dev->archdata.dma_mask = 0xffffffffUL; - dev->dev.bus = &of_platform_bus_type; - - /* We do not fill the DMA ops for platform devices by default. - * This is currently the responsibility of the platform code - * to do such, possibly using a device notifier - */ - - if (of_device_register(dev) != 0) { - of_device_free(dev); - return NULL; - } - - return dev; -} -EXPORT_SYMBOL(of_platform_device_create); - -/** - * of_platform_bus_create - Create an OF device for a bus node and all its - * children. Optionally recursively instanciate matching busses. - * @bus: device node of the bus to instanciate - * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to - * disallow recursive creation of child busses - */ -static int of_platform_bus_create(const struct device_node *bus, - const struct of_device_id *matches, - struct device *parent) -{ - struct device_node *child; - struct of_device *dev; - int rc = 0; - - for_each_child_of_node(bus, child) { - pr_debug(" create child: %s\n", child->full_name); - dev = of_platform_device_create(child, NULL, parent); - if (dev == NULL) - rc = -ENOMEM; - else if (!of_match_node(matches, child)) - continue; - if (rc == 0) { - pr_debug(" and sub busses\n"); - rc = of_platform_bus_create(child, matches, &dev->dev); - } - if (rc) { - of_node_put(child); - break; - } - } - return rc; -} - - -/** - * of_platform_bus_probe - Probe the device-tree for platform busses - * @root: parent of the first level to probe or NULL for the root of the tree - * @matches: match table, NULL to use the default - * @parent: parent to hook devices from, NULL for toplevel +/* + * The list of OF IDs below is used for matching bus types in the + * system whose devices are to be exposed as of_platform_devices. * - * Note that children of the provided root are not instanciated as devices - * unless the specified root itself matches the bus list and is not NULL. + * This is the default list valid for most platforms. This file provides + * functions who can take an explicit list if necessary though + * + * The search is always performed recursively looking for children of + * the provided device_node and recursively if such a children matches + * a bus type in the list */ -int of_platform_bus_probe(struct device_node *root, - const struct of_device_id *matches, - struct device *parent) -{ - struct device_node *child; - struct of_device *dev; - int rc = 0; - - if (matches == NULL) - matches = of_default_bus_ids; - if (matches == OF_NO_DEEP_PROBE) - return -EINVAL; - if (root == NULL) - root = of_find_node_by_path("/"); - else - of_node_get(root); - - pr_debug("of_platform_bus_probe()\n"); - pr_debug(" starting at: %s\n", root->full_name); - - /* Do a self check of bus type, if there's a match, create - * children - */ - if (of_match_node(matches, root)) { - pr_debug(" root match, create all sub devices\n"); - dev = of_platform_device_create(root, NULL, parent); - if (dev == NULL) { - rc = -ENOMEM; - goto bail; - } - pr_debug(" create all sub busses\n"); - rc = of_platform_bus_create(root, matches, &dev->dev); - goto bail; - } - for_each_child_of_node(root, child) { - if (!of_match_node(matches, child)) - continue; - - pr_debug(" match: %s\n", child->full_name); - dev = of_platform_device_create(child, NULL, parent); - if (dev == NULL) - rc = -ENOMEM; - else - rc = of_platform_bus_create(child, matches, &dev->dev); - if (rc) { - of_node_put(child); - break; - } - } - bail: - of_node_put(root); - return rc; -} -EXPORT_SYMBOL(of_platform_bus_probe); +const struct of_device_id of_default_bus_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .type = "plb5", }, + { .type = "plb4", }, + { .type = "opb", }, + { .type = "simple", }, + {}, +}; static int of_dev_node_match(struct device *dev, void *data) { diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h index d4aaa34..b37d2dc 100644 --- a/arch/powerpc/include/asm/of_platform.h +++ b/arch/powerpc/include/asm/of_platform.h @@ -11,17 +11,6 @@ * */ -/* Platform devices and busses creation */ -extern struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent); -/* pseudo "matches" value to not do deep probe */ -#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) - -extern int of_platform_bus_probe(struct device_node *root, - const struct of_device_id *matches, - struct device *parent); - extern struct of_device *of_find_device_by_phandle(phandle ph); extern void of_instantiate_rtc(void); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 487a988..0b5cc6d 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -40,7 +40,7 @@ * a bus type in the list */ -static const struct of_device_id of_default_bus_ids[] = { +const struct of_device_id of_default_bus_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "spider", }, @@ -64,135 +64,6 @@ static int __init of_bus_driver_init(void) postcore_initcall(of_bus_driver_init); -struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = of_device_alloc(np, bus_id, parent); - if (!dev) - return NULL; - - dev->archdata.dma_mask = 0xffffffffUL; - dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - - dev->dev.bus = &of_platform_bus_type; - - /* We do not fill the DMA ops for platform devices by default. - * This is currently the responsibility of the platform code - * to do such, possibly using a device notifier - */ - - if (of_device_register(dev) != 0) { - of_device_free(dev); - return NULL; - } - - return dev; -} -EXPORT_SYMBOL(of_platform_device_create); - - - -/** - * of_platform_bus_create - Create an OF device for a bus node and all its - * children. Optionally recursively instanciate matching busses. - * @bus: device node of the bus to instanciate - * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to - * disallow recursive creation of child busses - */ -static int of_platform_bus_create(const struct device_node *bus, - const struct of_device_id *matches, - struct device *parent) -{ - struct device_node *child; - struct of_device *dev; - int rc = 0; - - for_each_child_of_node(bus, child) { - pr_debug(" create child: %s\n", child->full_name); - dev = of_platform_device_create(child, NULL, parent); - if (dev == NULL) - rc = -ENOMEM; - else if (!of_match_node(matches, child)) - continue; - if (rc == 0) { - pr_debug(" and sub busses\n"); - rc = of_platform_bus_create(child, matches, &dev->dev); - } if (rc) { - of_node_put(child); - break; - } - } - return rc; -} - -/** - * of_platform_bus_probe - Probe the device-tree for platform busses - * @root: parent of the first level to probe or NULL for the root of the tree - * @matches: match table, NULL to use the default - * @parent: parent to hook devices from, NULL for toplevel - * - * Note that children of the provided root are not instanciated as devices - * unless the specified root itself matches the bus list and is not NULL. - */ - -int of_platform_bus_probe(struct device_node *root, - const struct of_device_id *matches, - struct device *parent) -{ - struct device_node *child; - struct of_device *dev; - int rc = 0; - - if (matches == NULL) - matches = of_default_bus_ids; - if (matches == OF_NO_DEEP_PROBE) - return -EINVAL; - if (root == NULL) - root = of_find_node_by_path("/"); - else - of_node_get(root); - - pr_debug("of_platform_bus_probe()\n"); - pr_debug(" starting at: %s\n", root->full_name); - - /* Do a self check of bus type, if there's a match, create - * children - */ - if (of_match_node(matches, root)) { - pr_debug(" root match, create all sub devices\n"); - dev = of_platform_device_create(root, NULL, parent); - if (dev == NULL) { - rc = -ENOMEM; - goto bail; - } - pr_debug(" create all sub busses\n"); - rc = of_platform_bus_create(root, matches, &dev->dev); - goto bail; - } - for_each_child_of_node(root, child) { - if (!of_match_node(matches, child)) - continue; - - pr_debug(" match: %s\n", child->full_name); - dev = of_platform_device_create(child, NULL, parent); - if (dev == NULL) - rc = -ENOMEM; - else - rc = of_platform_bus_create(child, matches, &dev->dev); - if (rc) { - of_node_put(child); - break; - } - } - bail: - of_node_put(root); - return rc; -} -EXPORT_SYMBOL(of_platform_bus_probe); - static int of_dev_node_match(struct device *dev, void *data) { return to_of_device(dev)->dev.of_node == data; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 7dacc1e..d9c81e9 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -396,3 +397,145 @@ void of_unregister_driver(struct of_platform_driver *drv) driver_unregister(&drv->driver); } EXPORT_SYMBOL(of_unregister_driver); + +#if !defined(CONFIG_SPARC) +/* + * The following routines scan a subtree and registers a device for + * each applicable node. + * + * Note: sparc doesn't use these routines because it has a different + * mechanism for creating devices from device tree nodes. + */ + +/** + * of_platform_device_create - Alloc, initialize and register an of_device + * @np: pointer to node to create device for + * @bus_id: name to assign device + * @parent: Linux device model parent device. + */ +struct of_device *of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = of_device_alloc(np, bus_id, parent); + if (!dev) + return NULL; + + dev->archdata.dma_mask = 0xffffffffUL; + dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + dev->dev.bus = &of_platform_bus_type; + + /* We do not fill the DMA ops for platform devices by default. + * This is currently the responsibility of the platform code + * to do such, possibly using a device notifier + */ + + if (of_device_register(dev) != 0) { + of_device_free(dev); + return NULL; + } + + return dev; +} +EXPORT_SYMBOL(of_platform_device_create); + +/** + * of_platform_bus_create - Create an OF device for a bus node and all its + * children. Optionally recursively instantiate matching busses. + * @bus: device node of the bus to instantiate + * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to + * disallow recursive creation of child busses + */ +static int of_platform_bus_create(const struct device_node *bus, + const struct of_device_id *matches, + struct device *parent) +{ + struct device_node *child; + struct of_device *dev; + int rc = 0; + + for_each_child_of_node(bus, child) { + pr_debug(" create child: %s\n", child->full_name); + dev = of_platform_device_create(child, NULL, parent); + if (dev == NULL) + rc = -ENOMEM; + else if (!of_match_node(matches, child)) + continue; + if (rc == 0) { + pr_debug(" and sub busses\n"); + rc = of_platform_bus_create(child, matches, &dev->dev); + } + if (rc) { + of_node_put(child); + break; + } + } + return rc; +} + +/** + * of_platform_bus_probe - Probe the device-tree for platform busses + * @root: parent of the first level to probe or NULL for the root of the tree + * @matches: match table, NULL to use the default + * @parent: parent to hook devices from, NULL for toplevel + * + * Note that children of the provided root are not instantiated as devices + * unless the specified root itself matches the bus list and is not NULL. + */ +int of_platform_bus_probe(struct device_node *root, + const struct of_device_id *matches, + struct device *parent) +{ + struct device_node *child; + struct of_device *dev; + int rc = 0; + + if (matches == NULL) + matches = of_default_bus_ids; + if (matches == OF_NO_DEEP_PROBE) + return -EINVAL; + if (root == NULL) + root = of_find_node_by_path("/"); + else + of_node_get(root); + + pr_debug("of_platform_bus_probe()\n"); + pr_debug(" starting at: %s\n", root->full_name); + + /* Do a self check of bus type, if there's a match, create + * children + */ + if (of_match_node(matches, root)) { + pr_debug(" root match, create all sub devices\n"); + dev = of_platform_device_create(root, NULL, parent); + if (dev == NULL) { + rc = -ENOMEM; + goto bail; + } + pr_debug(" create all sub busses\n"); + rc = of_platform_bus_create(root, matches, &dev->dev); + goto bail; + } + for_each_child_of_node(root, child) { + if (!of_match_node(matches, child)) + continue; + + pr_debug(" match: %s\n", child->full_name); + dev = of_platform_device_create(child, NULL, parent); + if (dev == NULL) + rc = -ENOMEM; + else + rc = of_platform_bus_create(child, matches, &dev->dev); + if (rc) { + of_node_put(child); + break; + } + } + bail: + of_node_put(root); + return rc; +} +EXPORT_SYMBOL(of_platform_bus_probe); +#endif /* !CONFIG_SPARC */ diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 1643d37..4bbba41 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -25,6 +25,8 @@ */ extern struct bus_type of_platform_bus_type; +extern const struct of_device_id of_default_bus_ids[]; + /* * An of_platform_driver driver is attached to a basic of_device on * the "platform bus" (of_platform_bus_type). @@ -63,6 +65,21 @@ static inline void of_unregister_platform_driver(struct of_platform_driver *drv) extern struct of_device *of_find_device_by_node(struct device_node *np); extern int of_bus_type_init(struct bus_type *bus, const char *name); + +#if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */ +/* Platform devices and busses creation */ +extern struct of_device *of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent); + +/* pseudo "matches" value to not do deep probe */ +#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) + +extern int of_platform_bus_probe(struct device_node *root, + const struct of_device_id *matches, + struct device *parent); +#endif /* !CONFIG_SPARC */ + #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_PLATFORM_H */ -- cgit v0.10.2 From 94c0931983ee9d1cd96c32d52ac64c17464f0bbd Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:14 -0600 Subject: of: Merge of_device_alloc() and of_device_make_bus_id() This patch merges the common routines of_device_alloc() and of_device_make_bus_id() from powerpc and microblaze. Signed-off-by: Grant Likely CC: Michal Simek CC: Grant Likely CC: Benjamin Herrenschmidt CC: Stephen Rothwell CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org CC: devicetree-discuss@lists.ozlabs.org diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index c9be534..47e8d42 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -10,19 +10,4 @@ #ifndef _ASM_MICROBLAZE_OF_DEVICE_H #define _ASM_MICROBLAZE_OF_DEVICE_H -#ifdef __KERNEL__ - -#include -#include - -extern struct of_device *of_device_alloc(struct device_node *np, - const char *bus_id, - struct device *parent); - -extern void of_device_make_bus_id(struct of_device *dev); - -/* This is just here during the transition */ -#include - -#endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_OF_DEVICE_H */ diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index e51bc15..727e2cb 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -15,7 +15,7 @@ endif extra-y := head.o vmlinux.lds obj-y += dma.o exceptions.o \ - hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ + hw_exception_handler.o init_task.o intc.o irq.o \ of_platform.o process.o prom.o prom_parse.o ptrace.o \ setup.o signal.o sys_microblaze.o timer.o traps.o reset.o diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c deleted file mode 100644 index 3a367d7..0000000 --- a/arch/microblaze/kernel/of_device.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -void of_device_make_bus_id(struct of_device *dev) -{ - static atomic_t bus_no_reg_magic; - struct device_node *node = dev->dev.of_node; - const u32 *reg; - u64 addr; - int magic; - - /* - * For MMIO, get the physical address - */ - reg = of_get_property(node, "reg", NULL); - if (reg) { - addr = of_translate_address(node, reg); - if (addr != OF_BAD_ADDR) { - dev_set_name(&dev->dev, "%llx.%s", - (unsigned long long)addr, node->name); - return; - } - } - - /* - * No BusID, use the node name and add a globally incremented - * counter (and pray...) - */ - magic = atomic_add_return(1, &bus_no_reg_magic); - dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); -} -EXPORT_SYMBOL(of_device_make_bus_id); - -struct of_device *of_device_alloc(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - - dev->dev.of_node = of_node_get(np); - dev->dev.dma_mask = &dev->archdata.dma_mask; - dev->dev.parent = parent; - dev->dev.release = of_release_dev; - - if (bus_id) - dev_set_name(&dev->dev, bus_id); - else - of_device_make_bus_id(dev); - - return dev; -} -EXPORT_SYMBOL(of_device_alloc); diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index 5d5103c..04f7671 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -1,13 +1,3 @@ #ifndef _ASM_POWERPC_OF_DEVICE_H #define _ASM_POWERPC_OF_DEVICE_H -#ifdef __KERNEL__ - -#include -#include - -extern struct of_device *of_device_alloc(struct device_node *np, - const char *bus_id, - struct device *parent); - -#endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 58d0572..83aa1fd 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -40,7 +40,7 @@ obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o obj-$(CONFIG_PPC_970_NAP) += idle_power4.o -obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o +obj-$(CONFIG_PPC_OF) += of_platform.o prom_parse.o obj-$(CONFIG_PPC_CLOCK) += clock.o procfs-y := proc_powerpc.o obj-$(CONFIG_PROC_FS) += $(procfs-y) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c deleted file mode 100644 index db91a9d..0000000 --- a/arch/powerpc/kernel/of_device.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static void of_device_make_bus_id(struct of_device *dev) -{ - static atomic_t bus_no_reg_magic; - struct device_node *node = dev->dev.of_node; - const u32 *reg; - u64 addr; - int magic; - - /* - * If it's a DCR based device, use 'd' for native DCRs - * and 'D' for MMIO DCRs. - */ -#ifdef CONFIG_PPC_DCR - reg = of_get_property(node, "dcr-reg", NULL); - if (reg) { -#ifdef CONFIG_PPC_DCR_NATIVE - dev_set_name(&dev->dev, "d%x.%s", *reg, node->name); -#else /* CONFIG_PPC_DCR_NATIVE */ - addr = of_translate_dcr_address(node, *reg, NULL); - if (addr != OF_BAD_ADDR) { - dev_set_name(&dev->dev, "D%llx.%s", - (unsigned long long)addr, node->name); - return; - } -#endif /* !CONFIG_PPC_DCR_NATIVE */ - } -#endif /* CONFIG_PPC_DCR */ - - /* - * For MMIO, get the physical address - */ - reg = of_get_property(node, "reg", NULL); - if (reg) { - addr = of_translate_address(node, reg); - if (addr != OF_BAD_ADDR) { - dev_set_name(&dev->dev, "%llx.%s", - (unsigned long long)addr, node->name); - return; - } - } - - /* - * No BusID, use the node name and add a globally incremented - * counter (and pray...) - */ - magic = atomic_add_return(1, &bus_no_reg_magic); - dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); -} - -struct of_device *of_device_alloc(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - - dev->dev.of_node = of_node_get(np); - dev->dev.dma_mask = &dev->archdata.dma_mask; - dev->dev.parent = parent; - dev->dev.release = of_release_dev; - - if (bus_id) - dev_set_name(&dev->dev, "%s", bus_id); - else - of_device_make_bus_id(dev); - - return dev; -} -EXPORT_SYMBOL(of_device_alloc); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d9c81e9..ea87a3c 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -408,6 +408,93 @@ EXPORT_SYMBOL(of_unregister_driver); */ /** + * of_device_make_bus_id - Use the device node data to assign a unique name + * @dev: pointer to device structure that is linked to a device tree node + * + * This routine will first try using either the dcr-reg or the reg property + * value to derive a unique name. As a last resort it will use the node + * name followed by a unique number. + */ +static void of_device_make_bus_id(struct device *dev) +{ + static atomic_t bus_no_reg_magic; + struct device_node *node = dev->of_node; + const u32 *reg; + u64 addr; + int magic; + +#ifdef CONFIG_PPC_DCR + /* + * If it's a DCR based device, use 'd' for native DCRs + * and 'D' for MMIO DCRs. + */ + reg = of_get_property(node, "dcr-reg", NULL); + if (reg) { +#ifdef CONFIG_PPC_DCR_NATIVE + dev_set_name(dev, "d%x.%s", *reg, node->name); +#else /* CONFIG_PPC_DCR_NATIVE */ + u64 addr = of_translate_dcr_address(node, *reg, NULL); + if (addr != OF_BAD_ADDR) { + dev_set_name(dev, "D%llx.%s", + (unsigned long long)addr, node->name); + return; + } +#endif /* !CONFIG_PPC_DCR_NATIVE */ + } +#endif /* CONFIG_PPC_DCR */ + + /* + * For MMIO, get the physical address + */ + reg = of_get_property(node, "reg", NULL); + if (reg) { + addr = of_translate_address(node, reg); + if (addr != OF_BAD_ADDR) { + dev_set_name(dev, "%llx.%s", + (unsigned long long)addr, node->name); + return; + } + } + + /* + * No BusID, use the node name and add a globally incremented + * counter (and pray...) + */ + magic = atomic_add_return(1, &bus_no_reg_magic); + dev_set_name(dev, "%s.%d", node->name, magic - 1); +} + +/** + * of_device_alloc - Allocate and initialize an of_device + * @np: device node to assign to device + * @bus_id: Name to assign to the device. May be null to use default name. + * @parent: Parent device. + */ +struct of_device *of_device_alloc(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->dev.of_node = of_node_get(np); + dev->dev.dma_mask = &dev->archdata.dma_mask; + dev->dev.parent = parent; + dev->dev.release = of_release_dev; + + if (bus_id) + dev_set_name(&dev->dev, "%s", bus_id); + else + of_device_make_bus_id(&dev->dev); + + return dev; +} +EXPORT_SYMBOL(of_device_alloc); + +/** * of_platform_device_create - Alloc, initialize and register an of_device * @np: pointer to node to create device for * @bus_id: name to assign device diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 4bbba41..a51fd30 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -60,6 +60,9 @@ static inline void of_unregister_platform_driver(struct of_platform_driver *drv) of_unregister_driver(drv); } +extern struct of_device *of_device_alloc(struct device_node *np, + const char *bus_id, + struct device *parent); #include extern struct of_device *of_find_device_by_node(struct device_node *np); -- cgit v0.10.2 From ac80a51e2ce5c431de9997085f33cb6093218b1f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:15 -0600 Subject: of/device: populate platform_device (of_device) resource table on allocation When allocating a platform_device to represent an OF node, also allocate space for the resource table and populate it with IRQ and reg property information. This change is in preparation for merging the of_platform_bus_type with the platform_bus_type so that existing platform_driver code can retrieve base addresses and IRQs data. Background: a previous commit removed struct of_device and made it a #define alias for platform_device. Signed-off-by: Grant Likely CC: Michal Simek CC: Grant Likely CC: Benjamin Herrenschmidt CC: Stephen Rothwell CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org CC: devicetree-discuss@lists.ozlabs.org diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ea87a3c..5cc9a8e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -475,10 +475,35 @@ struct of_device *of_device_alloc(struct device_node *np, struct device *parent) { struct of_device *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + int rc, i, num_reg = 0, num_irq = 0; + struct resource *res, temp_res; + + /* First count how many resources are needed */ + while (of_address_to_resource(np, num_reg, &temp_res) == 0) + num_reg++; + while (of_irq_to_resource(np, num_irq, &temp_res) != NO_IRQ) + num_irq++; + + /* Allocate memory for both the struct device and the resource table */ + dev = kzalloc(sizeof(*dev) + (sizeof(*res) * (num_reg + num_irq)), + GFP_KERNEL); if (!dev) return NULL; + res = (struct resource *) &dev[1]; + + /* Populate the resource table */ + if (num_irq || num_reg) { + dev->num_resources = num_reg + num_irq; + dev->resource = res; + for (i = 0; i < num_reg; i++, res++) { + rc = of_address_to_resource(np, i, res); + WARN_ON(rc); + } + for (i = 0; i < num_irq; i++, res++) { + rc = of_irq_to_resource(np, i, res); + WARN_ON(rc == NO_IRQ); + } + } dev->dev.of_node = of_node_get(np); dev->dev.dma_mask = &dev->archdata.dma_mask; -- cgit v0.10.2 From cedb1881ba32f7e9cd49250bd79debccbe52b094 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Jun 2010 07:48:15 -0600 Subject: gpiolib: cosmetic improvements for error handling in gpiochip_add() Hopefully it makes the code look nicer and makes it easier to extend this function. Signed-off-by: Anton Vorontsov Signed-off-by: Andrew Morton Signed-off-by: Grant Likely CC: devicetree-discuss@lists.ozlabs.org CC: linux-kernel@vger.kernel.org diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 3ca3654..713ca0e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1101,14 +1101,20 @@ int gpiochip_add(struct gpio_chip *chip) unlock: spin_unlock_irqrestore(&gpio_lock, flags); - if (status == 0) - status = gpiochip_export(chip); + + if (status) + goto fail; + + status = gpiochip_export(chip); + if (status) + goto fail; + + return 0; fail: /* failures here can mean systems won't boot... */ - if (status) - pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", - chip->base, chip->base + chip->ngpio - 1, - chip->label ? : "generic"); + pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", + chip->base, chip->base + chip->ngpio - 1, + chip->label ? : "generic"); return status; } EXPORT_SYMBOL_GPL(gpiochip_add); -- cgit v0.10.2 From a19e3da5bc5fc6c10ab73f310bea80f3845b4531 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Jun 2010 07:48:16 -0600 Subject: of/gpio: Kill of_gpio_chip and add members directly to gpio_chip The OF gpio infrastructure is great for describing GPIO connections within the device tree. However, using a GPIO binding still requires changes to the gpio controller just to add an of_gpio structure. In most cases, the gpio controller doesn't actually need any special support and the simple OF gpio mapping function is more than sufficient. Additional, the current scheme of using of_gpio_chip requires a convoluted scheme to maintain 1:1 mappings between of_gpio_chip and gpio_chip instances. If the struct of_gpio_chip data members were moved into struct gpio_chip, then it would simplify the processing of OF gpio bindings, and it would make it trivial to use device tree OF connections on existing gpiolib controller drivers. This patch eliminates the of_gpio_chip structure and moves the relevant fields into struct gpio_chip (conditional on CONFIG_OF_GPIO). This move simplifies the existing code and prepares for adding automatic device tree support to existing drivers. Signed-off-by: Grant Likely Cc: Andrew Morton Cc: Anton Vorontsov Cc: Grant Likely Cc: David Brownell Cc: Bill Gatliff Cc: Dmitry Eremin-Solenikov Cc: Benjamin Herrenschmidt Cc: Jean Delvare diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index a1721a3..5476d3c 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -24,8 +24,8 @@ static int of_reset_gpio_handle(void) int ret; /* variable which stored handle reset gpio pin */ struct device_node *root; /* root node */ struct device_node *gpio; /* gpio node */ - struct of_gpio_chip *of_gc = NULL; - enum of_gpio_flags flags ; + struct gpio_chip *gc; + u32 flags; const void *gpio_spec; /* find out root node */ @@ -39,19 +39,19 @@ static int of_reset_gpio_handle(void) goto err0; } - of_gc = gpio->data; - if (!of_gc) { + gc = gpio->data; + if (!gc) { pr_debug("%s: gpio controller %s isn't registered\n", root->full_name, gpio->full_name); ret = -ENODEV; goto err1; } - ret = of_gc->xlate(of_gc, root, gpio_spec, &flags); + ret = gc->of_xlate(gc, root, gpio_spec, &flags); if (ret < 0) goto err1; - ret += of_gc->gc.base; + ret += gc->base; err1: of_node_put(gpio); err0: diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index ca5305a..fd0912e 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -152,21 +152,21 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, { struct mpc52xx_gpiochip *chip; struct mpc52xx_gpio_wkup __iomem *regs; - struct of_gpio_chip *ofchip; + struct gpio_chip *gc; int ret; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; - ofchip = &chip->mmchip.of_gc; + gc = &chip->mmchip.gc; - ofchip->gpio_cells = 2; - ofchip->gc.ngpio = 8; - ofchip->gc.direction_input = mpc52xx_wkup_gpio_dir_in; - ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out; - ofchip->gc.get = mpc52xx_wkup_gpio_get; - ofchip->gc.set = mpc52xx_wkup_gpio_set; + gc->of_gpio_n_cells = 2; + gc->ngpio = 8; + gc->direction_input = mpc52xx_wkup_gpio_dir_in; + gc->direction_output = mpc52xx_wkup_gpio_dir_out; + gc->get = mpc52xx_wkup_gpio_get; + gc->set = mpc52xx_wkup_gpio_set; ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) @@ -315,7 +315,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, const struct of_device_id *match) { struct mpc52xx_gpiochip *chip; - struct of_gpio_chip *ofchip; + struct gpio_chip *gc; struct mpc52xx_gpio __iomem *regs; int ret; @@ -323,14 +323,14 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, if (!chip) return -ENOMEM; - ofchip = &chip->mmchip.of_gc; + gc = &chip->mmchip.gc; - ofchip->gpio_cells = 2; - ofchip->gc.ngpio = 32; - ofchip->gc.direction_input = mpc52xx_simple_gpio_dir_in; - ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out; - ofchip->gc.get = mpc52xx_simple_gpio_get; - ofchip->gc.set = mpc52xx_simple_gpio_set; + gc->of_gpio_n_cells = 2; + gc->ngpio = 32; + gc->direction_input = mpc52xx_simple_gpio_dir_in; + gc->direction_output = mpc52xx_simple_gpio_dir_out; + gc->get = mpc52xx_simple_gpio_get; + gc->set = mpc52xx_simple_gpio_set; ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 46c9357..3f2ee47 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -78,7 +78,7 @@ MODULE_LICENSE("GPL"); * @dev: pointer to device structure * @regs: virtual address of GPT registers * @lock: spinlock to coordinate between different functions. - * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled + * @gc: gpio_chip instance structure; used when GPIO is enabled * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates * if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates @@ -94,7 +94,7 @@ struct mpc52xx_gpt_priv { u8 wdt_mode; #if defined(CONFIG_GPIOLIB) - struct of_gpio_chip of_gc; + struct gpio_chip gc; #endif }; @@ -280,7 +280,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) #if defined(CONFIG_GPIOLIB) static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc) { - return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc); + return container_of(gc, struct mpc52xx_gpt_priv, gc); } static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio) @@ -336,28 +336,27 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) if (!of_find_property(node, "gpio-controller", NULL)) return; - gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL); - if (!gpt->of_gc.gc.label) { + gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL); + if (!gpt->gc.label) { dev_err(gpt->dev, "out of memory\n"); return; } - gpt->of_gc.gpio_cells = 2; - gpt->of_gc.gc.ngpio = 1; - gpt->of_gc.gc.direction_input = mpc52xx_gpt_gpio_dir_in; - gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out; - gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get; - gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set; - gpt->of_gc.gc.base = -1; - gpt->of_gc.xlate = of_gpio_simple_xlate; - node->data = &gpt->of_gc; + gpt->gc.ngpio = 1; + gpt->gc.direction_input = mpc52xx_gpt_gpio_dir_in; + gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out; + gpt->gc.get = mpc52xx_gpt_gpio_get; + gpt->gc.set = mpc52xx_gpt_gpio_set; + gpt->gc.base = -1; + gpt->gc.of_gpio_n_cells = 2; + gpt->gc.of_xlate = of_gpio_simple_xlate; of_node_get(node); /* Setup external pin in GPIO mode */ clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, MPC52xx_GPT_MODE_MS_GPIO); - rc = gpiochip_add(&gpt->of_gc.gc); + rc = gpiochip_add(&gpt->gc); if (rc) dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc); diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index d119a7c..e49f4bd 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -37,7 +37,7 @@ struct mcu { struct mutex lock; struct device_node *np; struct i2c_client *client; - struct of_gpio_chip of_gc; + struct gpio_chip gc; u8 reg_ctrl; }; @@ -56,8 +56,7 @@ static void mcu_power_off(void) static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) { - struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); - struct mcu *mcu = container_of(of_gc, struct mcu, of_gc); + struct mcu *mcu = container_of(gc, struct mcu, gc); u8 bit = 1 << (4 + gpio); mutex_lock(&mcu->lock); @@ -79,8 +78,7 @@ static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) static int mcu_gpiochip_add(struct mcu *mcu) { struct device_node *np; - struct of_gpio_chip *of_gc = &mcu->of_gc; - struct gpio_chip *gc = &of_gc->gc; + struct gpio_chip *gc = &mcu->gc; int ret; np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); @@ -94,10 +92,9 @@ static int mcu_gpiochip_add(struct mcu *mcu) gc->base = -1; gc->set = mcu_gpio_set; gc->direction_output = mcu_gpio_dir_out; - of_gc->gpio_cells = 2; - of_gc->xlate = of_gpio_simple_xlate; + gc->of_gpio_n_cells = 2; + gc->of_xlate = of_gpio_simple_xlate; - np->data = of_gc; mcu->np = np; /* @@ -114,7 +111,7 @@ static int mcu_gpiochip_remove(struct mcu *mcu) { int ret; - ret = gpiochip_remove(&mcu->of_gc.gc); + ret = gpiochip_remove(&mcu->gc); if (ret) return ret; of_node_put(mcu->np); diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c index b8cb08d..4ff7b1e 100644 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/arch/powerpc/platforms/86xx/gef_gpio.c @@ -118,12 +118,12 @@ static int __init gef_gpio_init(void) } /* Setup pointers to chip functions */ - gef_gpio_chip->of_gc.gpio_cells = 2; - gef_gpio_chip->of_gc.gc.ngpio = 19; - gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->of_gc.gc.get = gef_gpio_get; - gef_gpio_chip->of_gc.gc.set = gef_gpio_set; + gef_gpio_chip->gc.of_gpio_n_cells = 2; + gef_gpio_chip->gc.ngpio = 19; + gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; + gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; + gef_gpio_chip->gc.get = gef_gpio_get; + gef_gpio_chip->gc.set = gef_gpio_set; /* This function adds a memory mapped GPIO chip */ retval = of_mm_gpiochip_add(np, gef_gpio_chip); @@ -146,12 +146,12 @@ static int __init gef_gpio_init(void) } /* Setup pointers to chip functions */ - gef_gpio_chip->of_gc.gpio_cells = 2; - gef_gpio_chip->of_gc.gc.ngpio = 6; - gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->of_gc.gc.get = gef_gpio_get; - gef_gpio_chip->of_gc.gc.set = gef_gpio_set; + gef_gpio_chip->gc.of_gpio_n_cells = 2; + gef_gpio_chip->gc.ngpio = 6; + gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; + gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; + gef_gpio_chip->gc.get = gef_gpio_get; + gef_gpio_chip->gc.set = gef_gpio_set; /* This function adds a memory mapped GPIO chip */ retval = of_mm_gpiochip_add(np, gef_gpio_chip); diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 8d103ca..d5cf7d4 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -621,7 +621,6 @@ int cpm1_gpiochip_add16(struct device_node *np) { struct cpm1_gpio16_chip *cpm1_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); @@ -631,11 +630,10 @@ int cpm1_gpiochip_add16(struct device_node *np) spin_lock_init(&cpm1_gc->lock); mm_gc = &cpm1_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = cpm1_gpio16_save_regs; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = 16; gc->direction_input = cpm1_gpio16_dir_in; gc->direction_output = cpm1_gpio16_dir_out; @@ -745,7 +743,6 @@ int cpm1_gpiochip_add32(struct device_node *np) { struct cpm1_gpio32_chip *cpm1_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); @@ -755,11 +752,10 @@ int cpm1_gpiochip_add32(struct device_node *np) spin_lock_init(&cpm1_gc->lock); mm_gc = &cpm1_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = cpm1_gpio32_save_regs; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = cpm1_gpio32_dir_in; gc->direction_output = cpm1_gpio32_dir_out; diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 88b9812..67e9b47 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -325,7 +325,6 @@ int cpm2_gpiochip_add32(struct device_node *np) { struct cpm2_gpio32_chip *cpm2_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL); @@ -335,11 +334,10 @@ int cpm2_gpiochip_add32(struct device_node *np) spin_lock_init(&cpm2_gc->lock); mm_gc = &cpm2_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = cpm2_gpio32_save_regs; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = cpm2_gpio32_dir_in; gc->direction_output = cpm2_gpio32_dir_out; diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 83f5196..ec8fcd4 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -257,7 +257,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) { struct mpc8xxx_gpio_chip *mpc8xxx_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; unsigned hwirq; int ret; @@ -271,11 +270,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) spin_lock_init(&mpc8xxx_gc->lock); mm_gc = &mpc8xxx_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = mpc8xxx_gpio_save_regs; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = MPC8XXX_GPIO_PINS; gc->direction_input = mpc8xxx_gpio_dir_in; gc->direction_output = mpc8xxx_gpio_dir_out; diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 3812fc3..42e7a5e 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c @@ -181,7 +181,6 @@ static int __init ppc4xx_add_gpiochips(void) int ret; struct ppc4xx_gpio_chip *ppc4xx_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); @@ -193,10 +192,9 @@ static int __init ppc4xx_add_gpiochips(void) spin_lock_init(&ppc4xx_gc->lock); mm_gc = &ppc4xx_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = ppc4xx_gpio_dir_in; gc->direction_output = ppc4xx_gpio_dir_out; diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index dc8f8d6..194478c 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -138,8 +138,8 @@ struct qe_pin { struct qe_pin *qe_pin_request(struct device_node *np, int index) { struct qe_pin *qe_pin; - struct device_node *gc; - struct of_gpio_chip *of_gc = NULL; + struct device_node *gpio_np; + struct gpio_chip *gc; struct of_mm_gpio_chip *mm_gc; struct qe_gpio_chip *qe_gc; int err; @@ -155,40 +155,40 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) } err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, - &gc, &gpio_spec); + &gpio_np, &gpio_spec); if (err) { pr_debug("%s: can't parse gpios property\n", __func__); goto err0; } - if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) { + if (!of_device_is_compatible(gpio_np, "fsl,mpc8323-qe-pario-bank")) { pr_debug("%s: tried to get a non-qe pin\n", __func__); err = -EINVAL; goto err1; } - of_gc = gc->data; - if (!of_gc) { + gc = gpio_np->data; + if (!gc) { pr_debug("%s: gpio controller %s isn't registered\n", - np->full_name, gc->full_name); + np->full_name, gpio_np->full_name); err = -ENODEV; goto err1; } - gpio_cells = of_get_property(gc, "#gpio-cells", &size); + gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size); if (!gpio_cells || size != sizeof(*gpio_cells) || - *gpio_cells != of_gc->gpio_cells) { + *gpio_cells != gc->of_gpio_n_cells) { pr_debug("%s: wrong #gpio-cells for %s\n", - np->full_name, gc->full_name); + np->full_name, gpio_np->full_name); err = -EINVAL; goto err1; } - err = of_gc->xlate(of_gc, np, gpio_spec, NULL); + err = gc->of_xlate(gc, np, gpio_spec, NULL); if (err < 0) goto err1; - mm_gc = to_of_mm_gpio_chip(&of_gc->gc); + mm_gc = to_of_mm_gpio_chip(gc); qe_gc = to_qe_gpio_chip(mm_gc); spin_lock_irqsave(&qe_gc->lock, flags); @@ -206,7 +206,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) if (!err) return qe_pin; err1: - of_node_put(gc); + of_node_put(gpio_np); err0: kfree(qe_pin); pr_debug("%s failed with status %d\n", __func__, err); @@ -307,7 +307,6 @@ static int __init qe_add_gpiochips(void) int ret; struct qe_gpio_chip *qe_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); @@ -319,11 +318,10 @@ static int __init qe_add_gpiochips(void) spin_lock_init(&qe_gc->lock); mm_gc = &qe_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = qe_gpio_save_regs; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = QE_PIO_PINS; gc->direction_input = qe_gpio_dir_in; gc->direction_output = qe_gpio_dir_out; diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index d5fb173..b7559aa 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c @@ -91,7 +91,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) int ret; struct u8_gpio_chip *u8_gc; struct of_mm_gpio_chip *mm_gc; - struct of_gpio_chip *of_gc; struct gpio_chip *gc; u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL); @@ -101,11 +100,10 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) spin_lock_init(&u8_gc->lock); mm_gc = &u8_gc->mm_gc; - of_gc = &mm_gc->of_gc; - gc = &of_gc->gc; + gc = &mm_gc->gc; mm_gc->save_regs = u8_gpio_save_regs; - of_gc->gpio_cells = 2; + gc->of_gpio_n_cells = 2; gc->ngpio = 8; gc->direction_input = u8_gpio_dir_in; gc->direction_output = u8_gpio_dir_out; diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c index b8fa65b..2993c40 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/xilinx_gpio.c @@ -161,14 +161,12 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) static int __devinit xgpio_of_probe(struct device_node *np) { struct xgpio_instance *chip; - struct of_gpio_chip *ofchip; int status = 0; const u32 *tree_info; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; - ofchip = &chip->mmchip.of_gc; /* Update GPIO state shadow register with default value */ tree_info = of_get_property(np, "xlnx,dout-default", NULL); @@ -182,21 +180,21 @@ static int __devinit xgpio_of_probe(struct device_node *np) chip->gpio_dir = *tree_info; /* Check device node and parent device node for device width */ - ofchip->gc.ngpio = 32; /* By default assume full GPIO controller */ + chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */ tree_info = of_get_property(np, "xlnx,gpio-width", NULL); if (!tree_info) tree_info = of_get_property(np->parent, "xlnx,gpio-width", NULL); if (tree_info) - ofchip->gc.ngpio = *tree_info; + chip->mmchip.gc.ngpio = *tree_info; spin_lock_init(&chip->gpio_lock); - ofchip->gpio_cells = 2; - ofchip->gc.direction_input = xgpio_dir_in; - ofchip->gc.direction_output = xgpio_dir_out; - ofchip->gc.get = xgpio_get; - ofchip->gc.set = xgpio_set; + chip->mmchip.gc.of_gpio_n_cells = 2; + chip->mmchip.gc.direction_input = xgpio_dir_in; + chip->mmchip.gc.direction_output = xgpio_dir_out; + chip->mmchip.gc.get = xgpio_get; + chip->mmchip.gc.set = xgpio_set; chip->mmchip.save_regs = xgpio_save_regs; diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index a1b31a4..fde53a3 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -33,32 +33,32 @@ int of_get_gpio_flags(struct device_node *np, int index, enum of_gpio_flags *flags) { int ret; - struct device_node *gc; - struct of_gpio_chip *of_gc = NULL; + struct device_node *gpio_np; + struct gpio_chip *gc; int size; const void *gpio_spec; const __be32 *gpio_cells; ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, - &gc, &gpio_spec); + &gpio_np, &gpio_spec); if (ret) { pr_debug("%s: can't parse gpios property\n", __func__); goto err0; } - of_gc = gc->data; - if (!of_gc) { + gc = gpio_np->data; + if (!gc) { pr_debug("%s: gpio controller %s isn't registered\n", - np->full_name, gc->full_name); + np->full_name, gpio_np->full_name); ret = -ENODEV; goto err1; } - gpio_cells = of_get_property(gc, "#gpio-cells", &size); + gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size); if (!gpio_cells || size != sizeof(*gpio_cells) || - be32_to_cpup(gpio_cells) != of_gc->gpio_cells) { + be32_to_cpup(gpio_cells) != gc->of_gpio_n_cells) { pr_debug("%s: wrong #gpio-cells for %s\n", - np->full_name, gc->full_name); + np->full_name, gpio_np->full_name); ret = -EINVAL; goto err1; } @@ -67,13 +67,13 @@ int of_get_gpio_flags(struct device_node *np, int index, if (flags) *flags = 0; - ret = of_gc->xlate(of_gc, np, gpio_spec, flags); + ret = gc->of_xlate(gc, np, gpio_spec, flags); if (ret < 0) goto err1; - ret += of_gc->gc.base; + ret += gc->base; err1: - of_node_put(gc); + of_node_put(gpio_np); err0: pr_debug("%s exited with status %d\n", __func__, ret); return ret; @@ -116,7 +116,7 @@ EXPORT_SYMBOL(of_gpio_count); /** * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags - * @of_gc: pointer to the of_gpio_chip structure + * @gc: pointer to the gpio_chip structure * @np: device node of the GPIO chip * @gpio_spec: gpio specifier as found in the device tree * @flags: a flags pointer to fill in @@ -125,8 +125,8 @@ EXPORT_SYMBOL(of_gpio_count); * gpio chips. This function performs only one sanity check: whether gpio * is less than ngpios (that is specified in the gpio_chip). */ -int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, - const void *gpio_spec, enum of_gpio_flags *flags) +int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags) { const __be32 *gpio = gpio_spec; const u32 n = be32_to_cpup(gpio); @@ -137,12 +137,12 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, * number and the flags from a single gpio cell -- this is possible, * but not recommended). */ - if (of_gc->gpio_cells < 2) { + if (gc->of_gpio_n_cells < 2) { WARN_ON(1); return -EINVAL; } - if (n > of_gc->gc.ngpio) + if (n > gc->ngpio) return -EINVAL; if (flags) @@ -161,10 +161,8 @@ EXPORT_SYMBOL(of_gpio_simple_xlate); * * 1) In the gpio_chip structure: * - all the callbacks - * - * 2) In the of_gpio_chip structure: - * - gpio_cells - * - xlate callback (optional) + * - of_gpio_n_cells + * - of_xlate callback (optional) * * 3) In the of_mm_gpio_chip structure: * - save_regs callback (optional) @@ -177,8 +175,7 @@ int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc) { int ret = -ENOMEM; - struct of_gpio_chip *of_gc = &mm_gc->of_gc; - struct gpio_chip *gc = &of_gc->gc; + struct gpio_chip *gc = &mm_gc->gc; gc->label = kstrdup(np->full_name, GFP_KERNEL); if (!gc->label) @@ -190,13 +187,14 @@ int of_mm_gpiochip_add(struct device_node *np, gc->base = -1; - if (!of_gc->xlate) - of_gc->xlate = of_gpio_simple_xlate; + if (!gc->of_xlate) + gc->of_xlate = of_gpio_simple_xlate; if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); - np->data = of_gc; + np->data = &mm_gc->gc; + mm_gc->gc.of_node = np; ret = gpiochip_add(gc); if (ret) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 4f3d75e..af2544e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -31,6 +31,7 @@ static inline int gpio_is_valid(int number) struct device; struct seq_file; struct module; +struct device_node; /** * struct gpio_chip - abstract a GPIO controller @@ -106,6 +107,17 @@ struct gpio_chip { const char *const *names; unsigned can_sleep:1; unsigned exported:1; + +#if defined(CONFIG_OF_GPIO) + /* + * If CONFIG_OF is enabled, then all GPIO controllers described in the + * device tree automatically may have an OF translation + */ + struct device_node *of_node; + int of_gpio_n_cells; + int (*of_xlate)(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags); +#endif }; extern const char *gpiochip_is_requested(struct gpio_chip *chip, diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index fc2472c..460d681 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -33,34 +33,17 @@ enum of_gpio_flags { #ifdef CONFIG_OF_GPIO /* - * Generic OF GPIO chip - */ -struct of_gpio_chip { - struct gpio_chip gc; - int gpio_cells; - int (*xlate)(struct of_gpio_chip *of_gc, struct device_node *np, - const void *gpio_spec, enum of_gpio_flags *flags); -}; - -static inline struct of_gpio_chip *to_of_gpio_chip(struct gpio_chip *gc) -{ - return container_of(gc, struct of_gpio_chip, gc); -} - -/* * OF GPIO chip for memory mapped banks */ struct of_mm_gpio_chip { - struct of_gpio_chip of_gc; + struct gpio_chip gc; void (*save_regs)(struct of_mm_gpio_chip *mm_gc); void __iomem *regs; }; static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc) { - struct of_gpio_chip *of_gc = to_of_gpio_chip(gc); - - return container_of(of_gc, struct of_mm_gpio_chip, of_gc); + return container_of(gc, struct of_mm_gpio_chip, gc); } extern int of_get_gpio_flags(struct device_node *np, int index, @@ -69,11 +52,9 @@ extern unsigned int of_gpio_count(struct device_node *np); extern int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc); -extern int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, - struct device_node *np, - const void *gpio_spec, - enum of_gpio_flags *flags); -#else +extern int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags); +#else /* CONFIG_OF_GPIO */ /* Drivers may not strictly depend on the GPIO support, so let them link. */ static inline int of_get_gpio_flags(struct device_node *np, int index, -- cgit v0.10.2 From 594fa265e084073443390c5b93d5410fd28e9bcd Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:16 -0600 Subject: of/gpio: stop using device_node data pointer to find gpio_chip Currently the kernel uses the struct device_node.data pointer to resolve a struct gpio_chip pointer from a device tree node. However, the .data member doesn't provide any type checking and there aren't any rules enforced on what it should be used for. There's no guarantee that the data stored in it actually points to an gpio_chip pointer. Instead of relying on the .data pointer, this patch modifies the code to add a lookup function which scans through the registered gpio_chips and returns the gpio_chip that has a pointer to the specified device_node. Signed-off-by: Grant Likely CC: Andrew Morton CC: Anton Vorontsov CC: Grant Likely CC: David Brownell CC: Bill Gatliff CC: Dmitry Eremin-Solenikov CC: Benjamin Herrenschmidt CC: Jean Delvare CC: linux-kernel@vger.kernel.org CC: devicetree-discuss@lists.ozlabs.org diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index 5476d3c..bd8ccab 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -39,7 +39,7 @@ static int of_reset_gpio_handle(void) goto err0; } - gc = gpio->data; + gc = of_node_to_gpiochip(gpio); if (!gc) { pr_debug("%s: gpio controller %s isn't registered\n", root->full_name, gpio->full_name); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 3f2ee47..6e82bd2 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -350,6 +350,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) gpt->gc.base = -1; gpt->gc.of_gpio_n_cells = 2; gpt->gc.of_xlate = of_gpio_simple_xlate; + gpt->gc.of_node = node; of_node_get(node); /* Setup external pin in GPIO mode */ diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index e49f4bd..f0dbace 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -35,7 +35,6 @@ struct mcu { struct mutex lock; - struct device_node *np; struct i2c_client *client; struct gpio_chip gc; u8 reg_ctrl; @@ -79,7 +78,6 @@ static int mcu_gpiochip_add(struct mcu *mcu) { struct device_node *np; struct gpio_chip *gc = &mcu->gc; - int ret; np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx"); if (!np) @@ -94,29 +92,14 @@ static int mcu_gpiochip_add(struct mcu *mcu) gc->direction_output = mcu_gpio_dir_out; gc->of_gpio_n_cells = 2; gc->of_xlate = of_gpio_simple_xlate; + gc->of_node = np; - mcu->np = np; - - /* - * We don't want to lose the node, its ->data and ->full_name... - * So, if succeeded, we don't put the node here. - */ - ret = gpiochip_add(gc); - if (ret) - of_node_put(np); - return ret; + return gpiochip_add(gc); } static int mcu_gpiochip_remove(struct mcu *mcu) { - int ret; - - ret = gpiochip_remove(&mcu->gc); - if (ret) - return ret; - of_node_put(mcu->np); - - return 0; + return gpiochip_remove(&mcu->gc); } static int __devinit mcu_probe(struct i2c_client *client, diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 194478c..32e9440 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -167,7 +167,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index) goto err1; } - gc = gpio_np->data; + gc = of_node_to_gpiochip(gpio_np); if (!gc) { pr_debug("%s: gpio controller %s isn't registered\n", np->full_name, gpio_np->full_name); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 713ca0e..73fd328 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1153,6 +1153,38 @@ int gpiochip_remove(struct gpio_chip *chip) } EXPORT_SYMBOL_GPL(gpiochip_remove); +/** + * gpiochip_find() - iterator for locating a specific gpio_chip + * @data: data to pass to match function + * @callback: Callback function to check gpio_chip + * + * Similar to bus_find_device. It returns a reference to a gpio_chip as + * determined by a user supplied @match callback. The callback should return + * 0 if the device doesn't match and non-zero if it does. If the callback is + * non-zero, this function will return to the caller and not iterate over any + * more gpio_chips. + */ +struct gpio_chip *gpiochip_find(void *data, + int (*match)(struct gpio_chip *chip, void *data)) +{ + struct gpio_chip *chip = NULL; + unsigned long flags; + int i; + + spin_lock_irqsave(&gpio_lock, flags); + for (i = 0; i < ARCH_NR_GPIOS; i++) { + if (!gpio_desc[i].chip) + continue; + + if (match(gpio_desc[i].chip, data)) { + chip = gpio_desc[i].chip; + break; + } + } + spin_unlock_irqrestore(&gpio_lock, flags); + + return chip; +} /* These "optional" allocation calls help prevent drivers from stomping * on each other, and help provide better diagnostics in debugfs. diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index fde53a3..c8618d3 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -46,7 +46,7 @@ int of_get_gpio_flags(struct device_node *np, int index, goto err0; } - gc = gpio_np->data; + gc = of_node_to_gpiochip(gpio_np); if (!gc) { pr_debug("%s: gpio controller %s isn't registered\n", np->full_name, gpio_np->full_name); @@ -193,7 +193,6 @@ int of_mm_gpiochip_add(struct device_node *np, if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); - np->data = &mm_gc->gc; mm_gc->gc.of_node = np; ret = gpiochip_add(gc); @@ -207,7 +206,6 @@ int of_mm_gpiochip_add(struct device_node *np, np->full_name, gc->base); return 0; err2: - np->data = NULL; iounmap(mm_gc->regs); err1: kfree(gc->label); @@ -217,3 +215,14 @@ err0: return ret; } EXPORT_SYMBOL(of_mm_gpiochip_add); + +/* Private function for resolving node pointer to gpio_chip */ +static int of_gpiochip_is_match(struct gpio_chip *chip, void *data) +{ + return chip->of_node == data; +} + +struct gpio_chip *of_node_to_gpiochip(struct device_node *np) +{ + return gpiochip_find(np, of_gpiochip_is_match); +} diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index af2544e..c7376bf 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -127,6 +127,9 @@ extern int __must_check gpiochip_reserve(int start, int ngpio); /* add/remove chips */ extern int gpiochip_add(struct gpio_chip *chip); extern int __must_check gpiochip_remove(struct gpio_chip *chip); +extern struct gpio_chip *gpiochip_find(void *data, + int (*match)(struct gpio_chip *chip, + void *data)); /* Always use the library code for GPIO management calls, diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 460d681..1020587 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -54,6 +54,9 @@ extern int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc); extern int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, const void *gpio_spec, u32 *flags); + +extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); + #else /* CONFIG_OF_GPIO */ /* Drivers may not strictly depend on the GPIO support, so let them link. */ -- cgit v0.10.2 From 391c970c0dd1100e3b9e1681f7d0f20aac35455a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Jun 2010 07:48:17 -0600 Subject: of/gpio: add default of_xlate function if device has a node pointer Implement generic OF gpio hooks and thus make device-enabled GPIO chips (i.e. the ones that have gpio_chip->dev specified) automatically attach to the OpenFirmware subsystem. Which means that now we can handle I2C and SPI GPIO chips almost* transparently. * "Almost" because some chips still require platform data, and for these chips OF-glue is still needed, though with this change the glue will be much smaller. Signed-off-by: Anton Vorontsov Signed-off-by: Grant Likely Cc: David Brownell Cc: Bill Gatliff Cc: Dmitry Eremin-Solenikov Cc: Benjamin Herrenschmidt Cc: Jean Delvare Cc: Andrew Morton CC: linux-kernel@vger.kernel.org CC: devicetree-discuss@lists.ozlabs.org diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index fd0912e..0855e80 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -161,7 +161,6 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, gc = &chip->mmchip.gc; - gc->of_gpio_n_cells = 2; gc->ngpio = 8; gc->direction_input = mpc52xx_wkup_gpio_dir_in; gc->direction_output = mpc52xx_wkup_gpio_dir_out; @@ -325,7 +324,6 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, gc = &chip->mmchip.gc; - gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = mpc52xx_simple_gpio_dir_in; gc->direction_output = mpc52xx_simple_gpio_dir_out; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 6e82bd2..5d7d607 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -348,10 +348,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) gpt->gc.get = mpc52xx_gpt_gpio_get; gpt->gc.set = mpc52xx_gpt_gpio_set; gpt->gc.base = -1; - gpt->gc.of_gpio_n_cells = 2; - gpt->gc.of_xlate = of_gpio_simple_xlate; gpt->gc.of_node = node; - of_node_get(node); /* Setup external pin in GPIO mode */ clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index f0dbace..59b0ed1a 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -90,8 +90,6 @@ static int mcu_gpiochip_add(struct mcu *mcu) gc->base = -1; gc->set = mcu_gpio_set; gc->direction_output = mcu_gpio_dir_out; - gc->of_gpio_n_cells = 2; - gc->of_xlate = of_gpio_simple_xlate; gc->of_node = np; return gpiochip_add(gc); diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index d5cf7d4..0085212 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -633,7 +633,6 @@ int cpm1_gpiochip_add16(struct device_node *np) gc = &mm_gc->gc; mm_gc->save_regs = cpm1_gpio16_save_regs; - gc->of_gpio_n_cells = 2; gc->ngpio = 16; gc->direction_input = cpm1_gpio16_dir_in; gc->direction_output = cpm1_gpio16_dir_out; @@ -755,7 +754,6 @@ int cpm1_gpiochip_add32(struct device_node *np) gc = &mm_gc->gc; mm_gc->save_regs = cpm1_gpio32_save_regs; - gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = cpm1_gpio32_dir_in; gc->direction_output = cpm1_gpio32_dir_out; diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 67e9b47..2b69aa0 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -337,7 +337,6 @@ int cpm2_gpiochip_add32(struct device_node *np) gc = &mm_gc->gc; mm_gc->save_regs = cpm2_gpio32_save_regs; - gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = cpm2_gpio32_dir_in; gc->direction_output = cpm2_gpio32_dir_out; diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index ec8fcd4..2b69084 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -273,7 +273,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) gc = &mm_gc->gc; mm_gc->save_regs = mpc8xxx_gpio_save_regs; - gc->of_gpio_n_cells = 2; gc->ngpio = MPC8XXX_GPIO_PINS; gc->direction_input = mpc8xxx_gpio_dir_in; gc->direction_output = mpc8xxx_gpio_dir_out; diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 42e7a5e..fc65ad1 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c @@ -194,7 +194,6 @@ static int __init ppc4xx_add_gpiochips(void) mm_gc = &ppc4xx_gc->mm_gc; gc = &mm_gc->gc; - gc->of_gpio_n_cells = 2; gc->ngpio = 32; gc->direction_input = ppc4xx_gpio_dir_in; gc->direction_output = ppc4xx_gpio_dir_out; diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 32e9440..36bf845 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -321,7 +321,6 @@ static int __init qe_add_gpiochips(void) gc = &mm_gc->gc; mm_gc->save_regs = qe_gpio_save_regs; - gc->of_gpio_n_cells = 2; gc->ngpio = QE_PIO_PINS; gc->direction_input = qe_gpio_dir_in; gc->direction_output = qe_gpio_dir_out; diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index b7559aa..b6defda 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c @@ -103,7 +103,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) gc = &mm_gc->gc; mm_gc->save_regs = u8_gpio_save_regs; - gc->of_gpio_n_cells = 2; gc->ngpio = 8; gc->direction_input = u8_gpio_dir_in; gc->direction_output = u8_gpio_dir_out; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 73fd328..83cbc34 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -1099,6 +1100,8 @@ int gpiochip_add(struct gpio_chip *chip) } } + of_gpiochip_add(chip); + unlock: spin_unlock_irqrestore(&gpio_lock, flags); @@ -1133,6 +1136,8 @@ int gpiochip_remove(struct gpio_chip *chip) spin_lock_irqsave(&gpio_lock, flags); + of_gpiochip_remove(chip); + for (id = chip->base; id < chip->base + chip->ngpio; id++) { if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { status = -EBUSY; diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c index 2993c40..7096909 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/xilinx_gpio.c @@ -190,7 +190,6 @@ static int __devinit xgpio_of_probe(struct device_node *np) spin_lock_init(&chip->gpio_lock); - chip->mmchip.gc.of_gpio_n_cells = 2; chip->mmchip.gc.direction_input = xgpio_dir_in; chip->mmchip.gc.direction_output = xgpio_dir_out; chip->mmchip.gc.get = xgpio_get; diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index c8618d3..09f05a1 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -125,8 +125,8 @@ EXPORT_SYMBOL(of_gpio_count); * gpio chips. This function performs only one sanity check: whether gpio * is less than ngpios (that is specified in the gpio_chip). */ -int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, - const void *gpio_spec, u32 *flags) +static int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags) { const __be32 *gpio = gpio_spec; const u32 n = be32_to_cpup(gpio); @@ -150,7 +150,6 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, return n; } -EXPORT_SYMBOL(of_gpio_simple_xlate); /** * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) @@ -187,9 +186,6 @@ int of_mm_gpiochip_add(struct device_node *np, gc->base = -1; - if (!gc->of_xlate) - gc->of_xlate = of_gpio_simple_xlate; - if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); @@ -199,9 +195,6 @@ int of_mm_gpiochip_add(struct device_node *np, if (ret) goto err2; - /* We don't want to lose the node and its ->data */ - of_node_get(np); - pr_debug("%s: registered as generic GPIO chip, base is %d\n", np->full_name, gc->base); return 0; @@ -216,6 +209,28 @@ err0: } EXPORT_SYMBOL(of_mm_gpiochip_add); +void of_gpiochip_add(struct gpio_chip *chip) +{ + if ((!chip->of_node) && (chip->dev)) + chip->of_node = chip->dev->of_node; + + if (!chip->of_node) + return; + + if (!chip->of_xlate) { + chip->of_gpio_n_cells = 2; + chip->of_xlate = of_gpio_simple_xlate; + } + + of_node_get(chip->of_node); +} + +void of_gpiochip_remove(struct gpio_chip *chip) +{ + if (chip->of_node) + of_node_put(chip->of_node); +} + /* Private function for resolving node pointer to gpio_chip */ static int of_gpiochip_is_match(struct gpio_chip *chip, void *data) { diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 1020587..6598c04 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -52,9 +52,9 @@ extern unsigned int of_gpio_count(struct device_node *np); extern int of_mm_gpiochip_add(struct device_node *np, struct of_mm_gpio_chip *mm_gc); -extern int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, - const void *gpio_spec, u32 *flags); +extern void of_gpiochip_add(struct gpio_chip *gc); +extern void of_gpiochip_remove(struct gpio_chip *gc); extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); #else /* CONFIG_OF_GPIO */ @@ -71,6 +71,9 @@ static inline unsigned int of_gpio_count(struct device_node *np) return 0; } +static inline void of_gpiochip_add(struct gpio_chip *gc) { } +static inline void of_gpiochip_remove(struct gpio_chip *gc) { } + #endif /* CONFIG_OF_GPIO */ /** -- cgit v0.10.2 From 2e13cba8dc35774bf1d7169733e876c5b7adee54 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 5 Jul 2010 16:11:55 -0600 Subject: of/gpio: fix of_gpio includes drivers/of/gpio.c is missing includes for of_irq and struct device which cause build failures on ARM. This patch adds the correct include files and removes the unneeded kernel.h include Signed-off-by: Grant Likely diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 09f05a1..9059603 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -11,13 +11,14 @@ * (at your option) any later version. */ -#include +#include #include +#include #include #include -#include +#include #include -#include +#include /** * of_get_gpio_flags - Get a GPIO number and flags to use with GPIO API -- cgit v0.10.2 From 8cec0e7b4c7c0b76f2b5285f250211ad81c3eafd Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:17 -0600 Subject: of/device: Add OF style matching helper function Add of_driver_match_device() helper function. This function can be used by bus types to determine if a driver works with a device when using OF style matching. If CONFIG_OF is unselected, then it is a nop. Signed-off-by: Grant Likely CC: Greg Kroah-Hartman CC: Michal Simek CC: Grant Likely CC: Benjamin Herrenschmidt CC: Stephen Rothwell CC: linux-kernel@vger.kernel.org CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org CC: devicetree-discuss@lists.ozlabs.org diff --git a/drivers/of/device.c b/drivers/of/device.c index c2a98f5..5282a20 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -20,7 +20,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct device *dev) { - if (!dev->of_node) + if ((!matches) || (!dev->of_node)) return NULL; return of_match_node(matches, dev->of_node); } diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 238e92e..91d75fb 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -30,6 +30,17 @@ extern const struct of_device_id *of_match_device( const struct of_device_id *matches, const struct device *dev); +/** + * of_driver_match_device - Tell if a driver's of_match_table matches a device. + * @drv: the device_driver structure to test + * @dev: the device structure to match against + */ +static inline int of_driver_match_device(const struct device *dev, + const struct device_driver *drv) +{ + return of_match_device(drv->of_match_table, dev) != NULL; +} + extern struct of_device *of_dev_get(struct of_device *dev); extern void of_dev_put(struct of_device *dev); @@ -48,6 +59,14 @@ extern ssize_t of_device_get_modalias(struct device *dev, extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +#else /* CONFIG_OF_DEVICE */ + +static inline int of_driver_match_device(struct device *dev, + struct device_driver *drv) +{ + return 0; +} + #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ -- cgit v0.10.2 From f9f5a4669f1334a558f102c311debfd008e7c2bc Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 9 Jun 2010 22:22:17 -0600 Subject: of/device: Move struct of_device define outside of CONFIG_OF_DEVICE test Some code uses of_device even when CONFIG_OF_DEVICE is not set. This patch makes of_device valid all the time by moving it outside of the ifdef CONFIG_OF_DEVICE test. Reported-by: Randy Dunlap Signed-off-by: Grant Likely Acked-by: Randy Dunlap diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 91d75fb..7d27f5a 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -1,13 +1,6 @@ #ifndef _LINUX_OF_DEVICE_H #define _LINUX_OF_DEVICE_H -#ifdef CONFIG_OF_DEVICE -#include -#include -#include -#include - - /* * The of_device *was* a kind of "base class" that was a superset of * struct device for use by devices attached to an OF node and probed @@ -22,7 +15,12 @@ * from the kernel. */ #define of_device platform_device +#include +#ifdef CONFIG_OF_DEVICE +#include +#include +#include #include #define to_of_device(d) container_of(d, struct of_device, dev) -- cgit v0.10.2 From 4f0ddcb020ef8afae65b4edb9aeb4a42ab74f4cf Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 9 Jun 2010 15:44:09 -0700 Subject: niu: always include of_device.h The niu driver uses struct of_device when built on any arch, not only SPARC64, so always #include . drivers/net/niu.c:9700: warning: 'struct of_device' declared inside parameter list drivers/net/niu.c:9700: warning: its scope is only this definition or declaration, which is probably not what you want drivers/net/niu.c:9716: warning: assignment from incompatible pointer type Signed-off-by: Randy Dunlap Acked-by: Dave S. Miller Signed-off-by: Grant Likely diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 5dd50b6..f6ecf61 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -28,10 +28,7 @@ #include #include - -#ifdef CONFIG_SPARC64 #include -#endif #include "niu.h" -- cgit v0.10.2 From 9fd049927ccba1c1d0343239b82f28c4e07fb95d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:18 -0600 Subject: of/i2c: Generalize OF support This patch cleans up the i2c OF support code to make it selectable by all architectures and allow for automatic registration of i2c devices. Signed-off-by: Grant Likely diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index b02b453..03ae62e 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -652,6 +652,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, cpm->adap = cpm_ops; i2c_set_adapdata(&cpm->adap, cpm); cpm->adap.dev.parent = &ofdev->dev; + cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node); result = cpm_i2c_setup(cpm); if (result) { @@ -679,7 +680,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* * register OF I2C devices */ - of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); + of_i2c_register_devices(&cpm->adap); return 0; out_shut: diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index bf34413..d964121 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -745,6 +745,7 @@ static int __devinit iic_probe(struct of_device *ofdev, /* Register it with i2c layer */ adap = &dev->adap; adap->dev.parent = &ofdev->dev; + adap->dev.of_node = of_node_get(np); strlcpy(adap->name, "IBM IIC", sizeof(adap->name)); i2c_set_adapdata(adap, dev); adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; @@ -761,7 +762,7 @@ static int __devinit iic_probe(struct of_device *ofdev, dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); /* Now register all the child nodes */ - of_register_i2c_devices(adap, np); + of_i2c_register_devices(adap); return 0; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index df00eb1..d2e26d2 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -600,13 +600,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op, i2c->adap = mpc_ops; i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &op->dev; + i2c->adap.dev.of_node = of_node_get(op->dev.of_node); result = i2c_add_adapter(&i2c->adap); if (result < 0) { dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } - of_register_i2c_devices(&i2c->adap, op->dev.of_node); + of_i2c_register_devices(&i2c->adap); return result; diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 097f42a..80dd631 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -26,7 +26,7 @@ config OF_GPIO config OF_I2C def_tristate I2C - depends on (PPC_OF || MICROBLAZE) && I2C + depends on OF && !SPARC && I2C help OpenFirmware I2C accessors diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index ab6522c..0a694de 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -14,57 +14,65 @@ #include #include #include +#include #include -void of_register_i2c_devices(struct i2c_adapter *adap, - struct device_node *adap_node) +void of_i2c_register_devices(struct i2c_adapter *adap) { void *result; struct device_node *node; - for_each_child_of_node(adap_node, node) { + /* Only register child devices if the adapter has a node pointer set */ + if (!adap->dev.of_node) + return; + + dev_dbg(&adap->dev, "of_i2c: walking child nodes\n"); + + for_each_child_of_node(adap->dev.of_node, node) { struct i2c_board_info info = {}; struct dev_archdata dev_ad = {}; const __be32 *addr; int len; - if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) + dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name); + + if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { + dev_err(&adap->dev, "of_i2c: modalias failure on %s\n", + node->full_name); continue; + } addr = of_get_property(node, "reg", &len); - if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { - printk(KERN_ERR - "of-i2c: invalid i2c device entry\n"); + if (!addr || (len < sizeof(int))) { + dev_err(&adap->dev, "of_i2c: invalid reg on %s\n", + node->full_name); continue; } - info.irq = irq_of_parse_and_map(node, 0); - info.addr = be32_to_cpup(addr); + if (info.addr > (1 << 10) - 1) { + dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n", + info.addr, node->full_name); + continue; + } - info.of_node = node; + info.irq = irq_of_parse_and_map(node, 0); + info.of_node = of_node_get(node); info.archdata = &dev_ad; request_module("%s", info.type); result = i2c_new_device(adap, &info); if (result == NULL) { - printk(KERN_ERR - "of-i2c: Failed to load driver for %s\n", - info.type); + dev_err(&adap->dev, "of_i2c: Failure registering %s\n", + node->full_name); + of_node_put(node); irq_dispose_mapping(info.irq); continue; } - - /* - * Get the node to not lose the dev_archdata->of_node. - * Currently there is no way to put it back, as well as no - * of_unregister_i2c_devices() call. - */ - of_node_get(node); } } -EXPORT_SYMBOL(of_register_i2c_devices); +EXPORT_SYMBOL(of_i2c_register_devices); static int of_dev_node_match(struct device *dev, void *data) { diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h index 34974b5..0efe8d4 100644 --- a/include/linux/of_i2c.h +++ b/include/linux/of_i2c.h @@ -12,12 +12,19 @@ #ifndef __LINUX_OF_I2C_H #define __LINUX_OF_I2C_H +#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE) #include -void of_register_i2c_devices(struct i2c_adapter *adap, - struct device_node *adap_node); +extern void of_i2c_register_devices(struct i2c_adapter *adap); /* must call put_device() when done with returned i2c_client device */ -struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); +extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node); + +#else +static inline void of_i2c_register_devices(struct i2c_adapter *adap) +{ + return; +} +#endif /* CONFIG_OF_I2C */ #endif /* __LINUX_OF_I2C_H */ -- cgit v0.10.2 From 959e85f7751c33d1a2dabc5cc3fe2ed0db7052e5 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:19 -0600 Subject: i2c: Add OF-style registration and binding This patch adds OF hooks to the i2c core so that devices can automatically be registered based on device tree data. Signed-off-by: Grant Likely diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 03ae62e..e591de1 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -677,11 +677,6 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", cpm->adap.name); - /* - * register OF I2C devices - */ - of_i2c_register_devices(&cpm->adap); - return 0; out_shut: cpm_i2c_shutdown(cpm); diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index d964121..1168d61 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -761,9 +761,6 @@ static int __devinit iic_probe(struct of_device *ofdev, dev_info(&ofdev->dev, "using %s mode\n", dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); - /* Now register all the child nodes */ - of_i2c_register_devices(adap); - return 0; error_cleanup: diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index d2e26d2..9f7fef8c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -607,7 +607,6 @@ static int __devinit fsl_i2c_probe(struct of_device *op, dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } - of_i2c_register_devices(&i2c->adap); return result; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1cca263..5588ac1 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -70,6 +72,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) if (!client) return 0; + /* Attempt an OF style match */ + if (of_driver_match_device(dev, drv)) + return 1; + driver = to_i2c_driver(drv); /* match on an id table if there is one */ if (driver->id_table) @@ -790,6 +796,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap) if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); + /* Register devices from the device tree */ + of_i2c_register_devices(adap); + /* Notify drivers */ mutex_lock(&core_lock); dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, -- cgit v0.10.2 From 2ffe8c5f323c3b9749bf7bc2375d909d20bdbb15 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:19 -0600 Subject: of: refactor of_modalias_node() and remove explicit match table. This patch tightens up the behaviour of of_modalias_node() to be more predicatable and to eliminate the explicit of_modalias_tablep[] that is currently used to override the first entry in the compatible list of a device. The override table was needed originally because spi and i2c drivers had no way to do of-style matching. Now that all devices can have an of_node pointer, and all drivers can have an of_match_table, the explicit override table is no longer needed because each driver can specify its own OF-style match data. The mpc8349emitx-mcu driver is modified to explicitly specify the correct device to bind against. Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 59b0ed1a..70798ac 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -160,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = { }; MODULE_DEVICE_TABLE(i2c, mcu_ids); +static struct of_device_id mcu_of_match_table[] __devinitdata = { + { .compatible = "fsl,mcu-mpc8349emitx", }, + { }, +}; + static struct i2c_driver mcu_driver = { .driver = { .name = "mcu-mpc8349emitx", .owner = THIS_MODULE, + .of_match_table = mcu_of_match_table, }, .probe = mcu_probe, .remove = __devexit_p(mcu_remove), diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index ad847a2..7b0f3ef 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1533,12 +1533,20 @@ static int __devexit mmc_spi_remove(struct spi_device *spi) return 0; } +#if defined(CONFIG_OF) +static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { + { .compatible = "mmc-spi-slot", }, +}; +#endif static struct spi_driver mmc_spi_driver = { .driver = { .name = "mmc_spi", .bus = &spi_bus_type, .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = mmc_spi_of_match_table, +#endif }, .probe = mmc_spi_probe, .remove = __devexit_p(mmc_spi_remove), diff --git a/drivers/of/base.c b/drivers/of/base.c index b5ad974..e3f7af8 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -545,74 +545,28 @@ struct device_node *of_find_matching_node(struct device_node *from, EXPORT_SYMBOL(of_find_matching_node); /** - * of_modalias_table: Table of explicit compatible ==> modalias mappings - * - * This table allows particulare compatible property values to be mapped - * to modalias strings. This is useful for busses which do not directly - * understand the OF device tree but are populated based on data contained - * within the device tree. SPI and I2C are the two current users of this - * table. - * - * In most cases, devices do not need to be listed in this table because - * the modalias value can be derived directly from the compatible table. - * However, if for any reason a value cannot be derived, then this table - * provides a method to override the implicit derivation. - * - * At the moment, a single table is used for all bus types because it is - * assumed that the data size is small and that the compatible values - * should already be distinct enough to differentiate between SPI, I2C - * and other devices. - */ -struct of_modalias_table { - char *of_device; - char *modalias; -}; -static struct of_modalias_table of_modalias_table[] = { - { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" }, - { "mmc-spi-slot", "mmc_spi" }, -}; - -/** * of_modalias_node - Lookup appropriate modalias for a device node * @node: pointer to a device tree node * @modalias: Pointer to buffer that modalias value will be copied into * @len: Length of modalias value * - * Based on the value of the compatible property, this routine will determine - * an appropriate modalias value for a particular device tree node. Two - * separate methods are attempted to derive a modalias value. + * Based on the value of the compatible property, this routine will attempt + * to choose an appropriate modalias value for a particular device tree node. + * It does this by stripping the manufacturer prefix (as delimited by a ',') + * from the first entry in the compatible list property. * - * First method is to lookup the compatible value in of_modalias_table. - * Second is to strip off the manufacturer prefix from the first - * compatible entry and use the remainder as modalias - * - * This routine returns 0 on success + * This routine returns 0 on success, <0 on failure. */ int of_modalias_node(struct device_node *node, char *modalias, int len) { - int i, cplen; - const char *compatible; - const char *p; - - /* 1. search for exception list entry */ - for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) { - compatible = of_modalias_table[i].of_device; - if (!of_device_is_compatible(node, compatible)) - continue; - strlcpy(modalias, of_modalias_table[i].modalias, len); - return 0; - } + const char *compatible, *p; + int cplen; compatible = of_get_property(node, "compatible", &cplen); - if (!compatible) + if (!compatible || strlen(compatible) > cplen) return -ENODEV; - - /* 2. take first compatible entry and strip manufacturer */ p = strchr(compatible, ','); - if (!p) - return -ENODEV; - p++; - strlcpy(modalias, p, len); + strlcpy(modalias, p ? p + 1 : compatible, len); return 0; } EXPORT_SYMBOL_GPL(of_modalias_node); -- cgit v0.10.2 From 50ef5284eb4f48810dd83255631a7f3de0d78d6b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:20 -0600 Subject: of: Fix missing include Fix a build failure on ARM Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 5cc9a8e..125f2bc 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include -- cgit v0.10.2 From ae5bf63f2d8bad78e427e77f3f896e81cbdbde0d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 29 Jun 2010 12:42:00 +1000 Subject: microblaze: turn CONFIG_OF into a select so that we can make CONFIG_OF global and remove it from the architecture Kconfig files later. Signed-off-by: Stephen Rothwell Acked-by: Michal Simek Signed-off-by: Grant Likely diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 76818f9..2b378205 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -17,6 +17,8 @@ config MICROBLAZE select HAVE_DMA_ATTRS select HAVE_DMA_API_DEBUG select TRACING_SUPPORT + select OF + select OF_FLATTREE config SWAP def_bool n @@ -125,8 +127,7 @@ config CMDLINE_FORCE override those passed by the boot loader. config OF - def_bool y - select OF_FLATTREE + bool config PROC_DEVICETREE bool "Support for device tree in /proc" -- cgit v0.10.2 From 10f85f43ef134014da72d2bcc1bff1abb9b0640c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 29 Jun 2010 12:43:34 +1000 Subject: powerpc: turn CONFIG_OF into a select so that we can make CONFIG_OF global and remove it from the architecture Kconfig files later. Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 328774b..3697231 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -120,6 +120,8 @@ config ARCH_NO_VIRT_TO_BUS config PPC bool default y + select OF + select OF_FLATTREE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER @@ -173,8 +175,7 @@ config PPC_OF def_bool y config OF - def_bool y - select OF_FLATTREE + bool config PPC_UDBG_16550 bool -- cgit v0.10.2 From 7b14c647aee98db2d10705da385f9c19cc83a9af Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 29 Jun 2010 12:44:50 +1000 Subject: sparc: turn CONFIG_OF into a select so that we can make CONFIG_OF global and remove it from the architecture Kconfig files later. Signed-off-by: Stephen Rothwell Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 6f1470b..d02e8ac 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -18,6 +18,7 @@ config 64BIT config SPARC bool default y + select OF select HAVE_IDE select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 @@ -149,7 +150,7 @@ config ARCH_NO_VIRT_TO_BUS def_bool y config OF - def_bool y + bool config ARCH_SUPPORTS_DEBUG_PAGEALLOC def_bool y if SPARC64 -- cgit v0.10.2 From bcbefae2bcad0996bcef7245e34176960e95a191 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 29 Jun 2010 12:45:51 +1000 Subject: of: define CONFIG_OF globally so architectures can select it Signed-off-by: Stephen Rothwell Signed-off-by: Grant Likely diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 80dd631..d836b47 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -1,3 +1,6 @@ +config OF + bool + config OF_FLATTREE bool depends on OF -- cgit v0.10.2 From dd5e73794c9af30d6491963e13436d9f05ee6df6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 29 Jun 2010 12:47:01 +1000 Subject: of: remove architecture CONFIG_OF definitions now that CONFIG_OF is defined globally Signed-off-by: Stephen Rothwell Acked-by: Michal Simek Signed-off-by: Grant Likely diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 2b378205..1a8f682 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -126,9 +126,6 @@ config CMDLINE_FORCE Set this to have arguments from the default kernel command string override those passed by the boot loader. -config OF - bool - config PROC_DEVICETREE bool "Support for device tree in /proc" depends on PROC_FS diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3697231..402f4c0 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -174,9 +174,6 @@ config ARCH_MAY_HAVE_PC_FDC config PPC_OF def_bool y -config OF - bool - config PPC_UDBG_16550 bool default n diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index d02e8ac..13a9f2f 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -149,9 +149,6 @@ config GENERIC_GPIO config ARCH_NO_VIRT_TO_BUS def_bool y -config OF - bool - config ARCH_SUPPORTS_DEBUG_PAGEALLOC def_bool y if SPARC64 -- cgit v0.10.2 From 5ab5fc7e35705cf1a8a506d8e8b71acc27feec75 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 5 Jul 2010 12:02:13 -0600 Subject: of: Put all CONFIG_OF dependencies into a Kconfig menu block All of the options in drivers/of/Kconfig depend on CONFIG_OF. Putting all of them inside a menu block simplifies the dependency statements. It also creates a logical group for adding user selectable OF options. This patch also changes (PPC_OF || MICROBLAZE) statements to (!SPARC) so that those options are available to other architectures (and in fact the !SPARC conditions should probably be re-evalutated since the code is more generic now) This patch also moves the definition of CONFIG_DTC from arch/* to drivers/of/Kconfig Signed-off-by: Grant Likely diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 1a8f682..971f867 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -77,9 +77,6 @@ config LOCKDEP_SUPPORT config HAVE_LATENCYTOP_SUPPORT def_bool y -config DTC - def_bool y - source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 402f4c0..9b8e479 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -196,10 +196,6 @@ config SYS_SUPPORTS_APM_EMULATION default y if PMAC_APM_EMU bool -config DTC - bool - default y - config DEFAULT_UIMAGE bool help diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index d836b47..ae2d4ad 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -1,46 +1,53 @@ +config DTC + bool + config OF bool +menu "Flattened Device Tree and Open Firmware support" + depends on OF + config OF_FLATTREE bool - depends on OF + select DTC config OF_DYNAMIC def_bool y - depends on OF && PPC_OF + depends on PPC_OF config OF_ADDRESS def_bool y - depends on OF && !SPARC + depends on !SPARC config OF_IRQ def_bool y - depends on OF && !SPARC + depends on !SPARC config OF_DEVICE def_bool y - depends on OF && (SPARC || PPC_OF || MICROBLAZE) config OF_GPIO def_bool y - depends on OF && (PPC_OF || MICROBLAZE) && GPIOLIB + depends on GPIOLIB && !SPARC help OpenFirmware GPIO accessors config OF_I2C def_tristate I2C - depends on OF && !SPARC && I2C + depends on I2C && !SPARC help OpenFirmware I2C accessors config OF_SPI def_tristate SPI - depends on OF && (PPC_OF || MICROBLAZE) && SPI + depends on SPI && !SPARC help OpenFirmware SPI accessors config OF_MDIO def_tristate PHYLIB - depends on OF && PHYLIB + depends on PHYLIB help OpenFirmware MDIO bus (Ethernet PHY) accessors + +endmenu # OF -- cgit v0.10.2 From ef2a4524d6e776bbce819eeccbdcaeee5ce74027 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 28 Jun 2010 22:00:48 -0400 Subject: proc: unify PROC_DEVICETREE config Microblaze and PPC both use PROC_DEVICETREE, and OLPC will as well.. put the Kconfig option into fs/ rather than in arch/*/Kconfig. Signed-off-by: Andres Salomon [grant.likely@secretlab.ca: changed depends to PROC_FS && !SPARC] [grant.likely@secretlab.ca: moved to drivers/of/Kconfig] Signed-off-by: Grant Likely diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 971f867..6c4fee5 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -123,14 +123,6 @@ config CMDLINE_FORCE Set this to have arguments from the default kernel command string override those passed by the boot loader. -config PROC_DEVICETREE - bool "Support for device tree in /proc" - depends on PROC_FS - help - This option adds a device-tree directory under /proc which contains - an image of the device tree that the kernel copies from Open - Firmware or other boot firmware. If unsure, say Y here. - endmenu menu "Advanced setup" diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9b8e479..c9ae321 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -572,14 +572,6 @@ config SCHED_SMT when dealing with POWER5 cpus at a cost of slightly increased overhead in some places. If unsure say N here. -config PROC_DEVICETREE - bool "Support for device tree in /proc" - depends on PROC_FS - help - This option adds a device-tree directory under /proc which contains - an image of the device tree that the kernel copies from Open - Firmware or other boot firmware. If unsure, say Y here. - config CMDLINE_BOOL bool "Default bootloader kernel arguments" diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index ae2d4ad..6acbff3 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -7,6 +7,14 @@ config OF menu "Flattened Device Tree and Open Firmware support" depends on OF +config PROC_DEVICETREE + bool "Support for device tree in /proc" + depends on PROC_FS && !SPARC + help + This option adds a device-tree directory under /proc which contains + an image of the device tree that the kernel copies from Open + Firmware or other boot firmware. If unsure, say Y here. + config OF_FLATTREE bool select DTC -- cgit v0.10.2 From 035ebefc737cce56d3938e9b7eaa5ac0e9c28715 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Tue, 13 Jul 2010 09:42:26 +0000 Subject: of/sparc: move is_root_node() to of.h Rename is_root_node() to of_node_is_root() and make it available for all archs to use, as it's not PROM-specific. Signed-off-by: Andres Salomon Acked-by: David S. Miller Signed-off-by: Grant Likely diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h index a8591ef..eeb04a7 100644 --- a/arch/sparc/kernel/prom.h +++ b/arch/sparc/kernel/prom.h @@ -9,14 +9,6 @@ extern void irq_trans_init(struct device_node *dp); extern unsigned int prom_unique_id; -static inline int is_root_node(const struct device_node *dp) -{ - if (!dp) - return 0; - - return (dp->parent == NULL); -} - extern char *build_path_component(struct device_node *dp); extern void of_console_init(void); diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index fb06ac2..0bffafd 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include @@ -81,7 +81,7 @@ static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf) return; regs = rprop->value; - if (!is_root_node(dp->parent)) { + if (!of_node_is_root(dp->parent)) { sprintf(tmp_buf, "%s@%x,%x", dp->name, (unsigned int) (regs->phys_addr >> 32UL), @@ -121,7 +121,7 @@ static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf) return; regs = prop->value; - if (!is_root_node(dp->parent)) { + if (!of_node_is_root(dp->parent)) { sprintf(tmp_buf, "%s@%x,%x", dp->name, (unsigned int) (regs->phys_addr >> 32UL), diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 57ac9e2..1f830da 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c @@ -244,7 +244,7 @@ char * __init build_full_name(struct device_node *dp) n = prom_early_alloc(len); strcpy(n, dp->parent->full_name); - if (!is_root_node(dp->parent)) { + if (!of_node_is_root(dp->parent)) { strcpy(n + plen, "/"); plen++; } diff --git a/include/linux/of.h b/include/linux/of.h index a367e19..b0756f3 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -70,6 +70,11 @@ extern struct device_node *allnodes; extern struct device_node *of_chosen; extern rwlock_t devtree_lock; +static inline bool of_node_is_root(const struct device_node *node) +{ + return node && (node->parent == NULL); +} + static inline int of_node_check_flag(struct device_node *n, unsigned long flag) { return test_bit(flag, &n->_flags); -- cgit v0.10.2 From 596c955c126608b51ac1ca56de9d670c1f6464cb Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 14 Jul 2010 23:51:43 -0600 Subject: drivers/of: fix build error when CONFIG_PPC_DCR is set Commit 94c0931983ee9d1cd96c32d52ac64c17464f0bbd (of: Merge of_device_alloc() and of_device_make_bus_id()) moved code that does calls a dcr routine without including the correct header which causes the following build error on some powerpc configurations: drivers/of/platform.c: In function 'of_device_make_bus_id': drivers/of/platform.c:437: error: implicit declaration of function 'of_translate_dcr_address' This patch adds the appropriate header to drivers/of/platform.c Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 125f2bc..5be0080 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -19,6 +19,10 @@ #include #include +#if defined(CONFIG_PPC_DCR) +#include +#endif + extern struct device_attribute of_platform_device_attrs[]; static int of_platform_bus_match(struct device *dev, struct device_driver *drv) -- cgit v0.10.2 From f1d4c3a76981addcd7669f404f75041435a04e6a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 25 Jun 2010 12:16:52 -0600 Subject: of/flattree: Use common ALIGN() macro instead of arch specific _ALIGN There's no reason to use the powerpc-specific _ALIGN macro in the fdt code. Replace it with ALIGN() from kernel.h Signed-off-by: Grant Likely Acked-By: Jeremy Kerr Acked-by: Benjamin Herrenschmidt diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index 464ff32..2fd4761 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -39,13 +39,6 @@ #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) -/* align addr on a size boundary - adjust address up/down if needed */ -#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) -#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) - -/* align addr on a size boundary - adjust address up if needed */ -#define _ALIGN(addr, size) _ALIGN_UP(addr, size) - #ifndef CONFIG_MMU /* * PAGE_OFFSET -- the first address of the first page of memory. When not diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index b6987bb..d61fda8 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -69,9 +69,9 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, u32 sz = be32_to_cpup((__be32 *)p); p += 8; if (be32_to_cpu(initial_boot_params->version) < 0x10) - p = _ALIGN(p, sz >= 8 ? 8 : 4); + p = ALIGN(p, sz >= 8 ? 8 : 4); p += sz; - p = _ALIGN(p, 4); + p = ALIGN(p, 4); continue; } if (tag != OF_DT_BEGIN_NODE) { @@ -80,7 +80,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, } depth++; pathp = (char *)p; - p = _ALIGN(p + strlen(pathp) + 1, 4); + p = ALIGN(p + strlen(pathp) + 1, 4); if ((*pathp) == '/') { char *lp, *np; for (lp = NULL, np = pathp; *np; np++) @@ -109,7 +109,7 @@ unsigned long __init of_get_flat_dt_root(void) p += 4; BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); p += 4; - return _ALIGN(p + strlen((char *)p) + 1, 4); + return ALIGN(p + strlen((char *)p) + 1, 4); } /** @@ -138,7 +138,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name, noff = be32_to_cpup((__be32 *)(p + 4)); p += 8; if (be32_to_cpu(initial_boot_params->version) < 0x10) - p = _ALIGN(p, sz >= 8 ? 8 : 4); + p = ALIGN(p, sz >= 8 ? 8 : 4); nstr = find_flat_dt_string(noff); if (nstr == NULL) { @@ -151,7 +151,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name, return (void *)p; } p += sz; - p = _ALIGN(p, 4); + p = ALIGN(p, 4); } while (1); } @@ -184,7 +184,7 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, { void *res; - *mem = _ALIGN(*mem, align); + *mem = ALIGN(*mem, align); res = (void *)*mem; *mem += size; @@ -220,7 +220,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, *p += 4; pathp = (char *)*p; l = allocl = strlen(pathp) + 1; - *p = _ALIGN(*p + l, 4); + *p = ALIGN(*p + l, 4); /* version 0x10 has a more compact unit name here instead of the full * path. we accumulate the full path size using "fpsize", we'll rebuild @@ -299,7 +299,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, noff = be32_to_cpup((__be32 *)((*p) + 4)); *p += 8; if (be32_to_cpu(initial_boot_params->version) < 0x10) - *p = _ALIGN(*p, sz >= 8 ? 8 : 4); + *p = ALIGN(*p, sz >= 8 ? 8 : 4); pname = find_flat_dt_string(noff); if (pname == NULL) { @@ -333,7 +333,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, *prev_pp = pp; prev_pp = &pp->next; } - *p = _ALIGN((*p) + sz, 4); + *p = ALIGN((*p) + sz, 4); } /* with version 0x10 we may not have the name property, recreate * it here from the unit name if absent -- cgit v0.10.2 From 60d599133011eaca6073696f6a86cd516854d547 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:25 -0600 Subject: of/flattree: Fix crash when device tree absent This patch fixes the condition where device tree support is compiled in, but no device tree was proved by firmware. It makes of_platform_bus_probe() explicitly check for a NULL device tree pointer. Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 5be0080..c52a798 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -617,6 +617,8 @@ int of_platform_bus_probe(struct device_node *root, root = of_find_node_by_path("/"); else of_node_get(root); + if (root == NULL) + return -EINVAL; pr_debug("of_platform_bus_probe()\n"); pr_debug(" starting at: %s\n", root->full_name); -- cgit v0.10.2 From c5f5849bffb36478dd8a1e350860ff18b654bc44 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 29 Jun 2010 09:19:30 -0700 Subject: of: Remove unused of_find_device_by_phandle() Signed-off-by: Grant Likely Acked-by: Benjamin Herrenschmidt diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h index 625003f..353d8f6 100644 --- a/arch/microblaze/include/asm/of_platform.h +++ b/arch/microblaze/include/asm/of_platform.h @@ -14,8 +14,6 @@ /* This is just here during the transition */ #include -extern struct of_device *of_find_device_by_phandle(phandle ph); - extern void of_instantiate_rtc(void); #endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */ diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index a07abdd..da79edf 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -75,21 +75,3 @@ struct of_device *of_find_device_by_node(struct device_node *np) return NULL; } EXPORT_SYMBOL(of_find_device_by_node); - -static int of_dev_phandle_match(struct device *dev, void *data) -{ - phandle *ph = data; - return to_of_device(dev)->dev.of_node->phandle == *ph; -} - -struct of_device *of_find_device_by_phandle(phandle ph) -{ - struct device *dev; - - dev = bus_find_device(&of_platform_bus_type, - NULL, &ph, of_dev_phandle_match); - if (dev) - return to_of_device(dev); - return NULL; -} -EXPORT_SYMBOL(of_find_device_by_phandle); diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h index b37d2dc..d506aa6 100644 --- a/arch/powerpc/include/asm/of_platform.h +++ b/arch/powerpc/include/asm/of_platform.h @@ -11,8 +11,6 @@ * */ -extern struct of_device *of_find_device_by_phandle(phandle ph); - extern void of_instantiate_rtc(void); #endif /* _ASM_POWERPC_OF_PLATFORM_H */ diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 0b5cc6d..4e0a2f7 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -81,25 +81,6 @@ struct of_device *of_find_device_by_node(struct device_node *np) } EXPORT_SYMBOL(of_find_device_by_node); -static int of_dev_phandle_match(struct device *dev, void *data) -{ - phandle *ph = data; - return to_of_device(dev)->dev.of_node->phandle == *ph; -} - -struct of_device *of_find_device_by_phandle(phandle ph) -{ - struct device *dev; - - dev = bus_find_device(&of_platform_bus_type, - NULL, &ph, of_dev_phandle_match); - if (dev) - return to_of_device(dev); - return NULL; -} -EXPORT_SYMBOL(of_find_device_by_phandle); - - #ifdef CONFIG_PPC_OF_PLATFORM_PCI /* The probing of PCI controllers from of_platform is currently -- cgit v0.10.2 From 9e3288dc9a94fab5ea87db42177d3a9e0345a614 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:26 -0600 Subject: of/device: Fix build errors for non-ppc and non-microblaze Only powerpc and microblaze supply (struct device *)->archdata.dma_mask. This patch stops referencing it on other architectures. Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index c52a798..9d3d932 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -16,7 +16,9 @@ #include #include #include +#include #include +#include #include #if defined(CONFIG_PPC_DCR) @@ -511,7 +513,9 @@ struct of_device *of_device_alloc(struct device_node *np, } dev->dev.of_node = of_node_get(np); +#if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE) dev->dev.dma_mask = &dev->archdata.dma_mask; +#endif dev->dev.parent = parent; dev->dev.release = of_release_dev; @@ -540,7 +544,9 @@ struct of_device *of_platform_device_create(struct device_node *np, if (!dev) return NULL; +#if defined(CONFIG_PPC) || defined(CONFIG_MICROBLAZE) dev->archdata.dma_mask = 0xffffffffUL; +#endif dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); dev->dev.bus = &of_platform_bus_type; -- cgit v0.10.2 From 05212157e94ccf4cf458413bbba509cfa95ff92b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:20 -0600 Subject: drivercore/of: Add OF style matching to platform bus As part of the merge between platform bus and of_platform bus, add the ability to do of-style matching to the platform bus. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman CC: Michal Simek CC: Grant Likely CC: Benjamin Herrenschmidt CC: Stephen Rothwell CC: linux-kernel@vger.kernel.org CC: microblaze-uclinux@itee.uq.edu.au CC: linuxppc-dev@ozlabs.org CC: devicetree-discuss@lists.ozlabs.org diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 4d99c8b..fac3633 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -673,7 +674,11 @@ static int platform_match(struct device *dev, struct device_driver *drv) struct platform_device *pdev = to_platform_device(dev); struct platform_driver *pdrv = to_platform_driver(drv); - /* match against the id table first */ + /* Attempt an OF style match first */ + if (of_driver_match_device(dev, drv)) + return 1; + + /* Then try to match against the id table */ if (pdrv->id_table) return platform_match_id(pdrv->id_table, pdev) != NULL; -- cgit v0.10.2 From eca3930163ba8884060ce9d9ff5ef0d9b7c7b00f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 8 Jun 2010 07:48:21 -0600 Subject: of: Merge of_platform_bus_type with platform_bus_type of_platform_bus was being used in the same manner as the platform_bus. The only difference being that of_platform_bus devices are generated from data in the device tree, and platform_bus devices are usually statically allocated in platform code. Having them separate causes the problem of device drivers having to be registered twice if it was possible for the same device to appear on either bus. This patch removes of_platform_bus_type and registers all of_platform bus devices and drivers on the platform bus instead. A previous patch made the of_device structure an alias for the platform_device structure, and a shim is used to adapt of_platform_drivers to the platform bus. After all of of_platform_bus drivers are converted to be normal platform drivers, the shim code can be removed. Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index da79edf..fb28661 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -26,17 +26,6 @@ #include #include -struct bus_type of_platform_bus_type = { - .uevent = of_device_uevent, -}; -EXPORT_SYMBOL(of_platform_bus_type); - -static int __init of_bus_driver_init(void) -{ - return of_bus_type_init(&of_platform_bus_type, "of_platform"); -} -postcore_initcall(of_bus_driver_init); - /* * The list of OF IDs below is used for matching bus types in the * system whose devices are to be exposed as of_platform_devices. diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 17c98db..f5f7688 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = { .priority = INT_MAX, }; -static struct notifier_block dflt_of_bus_notifier = { - .notifier_call = dflt_bus_notify, - .priority = INT_MAX, -}; - static int __init setup_bus_notifier(void) { bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier); return 0; } diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 02f724f..4295e0b 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = { .priority = 0, }; -static struct notifier_block ppc_swiotlb_of_bus_notifier = { - .notifier_call = ppc_swiotlb_bus_notify, - .priority = 0, -}; - int __init swiotlb_setup_bus_notifier(void) { bus_register_notifier(&platform_bus_type, &ppc_swiotlb_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, - &ppc_swiotlb_of_bus_notifier); - return 0; } diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 4e0a2f7..d3497cd 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -52,18 +52,6 @@ const struct of_device_id of_default_bus_ids[] = { {}, }; -struct bus_type of_platform_bus_type = { - .uevent = of_device_uevent, -}; -EXPORT_SYMBOL(of_platform_bus_type); - -static int __init of_bus_driver_init(void) -{ - return of_bus_type_init(&of_platform_bus_type, "of_platform"); -} - -postcore_initcall(of_bus_driver_init); - static int of_dev_node_match(struct device *dev, void *data) { return to_of_device(dev)->dev.of_node == data; diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index b7e6c7e..d1a5304 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -701,16 +701,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = { .priority = INT_MAX, }; -static struct notifier_block ppc_dflt_of_bus_notifier = { - .notifier_call = ppc_dflt_bus_notify, - .priority = INT_MAX, -}; - static int __init setup_bus_notifier(void) { bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier); - bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier); - return 0; } diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c index 39d361c..beec405 100644 --- a/arch/powerpc/platforms/cell/beat_iommu.c +++ b/arch/powerpc/platforms/cell/beat_iommu.c @@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void) celleb_init_direct_mapping(); set_pci_dma_ops(&dma_direct_ops); ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; - bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); + bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier); return 0; } diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 3712900..58b13ce 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void) /* Register callbacks on OF platform device addition/removal * to handle linking them to the right DMA operations */ - bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); + bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier); return 0; } diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 31acd3b..1398bc4 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -20,12 +20,7 @@ #include -/* - * These functions provide the necessary setup for the mv64x60 drivers. - * These drivers are unusual in that they work on both the MIPS and PowerPC - * architectures. Because of that, the drivers do not support the normal - * PowerPC of_platform_bus_type. They support platform_bus_type instead. - */ +/* These functions provide the necessary setup for the mv64x60 drivers. */ static struct of_device_id __initdata of_mv64x60_devices[] = { { .compatible = "marvell,mv64306-devctrl", }, diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 331de91..75fc9d5 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -424,7 +424,7 @@ build_resources: build_device_resources(op, parent); op->dev.parent = parent; - op->dev.bus = &of_platform_bus_type; + op->dev.bus = &platform_bus_type; if (!parent) dev_set_name(&op->dev, "root"); else @@ -452,30 +452,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) } } -static void __init scan_of_devices(void) +static int __init scan_of_devices(void) { struct device_node *root = of_find_node_by_path("/"); struct of_device *parent; parent = scan_one_device(root, NULL); if (!parent) - return; + return 0; scan_tree(root->child, &parent->dev); + return 0; } - -static int __init of_bus_driver_init(void) -{ - int err; - - err = of_bus_type_init(&of_platform_bus_type, "of"); - if (!err) - scan_of_devices(); - - return err; -} - -postcore_initcall(of_bus_driver_init); +postcore_initcall(scan_of_devices); static int __init of_debug(char *str) { diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5e8cbb9..9743d1d 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -667,7 +667,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, 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; + op->dev.bus = &platform_bus_type; if (!parent) dev_set_name(&op->dev, "root"); else @@ -695,30 +695,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) } } -static void __init scan_of_devices(void) +static int __init scan_of_devices(void) { struct device_node *root = of_find_node_by_path("/"); struct of_device *parent; parent = scan_one_device(root, NULL); if (!parent) - return; + return 0; scan_tree(root->child, &parent->dev); + return 0; } - -static int __init of_bus_driver_init(void) -{ - int err; - - err = of_bus_type_init(&of_platform_bus_type, "of"); - if (!err) - scan_of_devices(); - - return err; -} - -postcore_initcall(of_bus_driver_init); +postcore_initcall(scan_of_devices); static int __init of_debug(char *str) { diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 016c947..01f380c 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -64,9 +64,6 @@ void of_propagate_archdata(struct of_device *bus) } } -struct bus_type of_platform_bus_type; -EXPORT_SYMBOL(of_platform_bus_type); - static void get_cells(struct device_node *dp, int *addrc, int *sizec) { if (addrc) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index fac3633..f699fab 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -636,6 +636,12 @@ static struct device_attribute platform_dev_attrs[] = { static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) { struct platform_device *pdev = to_platform_device(dev); + int rc; + + /* Some devices have extra OF data and an OF-style MODALIAS */ + rc = of_device_uevent(dev,env); + if (rc != -ENODEV) + return rc; add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX, (pdev->id_entry) ? pdev->id_entry->name : pdev->name); diff --git a/drivers/of/device.c b/drivers/of/device.c index 5282a20..12a44b4 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -104,6 +104,11 @@ int of_device_register(struct of_device *ofdev) device_initialize(&ofdev->dev); + /* name and id have to be set so that the platform bus doesn't get + * confused on matching */ + ofdev->name = dev_name(&ofdev->dev); + ofdev->id = -1; + /* device_add will assume that this device is on the same node as * the parent. If there is no parent defined, set the node * explicitly */ diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9d3d932..712dfd8 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -20,6 +20,54 @@ #include #include #include +#include + +static int platform_driver_probe_shim(struct platform_device *pdev) +{ + struct platform_driver *pdrv; + struct of_platform_driver *ofpdrv; + const struct of_device_id *match; + + pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); + ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); + match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); + return ofpdrv->probe(pdev, match); +} + +static void platform_driver_shutdown_shim(struct platform_device *pdev) +{ + struct platform_driver *pdrv; + struct of_platform_driver *ofpdrv; + + pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); + ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); + ofpdrv->shutdown(pdev); +} + +/** + * of_register_platform_driver + */ +int of_register_platform_driver(struct of_platform_driver *drv) +{ + /* setup of_platform_driver to platform_driver adaptors */ + drv->platform_driver.driver = drv->driver; + if (drv->probe) + drv->platform_driver.probe = platform_driver_probe_shim; + drv->platform_driver.remove = drv->remove; + if (drv->shutdown) + drv->platform_driver.shutdown = platform_driver_shutdown_shim; + drv->platform_driver.suspend = drv->suspend; + drv->platform_driver.resume = drv->resume; + + return platform_driver_register(&drv->platform_driver); +} +EXPORT_SYMBOL(of_register_platform_driver); + +void of_unregister_platform_driver(struct of_platform_driver *drv) +{ + platform_driver_unregister(&drv->platform_driver); +} +EXPORT_SYMBOL(of_unregister_platform_driver); #if defined(CONFIG_PPC_DCR) #include @@ -392,16 +440,29 @@ int of_bus_type_init(struct bus_type *bus, const char *name) int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { - drv->driver.bus = bus; + /* + * Temporary: of_platform_bus used to be distinct from the platform + * bus. It isn't anymore, and so drivers on the platform bus need + * to be registered in a special way. + * + * After all of_platform_bus_type drivers are converted to + * platform_drivers, this exception can be removed. + */ + if (bus == &platform_bus_type) + return of_register_platform_driver(drv); /* register with core */ + drv->driver.bus = bus; return driver_register(&drv->driver); } EXPORT_SYMBOL(of_register_driver); void of_unregister_driver(struct of_platform_driver *drv) { - driver_unregister(&drv->driver); + if (drv->driver.bus == &platform_bus_type) + of_unregister_platform_driver(drv); + else + driver_unregister(&drv->driver); } EXPORT_SYMBOL(of_unregister_driver); @@ -548,7 +609,7 @@ struct of_device *of_platform_device_create(struct device_node *np, dev->archdata.dma_mask = 0xffffffffUL; #endif dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - dev->dev.bus = &of_platform_bus_type; + dev->dev.bus = &platform_bus_type; /* We do not fill the DMA ops for platform devices by default. * This is currently the responsibility of the platform code diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 7d27f5a..8cd1fe7 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -65,6 +65,12 @@ static inline int of_driver_match_device(struct device *dev, return 0; } +static inline int of_device_uevent(struct device *dev, + struct kobj_uevent_env *env) +{ + return -ENODEV; +} + #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index a51fd30..133ecf3 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -17,19 +17,19 @@ #include #include #include +#include /* - * The of_platform_bus_type is a bus type used by drivers that do not - * attach to a macio or similar bus but still use OF probing - * mechanism + * of_platform_bus_type isn't it's own bus anymore. It's now just an alias + * for the platform bus. */ -extern struct bus_type of_platform_bus_type; +#define of_platform_bus_type platform_bus_type extern const struct of_device_id of_default_bus_ids[]; /* * An of_platform_driver driver is attached to a basic of_device on - * the "platform bus" (of_platform_bus_type). + * the "platform bus" (platform_bus_type). */ struct of_platform_driver { @@ -42,6 +42,7 @@ struct of_platform_driver int (*shutdown)(struct of_device* dev); struct device_driver driver; + struct platform_driver platform_driver; }; #define to_of_platform_driver(drv) \ container_of(drv,struct of_platform_driver, driver) @@ -51,14 +52,8 @@ extern int of_register_driver(struct of_platform_driver *drv, extern void of_unregister_driver(struct of_platform_driver *drv); /* Platform drivers register/unregister */ -static inline int of_register_platform_driver(struct of_platform_driver *drv) -{ - return of_register_driver(drv, &of_platform_bus_type); -} -static inline void of_unregister_platform_driver(struct of_platform_driver *drv) -{ - of_unregister_driver(drv); -} +extern int of_register_platform_driver(struct of_platform_driver *drv); +extern void of_unregister_platform_driver(struct of_platform_driver *drv); extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, -- cgit v0.10.2 From 1ab1d63a85cee2545272f63a7644e9f855cb65d0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 24 Jun 2010 15:14:37 -0600 Subject: of/platform: remove all of_bus_type and of_platform_bus_type references Both of_bus_type and of_platform_bus_type are just #define aliases for the platform bus. This patch removes all references to them and switches to the of_register_platform_driver()/of_unregister_platform_driver() API for registering. Subsequent patches will convert each user of of_register_platform_driver() into plain platform_drivers without the of_platform_driver shim. At which point the of_register_platform_driver()/of_unregister_platform_driver() functions can be removed. Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index fb28661..80c9c49 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -57,8 +57,7 @@ struct of_device *of_find_device_by_node(struct device_node *np) { struct device *dev; - dev = bus_find_device(&of_platform_bus_type, - NULL, np, of_dev_node_match); + dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); if (dev) return to_of_device(dev); return NULL; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index d3497cd..b093d4b 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -61,8 +61,7 @@ struct of_device *of_find_device_by_node(struct device_node *np) { struct device *dev; - dev = bus_find_device(&of_platform_bus_type, - NULL, np, of_dev_node_match); + dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); if (dev) return to_of_device(dev); return NULL; diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h index 90da990..26540dd 100644 --- a/arch/sparc/include/asm/of_platform.h +++ b/arch/sparc/include/asm/of_platform.h @@ -13,6 +13,4 @@ * */ -#define of_bus_type of_platform_bus_type /* for compatibility */ - #endif diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 0c34a87..4891fbc 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -243,9 +243,7 @@ static struct of_platform_driver ecpp_driver = { static int parport_pc_find_nonpci_ports(int autoirq, int autodma) { - of_register_driver(&ecpp_driver, &of_bus_type); - - return 0; + return of_register_platform_driver(&ecpp_driver); } #endif /* !(_ASM_SPARC64_PARPORT_H */ diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index b27476c..c471251 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -184,7 +184,7 @@ static struct of_platform_driver apc_driver = { static int __init apc_init(void) { - return of_register_driver(&apc_driver, &of_bus_type); + return of_register_platform_driver(&apc_driver); } /* This driver is not critical to the boot process diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index ddc8412..46ba58a 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -142,7 +142,7 @@ static struct of_platform_driver auxio_driver = { static int __init auxio_init(void) { - return of_register_driver(&auxio_driver, &of_platform_bus_type); + return of_register_platform_driver(&auxio_driver); } /* Must be after subsys_initcall() so that busses are probed. Must diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 434335f..b6080c3 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -265,8 +265,8 @@ static struct of_platform_driver fhc_driver = { static int __init sunfire_init(void) { - (void) of_register_driver(&fhc_driver, &of_platform_bus_type); - (void) of_register_driver(&clock_board_driver, &of_platform_bus_type); + (void) of_register_platform_driver(&fhc_driver); + (void) of_register_platform_driver(&clock_board_driver); return 0; } diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 870cb65..04bb7df 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -848,7 +848,7 @@ static int __init us3mc_init(void) ret = register_dimm_printer(us3mc_dimm_printer); if (!ret) { - ret = of_register_driver(&us3mc_driver, &of_bus_type); + ret = of_register_platform_driver(&us3mc_driver); if (ret) unregister_dimm_printer(us3mc_dimm_printer); } @@ -859,7 +859,7 @@ static void __exit us3mc_cleanup(void) { if (us3mc_platform()) { unregister_dimm_printer(us3mc_dimm_printer); - of_unregister_driver(&us3mc_driver); + of_unregister_platform_driver(&us3mc_driver); } } diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 01f380c..2a5c639 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -21,7 +21,7 @@ static int node_match(struct device *dev, void *data) struct of_device *of_find_device_by_node(struct device_node *dp) { - struct device *dev = bus_find_device(&of_platform_bus_type, NULL, + struct device *dev = bus_find_device(&platform_bus_type, NULL, dp, node_match); if (dev) diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 51cfa09..885f10b 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -518,7 +518,7 @@ static struct of_platform_driver fire_driver = { static int __init fire_init(void) { - return of_register_driver(&fire_driver, &of_bus_type); + return of_register_platform_driver(&fire_driver); } subsys_initcall(fire_init); diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 93011e6..71550a7 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -612,7 +612,7 @@ static struct of_platform_driver psycho_driver = { static int __init psycho_init(void) { - return of_register_driver(&psycho_driver, &of_bus_type); + return of_register_platform_driver(&psycho_driver); } subsys_initcall(psycho_init); diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 99c6dba..2d7bf30 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -606,7 +606,7 @@ static struct of_platform_driver sabre_driver = { static int __init sabre_init(void) { - return of_register_driver(&sabre_driver, &of_bus_type); + return of_register_platform_driver(&sabre_driver); } subsys_initcall(sabre_init); diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 9041dae..04f29c4 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1501,7 +1501,7 @@ static struct of_platform_driver schizo_driver = { static int __init schizo_init(void) { - return of_register_driver(&schizo_driver, &of_bus_type); + return of_register_platform_driver(&schizo_driver); } subsys_initcall(schizo_init); diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index a24af6f..18ee8b6 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1019,7 +1019,7 @@ static struct of_platform_driver pci_sun4v_driver = { static int __init pci_sun4v_init(void) { - return of_register_driver(&pci_sun4v_driver, &of_bus_type); + return of_register_platform_driver(&pci_sun4v_driver); } subsys_initcall(pci_sun4v_init); diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 9589d8b..a4c73ed 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -89,7 +89,7 @@ static struct of_platform_driver pmc_driver = { static int __init pmc_init(void) { - return of_register_driver(&pmc_driver, &of_bus_type); + return of_register_platform_driver(&pmc_driver); } /* This driver is not critical to the boot process diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index 1cfee57..abc194e 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -70,7 +70,7 @@ static struct of_platform_driver power_driver = { static int __init power_init(void) { - return of_register_driver(&power_driver, &of_platform_bus_type); + return of_register_platform_driver(&power_driver); } device_initcall(power_init); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index e404b06..5dc2021 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -189,7 +189,7 @@ static struct of_platform_driver clock_driver = { /* Probe for the mostek real time clock chip. */ static int __init clock_init(void) { - return of_register_driver(&clock_driver, &of_platform_bus_type); + return of_register_platform_driver(&clock_driver); } /* Must be after subsys_initcall() so that busses are probed. Must * be before device_initcall() because things like the RTC driver diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 21e9fca..2423b33 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -586,9 +586,9 @@ static int __init clock_init(void) if (tlb_type == hypervisor) return platform_device_register(&rtc_sun4v_device); - (void) of_register_driver(&rtc_driver, &of_platform_bus_type); - (void) of_register_driver(&mostek_driver, &of_platform_bus_type); - (void) of_register_driver(&bq4802_driver, &of_platform_bus_type); + (void) of_register_platform_driver(&rtc_driver); + (void) of_register_platform_driver(&mostek_driver); + (void) of_register_platform_driver(&bq4802_driver); return 0; } diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 38df87b..b7385e0 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2795,7 +2795,7 @@ static int __init fore200e_module_init(void) printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); #ifdef CONFIG_SBUS - err = of_register_driver(&fore200e_sba_driver, &of_bus_type); + err = of_register_platform_driver(&fore200e_sba_driver); if (err) return err; #endif @@ -2806,7 +2806,7 @@ static int __init fore200e_module_init(void) #ifdef CONFIG_SBUS if (err) - of_unregister_driver(&fore200e_sba_driver); + of_unregister_platform_driver(&fore200e_sba_driver); #endif return err; @@ -2818,7 +2818,7 @@ static void __exit fore200e_module_cleanup(void) pci_unregister_driver(&fore200e_pca_driver); #endif #ifdef CONFIG_SBUS - of_unregister_driver(&fore200e_sba_driver); + of_unregister_platform_driver(&fore200e_sba_driver); #endif } diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 0f9cbf1..d8a4ca8 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -762,12 +762,12 @@ static struct of_platform_driver n2rng_driver = { static int __init n2rng_init(void) { - return of_register_driver(&n2rng_driver, &of_bus_type); + return of_register_platform_driver(&n2rng_driver); } static void __exit n2rng_exit(void) { - of_unregister_driver(&n2rng_driver); + of_unregister_platform_driver(&n2rng_driver); } module_init(n2rng_init); diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 23163fd..34ac8ac 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -2070,20 +2070,20 @@ static struct of_platform_driver n2_mau_driver = { static int __init n2_init(void) { - int err = of_register_driver(&n2_crypto_driver, &of_bus_type); + int err = of_register_platform_driver(&n2_crypto_driver); if (!err) { - err = of_register_driver(&n2_mau_driver, &of_bus_type); + err = of_register_platform_driver(&n2_mau_driver); if (err) - of_unregister_driver(&n2_crypto_driver); + of_unregister_platform_driver(&n2_crypto_driver); } return err; } static void __exit n2_exit(void) { - of_unregister_driver(&n2_mau_driver); - of_unregister_driver(&n2_crypto_driver); + of_unregister_platform_driver(&n2_mau_driver); + of_unregister_platform_driver(&n2_crypto_driver); } module_init(n2_init); diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 5da5942..8964326 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -311,12 +311,12 @@ static struct of_platform_driver env_driver = { static int __init env_init(void) { - return of_register_driver(&env_driver, &of_bus_type); + return of_register_platform_driver(&env_driver); } static void __exit env_exit(void) { - of_unregister_driver(&env_driver); + of_unregister_platform_driver(&env_driver); } module_init(env_init); diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 1dacae4..f3bb92e 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -353,14 +353,12 @@ static struct of_platform_driver grover_beep_driver = { static int __init sparcspkr_init(void) { - int err = of_register_driver(&bbc_beep_driver, - &of_platform_bus_type); + int err = of_register_platform_driver(&bbc_beep_driver); if (!err) { - err = of_register_driver(&grover_beep_driver, - &of_platform_bus_type); + err = of_register_platform_driver(&grover_beep_driver); if (err) - of_unregister_driver(&bbc_beep_driver); + of_unregister_platform_driver(&bbc_beep_driver); } return err; @@ -368,8 +366,8 @@ static int __init sparcspkr_init(void) static void __exit sparcspkr_exit(void) { - of_unregister_driver(&bbc_beep_driver); - of_unregister_driver(&grover_beep_driver); + of_unregister_platform_driver(&bbc_beep_driver); + of_unregister_platform_driver(&grover_beep_driver); } module_init(sparcspkr_init); diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index c7d50ff4..cb2a24b 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -116,8 +116,7 @@ static int __init i8042_platform_init(void) if (!kbd_iobase) return -ENODEV; } else { - int err = of_register_driver(&sparc_i8042_driver, - &of_bus_type); + int err = of_register_platform_driver(&sparc_i8042_driver); if (err) return err; @@ -141,7 +140,7 @@ static inline void i8042_platform_exit(void) struct device_node *root = of_find_node_by_path("/"); if (strcmp(root->name, "SUNW,JavaStation-1")) - of_unregister_driver(&sparc_i8042_driver); + of_unregister_platform_driver(&sparc_i8042_driver); } #else /* !CONFIG_PCI */ diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 0391c25..8984236 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -160,12 +160,12 @@ static struct of_platform_driver uflash_driver = { static int __init uflash_init(void) { - return of_register_driver(&uflash_driver, &of_bus_type); + return of_register_platform_driver(&uflash_driver); } static void __exit uflash_exit(void) { - of_unregister_driver(&uflash_driver); + of_unregister_platform_driver(&uflash_driver); } module_init(uflash_init); diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index b150c10..f10476f 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2339,11 +2339,11 @@ static int __devinit emac_wait_deps(struct emac_instance *dev) deps[EMAC_DEP_MDIO_IDX].phandle = dev->mdio_ph; if (dev->blist && dev->blist > emac_boot_list) deps[EMAC_DEP_PREV_IDX].phandle = 0xffffffffu; - bus_register_notifier(&of_platform_bus_type, &emac_of_bus_notifier); + bus_register_notifier(&platform_bus_type, &emac_of_bus_notifier); wait_event_timeout(emac_probe_wait, emac_check_deps(dev, deps), EMAC_PROBE_DEP_TIMEOUT); - bus_unregister_notifier(&of_platform_bus_type, &emac_of_bus_notifier); + bus_unregister_notifier(&platform_bus_type, &emac_of_bus_notifier); err = emac_check_deps(dev, deps) ? 0 : -ENODEV; for (i = 0; i < EMAC_DEP_COUNT; i++) { if (deps[i].node) diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 370d3c1..04e552a 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1172,12 +1172,12 @@ static struct of_platform_driver myri_sbus_driver = { static int __init myri_sbus_init(void) { - return of_register_driver(&myri_sbus_driver, &of_bus_type); + return of_register_platform_driver(&myri_sbus_driver); } static void __exit myri_sbus_exit(void) { - of_unregister_driver(&myri_sbus_driver); + of_unregister_platform_driver(&myri_sbus_driver); } module_init(myri_sbus_init); diff --git a/drivers/net/niu.c b/drivers/net/niu.c index f6ecf61..8cb2b30 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -10251,14 +10251,14 @@ static int __init niu_init(void) niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT); #ifdef CONFIG_SPARC64 - err = of_register_driver(&niu_of_driver, &of_bus_type); + err = of_register_platform_driver(&niu_of_driver); #endif if (!err) { err = pci_register_driver(&niu_pci_driver); #ifdef CONFIG_SPARC64 if (err) - of_unregister_driver(&niu_of_driver); + of_unregister_platform_driver(&niu_of_driver); #endif } @@ -10269,7 +10269,7 @@ static void __exit niu_exit(void) { pci_unregister_driver(&niu_pci_driver); #ifdef CONFIG_SPARC64 - of_unregister_driver(&niu_of_driver); + of_unregister_platform_driver(&niu_of_driver); #endif } diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 0b10d24..09c071b 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1301,12 +1301,12 @@ static struct of_platform_driver bigmac_sbus_driver = { static int __init bigmac_init(void) { - return of_register_driver(&bigmac_sbus_driver, &of_bus_type); + return of_register_platform_driver(&bigmac_sbus_driver); } static void __exit bigmac_exit(void) { - of_unregister_driver(&bigmac_sbus_driver); + of_unregister_platform_driver(&bigmac_sbus_driver); } module_init(bigmac_init); diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 0a63ebe..eec443f 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3304,7 +3304,7 @@ static int __init happy_meal_sbus_init(void) { int err; - err = of_register_driver(&hme_sbus_driver, &of_bus_type); + err = of_register_platform_driver(&hme_sbus_driver); if (!err) err = quattro_sbus_register_irqs(); @@ -3313,7 +3313,7 @@ static int __init happy_meal_sbus_init(void) static void happy_meal_sbus_exit(void) { - of_unregister_driver(&hme_sbus_driver); + of_unregister_platform_driver(&hme_sbus_driver); quattro_sbus_free_irqs(); while (qfe_sbus_list) { diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index c6bfdad..ee364fa 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1558,12 +1558,12 @@ static struct of_platform_driver sunlance_sbus_driver = { /* Find all the lance cards on the system and initialize them */ static int __init sparc_lance_init(void) { - return of_register_driver(&sunlance_sbus_driver, &of_bus_type); + return of_register_platform_driver(&sunlance_sbus_driver); } static void __exit sparc_lance_exit(void) { - of_unregister_driver(&sunlance_sbus_driver); + of_unregister_platform_driver(&sunlance_sbus_driver); } module_init(sparc_lance_init); diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 4465174..5f84a5d 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -988,12 +988,12 @@ static struct of_platform_driver qec_sbus_driver = { static int __init qec_init(void) { - return of_register_driver(&qec_sbus_driver, &of_bus_type); + return of_register_platform_driver(&qec_sbus_driver); } static void __exit qec_exit(void) { - of_unregister_driver(&qec_sbus_driver); + of_unregister_platform_driver(&qec_sbus_driver); while (root_qec_dev) { struct sunqec *next = root_qec_dev->next_module; diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 3cdfe96..210a644 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -393,12 +393,12 @@ static struct of_platform_driver bpp_sbus_driver = { static int __init parport_sunbpp_init(void) { - return of_register_driver(&bpp_sbus_driver, &of_bus_type); + return of_register_platform_driver(&bpp_sbus_driver); } static void __exit parport_sunbpp_exit(void) { - of_unregister_driver(&bpp_sbus_driver); + of_unregister_platform_driver(&bpp_sbus_driver); } MODULE_AUTHOR("Derrick J Brashear"); diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 40d7a1f..3e89c31 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -425,12 +425,12 @@ static struct of_platform_driver bbc_i2c_driver = { static int __init bbc_i2c_init(void) { - return of_register_driver(&bbc_i2c_driver, &of_bus_type); + return of_register_platform_driver(&bbc_i2c_driver); } static void __exit bbc_i2c_exit(void) { - of_unregister_driver(&bbc_i2c_driver); + of_unregister_platform_driver(&bbc_i2c_driver); } module_init(bbc_i2c_init); diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 7baf1b6..8fd362e 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -277,12 +277,12 @@ static struct of_platform_driver d7s_driver = { static int __init d7s_init(void) { - return of_register_driver(&d7s_driver, &of_bus_type); + return of_register_platform_driver(&d7s_driver); } static void __exit d7s_exit(void) { - of_unregister_driver(&d7s_driver); + of_unregister_platform_driver(&d7s_driver); } module_init(d7s_init); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index c8166ec..2c76f70 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1142,12 +1142,12 @@ static struct of_platform_driver envctrl_driver = { static int __init envctrl_init(void) { - return of_register_driver(&envctrl_driver, &of_bus_type); + return of_register_platform_driver(&envctrl_driver); } static void __exit envctrl_exit(void) { - of_unregister_driver(&envctrl_driver); + of_unregister_platform_driver(&envctrl_driver); } module_init(envctrl_init); diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 368d662..d79f386 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -218,12 +218,12 @@ static struct of_platform_driver flash_driver = { static int __init flash_init(void) { - return of_register_driver(&flash_driver, &of_bus_type); + return of_register_platform_driver(&flash_driver); } static void __exit flash_cleanup(void) { - of_unregister_driver(&flash_driver); + of_unregister_platform_driver(&flash_driver); } module_init(flash_init); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index b8b40e9..57f0612 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -437,12 +437,12 @@ static struct of_platform_driver uctrl_driver = { static int __init uctrl_init(void) { - return of_register_driver(&uctrl_driver, &of_bus_type); + return of_register_platform_driver(&uctrl_driver); } static void __exit uctrl_exit(void) { - of_unregister_driver(&uctrl_driver); + of_unregister_platform_driver(&uctrl_driver); } module_init(uctrl_init); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 3f5b541..53d7ed0 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1467,12 +1467,12 @@ static struct of_platform_driver qpti_sbus_driver = { static int __init qpti_init(void) { - return of_register_driver(&qpti_sbus_driver, &of_bus_type); + return of_register_platform_driver(&qpti_sbus_driver); } static void __exit qpti_exit(void) { - of_unregister_driver(&qpti_sbus_driver); + of_unregister_platform_driver(&qpti_sbus_driver); } MODULE_DESCRIPTION("QlogicISP SBUS driver"); diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index ddc221a..89ba6fe 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -644,12 +644,12 @@ static struct of_platform_driver esp_sbus_driver = { static int __init sunesp_init(void) { - return of_register_driver(&esp_sbus_driver, &of_bus_type); + return of_register_platform_driver(&esp_sbus_driver); } static void __exit sunesp_exit(void) { - of_unregister_driver(&esp_sbus_driver); + of_unregister_platform_driver(&esp_sbus_driver); } MODULE_DESCRIPTION("Sun ESP SCSI driver"); diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 36e2448..a779e22 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -644,12 +644,12 @@ static int __init sunhv_init(void) if (tlb_type != hypervisor) return -ENODEV; - return of_register_driver(&hv_driver, &of_bus_type); + return of_register_platform_driver(&hv_driver); } static void __exit sunhv_exit(void) { - of_unregister_driver(&hv_driver); + of_unregister_platform_driver(&hv_driver); } module_init(sunhv_init); diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 0a7dd68..9845fb1 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -1130,12 +1130,12 @@ static int __init sunsab_init(void) } } - return of_register_driver(&sab_driver, &of_bus_type); + return of_register_platform_driver(&sab_driver); } static void __exit sunsab_exit(void) { - of_unregister_driver(&sab_driver); + of_unregister_platform_driver(&sab_driver); if (sunsab_reg.nr) { sunserial_unregister_minors(&sunsab_reg, sunsab_reg.nr); } diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 5deafc8..3cdf748 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1586,7 +1586,7 @@ static int __init sunsu_init(void) return err; } - err = of_register_driver(&su_driver, &of_bus_type); + err = of_register_platform_driver(&su_driver); if (err && num_uart) sunserial_unregister_minors(&sunsu_reg, num_uart); diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index fcbe20d..d1e6bcb 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1576,7 +1576,7 @@ static int __init sunzilog_init(void) goto out_free_tables; } - err = of_register_driver(&zs_driver, &of_bus_type); + err = of_register_platform_driver(&zs_driver); if (err) goto out_unregister_uart; @@ -1604,7 +1604,7 @@ out: return err; out_unregister_driver: - of_unregister_driver(&zs_driver); + of_unregister_platform_driver(&zs_driver); out_unregister_uart: if (num_sunzilog) { @@ -1619,7 +1619,7 @@ out_free_tables: static void __exit sunzilog_exit(void) { - of_unregister_driver(&zs_driver); + of_unregister_platform_driver(&zs_driver); if (zilog_irq != -1) { struct uart_sunzilog_port *up = sunzilog_irq_chain; diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 09f1b9b..c779663 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -390,12 +390,12 @@ static int __init bw2_init(void) if (fb_get_options("bw2fb", NULL)) return -ENODEV; - return of_register_driver(&bw2_driver, &of_bus_type); + return of_register_platform_driver(&bw2_driver); } static void __exit bw2_exit(void) { - of_unregister_driver(&bw2_driver); + of_unregister_platform_driver(&bw2_driver); } module_init(bw2_init); diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index e5dc224..d09fde8 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -610,12 +610,12 @@ static int __init cg14_init(void) if (fb_get_options("cg14fb", NULL)) return -ENODEV; - return of_register_driver(&cg14_driver, &of_bus_type); + return of_register_platform_driver(&cg14_driver); } static void __exit cg14_exit(void) { - of_unregister_driver(&cg14_driver); + of_unregister_platform_driver(&cg14_driver); } module_init(cg14_init); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 558d73a..64aa298 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -477,12 +477,12 @@ static int __init cg3_init(void) if (fb_get_options("cg3fb", NULL)) return -ENODEV; - return of_register_driver(&cg3_driver, &of_bus_type); + return of_register_platform_driver(&cg3_driver); } static void __exit cg3_exit(void) { - of_unregister_driver(&cg3_driver); + of_unregister_platform_driver(&cg3_driver); } module_init(cg3_init); diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 480d761..2389a71 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -870,12 +870,12 @@ static int __init cg6_init(void) if (fb_get_options("cg6fb", NULL)) return -ENODEV; - return of_register_driver(&cg6_driver, &of_bus_type); + return of_register_platform_driver(&cg6_driver); } static void __exit cg6_exit(void) { - of_unregister_driver(&cg6_driver); + of_unregister_platform_driver(&cg6_driver); } module_init(cg6_init); diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 95c0227..f6ecfab 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -1067,12 +1067,12 @@ static int __init ffb_init(void) if (fb_get_options("ffb", NULL)) return -ENODEV; - return of_register_driver(&ffb_driver, &of_bus_type); + return of_register_platform_driver(&ffb_driver); } static void __exit ffb_exit(void) { - of_unregister_driver(&ffb_driver); + of_unregister_platform_driver(&ffb_driver); } module_init(ffb_init); diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 9e8bf7d..ad67763 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -677,12 +677,12 @@ static int __init leo_init(void) if (fb_get_options("leofb", NULL)) return -ENODEV; - return of_register_driver(&leo_driver, &of_bus_type); + return of_register_platform_driver(&leo_driver); } static void __exit leo_exit(void) { - of_unregister_driver(&leo_driver); + of_unregister_platform_driver(&leo_driver); } module_init(leo_init); diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 6552751..688b055 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -367,12 +367,12 @@ static int __init p9100_init(void) if (fb_get_options("p9100fb", NULL)) return -ENODEV; - return of_register_driver(&p9100_driver, &of_bus_type); + return of_register_platform_driver(&p9100_driver); } static void __exit p9100_exit(void) { - of_unregister_driver(&p9100_driver); + of_unregister_platform_driver(&p9100_driver); } module_init(p9100_init); diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index 489b44e..7288934 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -213,12 +213,12 @@ static int __init gfb_init(void) if (fb_get_options("gfb", NULL)) return -ENODEV; - return of_register_driver(&gfb_driver, &of_bus_type); + return of_register_platform_driver(&gfb_driver); } static void __exit gfb_exit(void) { - of_unregister_driver(&gfb_driver); + of_unregister_platform_driver(&gfb_driver); } module_init(gfb_init); diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index cc039b3..f375e0d 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -526,12 +526,12 @@ static int __init tcx_init(void) if (fb_get_options("tcxfb", NULL)) return -ENODEV; - return of_register_driver(&tcx_driver, &of_bus_type); + return of_register_platform_driver(&tcx_driver); } static void __exit tcx_exit(void) { - of_unregister_driver(&tcx_driver); + of_unregister_platform_driver(&tcx_driver); } module_init(tcx_init); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 8c03fd7..30a2512 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -688,12 +688,12 @@ static struct of_platform_driver cpwd_driver = { static int __init cpwd_init(void) { - return of_register_driver(&cpwd_driver, &of_bus_type); + return of_register_platform_driver(&cpwd_driver); } static void __exit cpwd_exit(void) { - of_unregister_driver(&cpwd_driver); + of_unregister_platform_driver(&cpwd_driver); } module_init(cpwd_init); diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index 5dceedd..4082b4a 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -250,12 +250,12 @@ static struct of_platform_driver riowd_driver = { static int __init riowd_init(void) { - return of_register_driver(&riowd_driver, &of_bus_type); + return of_register_platform_driver(&riowd_driver); } static void __exit riowd_exit(void) { - of_unregister_driver(&riowd_driver); + of_unregister_platform_driver(&riowd_driver); } module_init(riowd_init); diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 133ecf3..429513a 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -19,12 +19,6 @@ #include #include -/* - * of_platform_bus_type isn't it's own bus anymore. It's now just an alias - * for the platform bus. - */ -#define of_platform_bus_type platform_bus_type - extern const struct of_device_id of_default_bus_ids[]; /* diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 43c63d4..9eb1a4e 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1075,7 +1075,7 @@ static struct of_platform_driver amd7930_sbus_driver = { static int __init amd7930_init(void) { - return of_register_driver(&amd7930_sbus_driver, &of_bus_type); + return of_register_platform_driver(&amd7930_sbus_driver); } static void __exit amd7930_exit(void) @@ -1092,7 +1092,7 @@ static void __exit amd7930_exit(void) amd7930_list = NULL; - of_unregister_driver(&amd7930_sbus_driver); + of_unregister_platform_driver(&amd7930_sbus_driver); } module_init(amd7930_init); diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index f7f05c2..68570ee 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2120,12 +2120,12 @@ static struct of_platform_driver cs4231_driver = { static int __init cs4231_init(void) { - return of_register_driver(&cs4231_driver, &of_bus_type); + return of_register_platform_driver(&cs4231_driver); } static void __exit cs4231_exit(void) { - of_unregister_driver(&cs4231_driver); + of_unregister_platform_driver(&cs4231_driver); } module_init(cs4231_init); diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 491ce71..c421901 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2699,12 +2699,12 @@ static struct of_platform_driver dbri_sbus_driver = { /* Probe for the dbri chip and then attach the driver. */ static int __init dbri_init(void) { - return of_register_driver(&dbri_sbus_driver, &of_bus_type); + return of_register_platform_driver(&dbri_sbus_driver); } static void __exit dbri_exit(void) { - of_unregister_driver(&dbri_sbus_driver); + of_unregister_platform_driver(&dbri_sbus_driver); } module_init(dbri_init); -- cgit v0.10.2 From 129ac799ad627b1e08382739f9e8cd75d7477fa3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 29 Jun 2010 09:26:53 -0700 Subject: of: remove asm/of_platform.h Only thing left in it is of_instantiate_rtc() which can be moved to asm/prom.h on PowerPC and is unused in microblaze. Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h deleted file mode 100644 index 353d8f6..0000000 --- a/arch/microblaze/include/asm/of_platform.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _ASM_MICROBLAZE_OF_PLATFORM_H -#define _ASM_MICROBLAZE_OF_PLATFORM_H - -/* This is just here during the transition */ -#include - -extern void of_instantiate_rtc(void); - -#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */ diff --git a/arch/powerpc/include/asm/of_platform.h b/arch/powerpc/include/asm/of_platform.h deleted file mode 100644 index d506aa6..0000000 --- a/arch/powerpc/include/asm/of_platform.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _ASM_POWERPC_OF_PLATFORM_H -#define _ASM_POWERPC_OF_PLATFORM_H -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -extern void of_instantiate_rtc(void); - -#endif /* _ASM_POWERPC_OF_PLATFORM_H */ diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index f864722..da7dd63 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -117,5 +117,7 @@ extern const void *of_get_mac_address(struct device_node *np); struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); +extern void of_instantiate_rtc(void); + #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h deleted file mode 100644 index 26540dd..0000000 --- a/arch/sparc/include/asm/of_platform.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef ___ASM_SPARC_OF_PLATFORM_H -#define ___ASM_SPARC_OF_PLATFORM_H -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * Modified for Sparc by merging parts of asm/of_device.h - * by Stephen Rothwell - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#endif diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 429513a..a79f59b 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -52,8 +52,6 @@ extern void of_unregister_platform_driver(struct of_platform_driver *drv); extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -#include - extern struct of_device *of_find_device_by_node(struct device_node *np); extern int of_bus_type_init(struct bus_type *bus, const char *name); -- cgit v0.10.2 From 295960429675e17ec658320ebb24385727032bed Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 29 Jun 2010 11:15:54 -0600 Subject: of: remove asm/of_device.h It is mostly unused now. Sparc has a few defines left in it, but they can be moved to other headers. Removing this header means that new architectures adding CONFIG_OF support don't need to also add this header file. Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h deleted file mode 100644 index 47e8d42..0000000 --- a/arch/microblaze/include/asm/of_device.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2007-2008 Michal Simek - * - * based on PowerPC of_device.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#ifndef _ASM_MICROBLAZE_OF_DEVICE_H -#define _ASM_MICROBLAZE_OF_DEVICE_H -#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */ diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h deleted file mode 100644 index 04f7671..0000000 --- a/arch/powerpc/include/asm/of_device.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef _ASM_POWERPC_OF_DEVICE_H -#define _ASM_POWERPC_OF_DEVICE_H -#endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index fb220e4..daa6a8a 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -19,6 +19,8 @@ struct dev_archdata { int numa_node; }; +extern void of_propagate_archdata(struct platform_device *bus); + struct pdev_archdata { struct resource resource[PROMREG_MAX]; unsigned int irqs[PROMINTR_MAX]; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h deleted file mode 100644 index 22b9828..0000000 --- a/arch/sparc/include/asm/of_device.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ASM_SPARC_OF_DEVICE_H -#define _ASM_SPARC_OF_DEVICE_H -#ifdef __KERNEL__ - -#include -#include -#include -#include - -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); - -extern void of_propagate_archdata(struct of_device *bus); - -/* This is just here during the transition */ -#include - -#endif /* __KERNEL__ */ -#endif /* _ASM_SPARC_OF_DEVICE_H */ diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index ac69574..d35df5a 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -51,6 +51,10 @@ extern void prom_build_devicetree(void); extern void of_populate_present_mask(void); extern void of_fill_in_cpu_data(void); +struct resource; +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); + /* These routines are here to provide compatibility with how powerpc * handles IRQ mapping for OF device nodes. We precompute and permanently * register them in the of_device objects, whereas powerpc computes them diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 8cd1fe7..0f19119 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -16,12 +16,12 @@ */ #define of_device platform_device #include +#include /* temporary until merge */ #ifdef CONFIG_OF_DEVICE #include #include #include -#include #define to_of_device(d) container_of(d, struct of_device, dev) -- cgit v0.10.2 From c1b6d380b781b5238989a4bfba02450057670804 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 10:36:28 -0600 Subject: of/device: Protect against binding of_platform_drivers to non-OF devices There is an unlikely chance of this situation is occurring, but it is easy to protect against. If a matching entry cannot be found in the of_match_table, then don't bind the driver. Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 712dfd8..f3f1ec8 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -30,8 +30,13 @@ static int platform_driver_probe_shim(struct platform_device *pdev) pdrv = container_of(pdev->dev.driver, struct platform_driver, driver); ofpdrv = container_of(pdrv, struct of_platform_driver, platform_driver); + + /* There is an unlikely chance that an of_platform driver might match + * on a non-OF platform device. If so, then of_match_device() will + * come up empty. Return -EINVAL in this case so other drivers get + * the chance to bind. */ match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); - return ofpdrv->probe(pdev, match); + return match ? ofpdrv->probe(pdev, match) : -EINVAL; } static void platform_driver_shutdown_shim(struct platform_device *pdev) -- cgit v0.10.2 From 94a0cb1fc61ab7a0d47d268a7764374efeb2160b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 13:59:23 -0600 Subject: of/device: Replace of_device with platform_device in includes and core code of_device is currently just an #define alias to platform_device until it gets removed entirely. This patch removes references to it from the include directories and the core drivers/of code. Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index 675e159..7ab82c8 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h @@ -38,7 +38,7 @@ struct macio_dev { struct macio_bus *bus; /* macio bus this device is on */ struct macio_dev *media_bay; /* Device is part of a media bay */ - struct of_device ofdev; + struct platform_device ofdev; struct device_dma_parameters dma_parms; /* ide needs that */ int n_resources; struct resource resource[MACIO_DEV_COUNT_RESOURCES]; diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 4f5bde6..6597ce8 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -43,7 +43,7 @@ struct sun_flpy_controller { /* You'll only ever find one controller on an Ultra anyways. */ static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; unsigned long fdc_status; -static struct of_device *floppy_op = NULL; +static struct platform_device *floppy_op = NULL; struct sun_floppy_ops { unsigned char (*fd_inb) (unsigned long port); @@ -548,7 +548,7 @@ static unsigned long __init sun_floppy_init(void) { static int initialized = 0; struct device_node *dp; - struct of_device *op; + struct platform_device *op; const char *prop; char state[128]; @@ -661,7 +661,7 @@ static unsigned long __init sun_floppy_init(void) config = 0; for (dp = ebus_dp->child; dp; dp = dp->sibling) { if (!strcmp(dp->name, "ecpp")) { - struct of_device *ecpp_op; + struct platform_device *ecpp_op; ecpp_op = of_find_device_by_node(dp); if (ecpp_op) diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 4891fbc..4f7afa0 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -103,7 +103,7 @@ static inline unsigned int get_dma_residue(unsigned int dmanr) return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); } -static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit ecpp_probe(struct platform_device *op, const struct of_device_id *match) { unsigned long base = op->resource[0].start; unsigned long config = op->resource[1].start; @@ -192,7 +192,7 @@ out_err: return err; } -static int __devexit ecpp_remove(struct of_device *op) +static int __devexit ecpp_remove(struct platform_device *op) { struct parport *p = dev_get_drvdata(&op->dev); int slot = p->dma; diff --git a/drivers/of/device.c b/drivers/of/device.c index 12a44b4..0d8a064 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -26,7 +26,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, } EXPORT_SYMBOL(of_match_device); -struct of_device *of_dev_get(struct of_device *dev) +struct platform_device *of_dev_get(struct platform_device *dev) { struct device *tmp; @@ -34,13 +34,13 @@ struct of_device *of_dev_get(struct of_device *dev) return NULL; tmp = get_device(&dev->dev); if (tmp) - return to_of_device(tmp); + return to_platform_device(tmp); else return NULL; } EXPORT_SYMBOL(of_dev_get); -void of_dev_put(struct of_device *dev) +void of_dev_put(struct platform_device *dev) { if (dev) put_device(&dev->dev); @@ -50,18 +50,18 @@ EXPORT_SYMBOL(of_dev_put); static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev; + struct platform_device *ofdev; - ofdev = to_of_device(dev); + ofdev = to_platform_device(dev); return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev; + struct platform_device *ofdev; - ofdev = to_of_device(dev); + ofdev = to_platform_device(dev); return sprintf(buf, "%s\n", ofdev->dev.of_node->name); } @@ -90,15 +90,15 @@ struct device_attribute of_platform_device_attrs[] = { */ void of_release_dev(struct device *dev) { - struct of_device *ofdev; + struct platform_device *ofdev; - ofdev = to_of_device(dev); + ofdev = to_platform_device(dev); of_node_put(ofdev->dev.of_node); kfree(ofdev); } EXPORT_SYMBOL(of_release_dev); -int of_device_register(struct of_device *ofdev) +int of_device_register(struct platform_device *ofdev) { BUG_ON(ofdev->dev.of_node == NULL); @@ -119,7 +119,7 @@ int of_device_register(struct of_device *ofdev) } EXPORT_SYMBOL(of_device_register); -void of_device_unregister(struct of_device *ofdev) +void of_device_unregister(struct platform_device *ofdev) { device_unregister(&ofdev->dev); } diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f3f1ec8..9f3840c 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -94,11 +94,11 @@ static int of_platform_device_probe(struct device *dev) { int error = -ENODEV; struct of_platform_driver *drv; - struct of_device *of_dev; + struct platform_device *of_dev; const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); + of_dev = to_platform_device(dev); if (!drv->probe) return error; @@ -116,7 +116,7 @@ static int of_platform_device_probe(struct device *dev) static int of_platform_device_remove(struct device *dev) { - struct of_device *of_dev = to_of_device(dev); + struct platform_device *of_dev = to_platform_device(dev); struct of_platform_driver *drv = to_of_platform_driver(dev->driver); if (dev->driver && drv->remove) @@ -126,7 +126,7 @@ static int of_platform_device_remove(struct device *dev) static void of_platform_device_shutdown(struct device *dev) { - struct of_device *of_dev = to_of_device(dev); + struct platform_device *of_dev = to_platform_device(dev); struct of_platform_driver *drv = to_of_platform_driver(dev->driver); if (dev->driver && drv->shutdown) @@ -137,7 +137,7 @@ static void of_platform_device_shutdown(struct device *dev) static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg) { - struct of_device *of_dev = to_of_device(dev); + struct platform_device *of_dev = to_platform_device(dev); struct of_platform_driver *drv = to_of_platform_driver(dev->driver); int ret = 0; @@ -148,7 +148,7 @@ static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg) static int of_platform_legacy_resume(struct device *dev) { - struct of_device *of_dev = to_of_device(dev); + struct platform_device *of_dev = to_platform_device(dev); struct of_platform_driver *drv = to_of_platform_driver(dev->driver); int ret = 0; @@ -543,11 +543,11 @@ static void of_device_make_bus_id(struct device *dev) * @bus_id: Name to assign to the device. May be null to use default name. * @parent: Parent device. */ -struct of_device *of_device_alloc(struct device_node *np, +struct platform_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent) { - struct of_device *dev; + struct platform_device *dev; int rc, i, num_reg = 0, num_irq = 0; struct resource *res, temp_res; @@ -600,11 +600,11 @@ EXPORT_SYMBOL(of_device_alloc); * @bus_id: name to assign device * @parent: Linux device model parent device. */ -struct of_device *of_platform_device_create(struct device_node *np, +struct platform_device *of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent) { - struct of_device *dev; + struct platform_device *dev; dev = of_device_alloc(np, bus_id, parent); if (!dev) @@ -642,7 +642,7 @@ static int of_platform_bus_create(const struct device_node *bus, struct device *parent) { struct device_node *child; - struct of_device *dev; + struct platform_device *dev; int rc = 0; for_each_child_of_node(bus, child) { @@ -678,7 +678,7 @@ int of_platform_bus_probe(struct device_node *root, struct device *parent) { struct device_node *child; - struct of_device *dev; + struct platform_device *dev; int rc = 0; if (matches == NULL) diff --git a/include/linux/of_device.h b/include/linux/of_device.h index 0f19119..e11a0be 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -39,14 +39,14 @@ static inline int of_driver_match_device(const struct device *dev, return of_match_device(drv->of_match_table, dev) != NULL; } -extern struct of_device *of_dev_get(struct of_device *dev); -extern void of_dev_put(struct of_device *dev); +extern struct platform_device *of_dev_get(struct platform_device *dev); +extern void of_dev_put(struct platform_device *dev); -extern int of_device_register(struct of_device *ofdev); -extern void of_device_unregister(struct of_device *ofdev); +extern int of_device_register(struct platform_device *ofdev); +extern void of_device_unregister(struct platform_device *ofdev); extern void of_release_dev(struct device *dev); -static inline void of_device_free(struct of_device *dev) +static inline void of_device_free(struct platform_device *dev) { of_release_dev(&dev->dev); } diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index a79f59b..b24c5a5 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -27,13 +27,13 @@ extern const struct of_device_id of_default_bus_ids[]; */ struct of_platform_driver { - int (*probe)(struct of_device* dev, + int (*probe)(struct platform_device* dev, const struct of_device_id *match); - int (*remove)(struct of_device* dev); + int (*remove)(struct platform_device* dev); - int (*suspend)(struct of_device* dev, pm_message_t state); - int (*resume)(struct of_device* dev); - int (*shutdown)(struct of_device* dev); + int (*suspend)(struct platform_device* dev, pm_message_t state); + int (*resume)(struct platform_device* dev); + int (*shutdown)(struct platform_device* dev); struct device_driver driver; struct platform_driver platform_driver; @@ -49,16 +49,16 @@ extern void of_unregister_driver(struct of_platform_driver *drv); extern int of_register_platform_driver(struct of_platform_driver *drv); extern void of_unregister_platform_driver(struct of_platform_driver *drv); -extern struct of_device *of_device_alloc(struct device_node *np, +extern struct platform_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -extern struct of_device *of_find_device_by_node(struct device_node *np); +extern struct platform_device *of_find_device_by_node(struct device_node *np); extern int of_bus_type_init(struct bus_type *bus, const char *name); #if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */ /* Platform devices and busses creation */ -extern struct of_device *of_platform_device_create(struct device_node *np, +extern struct platform_device *of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent); -- cgit v0.10.2 From a454dc50590c6d758abba016a303a221f2f1b4b8 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 15:52:34 -0600 Subject: powerpc: remove references to of_device and to_of_device of_device is just a #define alias to platform_device. This patch replaces all references to it with platform_device. Signed-off-by: Grant Likely diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 21266ab..9b626cf 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -140,19 +140,19 @@ static struct dma_map_ops ibmebus_dma_ops = { static int ibmebus_match_path(struct device *dev, void *data) { - struct device_node *dn = to_of_device(dev)->dev.of_node; + struct device_node *dn = to_platform_device(dev)->dev.of_node; return (dn->full_name && (strcasecmp((char *)data, dn->full_name) == 0)); } static int ibmebus_match_node(struct device *dev, void *data) { - return to_of_device(dev)->dev.of_node == data; + return to_platform_device(dev)->dev.of_node == data; } static int ibmebus_create_device(struct device_node *dn) { - struct of_device *dev; + struct platform_device *dev; int ret; dev = of_device_alloc(dn, NULL, &ibmebus_bus_device); @@ -298,7 +298,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus, if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path, ibmebus_match_path))) { - of_device_unregister(to_of_device(dev)); + of_device_unregister(to_platform_device(dev)); kfree(path); return count; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index b093d4b..84439d1 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -54,16 +54,16 @@ const struct of_device_id of_default_bus_ids[] = { static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->dev.of_node == data; + return to_platform_device(dev)->dev.of_node == data; } -struct of_device *of_find_device_by_node(struct device_node *np) +struct platform_device *of_find_device_by_node(struct device_node *np) { struct device *dev; dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); if (dev) - return to_of_device(dev); + return to_platform_device(dev); return NULL; } EXPORT_SYMBOL(of_find_device_by_node); @@ -76,7 +76,7 @@ EXPORT_SYMBOL(of_find_device_by_node); * lacking some bits needed here. */ -static int __devinit of_pci_phb_probe(struct of_device *dev, +static int __devinit of_pci_phb_probe(struct platform_device *dev, const struct of_device_id *match) { struct pci_controller *phb; diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 4c42246..65e2d67 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c @@ -660,7 +660,7 @@ static void psc_clks_init(void) { struct device_node *np; const u32 *cell_index; - struct of_device *ofdev; + struct platform_device *ofdev; for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { cell_index = of_get_property(np, "cell-index", NULL); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 0855e80..0dad9a9 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -147,7 +147,7 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, +static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct mpc52xx_gpiochip *chip; @@ -179,7 +179,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, return 0; } -static int mpc52xx_gpiochip_remove(struct of_device *ofdev) +static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) { return -EBUSY; } @@ -310,7 +310,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, +static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct mpc52xx_gpiochip *chip; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 5d7d607..fea833e 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -720,7 +720,7 @@ static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt, /* --------------------------------------------------------------------- * of_platform bus binding code */ -static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, +static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct mpc52xx_gpt_priv *gpt; @@ -766,7 +766,7 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, return 0; } -static int mpc52xx_gpt_remove(struct of_device *ofdev) +static int mpc52xx_gpt_remove(struct platform_device *ofdev) { return -EBUSY; } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index e86aec6..f4ac213 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -436,8 +436,8 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req) } EXPORT_SYMBOL(mpc52xx_lpbfifo_abort); -static int __devinit -mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op, + const struct of_device_id *match) { struct resource res; int rc = -ENOMEM; @@ -507,7 +507,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) } -static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op) +static int __devexit mpc52xx_lpbfifo_remove(struct platform_device *op) { if (lpbfifo.dev != &op->dev) return 0; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 9f2e52b..1565e04 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -111,7 +111,7 @@ static struct mdiobb_ctrl ep8248e_mdio_ctrl = { .ops = &ep8248e_mdio_ops, }; -static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, +static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct mii_bus *bus; @@ -154,7 +154,7 @@ err_free_bus: return ret; } -static int ep8248e_mdio_remove(struct of_device *ofdev) +static int ep8248e_mdio_remove(struct platform_device *ofdev) { BUG(); return 0; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index ebe6c35..75ae77f 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -99,7 +99,7 @@ struct pmc_type { int has_deep_sleep; }; -static struct of_device *pmc_dev; +static struct platform_device *pmc_dev; static int has_deep_sleep, deep_sleeping; static int pmc_irq; static struct mpc83xx_pmc __iomem *pmc_regs; @@ -318,7 +318,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { .end = mpc83xx_suspend_end, }; -static int pmc_probe(struct of_device *ofdev, +static int pmc_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct device_node *np = ofdev->dev.of_node; @@ -396,7 +396,7 @@ out: return ret; } -static int pmc_remove(struct of_device *ofdev) +static int pmc_remove(struct platform_device *ofdev) { return -EPERM; }; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 6257e53..9708553 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -328,7 +328,7 @@ static struct irq_host_ops msic_host_ops = { .map = msic_host_map, }; -static int axon_msi_shutdown(struct of_device *device) +static int axon_msi_shutdown(struct platform_device *device) { struct axon_msic *msic = dev_get_drvdata(&device->dev); u32 tmp; @@ -342,7 +342,7 @@ static int axon_msi_shutdown(struct of_device *device) return 0; } -static int axon_msi_probe(struct of_device *device, +static int axon_msi_probe(struct platform_device *device, const struct of_device_id *device_id) { struct device_node *dn = device->dev.of_node; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 627ee08..a5d907b 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -216,7 +216,7 @@ static int gpio_mdio_reset(struct mii_bus *bus) } -static int __devinit gpio_mdio_probe(struct of_device *ofdev, +static int __devinit gpio_mdio_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; @@ -275,7 +275,7 @@ out: } -static int gpio_mdio_remove(struct of_device *dev) +static int gpio_mdio_remove(struct platform_device *dev) { struct mii_bus *bus = dev_get_drvdata(&dev->dev); diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 402d221..2659a60 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -60,7 +60,7 @@ static int azfs_major, azfs_minor; struct axon_ram_bank { - struct of_device *device; + struct platform_device *device; struct gendisk *disk; unsigned int irq_id; unsigned long ph_addr; @@ -72,7 +72,7 @@ struct axon_ram_bank { static ssize_t axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *device = to_of_device(dev); + struct platform_device *device = to_platform_device(dev); struct axon_ram_bank *bank = device->dev.platform_data; BUG_ON(!bank); @@ -90,7 +90,7 @@ static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL); static irqreturn_t axon_ram_irq_handler(int irq, void *dev) { - struct of_device *device = dev; + struct platform_device *device = dev; struct axon_ram_bank *bank = device->dev.platform_data; BUG_ON(!bank); @@ -174,8 +174,8 @@ static const struct block_device_operations axon_ram_devops = { * axon_ram_probe - probe() method for platform driver * @device, @device_id: see of_platform_driver method */ -static int -axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) +static int axon_ram_probe(struct platform_device *device, + const struct of_device_id *device_id) { static int axon_ram_bank_id = -1; struct axon_ram_bank *bank; @@ -304,7 +304,7 @@ failed: * @device: see of_platform_driver method */ static int -axon_ram_remove(struct of_device *device) +axon_ram_remove(struct platform_device *device) { struct axon_ram_bank *bank = device->dev.platform_data; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index a7c5c47..6502561 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -365,8 +365,8 @@ bcom_engine_cleanup(void) /* OF platform driver */ /* ======================================================================== */ -static int __devinit -mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit mpc52xx_bcom_probe(struct platform_device *op, + const struct of_device_id *match) { struct device_node *ofn_sram; struct resource res_bcom; @@ -461,8 +461,7 @@ error_ofput: } -static int -mpc52xx_bcom_remove(struct of_device *op) +static int mpc52xx_bcom_remove(struct platform_device *op) { /* Clean up the engine */ bcom_engine_cleanup(); diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 962c2d8..87991d3 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -250,7 +250,7 @@ unlock: raw_spin_unlock(&desc->lock); } -static int fsl_of_msi_remove(struct of_device *ofdev) +static int fsl_of_msi_remove(struct platform_device *ofdev) { struct fsl_msi *msi = ofdev->dev.platform_data; int virq, i; @@ -274,7 +274,7 @@ static int fsl_of_msi_remove(struct of_device *ofdev) return 0; } -static int __devinit fsl_of_msi_probe(struct of_device *dev, +static int __devinit fsl_of_msi_probe(struct platform_device *dev, const struct of_device_id *match) { struct fsl_msi *msi; diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 9082eb9..44de855 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -58,7 +58,8 @@ static struct platform_suspend_ops pmc_suspend_ops = { .enter = pmc_suspend_enter, }; -static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) +static int pmc_probe(struct platform_device *ofdev, + const struct of_device_id *id) { pmc_regs = of_iomap(ofdev->dev.of_node, 0); if (!pmc_regs) diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 30e1626..8bd8653 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1338,7 +1338,7 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr) * master port with system-specific info, and registers the * master port with the RapidIO subsystem. */ -int fsl_rio_setup(struct of_device *dev) +int fsl_rio_setup(struct platform_device *dev) { struct rio_ops *ops; struct rio_mport *port; @@ -1536,7 +1536,7 @@ err_ops: /* The probe function for RapidIO peer-to-peer network. */ -static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, +static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev, const struct of_device_id *match) { int rc; diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index d07137a..24a0bb9 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -43,7 +43,7 @@ struct pmi_data { struct mutex msg_mutex; pmi_message_t msg; struct completion *completion; - struct of_device *dev; + struct platform_device *dev; int irq; u8 __iomem *pmi_reg; struct work_struct work; @@ -121,7 +121,7 @@ static void pmi_notify_handlers(struct work_struct *work) spin_unlock(&data->handler_spinlock); } -static int pmi_of_probe(struct of_device *dev, +static int pmi_of_probe(struct platform_device *dev, const struct of_device_id *match) { struct device_node *np = dev->dev.of_node; @@ -185,7 +185,7 @@ out: return rc; } -static int pmi_of_remove(struct of_device *dev) +static int pmi_of_remove(struct platform_device *dev) { struct pmi_handler *handler, *tmp; diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 093e0ae..3da8014 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -651,14 +651,15 @@ unsigned int qe_get_num_of_snums(void) EXPORT_SYMBOL(qe_get_num_of_snums); #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) -static int qe_resume(struct of_device *ofdev) +static int qe_resume(struct platform_device *ofdev) { if (!qe_alive_during_sleep()) qe_reset(); return 0; } -static int qe_probe(struct of_device *ofdev, const struct of_device_id *id) +static int qe_probe(struct platform_device *ofdev, + const struct of_device_id *id) { return 0; } -- cgit v0.10.2 From cd4cd7306a403f62ef3ca783b9d1cf2a03e595ed Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 16:04:30 -0600 Subject: sparc: remove references to of_device and to_of_device of_device is just a #define alias to platform_device. This patch replaces all references to it with platform_device. Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index d35df5a..c82a7da 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -57,7 +57,7 @@ extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long s /* These routines are here to provide compatibility with how powerpc * handles IRQ mapping for OF device nodes. We precompute and permanently - * register them in the of_device objects, whereas powerpc computes them + * register them in the platform_device objects, whereas powerpc computes them * on request. */ static inline void irq_dispose_mapping(unsigned int virq) diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index c471251..2c0046e 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -68,7 +68,7 @@ static void apc_swift_idle(void) #endif } -static inline void apc_free(struct of_device *op) +static inline void apc_free(struct platform_device *op) { of_iounmap(&op->resource[0], regs, resource_size(&op->resource[0])); } @@ -136,7 +136,7 @@ static const struct file_operations apc_fops = { static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; -static int __devinit apc_probe(struct of_device *op, +static int __devinit apc_probe(struct platform_device *op, const struct of_device_id *match) { int err; diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 46ba58a..3efd3c5 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -102,7 +102,8 @@ static struct of_device_id __initdata auxio_match[] = { MODULE_DEVICE_TABLE(of, auxio_match); -static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match) +static int __devinit auxio_probe(struct platform_device *dev, + const struct of_device_id *match) { struct device_node *dp = dev->dev.of_node; unsigned long size; diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index b6080c3..cfa2624 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -59,7 +59,7 @@ static int __devinit clock_board_calc_nslots(struct clock_board *p) } } -static int __devinit clock_board_probe(struct of_device *op, +static int __devinit clock_board_probe(struct platform_device *op, const struct of_device_id *match) { struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL); @@ -157,7 +157,7 @@ static struct of_platform_driver clock_board_driver = { }, }; -static int __devinit fhc_probe(struct of_device *op, +static int __devinit fhc_probe(struct platform_device *op, const struct of_device_id *match) { struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL); diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 04bb7df..08c466e 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -392,7 +392,7 @@ static void __devinit jbusmc_construct_dimm_groups(struct jbusmc *p, } } -static int __devinit jbusmc_probe(struct of_device *op, +static int __devinit jbusmc_probe(struct platform_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *mem_regs; @@ -690,7 +690,7 @@ static void chmc_fetch_decode_regs(struct chmc *p) chmc_read_mcreg(p, CHMCTRL_DECODE4)); } -static int __devinit chmc_probe(struct of_device *op, +static int __devinit chmc_probe(struct platform_device *op, const struct of_device_id *match) { struct device_node *dp = op->dev.of_node; @@ -765,7 +765,7 @@ out_free: goto out; } -static int __devinit us3mc_probe(struct of_device *op, +static int __devinit us3mc_probe(struct platform_device *op, const struct of_device_id *match) { if (mc_type == MC_TYPE_SAFARI) @@ -775,21 +775,21 @@ static int __devinit us3mc_probe(struct of_device *op, return -ENODEV; } -static void __devexit chmc_destroy(struct of_device *op, struct chmc *p) +static void __devexit chmc_destroy(struct platform_device *op, struct chmc *p) { list_del(&p->list); of_iounmap(&op->resource[0], p->regs, 0x48); kfree(p); } -static void __devexit jbusmc_destroy(struct of_device *op, struct jbusmc *p) +static void __devexit jbusmc_destroy(struct platform_device *op, struct jbusmc *p) { mc_list_del(&p->list); of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE); kfree(p); } -static int __devexit us3mc_remove(struct of_device *op) +static int __devexit us3mc_remove(struct platform_device *op) { void *p = dev_get_drvdata(&op->dev); diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 703e4aa..41f7e4e 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -253,7 +253,7 @@ EXPORT_SYMBOL(sbus_set_sbus64); static void *sbus_alloc_coherent(struct device *dev, size_t len, dma_addr_t *dma_addrp, gfp_t gfp) { - struct of_device *op = to_of_device(dev); + struct platform_device *op = to_platform_device(dev); unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; unsigned long va; struct resource *res; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 75fc9d5..2d055a1 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -241,10 +241,10 @@ static int __init use_1to1_mapping(struct device_node *pp) static int of_resource_verbose; -static void __init build_device_resources(struct of_device *op, +static void __init build_device_resources(struct platform_device *op, struct device *parent) { - struct of_device *p_op; + struct platform_device *p_op; struct of_bus *bus; int na, ns; int index, num_reg; @@ -253,7 +253,7 @@ static void __init build_device_resources(struct of_device *op, if (!parent) return; - p_op = to_of_device(parent); + p_op = to_platform_device(parent); bus = of_match_bus(p_op->dev.of_node); bus->count_cells(op->dev.of_node, &na, &ns); @@ -335,10 +335,10 @@ static void __init build_device_resources(struct of_device *op, } } -static struct of_device * __init scan_one_device(struct device_node *dp, +static struct platform_device * __init scan_one_device(struct device_node *dp, struct device *parent) { - struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); + struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); const struct linux_prom_irqs *intr; struct dev_archdata *sd; int len, i; @@ -443,7 +443,7 @@ build_resources: static void __init scan_tree(struct device_node *dp, struct device *parent) { while (dp) { - struct of_device *op = scan_one_device(dp, parent); + struct platform_device *op = scan_one_device(dp, parent); if (op) scan_tree(dp->child, &op->dev); @@ -455,7 +455,7 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) static int __init scan_of_devices(void) { struct device_node *root = of_find_node_by_path("/"); - struct of_device *parent; + struct platform_device *parent; parent = scan_one_device(root, NULL); if (!parent) diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 9743d1d..63cd4e5 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -310,10 +310,10 @@ static int __init use_1to1_mapping(struct device_node *pp) static int of_resource_verbose; -static void __init build_device_resources(struct of_device *op, +static void __init build_device_resources(struct platform_device *op, struct device *parent) { - struct of_device *p_op; + struct platform_device *p_op; struct of_bus *bus; int na, ns; int index, num_reg; @@ -322,7 +322,7 @@ static void __init build_device_resources(struct of_device *op, if (!parent) return; - p_op = to_of_device(parent); + p_op = to_platform_device(parent); bus = of_match_bus(p_op->dev.of_node); bus->count_cells(op->dev.of_node, &na, &ns); @@ -528,7 +528,7 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp, static int of_irq_verbose; -static unsigned int __init build_one_device_irq(struct of_device *op, +static unsigned int __init build_one_device_irq(struct platform_device *op, struct device *parent, unsigned int irq) { @@ -630,10 +630,10 @@ out: return irq; } -static struct of_device * __init scan_one_device(struct device_node *dp, +static struct platform_device * __init scan_one_device(struct device_node *dp, struct device *parent) { - struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); + struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); const unsigned int *irq; struct dev_archdata *sd; int len, i; @@ -686,7 +686,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, static void __init scan_tree(struct device_node *dp, struct device *parent) { while (dp) { - struct of_device *op = scan_one_device(dp, parent); + struct platform_device *op = scan_one_device(dp, parent); if (op) scan_tree(dp->child, &op->dev); @@ -698,7 +698,7 @@ static void __init scan_tree(struct device_node *dp, struct device *parent) static int __init scan_of_devices(void) { struct device_node *root = of_find_node_by_path("/"); - struct of_device *parent; + struct platform_device *parent; parent = scan_one_device(root, NULL); if (!parent) diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 2a5c639..e80729b 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -13,19 +13,19 @@ static int node_match(struct device *dev, void *data) { - struct of_device *op = to_of_device(dev); + struct platform_device *op = to_platform_device(dev); struct device_node *dp = data; return (op->dev.of_node == dp); } -struct of_device *of_find_device_by_node(struct device_node *dp) +struct platform_device *of_find_device_by_node(struct device_node *dp) { struct device *dev = bus_find_device(&platform_bus_type, NULL, dp, node_match); if (dev) - return to_of_device(dev); + return to_platform_device(dev); return NULL; } @@ -33,7 +33,7 @@ EXPORT_SYMBOL(of_find_device_by_node); unsigned int irq_of_parse_and_map(struct device_node *node, int index) { - struct of_device *op = of_find_device_by_node(node); + struct platform_device *op = of_find_device_by_node(node); if (!op || index >= op->archdata.num_irqs) return 0; @@ -43,16 +43,16 @@ unsigned int irq_of_parse_and_map(struct device_node *node, int index) EXPORT_SYMBOL(irq_of_parse_and_map); /* Take the archdata values for IOMMU, STC, and HOSTDATA found in - * BUS and propagate to all child of_device objects. + * BUS and propagate to all child platform_device objects. */ -void of_propagate_archdata(struct of_device *bus) +void of_propagate_archdata(struct platform_device *bus) { struct dev_archdata *bus_sd = &bus->dev.archdata; struct device_node *bus_dp = bus->dev.of_node; struct device_node *dp; for (dp = bus_dp->child; dp; dp = dp->sibling) { - struct of_device *op = of_find_device_by_node(dp); + struct platform_device *op = of_find_device_by_node(dp); op->dev.archdata.iommu = bus_sd->iommu; op->dev.archdata.stc = bus_sd->stc; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 1523290..4137579 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -198,7 +198,7 @@ static unsigned long pci_parse_of_flags(u32 addr0) * into physical address resources, we only have to figure out the register * mapping. */ -static void pci_parse_of_addrs(struct of_device *op, +static void pci_parse_of_addrs(struct platform_device *op, struct device_node *node, struct pci_dev *dev) { @@ -248,7 +248,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, { struct dev_archdata *sd; struct pci_slot *slot; - struct of_device *op; + struct platform_device *op; struct pci_dev *dev; const char *type; u32 class; diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 885f10b..efb896d 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -410,7 +410,7 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) } static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, u32 portid) + struct platform_device *op, u32 portid) { const struct linux_prom64_registers *regs; struct device_node *dp = op->dev.of_node; @@ -455,7 +455,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, return 0; } -static int __devinit fire_probe(struct of_device *op, +static int __devinit fire_probe(struct platform_device *op, const struct of_device_id *match) { struct device_node *dp = op->dev.of_node; diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 0318682..e20ed5f 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -91,7 +91,7 @@ struct pci_pbm_info { char *name; /* OBP specific information. */ - struct of_device *op; + struct platform_device *op; u64 ino_bitmap; /* PBM I/O and Memory space resources. */ diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 71550a7..22eab7c 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -285,7 +285,7 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ static void psycho_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); + struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node); unsigned long base = pbm->controller_regs; u64 tmp; int err; @@ -483,7 +483,7 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, int is_pbm_a) + struct platform_device *op, int is_pbm_a) { psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO); psycho_pbm_strbuf_init(pbm, is_pbm_a); @@ -503,7 +503,7 @@ static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid) #define PSYCHO_CONFIGSPACE 0x001000000UL -static int __devinit psycho_probe(struct of_device *op, +static int __devinit psycho_probe(struct platform_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 2d7bf30..5c3f5ec 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -311,7 +311,7 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) static void sabre_register_error_handlers(struct pci_pbm_info *pbm) { struct device_node *dp = pbm->op->dev.of_node; - struct of_device *op; + struct platform_device *op; unsigned long base = pbm->controller_regs; u64 tmp; int err; @@ -443,7 +443,7 @@ static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm, } static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op) + struct platform_device *op) { psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE); pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR; @@ -452,7 +452,7 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, sabre_scan_bus(pbm, &op->dev); } -static int __devinit sabre_probe(struct of_device *op, +static int __devinit sabre_probe(struct platform_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 04f29c4..445a47a 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -844,7 +844,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) */ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); + struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -939,7 +939,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) static void schizo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); + struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -1307,7 +1307,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, u32 portid, + struct platform_device *op, u32 portid, int chip_type) { const struct linux_prom64_registers *regs; @@ -1413,7 +1413,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, return NULL; } -static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) +static int __devinit __schizo_init(struct platform_device *op, unsigned long chip_type) { struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; @@ -1460,7 +1460,7 @@ out_err: return err; } -static int __devinit schizo_probe(struct of_device *op, +static int __devinit schizo_probe(struct platform_device *op, const struct of_device_id *match) { return __schizo_init(op, (unsigned long) match->data); diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 18ee8b6..743344a 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -879,7 +879,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) #endif /* !(CONFIG_PCI_MSI) */ static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, - struct of_device *op, u32 devhandle) + struct platform_device *op, u32 devhandle) { struct device_node *dp = op->dev.of_node; int err; @@ -918,7 +918,7 @@ static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, return 0; } -static int __devinit pci_sun4v_probe(struct of_device *op, +static int __devinit pci_sun4v_probe(struct platform_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *regs; diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index a4c73ed..94536a8 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -51,7 +51,7 @@ static void pmc_swift_idle(void) #endif } -static int __devinit pmc_probe(struct of_device *op, +static int __devinit pmc_probe(struct platform_device *op, const struct of_device_id *match) { regs = of_ioremap(&op->resource[0], 0, diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index abc194e..2c59f4d 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -33,7 +33,7 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node * return 1; } -static int __devinit power_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit power_probe(struct platform_device *op, const struct of_device_id *match) { struct resource *res = &op->resource[0]; unsigned int irq = op->archdata.irqs[0]; diff --git a/arch/sparc/kernel/prom_irqtrans.c b/arch/sparc/kernel/prom_irqtrans.c index 5702ad4..ce65114 100644 --- a/arch/sparc/kernel/prom_irqtrans.c +++ b/arch/sparc/kernel/prom_irqtrans.c @@ -719,7 +719,7 @@ static unsigned int central_build_irq(struct device_node *dp, void *_data) { struct device_node *central_dp = _data; - struct of_device *central_op = of_find_device_by_node(central_dp); + struct platform_device *central_op = of_find_device_by_node(central_dp); struct resource *res; unsigned long imap, iclr; u32 tmp; diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c index 3f34ac8..fe2af66 100644 --- a/arch/sparc/kernel/psycho_common.c +++ b/arch/sparc/kernel/psycho_common.c @@ -447,7 +447,7 @@ int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, } -void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct of_device *op, +void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct platform_device *op, const char *chip_name, int chip_type) { struct device_node *dp = op->dev.of_node; diff --git a/arch/sparc/kernel/psycho_common.h b/arch/sparc/kernel/psycho_common.h index 092c278..590b4ed 100644 --- a/arch/sparc/kernel/psycho_common.h +++ b/arch/sparc/kernel/psycho_common.h @@ -42,7 +42,7 @@ extern int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, unsigned long write_complete_offset); extern void psycho_pbm_init_common(struct pci_pbm_info *pbm, - struct of_device *op, + struct platform_device *op, const char *chip_name, int chip_type); #endif /* _PSYCHO_COMMON_H */ diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index cfeaf04..2ca32d1 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -57,7 +57,7 @@ void sbus_set_sbus64(struct device *dev, int bursts) { struct iommu *iommu = dev->archdata.iommu; - struct of_device *op = to_of_device(dev); + struct platform_device *op = to_platform_device(dev); const struct linux_prom_registers *regs; unsigned long cfg_reg; int slot; @@ -204,7 +204,7 @@ static unsigned long sysio_imap_to_iclr(unsigned long imap) return imap + diff; } -static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino) +static unsigned int sbus_build_irq(struct platform_device *op, unsigned int ino) { struct iommu *iommu = op->dev.archdata.iommu; unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; @@ -267,7 +267,7 @@ static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino) #define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) { - struct of_device *op = dev_id; + struct platform_device *op = dev_id; struct iommu *iommu = op->dev.archdata.iommu; unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; unsigned long afsr_reg, afar_reg; @@ -341,7 +341,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) #define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) { - struct of_device *op = dev_id; + struct platform_device *op = dev_id; struct iommu *iommu = op->dev.archdata.iommu; unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; unsigned long afsr_reg, afar_reg; @@ -420,7 +420,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) #define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) { - struct of_device *op = dev_id; + struct platform_device *op = dev_id; struct iommu *iommu = op->dev.archdata.iommu; unsigned long afsr_reg, afar_reg, reg_base; unsigned long afsr, afar, error_bits; @@ -488,7 +488,7 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) #define SYSIO_CE_INO 0x35 #define SYSIO_SBUSERR_INO 0x36 -static void __init sysio_register_error_handlers(struct of_device *op) +static void __init sysio_register_error_handlers(struct platform_device *op) { struct iommu *iommu = op->dev.archdata.iommu; unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; @@ -534,7 +534,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) } /* Boot time initialization. */ -static void __init sbus_iommu_init(struct of_device *op) +static void __init sbus_iommu_init(struct platform_device *op) { const struct linux_prom64_registers *pr; struct device_node *dp = op->dev.of_node; @@ -663,7 +663,7 @@ static int __init sbus_init(void) struct device_node *dp; for_each_node_by_name(dp, "sbus") { - struct of_device *op = of_find_device_by_node(dp); + struct platform_device *op = of_find_device_by_node(dp); sbus_iommu_init(op); of_propagate_archdata(op); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 5dc2021..9c743b1 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -142,7 +142,7 @@ static struct platform_device m48t59_rtc = { }, }; -static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit clock_probe(struct platform_device *op, const struct of_device_id *match) { struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 2423b33..3bc9c99 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -419,7 +419,7 @@ static struct platform_device rtc_cmos_device = { .num_resources = 1, }; -static int __devinit rtc_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit rtc_probe(struct platform_device *op, const struct of_device_id *match) { struct resource *r; @@ -477,7 +477,7 @@ static struct platform_device rtc_bq4802_device = { .num_resources = 1, }; -static int __devinit bq4802_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit bq4802_probe(struct platform_device *op, const struct of_device_id *match) { printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", @@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = { }, }; -static int __devinit mostek_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit mostek_probe(struct platform_device *op, const struct of_device_id *match) { struct device_node *dp = op->dev.of_node; diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 005e758..fc58c3e 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -35,7 +35,7 @@ #define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID) #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) -static void __init iounit_iommu_init(struct of_device *op) +static void __init iounit_iommu_init(struct platform_device *op) { struct iounit_struct *iounit; iopte_t *xpt, *xptend; @@ -74,7 +74,7 @@ static int __init iounit_init(void) struct device_node *dp; for_each_node_by_name(dp, "sbi") { - struct of_device *op = of_find_device_by_node(dp); + struct platform_device *op = of_find_device_by_node(dp); iounit_iommu_init(op); of_propagate_archdata(op); diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index b2e6e73..73858066 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -56,7 +56,7 @@ static pgprot_t dvma_prot; /* Consistent mapping pte flags */ #define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID) #define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ) -static void __init sbus_iommu_init(struct of_device *op) +static void __init sbus_iommu_init(struct platform_device *op) { struct iommu_struct *iommu; unsigned int impl, vers; @@ -132,7 +132,7 @@ static int __init iommu_init(void) struct device_node *dp; for_each_node_by_name(dp, "iommu") { - struct of_device *op = of_find_device_by_node(dp); + struct platform_device *op = of_find_device_by_node(dp); sbus_iommu_init(op); of_propagate_archdata(op); -- cgit v0.10.2 From de48e369e8ea3a773cb2f959b76fcfad9966f4a0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 22 Jul 2010 16:10:32 -0600 Subject: microblaze: remove references to of_device and to_of_device of_device is just a #define alias to platform_device. This patch replaces all references to it with platform_device. Signed-off-by: Grant Likely diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index 80c9c49..c664b27 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -50,16 +50,16 @@ const struct of_device_id of_default_bus_ids[] = { static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->dev.of_node == data; + return to_platform_device(dev)->dev.of_node == data; } -struct of_device *of_find_device_by_node(struct device_node *np) +struct platform_device *of_find_device_by_node(struct device_node *np) { struct device *dev; dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); if (dev) - return to_of_device(dev); + return to_platform_device(dev); return NULL; } EXPORT_SYMBOL(of_find_device_by_node); -- cgit v0.10.2 From c608558407aa64d2b98d58bfc116e95c0afb357e Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Fri, 23 Jul 2010 19:19:35 +0200 Subject: of: make of_find_device_by_node generic There's no need for this function to be architecture specific and all four architectures defining it had the same definition. The function has been moved to drivers/of/platform.c. Signed-off-by: Jonas Bonn [grant.likely@secretlab.ca: moved to drivers/of/platform.c, simplified code, and added kerneldoc comment] Signed-off-by: Grant Likely Acked-by: David S. Miller diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index c664b27..6cffadb 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -47,19 +47,3 @@ const struct of_device_id of_default_bus_ids[] = { { .type = "simple", }, {}, }; - -static int of_dev_node_match(struct device *dev, void *data) -{ - return to_platform_device(dev)->dev.of_node == data; -} - -struct platform_device *of_find_device_by_node(struct device_node *np) -{ - struct device *dev; - - dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); - if (dev) - return to_platform_device(dev); - return NULL; -} -EXPORT_SYMBOL(of_find_device_by_node); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 84439d1..760a7af 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -52,22 +52,6 @@ const struct of_device_id of_default_bus_ids[] = { {}, }; -static int of_dev_node_match(struct device *dev, void *data) -{ - return to_platform_device(dev)->dev.of_node == data; -} - -struct platform_device *of_find_device_by_node(struct device_node *np) -{ - struct device *dev; - - dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); - if (dev) - return to_platform_device(dev); - return NULL; -} -EXPORT_SYMBOL(of_find_device_by_node); - #ifdef CONFIG_PPC_OF_PLATFORM_PCI /* The probing of PCI controllers from of_platform is currently diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index e80729b..49ddff5 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -11,26 +11,6 @@ #include "of_device_common.h" -static int node_match(struct device *dev, void *data) -{ - struct platform_device *op = to_platform_device(dev); - struct device_node *dp = data; - - return (op->dev.of_node == dp); -} - -struct platform_device *of_find_device_by_node(struct device_node *dp) -{ - struct device *dev = bus_find_device(&platform_bus_type, NULL, - dp, node_match); - - if (dev) - return to_platform_device(dev); - - return NULL; -} -EXPORT_SYMBOL(of_find_device_by_node); - unsigned int irq_of_parse_and_map(struct device_node *node, int index) { struct platform_device *op = of_find_device_by_node(node); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9f3840c..f79f40b 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -22,6 +22,26 @@ #include #include +static int of_dev_node_match(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +/** + * of_find_device_by_node - Find the platform_device associated with a node + * @np: Pointer to device tree node + * + * Returns platform_device pointer, or NULL if not found + */ +struct platform_device *of_find_device_by_node(struct device_node *np) +{ + struct device *dev; + + dev = bus_find_device(&platform_bus_type, NULL, np, of_dev_node_match); + return dev ? to_platform_device(dev) : NULL; +} +EXPORT_SYMBOL(of_find_device_by_node); + static int platform_driver_probe_shim(struct platform_device *pdev) { struct platform_driver *pdrv; -- cgit v0.10.2 From c0dd394ca5e78649b7013c3ce2d6338af9f228f0 Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Fri, 23 Jul 2010 20:19:24 +0200 Subject: of: remove of_default_bus_ids This list used was by only two platforms with all other platforms defining an own list of valid bus id's to pass to of_platform_bus_probe. This patch: i) copies the default list to the two platforms that depended on it (powerpc) ii) remove the usage of of_default_bus_ids in of_platform_bus_probe iii) removes the definition of the list from all architectures that defined it Passing a NULL 'matches' parameter to of_platform_bus_probe is still valid; the function returns no error in that case as the NULL value is equivalent to an empty list. Signed-off-by: Jonas Bonn [grant.likely@secretlab.ca: added __initdata annotations, warn on and return error on missing match table, and fix whitespace errors] Signed-off-by: Grant Likely diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index 727e2cb..7fcc5f7 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -16,7 +16,7 @@ extra-y := head.o vmlinux.lds obj-y += dma.o exceptions.o \ hw_exception_handler.o init_task.o intc.o irq.o \ - of_platform.o process.o prom.o prom_parse.o ptrace.o \ + process.o prom.o prom_parse.o ptrace.o \ setup.o signal.o sys_microblaze.o timer.o traps.o reset.o obj-y += cpu/ diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c deleted file mode 100644 index 6cffadb..0000000 --- a/arch/microblaze/kernel/of_platform.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. - * - * and Arnd Bergmann, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* - * The list of OF IDs below is used for matching bus types in the - * system whose devices are to be exposed as of_platform_devices. - * - * This is the default list valid for most platforms. This file provides - * functions who can take an explicit list if necessary though - * - * The search is always performed recursively looking for children of - * the provided device_node and recursively if such a children matches - * a bus type in the list - */ - -const struct of_device_id of_default_bus_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .type = "plb5", }, - { .type = "plb4", }, - { .type = "opb", }, - { .type = "simple", }, - {}, -}; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 760a7af..b2c363e 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -28,30 +28,6 @@ #include #include -/* - * The list of OF IDs below is used for matching bus types in the - * system whose devices are to be exposed as of_platform_devices. - * - * This is the default list valid for most platforms. This file provides - * functions who can take an explicit list if necessary though - * - * The search is always performed recursively looking for children of - * the provided device_node and recursively if such a children matches - * a bus type in the list - */ - -const struct of_device_id of_default_bus_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .type = "spider", }, - { .type = "axon", }, - { .type = "plb5", }, - { .type = "plb4", }, - { .type = "opb", }, - { .type = "ebc", }, - {}, -}; - #ifdef CONFIG_PPC_OF_PLATFORM_PCI /* The probing of PCI controllers from of_platform is currently diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c index c5ce02e..1b57490 100644 --- a/arch/powerpc/platforms/cell/qpace_setup.c +++ b/arch/powerpc/platforms/cell/qpace_setup.c @@ -61,12 +61,24 @@ static void qpace_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } +static const struct of_device_id qpace_bus_ids[] __initdata = { + { .type = "soc", }, + { .compatible = "soc", }, + { .type = "spider", }, + { .type = "axon", }, + { .type = "plb5", }, + { .type = "plb4", }, + { .type = "opb", }, + { .type = "ebc", }, + {}, +}; + static int __init qpace_publish_devices(void) { int node; /* Publish OF platform devices for southbridge IOs */ - of_platform_bus_probe(NULL, NULL, NULL); + of_platform_bus_probe(NULL, qpace_bus_ids, NULL); /* There is no device for the MIC memory controller, thus we create * a platform device for it to attach the EDAC driver to. diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 50385db..6919957 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -141,6 +141,18 @@ static int __devinit cell_setup_phb(struct pci_controller *phb) return 0; } +static const struct of_device_id cell_bus_ids[] __initdata = { + { .type = "soc", }, + { .compatible = "soc", }, + { .type = "spider", }, + { .type = "axon", }, + { .type = "plb5", }, + { .type = "plb4", }, + { .type = "opb", }, + { .type = "ebc", }, + {}, +}; + static int __init cell_publish_devices(void) { struct device_node *root = of_find_node_by_path("/"); @@ -148,7 +160,7 @@ static int __init cell_publish_devices(void) int node; /* Publish OF platform devices for southbridge IOs */ - of_platform_bus_probe(NULL, NULL, NULL); + of_platform_bus_probe(NULL, cell_bus_ids, NULL); /* On spider based blades, we need to manually create the OF * platform devices for the PCI host bridges diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f79f40b..033a224 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -701,9 +701,7 @@ int of_platform_bus_probe(struct device_node *root, struct platform_device *dev; int rc = 0; - if (matches == NULL) - matches = of_default_bus_ids; - if (matches == OF_NO_DEEP_PROBE) + if (WARN_ON(!matches || matches == OF_NO_DEEP_PROBE)) return -EINVAL; if (root == NULL) root = of_find_node_by_path("/"); diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index b24c5a5..4e6d989 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -19,8 +19,6 @@ #include #include -extern const struct of_device_id of_default_bus_ids[]; - /* * An of_platform_driver driver is attached to a basic of_device on * the "platform bus" (platform_bus_type). -- cgit v0.10.2 From 883c2cfc8bcc0fd00c5d9f596fb8870f481b5bda Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Fri, 23 Jul 2010 13:42:44 -0500 Subject: of/flattree: fix of_flat_dt_is_compatible() to match the full compatible string With the current string comparison, a device tree compatible of "foo-bar" would match as compatible with a driver looking for "foo". This patch fixes the function to use the of_compat_cmp() macro so that it does the right thing on all platforms (If sparc ever uses this code, it will still want the strncasecmp() behaviour). Signed-off-by: Stuart Yoder Signed-off-by: Grant Likely diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index d61fda8..dc876cb 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -169,7 +169,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) if (cp == NULL) return 0; while (cplen > 0) { - if (strncasecmp(cp, compat, strlen(compat)) == 0) + if (of_compat_cmp(cp, compat, strlen(compat)) == 0) return 1; l = strlen(cp) + 1; cp += l; -- cgit v0.10.2 From 9a6b2e588c7809e86161236da3d29581bf5f8402 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 23 Jul 2010 01:48:25 -0600 Subject: of: Fix phandle endian issues The flat tree code wasn't fixing the endianness on phandle values when unflattening the tree, and the code in drivers/of wasn't always doing a be32_to_cpu before trying to dereference the phandle values. This patch fixes them. Signed-off-by: Grant Likely diff --git a/drivers/of/base.c b/drivers/of/base.c index e3f7af8..aa80525 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -605,14 +605,14 @@ EXPORT_SYMBOL(of_find_node_by_phandle); struct device_node * of_parse_phandle(struct device_node *np, const char *phandle_name, int index) { - const phandle *phandle; + const __be32 *phandle; int size; phandle = of_get_property(np, phandle_name, &size); if ((!phandle) || (size < sizeof(*phandle) * (index + 1))) return NULL; - return of_find_node_by_phandle(phandle[index]); + return of_find_node_by_phandle(be32_to_cpup(phandle + index)); } EXPORT_SYMBOL(of_parse_phandle); @@ -668,16 +668,16 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, while (list < list_end) { const __be32 *cells; - const phandle *phandle; + phandle phandle; - phandle = list++; + phandle = be32_to_cpup(list++); args = list; /* one cell hole in the list = <>; */ - if (!*phandle) + if (!phandle) goto next; - node = of_find_node_by_phandle(*phandle); + node = of_find_node_by_phandle(phandle); if (!node) { pr_debug("%s: could not find phandle\n", np->full_name); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index dc876cb..65da5ae 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -320,13 +320,13 @@ unsigned long __init unflatten_dt_node(unsigned long mem, if ((strcmp(pname, "phandle") == 0) || (strcmp(pname, "linux,phandle") == 0)) { if (np->phandle == 0) - np->phandle = *((u32 *)*p); + np->phandle = be32_to_cpup((__be32*)*p); } /* And we process the "ibm,phandle" property * used in pSeries dynamic device tree * stuff */ if (strcmp(pname, "ibm,phandle") == 0) - np->phandle = *((u32 *)*p); + np->phandle = be32_to_cpup((__be32 *)*p); pp->name = pname; pp->length = sz; pp->value = (void *)*p; diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6cfb307..65cfae1 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -54,7 +54,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); static struct device_node *of_irq_find_parent(struct device_node *child) { struct device_node *p; - const phandle *parp; + const __be32 *parp; if (!of_node_get(child)) return NULL; @@ -67,7 +67,7 @@ static struct device_node *of_irq_find_parent(struct device_node *child) if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) p = of_node_get(of_irq_dflt_pic); else - p = of_find_node_by_phandle(*parp); + p = of_find_node_by_phandle(be32_to_cpup(parp)); } of_node_put(child); child = p; @@ -206,7 +206,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, 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); + newpar = of_find_node_by_phandle(be32_to_cpup(imap)); imap++; --imaplen; -- cgit v0.10.2 From d2f718398a21cdb925f12c2b332d206eacd967a6 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 23 Jul 2010 16:56:19 -0600 Subject: of/irq: Fix endian issues in parsing interrupt specifiers This patch fixes some instances where interrupt specifiers are dereferenced directly instead of doing a be32_to_cpu() conversion first. Signed-off-by: Grant Likely diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 65cfae1..6e595e5 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -91,8 +91,8 @@ static struct device_node *of_irq_find_parent(struct device_node *child) * properties, for example when resolving PCI interrupts when no device * node exist for the parent. */ -int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, - const u32 *addr, struct of_irq *out_irq) +int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, + u32 ointsize, const __be32 *addr, struct of_irq *out_irq) { struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; const __be32 *tmp, *imap, *imask; @@ -100,7 +100,8 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, 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); + parent->full_name, be32_to_cpup(intspec), + be32_to_cpup(intspec + 1), ointsize); ipar = of_node_get(parent); @@ -278,7 +279,7 @@ 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; + const __be32 *intspec, *tmp, *addr; u32 intsize, intlen; int res = -EINVAL; @@ -292,9 +293,9 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq intspec = of_get_property(device, "interrupts", &intlen); if (intspec == NULL) return -EINVAL; - intlen /= sizeof(u32); + intlen /= sizeof(*intspec); - pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen); + pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); /* Get the reg property (if any) */ addr = of_get_property(device, "reg", NULL); -- cgit v0.10.2 From c6601225380088018ae93df2ba7f0bb65334d63b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 23 Jul 2010 15:04:01 -0600 Subject: of/device: Make of_device_make_bus_id() usable by other code. The AMBA bus should also use of_device_make_bus_id() when populating device out of device tree data. This patch makes the function non-static, and adds a suitable prototype in of_device.h Signed-off-by: Grant Likely diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 033a224..30a4641 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -508,7 +508,7 @@ EXPORT_SYMBOL(of_unregister_driver); * value to derive a unique name. As a last resort it will use the node * name followed by a unique number. */ -static void of_device_make_bus_id(struct device *dev) +void of_device_make_bus_id(struct device *dev) { static atomic_t bus_no_reg_magic; struct device_node *node = dev->of_node; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index e11a0be..35aa44a 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -27,6 +27,7 @@ extern const struct of_device_id *of_match_device( const struct of_device_id *matches, const struct device *dev); +extern void of_device_make_bus_id(struct device *dev); /** * of_driver_match_device - Tell if a driver's of_match_table matches a device. -- cgit v0.10.2 From 559e2b7ee7a1c7753d534abcb2742a4775339293 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 23 Jul 2010 20:11:18 -0600 Subject: of: Provide default of_node_to_nid() implementation. of_node_to_nid() is only relevant in a few architectures. Don't force everyone to implement it anyway. Signed-off-by: Grant Likely diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h index 96bcea5..5428f33 100644 --- a/arch/microblaze/include/asm/topology.h +++ b/arch/microblaze/include/asm/topology.h @@ -1,11 +1 @@ #include - -#ifndef _ASM_MICROBLAZE_TOPOLOGY_H -#define _ASM_MICROBLAZE_TOPOLOGY_H - -struct device_node; -static inline int of_node_to_nid(struct device_node *device) -{ - return 0; -} -#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */ diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index da7dd63..55bccc0 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -103,6 +103,13 @@ 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); +#ifdef CONFIG_NUMA +extern int of_node_to_nid(struct device_node *device); +#else +static inline int of_node_to_nid(struct device_node *device) { return 0; } +#endif +#define of_node_to_nid of_node_to_nid + /** * 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/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 32adf72..09dd38c 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -41,8 +41,6 @@ static inline int cpu_to_node(int cpu) cpu_all_mask : \ node_to_cpumask_map[node]) -int of_node_to_nid(struct device_node *device); - struct pci_bus; #ifdef CONFIG_PCI extern int pcibus_to_node(struct pci_bus *bus); @@ -94,11 +92,6 @@ extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); #else -static inline int of_node_to_nid(struct device_node *device) -{ - return 0; -} - static inline void dump_numa_cpu_topology(void) {} static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index c82a7da..291f125 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -43,8 +43,7 @@ extern int of_getintprop_default(struct device_node *np, extern int of_find_in_proplist(const char *list, const char *match, int len); #ifdef CONFIG_NUMA extern int of_node_to_nid(struct device_node *dp); -#else -#define of_node_to_nid(dp) (-1) +#define of_node_to_nid of_node_to_nid #endif extern void prom_build_devicetree(void); diff --git a/include/linux/of.h b/include/linux/of.h index b0756f3..cad7cf0 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -146,6 +146,11 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size) #define OF_BAD_ADDR ((u64)-1) +#ifndef of_node_to_nid +static inline int of_node_to_nid(struct device_node *np) { return -1; } +#define of_node_to_nid of_node_to_nid +#endif + extern struct device_node *of_find_node_by_name(struct device_node *from, const char *name); #define for_each_node_by_name(dn, name) \ -- cgit v0.10.2 From 12b15e83289bc7cf2ec9a342412e0c955beeb395 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 27 Jul 2010 22:35:58 +0200 Subject: of/spi: call of_register_spi_devices() from spi core code Move of_register_spi_devices() call from drivers to spi_register_master(). Also change the function to use the struct device_node pointer from master spi device instead of passing it as function argument. Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index d504f1d..1dbce58 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -15,12 +15,11 @@ /** * of_register_spi_devices - Register child devices onto the SPI bus * @master: Pointer to spi_master device - * @np: parent node of SPI device nodes * - * Registers an spi_device for each child node of 'np' which has a 'reg' + * Registers an spi_device for each child node of master node which has a 'reg' * property. */ -void of_register_spi_devices(struct spi_master *master, struct device_node *np) +void of_register_spi_devices(struct spi_master *master) { struct spi_device *spi; struct device_node *nc; @@ -28,7 +27,10 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) int rc; int len; - for_each_child_of_node(np, nc) { + if (!master->dev.of_node) + return; + + for_each_child_of_node(master->dev.of_node, nc) { /* Alloc an spi_device */ spi = spi_alloc_device(master); if (!spi) { diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 2534b1e..1bb4315 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -440,6 +440,7 @@ static int __init mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, master->setup = mpc512x_psc_spi_setup; master->transfer = mpc512x_psc_spi_transfer; master->cleanup = mpc512x_psc_spi_cleanup; + master->dev.of_node = dev->of_node; tempp = ioremap(regaddr, size); if (!tempp) { diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7104cb7..bd81ff9 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -398,6 +397,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, master->setup = mpc52xx_psc_spi_setup; master->transfer = mpc52xx_psc_spi_transfer; master->cleanup = mpc52xx_psc_spi_cleanup; + master->dev.of_node = dev->of_node; mps->psc = ioremap(regaddr, size); if (!mps->psc) { @@ -470,7 +470,6 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, const u32 *regaddr_p; u64 regaddr64, size64; s16 id = -1; - int rc; regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { @@ -491,13 +490,8 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, id = *psc_nump + 1; } - rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, + return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, irq_of_parse_and_map(op->dev.of_node, 0), id); - if (rc == 0) - of_register_spi_devices(dev_get_drvdata(&op->dev), - op->dev.of_node); - - return rc; } static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op) diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index b1a76bf..56136ff 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -439,6 +438,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, master->setup = mpc52xx_spi_setup; master->transfer = mpc52xx_spi_transfer; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; + master->dev.of_node = op->dev.of_node; dev_set_drvdata(&op->dev, master); @@ -512,7 +512,6 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, if (rc) goto err_register; - of_register_spi_devices(master, op->dev.of_node); dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n"); return rc; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b3a1f92..1bb1b88 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -26,6 +26,7 @@ #include #include #include +#include /* SPI bustype and spi_master class are registered after board init code @@ -540,6 +541,9 @@ int spi_register_master(struct spi_master *master) /* populate children from any spi device tables */ scan_boardinfo(master); status = 0; + + /* Register devices from the device tree */ + of_register_spi_devices(master); done: return status; } diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 97ab0a8..aad9ae1 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -1009,6 +1008,7 @@ mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) master->setup = mpc8xxx_spi_setup; master->transfer = mpc8xxx_spi_transfer; master->cleanup = mpc8xxx_spi_cleanup; + master->dev.of_node = dev->of_node; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->dev = dev; @@ -1299,8 +1299,6 @@ static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, goto err; } - of_register_spi_devices(master, np); - return 0; err: diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index d53466a..0f5fa7e 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -407,6 +407,7 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op, master = spi_alloc_master(dev, sizeof *hw); if (master == NULL) return -ENOMEM; + master->dev.of_node = np; dev_set_drvdata(dev, master); hw = spi_master_get_devdata(master); hw->master = spi_master_get(master); @@ -545,7 +546,6 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op, } dev_info(dev, "driver initialized\n"); - of_register_spi_devices(master, np); return 0; diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 1b47363..80f2db5 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -390,6 +390,9 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, master->bus_num = bus_num; master->num_chipselect = pdata->num_chipselect; +#ifdef CONFIG_OF + master->dev.of_node = dev->of_node; +#endif xspi->mem = *mem; xspi->irq = irq; diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index 4654805..87cda09 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -80,9 +80,6 @@ static int __devinit xilinx_spi_of_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, master); - /* Add any subnodes on the SPI bus */ - of_register_spi_devices(master, ofdev->dev.of_node); - return 0; } diff --git a/include/linux/of_spi.h b/include/linux/of_spi.h index 5f71ee8..9e3e70f 100644 --- a/include/linux/of_spi.h +++ b/include/linux/of_spi.h @@ -9,10 +9,15 @@ #ifndef __LINUX_OF_SPI_H #define __LINUX_OF_SPI_H -#include #include -extern void of_register_spi_devices(struct spi_master *master, - struct device_node *np); +#if defined(CONFIG_OF_SPI) || defined(CONFIG_OF_SPI_MODULE) +extern void of_register_spi_devices(struct spi_master *master); +#else +static inline void of_register_spi_devices(struct spi_master *master) +{ + return; +} +#endif /* CONFIG_OF_SPI */ #endif /* __LINUX_OF_SPI */ -- cgit v0.10.2 From 22ae782f86b726f9cea752c0f269ff6dcdf2f6e1 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 29 Jul 2010 11:49:01 -0600 Subject: of/address: Clean up function declarations This patch moves the declaration of of_get_address(), of_get_pci_address(), and of_pci_address_to_resource() out of arch code and into the common linux/of_address header file. This patch also fixes some of the asm/prom.h ordering issues. It still includes some header files that it ideally shouldn't be, but at least the ordering is consistent now so that of_* overrides work. Signed-off-by: Grant Likely diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index cb9c3dd..101fa09 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -20,11 +20,6 @@ #ifndef __ASSEMBLY__ #include -#include -#include -#include -#include -#include #include #include @@ -52,25 +47,9 @@ extern void pci_create_OF_bus_map(void); * OF address retreival & translation */ -/* Extract an address from a device, returns the region size and - * the address space flags too. The PCI version uses a BAR number - * instead of an absolute index - */ -extern const u32 *of_get_address(struct device_node *dev, int index, - u64 *size, unsigned int *flags); -extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, - u64 *size, unsigned int *flags); - -extern int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r); - #ifdef CONFIG_PCI extern unsigned long pci_address_to_pio(phys_addr_t address); -#else -static inline unsigned long pci_address_to_pio(phys_addr_t address) -{ - return (unsigned long)-1; -} +#define pci_address_to_pio pci_address_to_pio #endif /* CONFIG_PCI */ /* Parse the ibm,dma-window property of an OF node into the busno, phys and @@ -99,8 +78,18 @@ extern const void *of_get_mac_address(struct device_node *np); * resolving using the OF tree walking. */ struct pci_dev; +struct of_irq; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ + +/* These includes are put at the bottom because they may contain things + * that are overridden by this file. Ideally they shouldn't be included + * by this file, but there are a bunch of .c files that currently depend + * on it. Eventually they will be cleaned up. */ +#include +#include +#include + #endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 55bccc0..ae26f2e 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -17,11 +17,6 @@ * 2 of the License, or (at your option) any later version. */ #include -#include -#include -#include -#include -#include #include #include @@ -49,41 +44,9 @@ extern void pci_create_OF_bus_map(void); extern u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr); -/* Extract an address from a device, returns the region size and - * the address space flags too. The PCI version uses a BAR number - * instead of an absolute index - */ -extern const u32 *of_get_address(struct device_node *dev, int index, - u64 *size, unsigned int *flags); -#ifdef CONFIG_PCI -extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, - u64 *size, unsigned int *flags); -#else -static inline const u32 *of_get_pci_address(struct device_node *dev, - int bar_no, u64 *size, unsigned int *flags) -{ - return NULL; -} -#endif /* CONFIG_PCI */ - -#ifdef CONFIG_PCI -extern int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r); -#else -static inline int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r) -{ - return -ENOSYS; -} -#endif /* CONFIG_PCI */ - #ifdef CONFIG_PCI extern unsigned long pci_address_to_pio(phys_addr_t address); -#else -static inline unsigned long pci_address_to_pio(phys_addr_t address) -{ - return (unsigned long)-1; -} +#define pci_address_to_pio pci_address_to_pio #endif /* CONFIG_PCI */ /* Parse the ibm,dma-window property of an OF node into the busno, phys and @@ -122,9 +85,19 @@ static inline int of_node_to_nid(struct device_node *device) { return 0; } * resolving using the OF tree walking. */ struct pci_dev; +struct of_irq; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); extern void of_instantiate_rtc(void); +/* These includes are put at the bottom because they may contain things + * that are overridden by this file. Ideally they shouldn't be included + * by this file, but there are a bunch of .c files that currently depend + * on it. Eventually they will be cleaned up. */ +#include +#include +#include +#include + #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 035ada5..c1fd0f9 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 5b38f6a..9021c4a 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index 6d584f4..de55bc0 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index fb4eb0d..03aabc0 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -13,12 +13,13 @@ */ #include +#include +#include #include #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index d2c1d49..33e5fc7 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 9e1b9fd..75eec03 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c index 5d74ef7..1225012 100644 --- a/arch/powerpc/sysdev/bestcomm/sram.c +++ b/arch/powerpc/sysdev/bestcomm/sram.c @@ -11,6 +11,7 @@ * kind, whether express or implied. */ +#include #include #include #include diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index eca4545..7dd2885 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 89d871e..9191713 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index b4c41d7..f53f850 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index d04c5b2..b2c2f39 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -20,7 +20,7 @@ #include #include #include - +#include #include #include #include diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 8acccd5..caf085d 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -21,6 +21,7 @@ #include #if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) #include +#include #include #include diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 1bb4315..10baac3 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index bd81ff9..66d1701 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index 87cda09..f53d3f6 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 82506ca..9648b75 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 49fcbe8..c225dcc 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/video/offb.c b/drivers/video/offb.c index 46dda7d..cb163a5 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -19,13 +19,14 @@ #include #include #include +#include +#include #include #include #include #include #include #include -#include #ifdef CONFIG_PPC64 #include diff --git a/include/linux/of_address.h b/include/linux/of_address.h index cc567df..8aea06f 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -8,5 +8,37 @@ extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); extern void __iomem *of_iomap(struct device_node *device, int index); +/* Extract an address from a device, returns the region size and + * the address space flags too. The PCI version uses a BAR number + * instead of an absolute index + */ +extern const u32 *of_get_address(struct device_node *dev, int index, + u64 *size, unsigned int *flags); + +#ifndef pci_address_to_pio +static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } +#define pci_address_to_pio pci_address_to_pio +#endif + +#ifdef CONFIG_PCI +extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, + u64 *size, unsigned int *flags); +extern int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r); +#else /* CONFIG_PCI */ +static inline int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r) +{ + return -ENOSYS; +} + +static inline const u32 *of_get_pci_address(struct device_node *dev, + int bar_no, u64 *size, unsigned int *flags) +{ + return NULL; +} +#endif /* CONFIG_PCI */ + + #endif /* __OF_ADDRESS_H */ -- cgit v0.10.2 From 7fb8f881c54beb05dd4d2c947dada1c636581d87 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 29 Jul 2010 17:55:50 -0600 Subject: of/platform: Register of_platform_drivers with an "of:" prefix Currently there are some drivers in tree which register both a platform_driver and an of_platform_driver with the same name. This is a temporary situation until all the relevant of_platform_drivers are converted to be normal platform_drivers. Until then, this patch gives all the of_platform_drivers an "of:" prefix to protect against bogus matches and namespace conflicts. diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 30a4641..bb72223 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -74,8 +74,22 @@ static void platform_driver_shutdown_shim(struct platform_device *pdev) */ int of_register_platform_driver(struct of_platform_driver *drv) { + char *of_name; + /* setup of_platform_driver to platform_driver adaptors */ drv->platform_driver.driver = drv->driver; + + /* Prefix the driver name with 'of:' to avoid namespace collisions + * and bogus matches. There are some drivers in the tree that + * register both an of_platform_driver and a platform_driver with + * the same name. This is a temporary measure until they are all + * cleaned up --gcl July 29, 2010 */ + of_name = kmalloc(strlen(drv->driver.name) + 5, GFP_KERNEL); + if (!of_name) + return -ENOMEM; + sprintf(of_name, "of:%s", drv->driver.name); + drv->platform_driver.driver.name = of_name; + if (drv->probe) drv->platform_driver.probe = platform_driver_probe_shim; drv->platform_driver.remove = drv->remove; @@ -91,6 +105,8 @@ EXPORT_SYMBOL(of_register_platform_driver); void of_unregister_platform_driver(struct of_platform_driver *drv) { platform_driver_unregister(&drv->platform_driver); + kfree(drv->platform_driver.driver.name); + drv->platform_driver.driver.name = NULL; } EXPORT_SYMBOL(of_unregister_platform_driver); -- cgit v0.10.2