diff mbox

soc: imx: gpcv2: fix regulator deferred probe

Message ID 20170802195129.20442-1-stefan@agner.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Agner Aug. 2, 2017, 7:51 p.m. UTC
If a regulator requests a deferred probe, the power domain gets
initialized twice. This leads to a list double add (without
list debugging the kernel hangs due to the double add later):

  WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
  list_add double add: new=c1229754, prev=c12383b4, next=c1229754.

Initialize the power domain after we get the regulator. Also do
not print an error in case the regulator defers probing.

Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
Hi Shawn,

Since this leads to a Kernel hang in v4.13-rc3, can you get this
into v4.13 still?

--
Stefan

 drivers/soc/imx/gpcv2.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

Comments

Shawn Guo Aug. 3, 2017, 2:50 a.m. UTC | #1
On Wed, Aug 02, 2017 at 12:51:29PM -0700, Stefan Agner wrote:
> If a regulator requests a deferred probe, the power domain gets
> initialized twice. This leads to a list double add (without
> list debugging the kernel hangs due to the double add later):
> 
>   WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
>   list_add double add: new=c1229754, prev=c12383b4, next=c1229754.
> 
> Initialize the power domain after we get the regulator. Also do
> not print an error in case the regulator defers probing.
> 
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Hi Shawn,
> 
> Since this leads to a Kernel hang in v4.13-rc3, can you get this
> into v4.13 still?

Sure.  But before doing that, I would like to get an ACK from Andrey on
this fix.

Shawn
Andrey Smirnov Aug. 3, 2017, 7:08 a.m. UTC | #2
On Wed, Aug 2, 2017 at 12:51 PM, Stefan Agner <stefan@agner.ch> wrote:
> If a regulator requests a deferred probe, the power domain gets
> initialized twice. This leads to a list double add (without
> list debugging the kernel hangs due to the double add later):
>
>   WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
>   list_add double add: new=c1229754, prev=c12383b4, next=c1229754.
>
> Initialize the power domain after we get the regulator. Also do
> not print an error in case the regulator defers probing.
>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
> Signed-off-by: Stefan Agner <stefan@agner.ch>

As the author of original bug:

Acked-by: Andrey Smirnov <andrew.smirnov@gmail.com>

I also went ahead and tested PCIe on my SabreSD with Intel Gigabit adapter, so

Tested-by: Andrey Smirnov <andrew.smirnov@gmail.com>

Thanks for debugging and fixing this!

Andrey Smirnov
Shawn Guo Aug. 5, 2017, 3:13 a.m. UTC | #3
On Wed, Aug 02, 2017 at 12:51:29PM -0700, Stefan Agner wrote:
> If a regulator requests a deferred probe, the power domain gets
> initialized twice. This leads to a list double add (without
> list debugging the kernel hangs due to the double add later):
> 
>   WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
>   list_add double add: new=c1229754, prev=c12383b4, next=c1229754.
> 
> Initialize the power domain after we get the regulator. Also do
> not print an error in case the regulator defers probing.
> 
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
> Signed-off-by: Stefan Agner <stefan@agner.ch>

Applied, thanks.
Stefan Agner Aug. 14, 2017, 5:12 a.m. UTC | #4
Hi Shawn,

On 2017-08-04 20:13, Shawn Guo wrote:
> On Wed, Aug 02, 2017 at 12:51:29PM -0700, Stefan Agner wrote:
>> If a regulator requests a deferred probe, the power domain gets
>> initialized twice. This leads to a list double add (without
>> list debugging the kernel hangs due to the double add later):
>>
>>   WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
>>   list_add double add: new=c1229754, prev=c12383b4, next=c1229754.
>>
>> Initialize the power domain after we get the regulator. Also do
>> not print an error in case the regulator defers probing.
>>
>> Cc: Fabio Estevam <fabio.estevam@nxp.com>
>> Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: linux-kernel@vger.kernel.org
>> Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
>> Signed-off-by: Stefan Agner <stefan@agner.ch>
> 
> Applied, thanks.

As of 4.13-rc5 this did not make it upstream yet, I guess still on its
way?

