From patchwork Thu Nov 21 00:05:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tony Lindgren X-Patchwork-Id: 292898 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from casper.infradead.org (unknown [IPv6:2001:770:15f::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 0ACB12C016A for ; Thu, 21 Nov 2013 11:06:20 +1100 (EST) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VjHmW-0007K8-Ab; Thu, 21 Nov 2013 00:06:04 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VjHmT-0003bL-E0; Thu, 21 Nov 2013 00:06:01 +0000 Received: from mho-03-ewr.mailhop.org ([204.13.248.66] helo=mho-01-ewr.mailhop.org) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VjHmQ-0003aa-7k for linux-arm-kernel@lists.infradead.org; Thu, 21 Nov 2013 00:05:59 +0000 Received: from c-50-131-214-131.hsd1.ca.comcast.net ([50.131.214.131] helo=localhost.localdomain) by mho-01-ewr.mailhop.org with esmtpa (Exim 4.72) (envelope-from ) id 1VjHm4-000DOq-Gb; Thu, 21 Nov 2013 00:05:36 +0000 Received: from Mutt by mutt-smtp-wrapper.pl 1.2 (www.zdo.com/articles/mutt-smtp-wrapper.shtml) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 50.131.214.131 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX1+f6oyDPM4bao9VjL0QHNs3 Date: Wed, 20 Nov 2013 16:05:34 -0800 From: Tony Lindgren To: Paul Walmsley Subject: Re: [PATCH] ARM: OMAP2+: Fix populating the hwmod data from device tree Message-ID: <20131121000533.GJ10317@atomide.com> References: <20131120025620.GF10317@atomide.com> <20131120181255.GG10317@atomide.com> <20131120192209.GI10317@atomide.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131120_190558_309864_8D829648 X-CRM114-Status: GOOD ( 38.19 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [204.13.248.66 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Cc: linux-omap@vger.kernel.org, =?utf-8?Q?Beno=C3=AEt?= Cousson , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org * Paul Walmsley [131120 13:59]: > On Wed, 20 Nov 2013, Tony Lindgren wrote: > > > * Tony Lindgren [131120 10:13]: > > > * Tony Lindgren [131119 18:57]: > > > > We have some device tree properties where the ti,hwmod has multiple > > > > values: > > > > > > > > am33xx.dtsi: ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; > > > > am4372.dtsi: ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; > > > > I think these should be defined in the .dtsi files as separate devices > > and removed from the related omap_hwmod_*_data.c files. > > > > > > dra7.dtsi: ti,hwmods = "l3_main_1", "l3_main_2"; > > > > These too should be defined in the .dtsi file. Looks like we're missing > > the related data in the omap_hwmod_7xx_data.c file anyways? > > > > > > omap3.dtsi: ti,hwmods = "mcbsp2", "mcbsp2_sidetone"; > > > > omap3.dtsi: ti,hwmods = "mcbsp3", "mcbsp3_sidetone"; > > > > OK the sidetone data we can probably parse using the ti,hwmods as > > an index. > > > > > > 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"; > > > > Benoit, I guess these mean that those devices should be created > > dynamically, right? > > > > Yet we've removed the related data in commit 3b9b10 and are not > > passing it in the .dtsi file? > > > > So these should be created as separate devices in the .dtsi file > > instead AFAIK. > > > > > Hmm I think this also needs part two to it to populate the right IO space > > > based on the index, this probably now wrongly populates the first IO space > > > for all the hwmod instances in the group. > > > > Yeah this patch clearly is not the right fix to the problem of > > missing data. > > In most of the cases with multiple hwmods per DT device, there's probably > something wrong with the data. So we should try to remove those when > possible. > > For example if you look at the SIDETONE blocks, those should definitely be > separate DT devices - they have separate address spaces, SYSCONFIG > registers, etc. (section 21.6.2 "SIDETONE register mapping summary", > OMAP36xx TRM) Agreed, those need to be fixed. > Would strongly suspect that's the case also for the EDMA blocks you > mention. Yes so it seems. > Am not 100% sure about the L3 cases; would have to dig deeper. 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. In any case, to handle this better and to fix the overwriting issue, here's a patch to deal with it and print out some warnings. Got any better ideas? Regards, Tony From: Tony Lindgren 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 because they are separate devices with their own address space, interrupts, SYSCONFIG registers and can set their PM states independently. So they should all be fixed to be separate devices in the .dts files. Until that happens, let's fix up the issue of overwriting the hwmod data with the first ioreg from device tree by using and index to keep track of the ioreg passed. That can then be used to handle the ti,hwmods string array instead of just the first string to find the related hwmod entrye. Let's also add some warnings for bad data so it's easier to fix. Cc: "BenoƮt Cousson" Cc: Paul Walmsley Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index e3f0eca..399c2a7 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2330,34 +2330,62 @@ 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 * + * @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; 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; + int count, i; + + count = of_property_count_strings(np0, "ti,hwmods"); + if (count < 1) + continue; + + for (i = 0; i < count; i++) { + struct device_node *np1; + const char *p; + int res, ci; + + res = of_property_read_string_index(np0, "ti,hwmods", + i, &p); + if (res) + continue; + + if (!strcmp(p, oh->name)) { + *found = np0; + *index = i; + return 0; + } + res = of_dev_hwmod_lookup(np0, oh, &ci, &np1); + if (res == 0) { + *found = np1; + *index = ci; + 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 +2396,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 +2418,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 +2454,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);