Commit 3a60f118 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'omap-for-v4.20/soc-signed' of...

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: default avatarArnd Bergmann <arnd@arndb.de>
parents 8e2649d0 6e771379
Loading
Loading
Loading
Loading
+51 −37
Original line number Diff line number Diff line
@@ -188,16 +188,16 @@

/**
 * 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,34 @@ 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);
	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_virt_alloc(sizeof(void *) * provider->num_addrs, 0);
	if (!provider->addr)
		return -ENOMEM;

	provider->size =
		memblock_virt_alloc(sizeof(u32) * provider->num_addrs, 0);
	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,25 +798,28 @@ 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) {
		int i;

		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;

				clkspec.np = provider->node;
				clkspec.args_count = 2;
			clkspec.args[0] = addr - provider->addr -
					  provider->offset;
				clkspec.args[0] = addr - provider->addr[0];
				clkspec.args[1] = 0;

				clk = of_clk_get_from_provider(&clkspec);

			pr_debug("%s: %s got %p (offset=%x, provider=%s)\n",
				 __func__, oh->name, clk, clkspec.args[0],
				 provider->node->parent->name);
				pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n",
					 __func__, oh->name, clk,
					 clkspec.args[0], provider->node);

				return clk;
			}
		}
	}

	return NULL;
}
@@ -2107,8 +2121,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 +2255,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 +2264,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 +2373,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) {