--
Stefan
Shawn Guo Aug. 14, 2017, 5:35 a.m. UTC | #5
On Sun, Aug 13, 2017 at 10:12:13PM -0700, Stefan Agner wrote:
> Hi Shawn,
> 
> On 2017-08-04 20:13, Shawn Guo wrote:
> > On Wed, Aug 02, 2017 at 12:51:29PM -0700, Stefan Agner wrote:
> >> If a regulator requests a deferred probe, the power domain gets
> >> initialized twice. This leads to a list double add (without
> >> list debugging the kernel hangs due to the double add later):
> >>
> >>   WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
> >>   list_add double add: new=c1229754, prev=c12383b4, next=c1229754.
> >>
> >> Initialize the power domain after we get the regulator. Also do
> >> not print an error in case the regulator defers probing.
> >>
> >> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> >> Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
> >> Cc: linux-arm-kernel@lists.infradead.org
> >> Cc: linux-kernel@vger.kernel.org
> >> Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> > 
> > Applied, thanks.
> 
> As of 4.13-rc5 this did not make it upstream yet, I guess still on its
> way?

Yes, Stefan. It's on the way to arm-soc [1], but not yet responded.

Shawn

[1] https://www.spinics.net/lists/arm-kernel/msg598634.html
Arnd Bergmann Aug. 15, 2017, 3:36 p.m. UTC | #6
On Mon, Aug 14, 2017 at 7:35 AM, Shawn Guo <shawnguo@kernel.org> wrote:
> On Sun, Aug 13, 2017 at 10:12:13PM -0700, Stefan Agner wrote:
>> Hi Shawn,
>>
>> On 2017-08-04 20:13, Shawn Guo wrote:
>> > On Wed, Aug 02, 2017 at 12:51:29PM -0700, Stefan Agner wrote:
>> >> If a regulator requests a deferred probe, the power domain gets
>> >> initialized twice. This leads to a list double add (without
>> >> list debugging the kernel hangs due to the double add later):
>> >>
>> >>   WARNING: CPU: 0 PID: 19 at lib/list_debug.c:31 __list_add_valid+0xbc/0xc4
>> >>   list_add double add: new=c1229754, prev=c12383b4, next=c1229754.
>> >>
>> >> Initialize the power domain after we get the regulator. Also do
>> >> not print an error in case the regulator defers probing.
>> >>
>> >> Cc: Fabio Estevam <fabio.estevam@nxp.com>
>> >> Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
>> >> Cc: linux-arm-kernel@lists.infradead.org
>> >> Cc: linux-kernel@vger.kernel.org
>> >> Fixes: 03aa12629fc4 ("soc: imx: Add GPCv2 power gating driver")
>> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
>> >
>> > Applied, thanks.
>>
>> As of 4.13-rc5 this did not make it upstream yet, I guess still on its
>> way?
>
> Yes, Stefan. It's on the way to arm-soc [1], but not yet responded.
>
> Shawn
>
> [1] https://www.spinics.net/lists/arm-kernel/msg598634.html

Merged into arm-soc now with Shawn's pull request.

      Arnd
diff mbox

Patch

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 3039072911a5..afc7ecc3c187 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -200,16 +200,11 @@  static int imx7_pgc_domain_probe(struct platform_device *pdev)
 
 	domain->dev = &pdev->dev;
 
-	ret = pm_genpd_init(&domain->genpd, NULL, true);
-	if (ret) {
-		dev_err(domain->dev, "Failed to init power domain\n");
-		return ret;
-	}
-
 	domain->regulator = devm_regulator_get_optional(domain->dev, "power");
 	if (IS_ERR(domain->regulator)) {
 		if (PTR_ERR(domain->regulator) != -ENODEV) {
-			dev_err(domain->dev, "Failed to get domain's regulator\n");
+			if (PTR_ERR(domain->regulator) != -EPROBE_DEFER)
+				dev_err(domain->dev, "Failed to get domain's regulator\n");
 			return PTR_ERR(domain->regulator);
 		}
 	} else {
@@ -217,6 +212,12 @@  static int imx7_pgc_domain_probe(struct platform_device *pdev)
 				      domain->voltage, domain->voltage);
 	}
 
+	ret = pm_genpd_init(&domain->genpd, NULL, true);
+	if (ret) {
+		dev_err(domain->dev, "Failed to init power domain\n");
+		return ret;
+	}
+
 	ret = of_genpd_add_provider_simple(domain->dev->of_node,
 					   &domain->genpd);
 	if (ret) {