diff options
author | Piyush Mehta <piyush.mehta@xilinx.com> | 2022-05-04 13:23:09 +0530 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-05-05 22:02:39 +0200 |
commit | ca05b38252d7bf6b0d42e80b3d3d98a642f4143b (patch) | |
tree | 58cb3edef537afe19b4ac917a319b9f875f7d0ee /drivers | |
parent | 1cda12b15d5035663e5a1d92e33d6443c285332c (diff) | |
download | linux-stable-ca05b38252d7bf6b0d42e80b3d3d98a642f4143b.tar.gz linux-stable-ca05b38252d7bf6b0d42e80b3d3d98a642f4143b.tar.bz2 linux-stable-ca05b38252d7bf6b0d42e80b3d3d98a642f4143b.zip |
usb: dwc3: xilinx: Add gpio-reset support
This patch adds a USB GPIO based reset for dwc3-xilinx driver. The PHY
needs to be reset after the completion of phy initialization. As part
of the reset, check for gpio-reset binding before toggling the pin.
This feature is advantageous when the user toggle GPIO to trigger the
ULPI-PHY reset.
Delay of milliseconds is added in between low and high to meet the setup
and hold time requirement of the reset. The reset-gpio error handling is
added for error notification.
Some GPIO controllers must be accessed using message-based buses, like
I2C or SPI, to address this problem, updates GPIO access with sleep API.
This reset is specific to the zynqMp.
Signed-off-by: Piyush Mehta <piyush.mehta@xilinx.com>
Link: https://lore.kernel.org/r/20220504075309.6244-3-piyush.mehta@xilinx.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/dwc3/dwc3-xilinx.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index a6f3a9b38789..67b237c7a76a 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -13,6 +13,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/pm_runtime.h> #include <linux/reset.h> @@ -98,6 +99,7 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) { struct device *dev = priv_data->dev; struct reset_control *crst, *hibrst, *apbrst; + struct gpio_desc *reset_gpio; struct phy *usb3_phy; int ret = 0; u32 reg; @@ -201,6 +203,21 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) } skip_usb3_phy: + /* ulpi reset via gpio-modepin or gpio-framework driver */ + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) { + return dev_err_probe(dev, PTR_ERR(reset_gpio), + "Failed to request reset GPIO\n"); + } + + if (reset_gpio) { + /* Toggle ulpi to reset the phy. */ + gpiod_set_value_cansleep(reset_gpio, 1); + usleep_range(5000, 10000); + gpiod_set_value_cansleep(reset_gpio, 0); + usleep_range(5000, 10000); + } + /* * This routes the USB DMA traffic to go through FPD path instead * of reaching DDR directly. This traffic routing is needed to |