summaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy-generic.c
diff options
context:
space:
mode:
authorFabio Estevam <fabio.estevam@freescale.com>2015-01-28 13:19:17 -0200
committerFelipe Balbi <balbi@ti.com>2015-01-30 10:38:51 -0600
commit74379991f6eb760c8767a39c60b4a918af30f80b (patch)
tree4212ef3b8e26cf29fdc3b5a72a27ad1031366fae /drivers/usb/phy/phy-generic.c
parentb7974de821bb65a7efe1961a600c850b5029ed6d (diff)
downloadop-kernel-dev-74379991f6eb760c8767a39c60b4a918af30f80b.zip
op-kernel-dev-74379991f6eb760c8767a39c60b4a918af30f80b.tar.gz
usb: phy: phy-generic: Fix USB PHY gpio reset
Since commit e9f2cefb0cdc2ae ("usb: phy: generic: migrate to gpio_desc") a kernel hang is observed on imx51-babbage board: [ 1.392824] ci_hdrc ci_hdrc.1: doesn't support gadget [ 1.397975] ci_hdrc ci_hdrc.1: EHCI Host Controller [ 1.403205] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 1 [ 1.422335] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00 [ 1.432962] hub 1-0:1.0: USB hub found [ 1.437119] hub 1-0:1.0: 1 port detected This hang happens because the reset GPIO stays at logic level 0. The USB PHY reset gpio is defined in the dts file as: reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; , which means it is active low, so what the gpio reset pin needs to do in this case is the following: - Go to logic level 0 to reset the USB PHY - Stay at 0 for a bit - Go back to logic level 1 When switching to gpiod API we need to following according to Documentation/gpio/consumer.txt: "The first thing a driver must do with a GPIO is setting its direction. If no direction-setting flags have been given to gpiod_get*(), this is done by invoking one of the gpiod_direction_*() functions: int gpiod_direction_input(struct gpio_desc *desc) int gpiod_direction_output(struct gpio_desc *desc, int value)" Since no direction-setting flags have been given to devm_gpiod_get_optional() in our case, we need to use gpiod_direction_output to comply with the gpiod API. With this change the USB PHY reset performs a proper reset, the kernel boots fine and USB host is functional. Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy/phy-generic.c')
-rw-r--r--drivers/usb/phy/phy-generic.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index 48af068..70be50b 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -64,11 +64,12 @@ static int nop_set_suspend(struct usb_phy *x, int suspend)
static void nop_reset_set(struct usb_phy_generic *nop, int asserted)
{
- if (nop->gpiod_reset)
- gpiod_set_value(nop->gpiod_reset, asserted);
+ if (!nop->gpiod_reset)
+ return;
- if (!asserted)
- usleep_range(10000, 20000);
+ gpiod_direction_output(nop->gpiod_reset, !asserted);
+ usleep_range(10000, 20000);
+ gpiod_set_value(nop->gpiod_reset, asserted);
}
/* interface to regulator framework */
OpenPOWER on IntegriCloud