From 64100a03ad0b94a45ed2753632d9dd68379ad3ac Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 2 Nov 2012 01:20:43 +0100 Subject: ARM: integrator: hook the CP into the SoC bus This hooks the Integrator/CP into the SoC bus when booting from device tree, by mapping the CP controller registers first, then registering the SoC device, and then populating the device tree with the SoC device as parent. Cc: Lee Jones Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/integrator_cp.c | 57 ++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-integrator/integrator_cp.c') diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 5b08e8e4cc83..9194a4f3339c 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -336,10 +337,62 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { { /* sentinel */ }, }; +/* Base address to the CP controller */ +static void __iomem *intcp_con_base; + static void __init intcp_init_of(void) { - of_platform_populate(NULL, of_default_bus_match_table, - intcp_auxdata_lookup, NULL); + struct device_node *root; + struct device_node *cpcon; + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + u32 intcp_sc_id; + int err; + + /* Here we create an SoC device for the root node */ + root = of_find_node_by_path("/"); + if (!root) + return; + cpcon = of_find_node_by_path("/cpcon"); + if (!cpcon) + return; + + intcp_con_base = of_iomap(cpcon, 0); + if (!intcp_con_base) + return; + + intcp_sc_id = readl(intcp_con_base); + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return; + + err = of_property_read_string(root, "compatible", + &soc_dev_attr->soc_id); + if (err) + return; + err = of_property_read_string(root, "model", &soc_dev_attr->machine); + if (err) + return; + soc_dev_attr->family = "Integrator"; + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%c", + 'A' + (intcp_sc_id & 0x0f)); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR_OR_NULL(soc_dev)) { + kfree(soc_dev_attr->revision); + kfree(soc_dev_attr); + return; + } + + parent = soc_device_to_device(soc_dev); + + if (!IS_ERR_OR_NULL(parent)) + integrator_init_sysfs(parent, intcp_sc_id); + + of_platform_populate(root, of_default_bus_match_table, + intcp_auxdata_lookup, parent); } static const char * intcp_dt_board_compat[] = { -- cgit