From: tony@atomide.com (Tony Lindgren)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: OMAP2+: Fix populating the hwmod data from device tree
Date: Thu, 21 Nov 2013 12:48:14 -0800 [thread overview]
Message-ID: <20131121204814.GC10023@atomide.com> (raw)
In-Reply-To: <20131121014555.GL10317@atomide.com>
* Tony Lindgren <tony@atomide.com> [131120 17:46]:
> * Tony Lindgren <tony@atomide.com> [131120 16:06]:
> >
> > They at least had interrupts listed looking at commit 3b9b10. Probably
> > the thing to do for now is to revert those changes, and see if we can
> > just remove the L3 entries from the .dtsi files.
>
> Actually the patch I posted should be able to handle also the
> ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3" property in omap4.dtsi,
> but we're not currently parsing that as we only look at the children
> and not the properties of the OCP bus. Should be fixable, will take a look
> tomorrow if this approach makes sense to you.
OK this one seems to do the right thing for me.
Tony
From: Tony Lindgren <tony@atomide.com>
Date: Wed, 20 Nov 2013 15:46:51 -0800
Subject: [PATCH] ARM: OMAP2+: Fix overwriting hwmod data with data from device tree
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We have some device tree properties where the ti,hwmod have multiple
values:
am33xx.dtsi: ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
am4372.dtsi: ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
dra7.dtsi: ti,hwmods = "l3_main_1", "l3_main_2";
omap3.dtsi: ti,hwmods = "mcbsp2", "mcbsp2_sidetone";
omap3.dtsi: ti,hwmods = "mcbsp3", "mcbsp3_sidetone";
omap4.dtsi: ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
omap5.dtsi: ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
That's not correct way of doing things in this case because these are
separate devices with their own address space, interrupts, SYSCONFIG
registers and can set their PM states independently.
So they should all be fixed up to be separate devices in the .dts files.
We also have the related data removed for at least omap4 in commit
3b9b10151c68 (ARM: OMAP4: hwmod data: Clean up the data file), so
that data is wrongly initialized as null data.
So we need to fix two bugs:
1. We are only checking the first entry of the ti,hwmods property
This means that we're only initializing the first hwmods entry
instead of the ones listed in the ti,hwmods property.
2. We are only checking the child nodes, not the nodes themselves
This means that anything listed at OCP level is currently just
ignored and unitialized and at least the omap4 case, with the
legacy data missing from the hwmod.
Fix both of the issues by using an index to the ti,hwmods property
and changing the hwmod lookup function to also check the current node
for ti,hwmods property instead of just the children.
While at it, let's also add some warnings for the bad data so it's
easier to fix.
Cc: "Beno?t Cousson" <bcousson@baylibre.com>
Cc: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e3f0eca..ee655da 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2326,38 +2326,80 @@ static int _shutdown(struct omap_hwmod *oh)
return 0;
}
+static int of_dev_find_hwmod(struct device_node *np,
+ struct omap_hwmod *oh)
+{
+ int count, i, res;
+ const char *p;
+
+ count = of_property_count_strings(np, "ti,hwmods");
+ if (count < 1)
+ return -ENODEV;
+
+ for (i = 0; i < count; i++) {
+ res = of_property_read_string_index(np, "ti,hwmods",
+ i, &p);
+ if (res)
+ continue;
+ if (!strcmp(p, oh->name)) {
+ pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
+ np->name, i, oh->name);
+ return i;
+ }
+ }
+
+ return -ENODEV;
+}
+
/**
* of_dev_hwmod_lookup - look up needed hwmod from dt blob
* @np: struct device_node *
* @oh: struct omap_hwmod *
+ * @index: index of the entry found
+ * @found: struct device_node * found or NULL
*
* 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.
+ * Return: Returns 0 on success, -ENODEV when not found.
*/
-static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
- struct omap_hwmod *oh)
+static int of_dev_hwmod_lookup(struct device_node *np,
+ struct omap_hwmod *oh,
+ int *index,
+ struct device_node **found)
{
- struct device_node *np0 = NULL, *np1 = NULL;
- const char *p;
+ struct device_node *np0 = NULL;
+ int res;
+
+ res = of_dev_find_hwmod(np, oh);
+ if (res >= 0) {
+ *found = np;
+ *index = res;
+ return 0;
+ }
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;
+ struct device_node *fc;
+ int i;
+
+ res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
+ if (res == 0) {
+ *found = fc;
+ *index = i;
+ return 0;
}
}
- return NULL;
+
+ *found = NULL;
+ *index = 0;
+
+ return -ENODEV;
}
/**
* _init_mpu_rt_base - populate the virtual address for a hwmod
* @oh: struct omap_hwmod * to locate the virtual address
* @data: (unused, caller should pass NULL)
+ * @index: index of the reg entry iospace in device tree
* @np: struct device_node * of the IP block's device node in the DT data
*
* Cache the virtual address used by the MPU to access this IP block's
@@ -2368,7 +2410,7 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
* -ENXIO on absent or invalid register target address space.
*/
static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
- struct device_node *np)
+ int index, struct device_node *np)
{
struct omap_hwmod_addr_space *mem;
void __iomem *va_start = NULL;
@@ -2390,13 +2432,17 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
if (!np)
return -ENXIO;
- va_start = of_iomap(np, oh->mpu_rt_idx);
+ va_start = of_iomap(np, index + oh->mpu_rt_idx);
} else {
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);
+ if (mem)
+ pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
+ else
+ pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
+ oh->name, index, np->full_name);
return -ENXIO;
}
@@ -2422,17 +2468,29 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
*/
static int __init _init(struct omap_hwmod *oh, void *data)
{
- int r;
+ int r, index;
struct device_node *np = NULL;
if (oh->_state != _HWMOD_STATE_REGISTERED)
return 0;
- if (of_have_populated_dt())
- np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
+ if (of_have_populated_dt()) {
+ struct device_node *bus;
+
+ bus = of_find_node_by_name(NULL, "ocp");
+ if (!bus)
+ return -ENODEV;
+
+ r = of_dev_hwmod_lookup(bus, oh, &index, &np);
+ 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);
+ }
if (oh->class->sysc) {
- r = _init_mpu_rt_base(oh, NULL, np);
+ r = _init_mpu_rt_base(oh, NULL, index, np);
if (r < 0) {
WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
oh->name);
next prev parent reply other threads:[~2013-11-21 20:48 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-20 2:56 [PATCH] ARM: OMAP2+: Fix populating the hwmod data from device tree Tony Lindgren
2013-11-20 18:12 ` Tony Lindgren
2013-11-20 19:22 ` Tony Lindgren
2013-11-20 21:58 ` Paul Walmsley
2013-11-21 0:05 ` Tony Lindgren
2013-11-21 1:45 ` Tony Lindgren
2013-11-21 20:48 ` Tony Lindgren [this message]
2013-12-05 17:29 ` Tony Lindgren
2013-12-06 0:07 ` Paul Walmsley
2013-12-06 0:25 ` Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131121204814.GC10023@atomide.com \
--to=tony@atomide.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).