Skip to contentSkip to conversation

More fixes for twl4030 charger

PATCH Superseded H. Nikolaus Schaller 3 participants 12 messages Jun 14, 2017 – Jun 19, 2017 Power supply

v6 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v6 cover More fixes for twl4030 charger

Changes V6:
* split up -EPROBE_DEFER and irq allocation patch into small steps:
* convert iio to devm allocation (by Sebsatian Reichel)
* fix potentially wrong initialization sequence (by Grygorii Strashko)
* add -EPROBE_DEFER

2017-05-21 12:38:24: Changes V5:

* reworked max_current removal patch (comments by Sebastian Reichel)
* resubmit missing madc connection for AC power detection
* resubmit patch for irq allocation and -EPROBE_DEFER
* rebased on 4.12-rc1

Changes V4:
* resent commit (original one did contain material not upstream)

2017-04-14 21:29:39: 2017-04-14 20:26:00: Changes V3:

* worked in comments by Sebsatian Reichel
* clarifications of some commit messages
* rebased on v4.11rc-6

It took a while (18 months) until we propose an updated patch for upstream...

2015-11-02 12:27:39: Changes V2:

* worked in comments by Nishanth Menon <[email protected]>
* added another patch which solves a probing/boot stall problem (irq allocation vs. -EPROBE_DEFER)

V1:
4.3-rc1 introduced a new charger driver for the twl4030. This patch set fixes some issues.

While making twl4030 changes from 4.3 operable we have found some issues during testing on GTA04 and OpenPandora.

H. Nikolaus Schaller (4):
power: supply: twl4030-charger: allocate iio by devm_iio_channel_get()
and fix error path
power: supply: twl4030-charger: move allocation of iio channel to the
beginning
power: supply: twl4030-charger: move irq allocation to just before
irqs are enabled
power: supply: twl4030-charger: add deferred probing for phy and iio

 drivers/power/supply/twl4030_charger.c | 54 +++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 27 deletions(-)
Signature · 1 line
2.12.2
#1 lore raw

PATCH v6 1/4 power: supply: twl4030-charger: allocate iio by devm_iio_channel_get() and fix error path

---
 drivers/power/supply/twl4030_charger.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/power/supply/twl4030_charger.c +2 -8
index 785a07bc4f39..9507c24495ba 100644
@@ -1017,7 +1017,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	bci->channel_vac = iio_channel_get(&pdev->dev, "vac");
+	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
 		bci->channel_vac = NULL;
 		dev_warn(&pdev->dev, "could not request vac iio channel");
@@ -1044,7 +1044,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 			       TWL4030_INTERRUPTS_BCIIMR1A);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret);
-		goto fail;
+		return ret;
 	}
 
 	reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
@@ -1073,10 +1073,6 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		twl4030_charger_enable_backup(0, 0);
 
 	return 0;
-fail:
-	iio_channel_release(bci->channel_vac);
-
-	return ret;
 }
 
 static int twl4030_bci_remove(struct platform_device *pdev)
@@ -1087,8 +1083,6 @@ static int twl4030_bci_remove(struct platform_device *pdev)
 	twl4030_charger_enable_usb(bci, false);
 	twl4030_charger_enable_backup(0, 0);
 
-	iio_channel_release(bci->channel_vac);
-
 	device_remove_file(&bci->usb->dev, &dev_attr_mode);
 	device_remove_file(&bci->ac->dev, &dev_attr_mode);
 	/* mask interrupts */
Signature · 1 line
2.12.2
#2 lore raw

Re: [PATCH v6 1/4] power: supply: twl4030-charger: allocate iio by devm_iio_channel_get() and fix error path

Hi,

Quoted 40 lines · H. Nikolaus Schaller
---
 drivers/power/supply/twl4030_charger.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/power/supply/twl4030_charger.c +2 -6
index 785a07bc4f39..9507c24495ba 100644
@@ -1017,7 +1017,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	bci->channel_vac = iio_channel_get(&pdev->dev, "vac");
+	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
 		bci->channel_vac = NULL;
 		dev_warn(&pdev->dev, "could not request vac iio channel");
@@ -1044,7 +1044,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 			       TWL4030_INTERRUPTS_BCIIMR1A);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret);
-		goto fail;
+		return ret;
 	}
 
 	reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV);
@@ -1073,10 +1073,6 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		twl4030_charger_enable_backup(0, 0);
 
 	return 0;
-fail:
-	iio_channel_release(bci->channel_vac);
-
-	return ret;
 }
 
 static int twl4030_bci_remove(struct platform_device *pdev)

