Merge tag 'compiler-attributes-for-linus-4.20-rc1' of https://github.com/ojeda/linux
[sfrench/cifs-2.6.git] / arch / arm / mach-omap2 / omap_hwmod.c
index cd65ea4e9c54e633bd66a0178ca3f06ad16e8db9..083dcd9942ce5c8643f0f56a8731f722fa514f63 100644 (file)
 #include <linux/cpu.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
 
 #include <linux/platform_data/ti-sysc.h>
 
 
 /**
  * struct clkctrl_provider - clkctrl provider mapping data
- * @addr: base address for the provider
- * @size: size of the provider address space
- * @offset: offset of the provider from PRCM instance base
+ * @num_addrs: number of base address ranges for the provider
+ * @addr: base address(es) for the provider
+ * @size: size(s) of the provider address space(s)
  * @node: device node associated with the provider
  * @link: list link
  */
 struct clkctrl_provider {
-       u32                     addr;
-       u32                     size;
-       u16                     offset;
+       int                     num_addrs;
+       u32                     *addr;
+       u32                     *size;
        struct device_node      *node;
        struct list_head        link;
 };
@@ -724,23 +724,36 @@ static int __init _setup_clkctrl_provider(struct device_node *np)
        const __be32 *addrp;
        struct clkctrl_provider *provider;
        u64 size;
+       int i;
 
-       provider = memblock_virt_alloc(sizeof(*provider), 0);
+       provider = memblock_alloc(sizeof(*provider), SMP_CACHE_BYTES);
        if (!provider)
                return -ENOMEM;
 
-       addrp = of_get_address(np, 0, &size, NULL);
-       provider->addr = (u32)of_translate_address(np, addrp);
-       addrp = of_get_address(np->parent, 0, NULL, NULL);
-       provider->offset = provider->addr -
-                          (u32)of_translate_address(np->parent, addrp);
-       provider->addr &= ~0xff;
-       provider->size = size | 0xff;
        provider->node = np;
 
-       pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name,
-                provider->addr, provider->addr + provider->size,
-                provider->offset);
+       provider->num_addrs =
+               of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2;
+
+       provider->addr =
+               memblock_alloc(sizeof(void *) * provider->num_addrs,
+                              SMP_CACHE_BYTES);
+       if (!provider->addr)
+               return -ENOMEM;
+
+       provider->size =
+               memblock_alloc(sizeof(u32) * provider->num_addrs,
+                              SMP_CACHE_BYTES);
+       if (!provider->size)
+               return -ENOMEM;
+
+       for (i = 0; i < provider->num_addrs; i++) {
+               addrp = of_get_address(np, i, &size, NULL);
+               provider->addr[i] = (u32)of_translate_address(np, addrp);
+               provider->size[i] = size;
+               pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i],
+                        provider->addr[i] + provider->size[i]);
+       }
 
        list_add(&provider->link, &clkctrl_providers);
 
@@ -787,23 +800,26 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
        pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
 
        list_for_each_entry(provider, &clkctrl_providers, link) {
-               if (provider->addr <= addr &&
-                   provider->addr + provider->size >= addr) {
-                       struct of_phandle_args clkspec;
+               int i;
 
-                       clkspec.np = provider->node;
-                       clkspec.args_count = 2;
-                       clkspec.args[0] = addr - provider->addr -
-                                         provider->offset;
-                       clkspec.args[1] = 0;
+               for (i = 0; i < provider->num_addrs; i++) {
+                       if (provider->addr[i] <= addr &&
+                           provider->addr[i] + provider->size[i] > addr) {
+                               struct of_phandle_args clkspec;
 
-                       clk = of_clk_get_from_provider(&clkspec);
+                               clkspec.np = provider->node;
+                               clkspec.args_count = 2;
+                               clkspec.args[0] = addr - provider->addr[0];
+                               clkspec.args[1] = 0;
 
-                       pr_debug("%s: %s got %p (offset=%x, provider=%s)\n",
-                                __func__, oh->name, clk, clkspec.args[0],
-                                provider->node->parent->name);
+                               clk = of_clk_get_from_provider(&clkspec);
 
-                       return clk;
+                               pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n",
+                                        __func__, oh->name, clk,
+                                        clkspec.args[0], provider->node);
+
+                               return clk;
+                       }
                }
        }
 
@@ -2107,8 +2123,8 @@ static int of_dev_find_hwmod(struct device_node *np,
                if (res)
                        continue;
                if (!strcmp(p, oh->name)) {
-                       pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
-                                np->name, i, oh->name);
+                       pr_debug("omap_hwmod: dt %pOFn[%i] uses hwmod %s\n",
+                                np, i, oh->name);
                        return i;
                }
        }
@@ -2241,8 +2257,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
                return -ENOENT;
 
        if (nr_addr != 1 || nr_size != 1) {
-               pr_err("%s: invalid range for %s->%s\n", __func__,
-                      oh->name, np->name);
+               pr_err("%s: invalid range for %s->%pOFn\n", __func__,
+                      oh->name, np);
                return -EINVAL;
        }
 
@@ -2250,8 +2266,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
        base = of_translate_address(np, ranges++);
        size = be32_to_cpup(ranges);
 
-       pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n",
-                oh ? oh->name : "", np->name, base, size);
+       pr_debug("omap_hwmod: %s %pOFn at 0x%llx size 0x%llx\n",
+                oh->name, np, base, size);
 
        if (oh && oh->mpu_rt_idx) {
                omap_hwmod_fix_mpu_rt_idx(oh, np, res);
@@ -2359,8 +2375,8 @@ static int __init _init(struct omap_hwmod *oh, void *data)
        if (r)
                pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
        else if (np && index)
-               pr_warn("omap_hwmod: %s using broken dt data from %s\n",
-                       oh->name, np->name);
+               pr_warn("omap_hwmod: %s using broken dt data from %pOFn\n",
+                       oh->name, np);
 
        r = _init_mpu_rt_base(oh, NULL, index, np);
        if (r < 0) {