diff options
author | Arnd Bergmann <arnd@arndb.de> | 2018-09-28 11:57:27 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2018-09-28 11:57:58 -0400 |
commit | 3a60f1182bce850c2f12343a78e157d40af7b1a0 (patch) | |
tree | 37c535121ac6c994cded769a35b62405b63e8ba0 | |
parent | 8e2649d00a8a7b292bd6410cbf976a3d957faa60 (diff) | |
parent | 6e77137927639fad66e17c06b50fd319d6b59833 (diff) |
Merge tag 'omap-for-v4.20/soc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc
SoC changes for omap variants
These changes improve support for clkctrl clocks to deal with
split memory ranges for clkctrl providers. And to use %pOFn
instead of device_node.name.
* tag 'omap-for-v4.20/soc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
ARM: OMAP2+: Convert to using %pOFn instead of device_node.name
ARM: OMAP2+: hwmod_core: improve the support for clkctrl clocks
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index cd65ea4e9c54..56a1fe90d394 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -188,16 +188,16 @@ | |||
188 | 188 | ||
189 | /** | 189 | /** |
190 | * struct clkctrl_provider - clkctrl provider mapping data | 190 | * struct clkctrl_provider - clkctrl provider mapping data |
191 | * @addr: base address for the provider | 191 | * @num_addrs: number of base address ranges for the provider |
192 | * @size: size of the provider address space | 192 | * @addr: base address(es) for the provider |
193 | * @offset: offset of the provider from PRCM instance base | 193 | * @size: size(s) of the provider address space(s) |
194 | * @node: device node associated with the provider | 194 | * @node: device node associated with the provider |
195 | * @link: list link | 195 | * @link: list link |
196 | */ | 196 | */ |
197 | struct clkctrl_provider { | 197 | struct clkctrl_provider { |
198 | u32 addr; | 198 | int num_addrs; |
199 | u32 size; | 199 | u32 *addr; |
200 | u16 offset; | 200 | u32 *size; |
201 | struct device_node *node; | 201 | struct device_node *node; |
202 | struct list_head link; | 202 | struct list_head link; |
203 | }; | 203 | }; |
@@ -724,23 +724,34 @@ static int __init _setup_clkctrl_provider(struct device_node *np) | |||
724 | const __be32 *addrp; | 724 | const __be32 *addrp; |
725 | struct clkctrl_provider *provider; | 725 | struct clkctrl_provider *provider; |
726 | u64 size; | 726 | u64 size; |
727 | int i; | ||
727 | 728 | ||
728 | provider = memblock_virt_alloc(sizeof(*provider), 0); | 729 | provider = memblock_virt_alloc(sizeof(*provider), 0); |
729 | if (!provider) | 730 | if (!provider) |
730 | return -ENOMEM; | 731 | return -ENOMEM; |
731 | 732 | ||
732 | addrp = of_get_address(np, 0, &size, NULL); | ||
733 | provider->addr = (u32)of_translate_address(np, addrp); | ||
734 | addrp = of_get_address(np->parent, 0, NULL, NULL); | ||
735 | provider->offset = provider->addr - | ||
736 | (u32)of_translate_address(np->parent, addrp); | ||
737 | provider->addr &= ~0xff; | ||
738 | provider->size = size | 0xff; | ||
739 | provider->node = np; | 733 | provider->node = np; |
740 | 734 | ||
741 | pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name, | 735 | provider->num_addrs = |
742 | provider->addr, provider->addr + provider->size, | 736 | of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2; |
743 | provider->offset); | 737 | |
738 | provider->addr = | ||
739 | memblock_virt_alloc(sizeof(void *) * provider->num_addrs, 0); | ||
740 | if (!provider->addr) | ||
741 | return -ENOMEM; | ||
742 | |||
743 | provider->size = | ||
744 | memblock_virt_alloc(sizeof(u32) * provider->num_addrs, 0); | ||
745 | if (!provider->size) | ||
746 | return -ENOMEM; | ||
747 | |||
748 | for (i = 0; i < provider->num_addrs; i++) { | ||
749 | addrp = of_get_address(np, i, &size, NULL); | ||
750 | provider->addr[i] = (u32)of_translate_address(np, addrp); | ||
751 | provider->size[i] = size; | ||
752 | pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i], | ||
753 | provider->addr[i] + provider->size[i]); | ||
754 | } | ||
744 | 755 | ||
745 | list_add(&provider->link, &clkctrl_providers); | 756 | list_add(&provider->link, &clkctrl_providers); |
746 | 757 | ||
@@ -787,23 +798,26 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh) | |||
787 | pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr); | 798 | pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr); |
788 | 799 | ||
789 | list_for_each_entry(provider, &clkctrl_providers, link) { | 800 | list_for_each_entry(provider, &clkctrl_providers, link) { |
790 | if (provider->addr <= addr && | 801 | int i; |
791 | provider->addr + provider->size >= addr) { | ||
792 | struct of_phandle_args clkspec; | ||
793 | 802 | ||
794 | clkspec.np = provider->node; | 803 | for (i = 0; i < provider->num_addrs; i++) { |
795 | clkspec.args_count = 2; | 804 | if (provider->addr[i] <= addr && |
796 | clkspec.args[0] = addr - provider->addr - | 805 | provider->addr[i] + provider->size[i] > addr) { |
797 | provider->offset; | 806 | struct of_phandle_args clkspec; |
798 | clkspec.args[1] = 0; | ||
799 | 807 | ||
800 | clk = of_clk_get_from_provider(&clkspec); | 808 | clkspec.np = provider->node; |
809 | clkspec.args_count = 2; | ||
810 | clkspec.args[0] = addr - provider->addr[0]; | ||
811 | clkspec.args[1] = 0; | ||
801 | 812 | ||
802 | pr_debug("%s: %s got %p (offset=%x, provider=%s)\n", | 813 | clk = of_clk_get_from_provider(&clkspec); |
803 | __func__, oh->name, clk, clkspec.args[0], | ||
804 | provider->node->parent->name); | ||
805 | 814 | ||
806 | return clk; | 815 | pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n", |
816 | __func__, oh->name, clk, | ||
817 | clkspec.args[0], provider->node); | ||
818 | |||
819 | return clk; | ||
820 | } | ||
807 | } | 821 | } |
808 | } | 822 | } |
809 | 823 | ||
@@ -2107,8 +2121,8 @@ static int of_dev_find_hwmod(struct device_node *np, | |||
2107 | if (res) | 2121 | if (res) |
2108 | continue; | 2122 | continue; |
2109 | if (!strcmp(p, oh->name)) { | 2123 | if (!strcmp(p, oh->name)) { |
2110 | pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n", | 2124 | pr_debug("omap_hwmod: dt %pOFn[%i] uses hwmod %s\n", |
2111 | np->name, i, oh->name); | 2125 | np, i, oh->name); |
2112 | return i; | 2126 | return i; |
2113 | } | 2127 | } |
2114 | } | 2128 | } |
@@ -2241,8 +2255,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh, | |||
2241 | return -ENOENT; | 2255 | return -ENOENT; |
2242 | 2256 | ||
2243 | if (nr_addr != 1 || nr_size != 1) { | 2257 | if (nr_addr != 1 || nr_size != 1) { |
2244 | pr_err("%s: invalid range for %s->%s\n", __func__, | 2258 | pr_err("%s: invalid range for %s->%pOFn\n", __func__, |
2245 | oh->name, np->name); | 2259 | oh->name, np); |
2246 | return -EINVAL; | 2260 | return -EINVAL; |
2247 | } | 2261 | } |
2248 | 2262 | ||
@@ -2250,8 +2264,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh, | |||
2250 | base = of_translate_address(np, ranges++); | 2264 | base = of_translate_address(np, ranges++); |
2251 | size = be32_to_cpup(ranges); | 2265 | size = be32_to_cpup(ranges); |
2252 | 2266 | ||
2253 | pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n", | 2267 | pr_debug("omap_hwmod: %s %pOFn at 0x%llx size 0x%llx\n", |
2254 | oh ? oh->name : "", np->name, base, size); | 2268 | oh->name, np, base, size); |
2255 | 2269 | ||
2256 | if (oh && oh->mpu_rt_idx) { | 2270 | if (oh && oh->mpu_rt_idx) { |
2257 | omap_hwmod_fix_mpu_rt_idx(oh, np, res); | 2271 | omap_hwmod_fix_mpu_rt_idx(oh, np, res); |
@@ -2359,8 +2373,8 @@ static int __init _init(struct omap_hwmod *oh, void *data) | |||
2359 | if (r) | 2373 | if (r) |
2360 | pr_debug("omap_hwmod: %s missing dt data\n", oh->name); | 2374 | pr_debug("omap_hwmod: %s missing dt data\n", oh->name); |
2361 | else if (np && index) | 2375 | else if (np && index) |
2362 | pr_warn("omap_hwmod: %s using broken dt data from %s\n", | 2376 | pr_warn("omap_hwmod: %s using broken dt data from %pOFn\n", |
2363 | oh->name, np->name); | 2377 | oh->name, np); |
2364 | 2378 | ||
2365 | r = _init_mpu_rt_base(oh, NULL, index, np); | 2379 | r = _init_mpu_rt_base(oh, NULL, index, np); |
2366 | if (r < 0) { | 2380 | if (r < 0) { |