drivers/power/supply/twl4030_charger.c static int twl4030_bci_remove(struct platform_device *pdev) · line 1088

Quoted 8 lines
drivers/power/supply/twl4030_charger.c +0 -2
@@ -1087,8 +1083,6 @@ static int twl4030_bci_remove(struct platform_device *pdev)
 	twl4030_charger_enable_usb(bci, false);
 	twl4030_charger_enable_backup(0, 0);
 
-	iio_channel_release(bci->channel_vac);
-
 	device_remove_file(&bci->usb->dev, &dev_attr_mode);
 	device_remove_file(&bci->ac->dev, &dev_attr_mode);
 	/* mask interrupts */

Thanks, queued.

-- Sebastian

#3 lore raw

PATCH v6 2/4 power: supply: twl4030-charger: move allocation of iio channel to the beginning

In reply to H. Nikolaus Schaller

This is in prepraration for EPROBE_DEFER handling because it is quite likely that geting the (madc) iio channel is deferred more often than later steps.

---
 drivers/power/supply/twl4030_charger.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/power/supply/twl4030_charger.c +6 -6
index 9507c24495ba..1fbbe0cc216a 100644
@@ -984,6 +984,12 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, bci);
 
+	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
+	if (IS_ERR(bci->channel_vac)) {
+		bci->channel_vac = NULL;
+		dev_warn(&pdev->dev, "could not request vac iio channel");
+	}
+
 	bci->ac = devm_power_supply_register(&pdev->dev, &twl4030_bci_ac_desc,
 					     NULL);
 	if (IS_ERR(bci->ac)) {
@@ -1017,12 +1023,6 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
-	if (IS_ERR(bci->channel_vac)) {
-		bci->channel_vac = NULL;
-		dev_warn(&pdev->dev, "could not request vac iio channel");
-	}
-
 	INIT_WORK(&bci->work, twl4030_bci_usb_work);
 	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
 
Signature · 1 line
2.12.2
#4 lore raw

Re: [PATCH v6 2/4] power: supply: twl4030-charger: move allocation of iio channel to the beginning

Hi,

Quoted 5 lines · H. Nikolaus Schaller

This is in prepraration for EPROBE_DEFER handling because it is quite likely that geting the (madc) iio channel is deferred more often than later steps.

Thanks, queued.

-- Sebastian

Quoted 36 lines
 drivers/power/supply/twl4030_charger.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/power/supply/twl4030_charger.c +6 -6
index 9507c24495ba..1fbbe0cc216a 100644
@@ -984,6 +984,12 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, bci);
 
+	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
+	if (IS_ERR(bci->channel_vac)) {
+		bci->channel_vac = NULL;
+		dev_warn(&pdev->dev, "could not request vac iio channel");
+	}
+
 	bci->ac = devm_power_supply_register(&pdev->dev, &twl4030_bci_ac_desc,
 					     NULL);
 	if (IS_ERR(bci->ac)) {
@@ -1017,12 +1023,6 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
-	if (IS_ERR(bci->channel_vac)) {
-		bci->channel_vac = NULL;
-		dev_warn(&pdev->dev, "could not request vac iio channel");
-	}
-
 	INIT_WORK(&bci->work, twl4030_bci_usb_work);
 	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
 
Signature · 1 line
2.12.2
#5 lore raw

PATCH v6 3/4 power: supply: twl4030-charger: move irq allocation to just before irqs are enabled

In reply to H. Nikolaus Schaller

This avoids a potential race if irqs are enabled and triggered too early before the worker is properly set up.

---
 drivers/power/supply/twl4030_charger.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/power/supply/twl4030_charger.c +14 -14
index 1fbbe0cc216a..3bebeecb4a1f 100644
@@ -984,6 +984,16 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, bci);
 
+	if (bci->dev->of_node) {
+		struct device_node *phynode;
+
+		phynode = of_find_compatible_node(bci->dev->of_node->parent,
+						  NULL, "ti,twl4030-usb");
+		if (phynode)
+			bci->transceiver = devm_usb_get_phy_by_node(
+				bci->dev, phynode, &bci->usb_nb);
+	}
+
 	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
 		bci->channel_vac = NULL;
@@ -1006,6 +1016,10 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	INIT_WORK(&bci->work, twl4030_bci_usb_work);
+	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
+
+	bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
 	ret = devm_request_threaded_irq(&pdev->dev, bci->irq_chg, NULL,
 			twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name,
 			bci);
