diff mbox

[4/7] driver core: fix automatic pinctrl management

Message ID 20170530162554.26159-5-johan@kernel.org (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Johan Hovold May 30, 2017, 4:25 p.m. UTC
Commit ab78029ecc34 ("drivers/pinctrl: grab default handles from device
core") added automatic pin-control management to driver core by looking
up and setting any default pinctrl state found in device tree while a
device is being probed.

This obviously runs into problems as soon as device-tree nodes are
reused for child devices which are later also probed as pins would
already have been claimed by the ancestor device.

For example if a USB host controller claims a pin, its root hub would
consequently fail to probe when its device-tree node is set to the node
of the controller:

    pinctrl-single 48002030.pinmux: pin PIN204 already requested by 48064800.ehci; cannot claim for usb1
    pinctrl-single 48002030.pinmux: pin-204 (usb1) status -22
    pinctrl-single 48002030.pinmux: could not request pin 204 (PIN204) from group usb_dbg_pins  on device pinctrl-single
    usb usb1: Error applying setting, reverse things back
    usb: probe of usb1 failed with error -22

Fix this by checking the new of_node_reused flag and skipping automatic
pinctrl configuration during probe if set.

Note that the flag is checked in driver core rather than in pinctrl
(e.g. in pinctrl_dt_to_map()) which would specifically have prevented
intentional use of a parent's pinctrl properties by a child device
(should such a need ever arise).

Fixes: ab78029ecc34 ("drivers/pinctrl: grab default handles from device core")
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/base/pinctrl.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Linus Walleij May 31, 2017, 12:39 a.m. UTC | #1
On Tue, May 30, 2017 at 6:25 PM, Johan Hovold <johan@kernel.org> wrote:

> Commit ab78029ecc34 ("drivers/pinctrl: grab default handles from device
> core") added automatic pin-control management to driver core by looking
> up and setting any default pinctrl state found in device tree while a
> device is being probed.

Actually we do not just support device tree, but also passing pin control
states from board files. It is handled by the core all the same.
So it's not a device tree thing.

One of those days we will have ACPI passing state tables too...

But I understand what you mean.

> Fix this by checking the new of_node_reused flag and skipping automatic
> pinctrl configuration during probe if set.

Seems like a solid idea. I hope we don't need another quirk for ACPI.
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
Johan Hovold May 31, 2017, 8:35 a.m. UTC | #2
On Wed, May 31, 2017 at 02:39:28AM +0200, Linus Walleij wrote:
> On Tue, May 30, 2017 at 6:25 PM, Johan Hovold <johan@kernel.org> wrote:
> 
> > Commit ab78029ecc34 ("drivers/pinctrl: grab default handles from device
> > core") added automatic pin-control management to driver core by looking
> > up and setting any default pinctrl state found in device tree while a
> > device is being probed.
> 
> Actually we do not just support device tree, but also passing pin control
> states from board files. It is handled by the core all the same.
> So it's not a device tree thing.
> 
> One of those days we will have ACPI passing state tables too...
> 
> But I understand what you mean.

Yes, I could have mentioned board files, but this problem only applies
to device-tree descriptions (for the time being at least).

> > Fix this by checking the new of_node_reused flag and skipping automatic
> > pinctrl configuration during probe if set.
> 
> Seems like a solid idea. I hope we don't need another quirk for ACPI.

We should be able to just generalise and rename the flag (or add a
second one) if it turns out ACPI needs this too.

> Acked-by: Linus Walleij <linus.walleij@linaro.org>

Thanks,
Johan
diff mbox

Patch

diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c
index 5917b4b5fb99..eb929dd6ef1e 100644
--- a/drivers/base/pinctrl.c
+++ b/drivers/base/pinctrl.c
@@ -23,6 +23,9 @@  int pinctrl_bind_pins(struct device *dev)
 {
 	int ret;
 
+	if (dev->of_node_reused)
+		return 0;
+
 	dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
 	if (!dev->pins)
 		return -ENOMEM;