diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-07 11:06:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-07 11:06:17 -0700 |
commit | 38f56f33ca381751f9b8910f67e7a805ec0b68cb (patch) | |
tree | 202f2ce60f3f43a948607ec76c8cc48c1cf73a4b /arch/arm/mach-omap2/omap_hwmod.c | |
parent | fcba914542082b272f31c8e4c40000b88ed3208d (diff) | |
parent | 4183bef2e093a2f0aab45f2d5fed82b0e02aeacf (diff) |
Merge tag 'dt-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC device tree updates (part 2) from Arnd Bergmann:
"These are mostly new device tree bindings for existing drivers, as
well as changes to the device tree source files to add support for
those devices, and a couple of new boards, most notably Samsung's
Exynos5 based Chromebook.
The changes depend on earlier platform specific updates and touch the
usual platforms: omap, exynos, tegra, mxs, mvebu and davinci."
* tag 'dt-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (169 commits)
ARM: exynos: dts: cros5250: add EC device
ARM: dts: Add sbs-battery for exynos5250-snow
ARM: dts: Add i2c-arbitrator bus for exynos5250-snow
ARM: dts: add mshc controller node for Exynos4x12 SoCs
ARM: dts: Add chip-id controller node on Exynos4/5 SoC
ARM: EXYNOS: Create virtual I/O mapping for Chip-ID controller using device tree
ARM: davinci: da850-evm: add SPI flash support
ARM: davinci: da850: override SPI DT node device name
ARM: davinci: da850: add SPI1 DT node
spi/davinci: add DT binding documentation
spi/davinci: no wildcards in DT compatible property
ARM: dts: mvebu: Convert mvebu device tree files to 64 bits
ARM: dts: mvebu: introduce internal-regs node
ARM: dts: mvebu: Convert all the mvebu files to use the range property
ARM: dts: mvebu: move all peripherals inside soc
ARM: dts: mvebu: fix cpus section indentation
ARM: davinci: da850: add EHRPWM & ECAP DT node
ARM/dts: OMAP3: fix pinctrl-single configuration
ARM: dts: Add OMAP3430 SDP NOR flash memory binding
ARM: dts: Add NOR flash bindings for OMAP2420 H4
...
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 93f213b6a78..d25a95fe992 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -139,6 +139,8 @@ #include <linux/slab.h> #include <linux/bootmem.h> #include <linux/cpu.h> +#include <linux/of.h> +#include <linux/of_address.h> #include <asm/system_misc.h> @@ -2350,6 +2352,34 @@ static int _shutdown(struct omap_hwmod *oh) } /** + * of_dev_hwmod_lookup - look up needed hwmod from dt blob + * @np: struct device_node * + * @oh: struct omap_hwmod * + * + * Parse the dt blob and find out needed hwmod. Recursive function is + * implemented to take care hierarchical dt blob parsing. + * Return: The device node on success or NULL on failure. + */ +static struct device_node *of_dev_hwmod_lookup(struct device_node *np, + struct omap_hwmod *oh) +{ + struct device_node *np0 = NULL, *np1 = NULL; + const char *p; + + for_each_child_of_node(np, np0) { + if (of_find_property(np0, "ti,hwmods", NULL)) { + p = of_get_property(np0, "ti,hwmods", NULL); + if (!strcmp(p, oh->name)) + return np0; + np1 = of_dev_hwmod_lookup(np0, oh); + if (np1) + return np1; + } + } + return NULL; +} + +/** * _init_mpu_rt_base - populate the virtual address for a hwmod * @oh: struct omap_hwmod * to locate the virtual address * @@ -2361,7 +2391,8 @@ static int _shutdown(struct omap_hwmod *oh) static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) { struct omap_hwmod_addr_space *mem; - void __iomem *va_start; + void __iomem *va_start = NULL; + struct device_node *np; if (!oh) return; @@ -2375,10 +2406,18 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) if (!mem) { pr_debug("omap_hwmod: %s: no MPU register target found\n", oh->name); - return; + + /* Extract the IO space from device tree blob */ + if (!of_have_populated_dt()) + return; + + np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); + if (np) + va_start = of_iomap(np, 0); + } else { + va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); } - va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); if (!va_start) { pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); return; @@ -2410,7 +2449,8 @@ static int __init _init(struct omap_hwmod *oh, void *data) if (oh->_state != _HWMOD_STATE_REGISTERED) return 0; - _init_mpu_rt_base(oh, NULL); + if (oh->class->sysc) + _init_mpu_rt_base(oh, NULL); r = _init_clocks(oh, NULL); if (r < 0) { |