@@ -1023,20 +1037,6 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	INIT_WORK(&bci->work, twl4030_bci_usb_work);
-	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
-
-	bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
-	if (bci->dev->of_node) {
-		struct device_node *phynode;
-
-		phynode = of_find_compatible_node(bci->dev->of_node->parent,
-						  NULL, "ti,twl4030-usb");
-		if (phynode)
-			bci->transceiver = devm_usb_get_phy_by_node(
-				bci->dev, phynode, &bci->usb_nb);
-	}
-
 	/* Enable interrupts now. */
 	reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
 		TWL4030_TBATOR1 | TWL4030_BATSTS);
Signature · 1 line
2.12.2
#6 lore raw

Re: [PATCH v6 3/4] power: supply: twl4030-charger: move irq allocation to just before irqs are enabled

Hi,

Quoted 17 lines · H. Nikolaus Schaller

This avoids a potential race if irqs are enabled and triggered too early before the worker is properly set up.

---
 drivers/power/supply/twl4030_charger.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/power/supply/twl4030_charger.c +0 -0
index 1fbbe0cc216a..3bebeecb4a1f 100644
@@ -984,6 +984,16 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, bci);
 

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 996

Quoted 10 lines
drivers/power/supply/twl4030_charger.c +10 -0
+	if (bci->dev->of_node) {
+		struct device_node *phynode;
+
+		phynode = of_find_compatible_node(bci->dev->of_node->parent,
+						  NULL, "ti,twl4030-usb");
+		if (phynode)
+			bci->transceiver = devm_usb_get_phy_by_node(
+				bci->dev, phynode, &bci->usb_nb);
+	}
+

The notifier is not that much different from an irq. I see the call can access at least the iio channel (so iio channel should be registered first). I suspect worker and power-supply should also be initialized/registered first. Best location seems to be directly before requesting the irqs.

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 1022

Quoted 11 lines
drivers/power/supply/twl4030_charger.c +4 -0
 	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
 		bci->channel_vac = NULL;
@@ -1006,6 +1016,10 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	INIT_WORK(&bci->work, twl4030_bci_usb_work);
+	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
+
+	bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;

You should configure the notifier block *before* registering it.

Quoted 14 lines
drivers/power/supply/twl4030_charger.c +0 -7
 	ret = devm_request_threaded_irq(&pdev->dev, bci->irq_chg, NULL,
 			twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name,
 			bci);
@@ -1023,20 +1037,6 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	INIT_WORK(&bci->work, twl4030_bci_usb_work);
-	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
-
-	bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;
-	if (bci->dev->of_node) {
-		struct device_node *phynode;
-

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 1042

Quoted 10 lines
drivers/power/supply/twl4030_charger.c +0 -7
-		phynode = of_find_compatible_node(bci->dev->of_node->parent,
-						  NULL, "ti,twl4030-usb");
-		if (phynode)
-			bci->transceiver = devm_usb_get_phy_by_node(
-				bci->dev, phynode, &bci->usb_nb);
-	}
-
 	/* Enable interrupts now. */
 	reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 |
 		TWL4030_TBATOR1 | TWL4030_BATSTS);

-- Sebastian

#7 lore raw

Re: [PATCH v6 3/4] power: supply: twl4030-charger: move irq allocation to just before irqs are enabled

Hi Sebastian,

Quoted 22 lines

Am 15.06.2017 um 13:47 schrieb Sebastian Reichel <[email protected]>:

Hi,

Quoted 17 lines · H. Nikolaus Schaller

This avoids a potential race if irqs are enabled and triggered too early before the worker is properly set up.

---
drivers/power/supply/twl4030_charger.c | 28 ++++++++++++++--------------

1 file changed, 14 insertions(+), 14 deletions(-)
drivers/power/supply/twl4030_charger.c +0 -0
index 1fbbe0cc216a..3bebeecb4a1f 100644
@@ -984,6 +984,16 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, bci);
 
Quoted 14 lines

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 996

Quoted 10 lines
drivers/power/supply/twl4030_charger.c +10 -0
+	if (bci->dev->of_node) {
+		struct device_node *phynode;
+
+		phynode = of_find_compatible_node(bci->dev->of_node->parent,
+						  NULL, "ti,twl4030-usb");
+		if (phynode)
+			bci->transceiver = devm_usb_get_phy_by_node(
+				bci->dev, phynode, &bci->usb_nb);
+	}
+

The notifier is not that much different from an irq. I see the call can access at least the iio channel (so iio channel should be registered first).

Hm. I only see that it can schedule the worker (which means the worker should be initialized first) but does not access iio by itself.

