From ed032c1bede83ec9bd5f7e803e663cb7f76e5947 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 6 Jun 2017 17:59:01 +0200 Subject: driver core: fix automatic pinctrl management 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") Acked-by: Linus Walleij Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/base/pinctrl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/base/pinctrl.c') 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; -- cgit v1.2.3