Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64100a03 authored by Linus Walleij's avatar Linus Walleij
Browse files

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 <lee.jones@linaro.org>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent e67ae6be
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -9,6 +9,10 @@ Required properties (in root node):

FPGA type interrupt controllers, see the versatile-fpga-irq binding doc.

In the root node the Integrator/CP must have a /cpcon node pointing
to the CP control registers, and the Integrator/AP must have a
/syscon node pointing to the Integrator/AP system controller.


ARM Versatile Application and Platform Baseboards
-------------------------------------------------
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@
		bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
	};

	cpcon {
		/* CP controller registers */
		reg = <0xcb000000 0x100>;
	};

	timer0: timer@13000000 {
		compatible = "arm,sp804", "arm,primecell";
	};
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ config ARCH_INTEGRATOR_CP
	select PLAT_VERSATILE_CLCD
	select SERIAL_AMBA_PL011
	select SERIAL_AMBA_PL011_CONSOLE
	select SOC_BUS
	help
	  Include support for the ARM(R) Integrator CP platform.

+55 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/sys_soc.h>

#include <mach/hardware.h>
#include <mach/platform.h>
@@ -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[] = {