Can the worker run before probe() succeeds?

Quoted 3 lines

I suspect worker and power-supply
should also be initialized/registered first. Best location seems to be directly before requesting the irqs.

I think they should be initialized even before devm_usb_get_phy_by_node().

Quoted 8 lines
Quoted 8 lines
drivers/power/supply/twl4030_charger.c +0 -0
 	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
 		bci->channel_vac = NULL;
@@ -1006,6 +1016,10 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 		return ret;
 	}
 
Quoted 6 lines

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 1022

Quoted 4 lines
drivers/power/supply/twl4030_charger.c +4 -0
+	INIT_WORK(&bci->work, twl4030_bci_usb_work);
+	INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker);
+
+	bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;

You should configure the notifier block *before* registering it.

Isn't the notifier block already configured by devm_usb_get_phy_by_node() - except for the pointer to the notifier_call?

So the only harmful thing I can see is that a notifier arrives with usb_nb.notifier_call still being uninitialized as NULL.

Is this harmful or not? I don't know.

I can only guess that it could equally well be set right after devm_usb_get_phy_by_node() and I have reworked it that way.

It still works on GTA04 and OpenPandora with neither observing a regression nor an improvement.

So I will send a v7 with what I think should be most robust.

BR and thanks,
Nikolaus

#8 lore raw

PATCH v6 4/4 power: supply: twl4030-charger: add deferred probing for phy and iio

In reply to H. Nikolaus Schaller

This fixes an issue if both this twl4030_charger driver and phy-twl4030-usb are compiled as modules and loaded in random order.

It has been observed on GTA04 and OpenPandora devices that in worst case the boot process hangs and in best case the AC detection fails with a warning.

Therefore we add deferred probing checks for the usb_phy and the iio channel for AC detection.

---
 drivers/power/supply/twl4030_charger.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/power/supply/twl4030_charger.c +8 -2
index 3bebeecb4a1f..6ac8816262bd 100644
@@ -989,15 +989,21 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 		phynode = of_find_compatible_node(bci->dev->of_node->parent,
 						  NULL, "ti,twl4030-usb");
-		if (phynode)
+		if (phynode) {
 			bci->transceiver = devm_usb_get_phy_by_node(
 				bci->dev, phynode, &bci->usb_nb);
+			if (IS_ERR(bci->transceiver) &&
+			    PTR_ERR(bci->transceiver) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;	/* PHY not ready */
+		}
 	}
 
 	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
