* [PATCH] Add of_platform_device_scan(). @ 2006-10-03 22:56 Scott Wood 2006-10-03 23:18 ` Arnd Bergmann 0 siblings, 1 reply; 5+ messages in thread From: Scott Wood @ 2006-10-03 22:56 UTC (permalink / raw) To: linuxppc-dev This patch adds of_platform_device_scan(), which adds matching device nodes to the of_platform bus. The goal is to let drivers reuse the match struct to do this, rather than have special code in fsl_soc.c (or equivalent) that knows which nodes to add. This will be used by the ucc_geth.c driver; in the current QE patchset, it registers an of_platform driver for devices that never get registered. Signed-off-by: Scott Wood <scottwood@freescale.com> --- arch/powerpc/kernel/of_device.c | 80 ++++++++++++++++++++++++++++++--------- include/asm-powerpc/of_device.h | 1 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 397c83e..1bd8fe6 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -8,36 +8,50 @@ #include <linux/slab.h> #include <asm/errno.h> #include <asm/of_device.h> +static const struct of_device_id * +of_match_device_by_node(const struct of_device_id *matches, + struct device_node *node) +{ + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { + int match = 1; + + if (matches->name[0] && (!node->name || + strcmp(matches->name, node->name))) + match = 0; + + if (matches->type[0] && (!node->type || + strcmp(matches->type, node->type))) + match = 0; + + if (matches->compatible[0] && + !device_is_compatible(node, matches->compatible)) + match = 0; + + if (match) + return matches; + + matches++; + } + + return NULL; +} + /** * of_match_device - Tell if an of_device structure has a matching * of_match structure - * @ids: array of of device match structures to search in + * @matches: array of of device match structures to search in * @dev: the of device structure to match against * * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) + const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= dev->node->name - && !strcmp(matches->name, dev->node->name); - if (matches->type[0]) - match &= dev->node->type - && !strcmp(matches->type, dev->node->type); - if (matches->compatible[0]) - match &= device_is_compatible(dev->node, - matches->compatible); - if (match) - return matches; - matches++; - } - return NULL; + + return of_match_device_by_node(matches, dev->node); } static int of_platform_bus_match(struct device *dev, struct device_driver *drv) @@ -236,6 +250,35 @@ struct of_device* of_platform_device_cre return dev; } +/** + * of_platform_device_scan - Find matching device tree nodes and + * call of_platform_device_create. + * @match: array of of device match structures to search in + * + * Used by a driver to add device nodes it supports to the platform bus. + * @match should be specified so as to exclude any devices that + * do not belong on the OF platform bus (e.g. PCI devices, + * devices that use the regular platform bus, etc). + */ +void of_platform_device_scan(const struct of_device_id *match) +{ + char bus_id[BUS_ID_SIZE]; + struct device_node *np = NULL; + + while ((np = of_find_all_nodes(np))) { + struct resource res; + + if (!of_match_device_by_node(match, np)) + continue; + + if (of_address_to_resource(np, 0, &res)) + continue; + + snprintf(bus_id, BUS_ID_SIZE, "%x", res.start); + of_platform_device_create(np, bus_id, NULL); + } +} + EXPORT_SYMBOL(of_match_device); EXPORT_SYMBOL(of_platform_bus_type); EXPORT_SYMBOL(of_register_driver); @@ -246,3 +289,4 @@ EXPORT_SYMBOL(of_dev_get); EXPORT_SYMBOL(of_dev_put); EXPORT_SYMBOL(of_platform_device_create); EXPORT_SYMBOL(of_release_dev); +EXPORT_SYMBOL(of_platform_device_scan); diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h index c5c0b0b..9f84c41 100644 --- a/include/asm-powerpc/of_device.h +++ b/include/asm-powerpc/of_device.h @@ -61,6 +61,7 @@ extern struct of_device *of_platform_dev const char *bus_id, struct device *parent); extern void of_release_dev(struct device *dev); +extern void of_platform_device_scan(const struct of_device_id *match); #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OF_DEVICE_H */ -- 1.4.2.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] Add of_platform_device_scan(). 2006-10-03 22:56 [PATCH] Add of_platform_device_scan() Scott Wood @ 2006-10-03 23:18 ` Arnd Bergmann 2006-10-04 16:32 ` Scott Wood 0 siblings, 1 reply; 5+ messages in thread From: Arnd Bergmann @ 2006-10-03 23:18 UTC (permalink / raw) To: linuxppc-dev On Wednesday 04 October 2006 00:56, Scott Wood wrote: > This patch adds of_platform_device_scan(), which adds matching device > nodes to the of_platform bus. =A0The goal is to let drivers reuse the mat= ch > struct to do this, rather than have special code in fsl_soc.c (or > equivalent) that knows which nodes to add. >=20 > This will be used by the ucc_geth.c driver; in the current QE patchset, > it registers an of_platform driver for devices that never get registered. >=20 I think it would be much more helpful to have working probing of all SOC buses during bootup. With your patch, we don't have the ability to autoload modules based on the available devices, but can only see devices that have been explicitly registered. This fundamentally violates the principles of the linux device model. Incidentally, I've experimented last week with doing exactly what I think we should have. It doesn't yet do the thing I want it for (allow PCI buses below SOC buses), but it should be able to scan nested soc buses fine and thereby add all your devices to the tree so you can attach drivers to them. Arnd <>< Index: linux-2.6/arch/powerpc/kernel/Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- linux-2.6.orig/arch/powerpc/kernel/Makefile +++ linux-2.6/arch/powerpc/kernel/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_TAU) +=3D tau_6xx.o obj32-$(CONFIG_SOFTWARE_SUSPEND) +=3D swsusp_32.o obj32-$(CONFIG_MODULES) +=3D module_32.o obj-$(CONFIG_E500) +=3D perfmon_fsl_booke.o +obj-$(CONFIG_SOC) +=3D soc.o =20 ifeq ($(CONFIG_PPC_MERGE),y) =20 Index: linux-2.6/arch/powerpc/kernel/soc.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- /dev/null +++ linux-2.6/arch/powerpc/kernel/soc.c @@ -0,0 +1,152 @@ +#include <linux/device.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/prom.h> +#include <asm/of_device.h> +#include <asm/ppc-pci.h> +#include <asm-powerpc/axon_dcr.h> + +static int of_soc_create_device_name(struct device_node *node, char *name) +{ + const u32 *reg; + u64 addr; + + reg =3D get_property(node, "dcr-reg", NULL); + if (reg) { + addr =3D of_translate_dcr_address(node, reg); + if (addr !=3D OF_BAD_ADDR) + goto found_dcr; + } + reg =3D get_property(node, "reg", NULL); + if (reg) { + addr =3D of_translate_address(node, reg); + if (addr !=3D OF_BAD_ADDR) + goto found; + } + + return -EINVAL; + +found_dcr: + sprintf(name, "D%lx.%s", addr, node->name); + return 0; + +found: + sprintf(name, "%lx.%s", addr, node->name); + return 0; +} + +static int of_soc_device_create(struct device_node *node, struct device *p= arent) +{ + char name[BUS_ID_SIZE]; + int ret; + + printk("found node %s\n", node->name); + ret =3D of_soc_create_device_name(node, name); + if (ret) + return ret; + + of_platform_device_create(node, name, parent); + return 0; +} + +static int of_soc_bus_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct device_node *child; + int ret =3D -ENODEV; + for (child =3D NULL; (child =3D of_get_next_child(dev->node, child)); ) { + ret =3D of_soc_device_create(child, &dev->dev); + if (ret) + break; + } + return ret; +} + +static struct of_device_id of_soc_ids[] =3D { + { .type =3D "soc", }, + { .compatible =3D "soc", }, + { .type =3D "spider", }, + { .type =3D "axon", }, + { .type =3D "plb5", }, + { .type =3D "plb4", }, + { .type =3D "opb", }, + {}, +}; + +static struct of_platform_driver of_soc_driver =3D { + .name =3D "soc", + .match_table =3D of_soc_ids, + .probe =3D of_soc_bus_probe, +}; + +#if 0 +static int of_pci_bus_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct pci_controller *phb; + + phb =3D pcibios_alloc_controller(dev->node); + if (!phb) + return -ENODEV; + setup_phb(dev->node, phb); + pci_process_bridge_OF_ranges(phb, dev->node, 0); + pci_setup_phb_io(phb, 0); + return 0; +} + +static struct of_device_id of_pci_ids[] =3D { + { .type =3D "pci", }, + { .type =3D "pcie", }, + { .type =3D "pciex", }, + { .type =3D "ht", }, + { .compatible =3D "pci", }, + { .compatible =3D "pcie", }, + { .compatible =3D "pciex", }, + { .compatible =3D "ht", }, +}; + +static struct of_platform_driver of_pci_driver =3D { + .name =3D "pci", + .match_table =3D of_pci_ids, + .probe =3D of_pci_bus_probe, +}; +#endif + +static int of_soc_probe(void) +{ + struct device_node *root, *child; + int ret; + + ret =3D 0; + root =3D of_find_node_by_path("/"); + if (!root) + goto out; + ret =3D of_register_driver(&of_soc_driver); + if (ret) + goto out; + +#if 0 + ret =3D of_register_driver(&of_pci_driver); + if (ret) + goto out2; +#endif + + for (child =3D NULL; (child =3D of_get_next_child(root, child)); ) { + if (strcmp(child->type, "spider") =3D=3D 0) { + ret =3D of_soc_device_create(child, NULL); + if (ret) + goto out3; + } + } + + return 0; +out3: + of_unregister_driver(&of_soc_driver); +out2: + of_unregister_driver(&of_pci_driver); +out: + return ret; +} +__initcall(of_soc_probe); Index: linux-2.6/arch/powerpc/Kconfig =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =2D-- linux-2.6.orig/arch/powerpc/Kconfig +++ linux-2.6/arch/powerpc/Kconfig @@ -450,6 +450,7 @@ config PPC_IBM_CELL_BLADE select MMIO_NVRAM select PPC_UDBG_16550 select UDBG_RTAS_CONSOLE + select SOC =20 config UDBG_RTAS_CONSOLE bool "RTAS based debug console" @@ -544,6 +545,13 @@ config PPC_970_NAP bool default n =20 +config SOC + bool + default n + help + Support for probing of SOC (system-on-a-chip) buses from + the device tree + source "drivers/cpufreq/Kconfig" =20 config CPU_FREQ_PMAC ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Add of_platform_device_scan(). 2006-10-03 23:18 ` Arnd Bergmann @ 2006-10-04 16:32 ` Scott Wood 2006-10-04 16:37 ` Arnd Bergmann 0 siblings, 1 reply; 5+ messages in thread From: Scott Wood @ 2006-10-04 16:32 UTC (permalink / raw) To: Arnd Bergmann; +Cc: linuxppc-dev Arnd Bergmann wrote: > I think it would be much more helpful to have working probing of all > SOC buses during bootup. I agree; I avoided doing that for now because I was uneasy about duplicating device nodes for SOC devices covered under the non-OF platform bus via code in sysdev/fsl_soc.c. It probably won't cause any real problems unless a single device matches drivers on both buses (in which case the of_device driver would probably be calling of_platform_device_scan() anyway), but still... What I'd really like (long-term, of course) is if platform_device and of_device were merged, with device tree support (or at least a means of passing on properties that *could* come from a device tree without special glue code that knows about each property) in arch-neutral code; the mechanism for discovering devices ideally shouldn't depend on the CPU's instruction set. > + for (child = NULL; (child = of_get_next_child(root, child)); ) { > + if (strcmp(child->type, "spider") == 0) { > + ret = of_soc_device_create(child, NULL); > + if (ret) > + goto out3; > + } > + } Why only spider? -Scott ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Add of_platform_device_scan(). 2006-10-04 16:32 ` Scott Wood @ 2006-10-04 16:37 ` Arnd Bergmann 2006-10-04 19:33 ` Scott Wood 0 siblings, 1 reply; 5+ messages in thread From: Arnd Bergmann @ 2006-10-04 16:37 UTC (permalink / raw) To: Scott Wood; +Cc: linuxppc-dev On Wednesday 04 October 2006 18:32, Scott Wood wrote: > What I'd really like (long-term, of course) is if platform_device and=20 > of_device were merged, with device tree support (or at least a means of=20 > passing on properties that *could* come from a device tree without=20 > special glue code that knows about each property) in arch-neutral code;=20 > the mechanism for discovering devices ideally shouldn't depend on the=20 > CPU's instruction set. My guess is that this won't happen, because other architectures normally don't describe their platform devices in a way that is anywhere near what we have on powerpc. Benh suggested moving some of the functionality of of_platform_device into the common of_device so we don't really have to use an of_platform_device for stuff that can be automatically probed. I guess we'll see a patch from him soon. > > +=A0=A0=A0=A0=A0for (child =3D NULL; (child =3D of_get_next_child(root,= child)); ) { > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0if (strcmp(child->type, "spider= ") =3D=3D 0) { > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0ret =3D= of_soc_device_create(child, NULL); > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0if (ret) > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0goto out3; > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0} > > +=A0=A0=A0=A0=A0} >=20 > Why only spider? Mistake on my side. That's what I have in my experimental device tree. It should be more generic. Arnd <>< ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Add of_platform_device_scan(). 2006-10-04 16:37 ` Arnd Bergmann @ 2006-10-04 19:33 ` Scott Wood 0 siblings, 0 replies; 5+ messages in thread From: Scott Wood @ 2006-10-04 19:33 UTC (permalink / raw) To: Arnd Bergmann; +Cc: linuxppc-dev Arnd Bergmann wrote: > On Wednesday 04 October 2006 18:32, Scott Wood wrote: > >>What I'd really like (long-term, of course) is if platform_device and >>of_device were merged, with device tree support (or at least a means of >>passing on properties that *could* come from a device tree without >>special glue code that knows about each property) in arch-neutral code; >>the mechanism for discovering devices ideally shouldn't depend on the >>CPU's instruction set. > > > My guess is that this won't happen, because other architectures > normally don't describe their platform devices in a way that is > anywhere near what we have on powerpc. They wouldn't need to, unless they want to support a driver that requires it. It would simply be an architecture-neutral mechanism for attaching a dynamic list of properties and OF-compatible matching criteria (or more generally the ability to match on any set of dynamic properties) to platform devices; the source of the platform data could choose to use it to represent an OF device tree, to supply a few properties needed by a specific driver, or not at all. Ideally, users of static structure-based platform data would gradually migrate to dynamic properties, but there's a benefit to the integration even if they don't. The main issue that I forsee being a problem is clashing with another standard for the naming and content of properties. There could be tagging to indicate which standard is being followed by a given property, but that could lead to some ugliness in drivers that need to support more than one if the differences can't be easily abstracted by get-me-this-piece-of-information accessor functions (or by code that generically converts properties from one standard to another, which is similar to what we've already got in fsl_soc.c, but hopefully less device-specific). -Scott ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-10-04 19:33 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-10-03 22:56 [PATCH] Add of_platform_device_scan() Scott Wood 2006-10-03 23:18 ` Arnd Bergmann 2006-10-04 16:32 ` Scott Wood 2006-10-04 16:37 ` Arnd Bergmann 2006-10-04 19:33 ` Scott Wood
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).