-		bci->channel_vac = NULL;
+		if (PTR_ERR(bci->channel_vac) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;	/* iio not ready */
 		dev_warn(&pdev->dev, "could not request vac iio channel");
+		bci->channel_vac = NULL;
 	}
 
 	bci->ac = devm_power_supply_register(&pdev->dev, &twl4030_bci_ac_desc,
Signature · 6 lines
2.12.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#9 lore raw

Re: [PATCH v6 4/4] power: supply: twl4030-charger: add deferred probing for phy and iio

Hi,

Quoted 22 lines · H. Nikolaus Schaller

This fixes an issue if both this twl4030_charger driver and phy-twl4030-usb are compiled as modules and loaded in random order.

It has been observed on GTA04 and OpenPandora devices that in worst case the boot process hangs and in best case the AC detection fails with a warning.

Therefore we add deferred probing checks for the usb_phy and the iio channel for AC detection.

---
 drivers/power/supply/twl4030_charger.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/power/supply/twl4030_charger.c +0 -0
index 3bebeecb4a1f..6ac8816262bd 100644
@@ -989,15 +989,21 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
 		phynode = of_find_compatible_node(bci->dev->of_node->parent,

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 999

Quoted 10 lines
drivers/power/supply/twl4030_charger.c +5 -1
 						  NULL, "ti,twl4030-usb");
-		if (phynode)
+		if (phynode) {
 			bci->transceiver = devm_usb_get_phy_by_node(
 				bci->dev, phynode, &bci->usb_nb);
+			if (IS_ERR(bci->transceiver) &&
+			    PTR_ERR(bci->transceiver) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;	/* PHY not ready */
+		}
 	}

Let's also set to NULL + dev_warn for other errors (like the iio channel error handling).

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 1009

Quoted 10 lines
drivers/power/supply/twl4030_charger.c +3 -1
 	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
-		bci->channel_vac = NULL;
+		if (PTR_ERR(bci->channel_vac) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;	/* iio not ready */
 		dev_warn(&pdev->dev, "could not request vac iio channel");
+		bci->channel_vac = NULL;
 	}
 
 	bci->ac = devm_power_supply_register(&pdev->dev, &twl4030_bci_ac_desc,

-- Sebastian

#10 lore raw

Re: [PATCH v6 4/4] power: supply: twl4030-charger: add deferred probing for phy and iio

Quoted 27 lines

Am 15.06.2017 um 13:57 schrieb Sebastian Reichel <[email protected]>:

Hi,

Quoted 21 lines · H. Nikolaus Schaller

This fixes an issue if both this twl4030_charger driver and phy-twl4030-usb are compiled as modules and loaded in random order.

It has been observed on GTA04 and OpenPandora devices that in worst case the boot process hangs and in best case the AC detection fails with a warning.

Therefore we add deferred probing checks for the usb_phy and the iio channel for AC detection.

---
drivers/power/supply/twl4030_charger.c | 10 ++++++++--

1 file changed, 8 insertions(+), 2 deletions(-)
drivers/power/supply/twl4030_charger.c +0 -0
index 3bebeecb4a1f..6ac8816262bd 100644
@@ -989,15 +989,21 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
Quoted 14 lines

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 999

Quoted 11 lines
drivers/power/supply/twl4030_charger.c +5 -1
 		phynode = of_find_compatible_node(bci->dev->of_node->parent,
 						  NULL, "ti,twl4030-usb");
-		if (phynode)
+		if (phynode) {
 			bci->transceiver = devm_usb_get_phy_by_node(
 				bci->dev, phynode, &bci->usb_nb);
+			if (IS_ERR(bci->transceiver) &&
+			    PTR_ERR(bci->transceiver) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;	/* PHY not ready */
+		}
 	}

Let's also set to NULL + dev_warn for other errors (like the iio channel error handling).

Added to v7.

Also added a %d to print the error number to aid spotting the problems.

Quoted 13 lines

drivers/power/supply/twl4030_charger.c static int twl4030_bci_probe(struct platform_device *pdev) · line 1009

Quoted 11 lines
drivers/power/supply/twl4030_charger.c +3 -1
 	bci->channel_vac = devm_iio_channel_get(&pdev->dev, "vac");
 	if (IS_ERR(bci->channel_vac)) {
-		bci->channel_vac = NULL;
+		if (PTR_ERR(bci->channel_vac) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;	/* iio not ready */
 		dev_warn(&pdev->dev, "could not request vac iio channel");
+		bci->channel_vac = NULL;
 	}
 
 	bci->ac = devm_power_supply_register(&pdev->dev, &twl4030_bci_ac_desc,

-- Sebastian

#11 lore raw
In reply to H. Nikolaus Schaller
Quoted 36 lines

Am 14.06.2017 um 11:25 schrieb H. Nikolaus Schaller <[email protected]>:

Changes V6:
* split up -EPROBE_DEFER and irq allocation patch into small steps:
* convert iio to devm allocation (by Sebsatian Reichel)
* fix potentially wrong initialization sequence (by Grygorii Strashko)
* add -EPROBE_DEFER

2017-05-21 12:38:24: Changes V5:

* reworked max_current removal patch (comments by Sebastian Reichel)
* resubmit missing madc connection for AC power detection
* resubmit patch for irq allocation and -EPROBE_DEFER
* rebased on 4.12-rc1

Changes V4:
* resent commit (original one did contain material not upstream)

2017-04-14 21:29:39: 2017-04-14 20:26:00: Changes V3:

* worked in comments by Sebsatian Reichel
* clarifications of some commit messages
* rebased on v4.11rc-6

It took a while (18 months) until we propose an updated patch for upstream...

2015-11-02 12:27:39: Changes V2:

* worked in comments by Nishanth Menon <[email protected]>
* added another patch which solves a probing/boot stall problem (irq allocation vs. -EPROBE_DEFER)

V1:
4.3-rc1 introduced a new charger driver for the twl4030. This patch set fixes some issues.

While making twl4030 changes from 4.3 operable we have found some issues during testing on GTA04 and OpenPandora.

Quoted 8 lines

H. Nikolaus Schaller (4):
power: supply: twl4030-charger: allocate iio by devm_iio_channel_get()
and fix error path
power: supply: twl4030-charger: move allocation of iio channel to the
beginning
power: supply: twl4030-charger: move irq allocation to just before
irqs are enabled
power: supply: twl4030-charger: add deferred probing for phy and iio

I should note that I have split up the original single commit into 4 separate patches. If maintainers thing this is too fine granularity, please squash them.

The result is tested to work on GTA04.