summaryrefslogtreecommitdiffstats
path: root/arm-tegra-USB-driver-dependency-fix.patch
diff options
context:
space:
mode:
authorPeter Robinson <pbrobinson@gmail.com>2018-05-07 15:05:53 +0100
committerPeter Robinson <pbrobinson@gmail.com>2018-05-07 15:05:53 +0100
commit8e0d842c37938d5c3a8ccd4afe42c979599523ef (patch)
tree1f3b2fa20191a36c7c1321dd5e4a631f2383ba36 /arm-tegra-USB-driver-dependency-fix.patch
parentd3854d75b079d389fd408246cb401da4f17e24a3 (diff)
downloadkernel-8e0d842c37938d5c3a8ccd4afe42c979599523ef.tar.gz
kernel-8e0d842c37938d5c3a8ccd4afe42c979599523ef.tar.xz
kernel-8e0d842c37938d5c3a8ccd4afe42c979599523ef.zip
add patch
Diffstat (limited to 'arm-tegra-USB-driver-dependency-fix.patch')
-rw-r--r--arm-tegra-USB-driver-dependency-fix.patch610
1 files changed, 610 insertions, 0 deletions
diff --git a/arm-tegra-USB-driver-dependency-fix.patch b/arm-tegra-USB-driver-dependency-fix.patch
new file mode 100644
index 000000000..b1a80137b
--- /dev/null
+++ b/arm-tegra-USB-driver-dependency-fix.patch
@@ -0,0 +1,610 @@
+From patchwork Mon Apr 9 22:02:57 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v3,1/3] usb: phy: tegra: Cleanup error messages
+X-Patchwork-Submitter: Dmitry Osipenko <digetx@gmail.com>
+X-Patchwork-Id: 896433
+Message-Id: <c08393c7ac6964d14750e8a4b0ffa34884b1416f.1523307883.git.digetx@gmail.com>
+To: Thierry Reding <thierry.reding@gmail.com>,
+ Jonathan Hunter <jonathanh@nvidia.com>, Felipe Balbi <balbi@kernel.org>,
+ Alan Stern <stern@rowland.harvard.edu>,
+ Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org,
+ linux-kernel@vger.kernel.org
+Date: Tue, 10 Apr 2018 01:02:57 +0300
+From: Dmitry Osipenko <digetx@gmail.com>
+List-Id: <linux-tegra.vger.kernel.org>
+
+Tegra's PHY driver has a mix of pr_err() and dev_err(), let's switch to
+dev_err() and use common errors message formatting across the driver for
+consistency.
+
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+---
+ drivers/usb/phy/phy-tegra-usb.c | 69 ++++++++++++++++++++++++-----------------
+ 1 file changed, 41 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
+index 0e8d23e51732..e46219e7fa93 100644
+--- a/drivers/usb/phy/phy-tegra-usb.c
++++ b/drivers/usb/phy/phy-tegra-usb.c
+@@ -236,10 +236,14 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable)
+
+ static int utmip_pad_open(struct tegra_usb_phy *phy)
+ {
++ int err;
++
+ phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads");
+ if (IS_ERR(phy->pad_clk)) {
+- pr_err("%s: can't get utmip pad clock\n", __func__);
+- return PTR_ERR(phy->pad_clk);
++ err = PTR_ERR(phy->pad_clk);
++ dev_err(phy->u_phy.dev,
++ "Failed to get UTMIP pad clock: %d\n", err);
++ return err;
+ }
+
+ return 0;
+@@ -282,7 +286,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy)
+ void __iomem *base = phy->pad_regs;
+
+ if (!utmip_pad_count) {
+- pr_err("%s: utmip pad already powered off\n", __func__);
++ dev_err(phy->u_phy.dev, "UTMIP pad already powered off\n");
+ return -EINVAL;
+ }
+
+@@ -338,7 +342,8 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
+ set_phcd(phy, true);
+
+ if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
+- pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
++ dev_err(phy->u_phy.dev,
++ "Timeout waiting for PHY to stabilize on disable\n");
+ }
+
+ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
+@@ -370,7 +375,8 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
+
+ if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
+ USB_PHY_CLK_VALID))
+- pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
++ dev_err(phy->u_phy.dev,
++ "Timeout waiting for PHY to stabilize on enable\n");
+ }
+
+ static int utmi_phy_power_on(struct tegra_usb_phy *phy)
+@@ -617,15 +623,15 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
+
+ ret = gpio_direction_output(phy->reset_gpio, 0);
+ if (ret < 0) {
+- dev_err(phy->u_phy.dev, "gpio %d not set to 0\n",
+- phy->reset_gpio);
++ dev_err(phy->u_phy.dev, "GPIO %d not set to 0: %d\n",
++ phy->reset_gpio, ret);
+ return ret;
+ }
+ msleep(5);
+ ret = gpio_direction_output(phy->reset_gpio, 1);
+ if (ret < 0) {
+- dev_err(phy->u_phy.dev, "gpio %d not set to 1\n",
+- phy->reset_gpio);
++ dev_err(phy->u_phy.dev, "GPIO %d not set to 1: %d\n",
++ phy->reset_gpio, ret);
+ return ret;
+ }
+
+@@ -661,13 +667,13 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
+ /* Fix VbusInvalid due to floating VBUS */
+ ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08);
+ if (ret) {
+- pr_err("%s: ulpi write failed\n", __func__);
++ dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B);
+ if (ret) {
+- pr_err("%s: ulpi write failed\n", __func__);
++ dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret);
+ return ret;
+ }
+
+@@ -728,28 +734,30 @@ static int ulpi_open(struct tegra_usb_phy *phy)
+
+ phy->clk = devm_clk_get(phy->u_phy.dev, "ulpi-link");
+ if (IS_ERR(phy->clk)) {
+- pr_err("%s: can't get ulpi clock\n", __func__);
+- return PTR_ERR(phy->clk);
++ err = PTR_ERR(phy->clk);
++ dev_err(phy->u_phy.dev, "Failed to get ULPI clock: %d\n", err);
++ return err;
+ }
+
+ err = devm_gpio_request(phy->u_phy.dev, phy->reset_gpio,
+ "ulpi_phy_reset_b");
+ if (err < 0) {
+- dev_err(phy->u_phy.dev, "request failed for gpio: %d\n",
+- phy->reset_gpio);
++ dev_err(phy->u_phy.dev, "Request failed for GPIO %d: %d\n",
++ phy->reset_gpio, err);
+ return err;
+ }
+
+ err = gpio_direction_output(phy->reset_gpio, 0);
+ if (err < 0) {
+- dev_err(phy->u_phy.dev, "gpio %d direction not set to output\n",
+- phy->reset_gpio);
++ dev_err(phy->u_phy.dev,
++ "GPIO %d direction not set to output: %d\n",
++ phy->reset_gpio, err);
+ return err;
+ }
+
+ phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
+ if (!phy->ulpi) {
+- dev_err(phy->u_phy.dev, "otg_ulpi_create returned NULL\n");
++ dev_err(phy->u_phy.dev, "Failed to create ULPI OTG\n");
+ err = -ENOMEM;
+ return err;
+ }
+@@ -766,8 +774,10 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
+
+ phy->pll_u = devm_clk_get(phy->u_phy.dev, "pll_u");
+ if (IS_ERR(phy->pll_u)) {
+- pr_err("Can't get pll_u clock\n");
+- return PTR_ERR(phy->pll_u);
++ err = PTR_ERR(phy->pll_u);
++ dev_err(phy->u_phy.dev,
++ "Failed to get pll_u clock: %d\n", err);
++ return err;
+ }
+
+ err = clk_prepare_enable(phy->pll_u);
+@@ -782,7 +792,8 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
+ }
+ }
+ if (!phy->freq) {
+- pr_err("invalid pll_u parent rate %ld\n", parent_rate);
++ dev_err(phy->u_phy.dev, "Invalid pll_u parent rate %ld\n",
++ parent_rate);
+ err = -EINVAL;
+ goto fail;
+ }
+@@ -791,7 +802,7 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy)
+ err = regulator_enable(phy->vbus);
+ if (err) {
+ dev_err(phy->u_phy.dev,
+- "failed to enable usb vbus regulator: %d\n",
++ "Failed to enable USB VBUS regulator: %d\n",
+ err);
+ goto fail;
+ }
+@@ -855,7 +866,8 @@ static int read_utmi_param(struct platform_device *pdev, const char *param,
+ int err = of_property_read_u32(pdev->dev.of_node, param, &value);
+ *dest = (u8)value;
+ if (err < 0)
+- dev_err(&pdev->dev, "Failed to read USB UTMI parameter %s: %d\n",
++ dev_err(&pdev->dev,
++ "Failed to read USB UTMI parameter %s: %d\n",
+ param, err);
+ return err;
+ }
+@@ -871,14 +883,14 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy,
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+- dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n");
++ dev_err(&pdev->dev, "Failed to get UTMI pad regs\n");
+ return -ENXIO;
+ }
+
+ tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!tegra_phy->pad_regs) {
+- dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n");
++ dev_err(&pdev->dev, "Failed to remap UTMI pad regs\n");
+ return -ENOMEM;
+ }
+
+@@ -1020,15 +1032,16 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
+ tegra_phy->reset_gpio =
+ of_get_named_gpio(np, "nvidia,phy-reset-gpio", 0);
+ if (!gpio_is_valid(tegra_phy->reset_gpio)) {
+- dev_err(&pdev->dev, "invalid gpio: %d\n",
+- tegra_phy->reset_gpio);
++ dev_err(&pdev->dev,
++ "Invalid GPIO: %d\n", tegra_phy->reset_gpio);
+ return tegra_phy->reset_gpio;
+ }
+ tegra_phy->config = NULL;
+ break;
+
+ default:
+- dev_err(&pdev->dev, "phy_type is invalid or unsupported\n");
++ dev_err(&pdev->dev, "phy_type %u is invalid or unsupported\n",
++ phy_type);
+ return -EINVAL;
+ }
+
+
+From patchwork Mon Apr 9 22:02:58 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v3,
+ 2/3] usb: tegra: Move utmi-pads reset from ehci-tegra to tegra-phy
+X-Patchwork-Submitter: Dmitry Osipenko <digetx@gmail.com>
+X-Patchwork-Id: 896435
+Message-Id: <66330166c6a53e8f463ec231e3cb8195fa3036cc.1523307883.git.digetx@gmail.com>
+To: Thierry Reding <thierry.reding@gmail.com>,
+ Jonathan Hunter <jonathanh@nvidia.com>, Felipe Balbi <balbi@kernel.org>,
+ Alan Stern <stern@rowland.harvard.edu>,
+ Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org,
+ linux-kernel@vger.kernel.org
+Date: Tue, 10 Apr 2018 01:02:58 +0300
+From: Dmitry Osipenko <digetx@gmail.com>
+List-Id: <linux-tegra.vger.kernel.org>
+
+UTMI pads are shared by USB controllers and reset of UTMI pads is shared
+with the reset of USB1 controller. Currently reset of UTMI pads is done by
+the EHCI driver and ChipIdea UDC works because EHCI driver always happen
+to be probed first. Move reset controls from ehci-tegra to tegra-phy in
+order to resolve the problem.
+
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+---
+ drivers/usb/host/ehci-tegra.c | 87 ++++++++++++++++++---------------------
+ drivers/usb/phy/phy-tegra-usb.c | 79 ++++++++++++++++++++++++++++++++---
+ include/linux/usb/tegra_usb_phy.h | 2 +
+ 3 files changed, 115 insertions(+), 53 deletions(-)
+
+diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
+index a6f4389f7e88..4d2cdec4cb78 100644
+--- a/drivers/usb/host/ehci-tegra.c
++++ b/drivers/usb/host/ehci-tegra.c
+@@ -36,7 +36,6 @@
+ #define DRV_NAME "tegra-ehci"
+
+ static struct hc_driver __read_mostly tegra_ehci_hc_driver;
+-static bool usb1_reset_attempted;
+
+ struct tegra_ehci_soc_config {
+ bool has_hostpc;
+@@ -51,67 +50,54 @@ struct tegra_ehci_hcd {
+ enum tegra_usb_phy_port_speed port_speed;
+ };
+
+-/*
+- * The 1st USB controller contains some UTMI pad registers that are global for
+- * all the controllers on the chip. Those registers are also cleared when
+- * reset is asserted to the 1st controller. This means that the 1st controller
+- * can only be reset when no other controlled has finished probing. So we'll
+- * reset the 1st controller before doing any other setup on any of the
+- * controllers, and then never again.
+- *
+- * Since this is a PHY issue, the Tegra PHY driver should probably be doing
+- * the resetting of the USB controllers. But to keep compatibility with old
+- * device trees that don't have reset phandles in the PHYs, do it here.
+- * Those old DTs will be vulnerable to total USB breakage if the 1st EHCI
+- * device isn't the first one to finish probing, so warn them.
+- */
+ static int tegra_reset_usb_controller(struct platform_device *pdev)
+ {
+ struct device_node *phy_np;
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct tegra_ehci_hcd *tegra =
+ (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv;
+- bool has_utmi_pad_registers = false;
++ struct reset_control *rst;
++ int err;
+
+ phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0);
+ if (!phy_np)
+ return -ENOENT;
+
+- if (of_property_read_bool(phy_np, "nvidia,has-utmi-pad-registers"))
+- has_utmi_pad_registers = true;
++ /*
++ * The 1st USB controller contains some UTMI pad registers that are
++ * global for all the controllers on the chip. Those registers are
++ * also cleared when reset is asserted to the 1st controller.
++ */
++ rst = of_reset_control_get_shared(phy_np, "utmi-pads");
++ if (IS_ERR(rst)) {
++ dev_warn(&pdev->dev,
++ "can't get utmi-pads reset from the PHY\n");
++ dev_warn(&pdev->dev,
++ "continuing, but please update your DT\n");
++ } else {
++ /*
++ * PHY driver performs UTMI-pads reset in a case of
++ * non-legacy DT.
++ */
++ reset_control_put(rst);
++ }
+
+- if (!usb1_reset_attempted) {
+- struct reset_control *usb1_reset;
++ of_node_put(phy_np);
+
+- if (!has_utmi_pad_registers)
+- usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
+- else
+- usb1_reset = tegra->rst;
+-
+- if (IS_ERR(usb1_reset)) {
+- dev_warn(&pdev->dev,
+- "can't get utmi-pads reset from the PHY\n");
+- dev_warn(&pdev->dev,
+- "continuing, but please update your DT\n");
+- } else {
+- reset_control_assert(usb1_reset);
+- udelay(1);
+- reset_control_deassert(usb1_reset);
+-
+- if (!has_utmi_pad_registers)
+- reset_control_put(usb1_reset);
+- }
++ /* reset control is shared, hence initialize it first */
++ err = reset_control_deassert(tegra->rst);
++ if (err)
++ return err;
+
+- usb1_reset_attempted = true;
+- }
++ err = reset_control_assert(tegra->rst);
++ if (err)
++ return err;
+
+- if (!has_utmi_pad_registers) {
+- reset_control_assert(tegra->rst);
+- udelay(1);
+- reset_control_deassert(tegra->rst);
+- }
++ udelay(1);
+
+- of_node_put(phy_np);
++ err = reset_control_deassert(tegra->rst);
++ if (err)
++ return err;
+
+ return 0;
+ }
+@@ -440,7 +426,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
+ goto cleanup_hcd_create;
+ }
+
+- tegra->rst = devm_reset_control_get(&pdev->dev, "usb");
++ tegra->rst = devm_reset_control_get_shared(&pdev->dev, "usb");
+ if (IS_ERR(tegra->rst)) {
+ dev_err(&pdev->dev, "Can't get ehci reset\n");
+ err = PTR_ERR(tegra->rst);
+@@ -452,8 +438,10 @@ static int tegra_ehci_probe(struct platform_device *pdev)
+ goto cleanup_hcd_create;
+
+ err = tegra_reset_usb_controller(pdev);
+- if (err)
++ if (err) {
++ dev_err(&pdev->dev, "Failed to reset controller\n");
+ goto cleanup_clk_en;
++ }
+
+ u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);
+ if (IS_ERR(u_phy)) {
+@@ -538,6 +526,9 @@ static int tegra_ehci_remove(struct platform_device *pdev)
+ usb_phy_shutdown(hcd->usb_phy);
+ usb_remove_hcd(hcd);
+
++ reset_control_assert(tegra->rst);
++ udelay(1);
++
+ clk_disable_unprepare(tegra->clk);
+
+ usb_put_hcd(hcd);
+diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c
+index e46219e7fa93..ea7ef1dc0b42 100644
+--- a/drivers/usb/phy/phy-tegra-usb.c
++++ b/drivers/usb/phy/phy-tegra-usb.c
+@@ -236,17 +236,83 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable)
+
+ static int utmip_pad_open(struct tegra_usb_phy *phy)
+ {
+- int err;
++ int ret;
+
+ phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads");
+ if (IS_ERR(phy->pad_clk)) {
+- err = PTR_ERR(phy->pad_clk);
++ ret = PTR_ERR(phy->pad_clk);
+ dev_err(phy->u_phy.dev,
+- "Failed to get UTMIP pad clock: %d\n", err);
+- return err;
++ "Failed to get UTMIP pad clock: %d\n", ret);
++ return ret;
+ }
+
+- return 0;
++ phy->pad_rst = devm_reset_control_get_optional_shared(
++ phy->u_phy.dev, "utmi-pads");
++ if (IS_ERR(phy->pad_rst)) {
++ ret = PTR_ERR(phy->pad_rst);
++ dev_err(phy->u_phy.dev,
++ "Failed to get UTMI-pads reset: %d\n", ret);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(phy->pad_clk);
++ if (ret) {
++ dev_err(phy->u_phy.dev,
++ "Failed to enable UTMI-pads clock: %d\n", ret);
++ return ret;
++ }
++
++ spin_lock(&utmip_pad_lock);
++
++ ret = reset_control_deassert(phy->pad_rst);
++ if (ret) {
++ dev_err(phy->u_phy.dev,
++ "Failed to initialize UTMI-pads reset: %d\n", ret);
++ goto unlock;
++ }
++
++ ret = reset_control_assert(phy->pad_rst);
++ if (ret) {
++ dev_err(phy->u_phy.dev,
++ "Failed to assert UTMI-pads reset: %d\n", ret);
++ goto unlock;
++ }
++
++ udelay(1);
++
++ ret = reset_control_deassert(phy->pad_rst);
++ if (ret)
++ dev_err(phy->u_phy.dev,
++ "Failed to deassert UTMI-pads reset: %d\n", ret);
++unlock:
++ spin_unlock(&utmip_pad_lock);
++
++ clk_disable_unprepare(phy->pad_clk);
++
++ return ret;
++}
++
++static int utmip_pad_close(struct tegra_usb_phy *phy)
++{
++ int ret;
++
++ ret = clk_prepare_enable(phy->pad_clk);
++ if (ret) {
++ dev_err(phy->u_phy.dev,
++ "Failed to enable UTMI-pads clock: %d\n", ret);
++ return ret;
++ }
++
++ ret = reset_control_assert(phy->pad_rst);
++ if (ret)
++ dev_err(phy->u_phy.dev,
++ "Failed to assert UTMI-pads reset: %d\n", ret);
++
++ udelay(1);
++
++ clk_disable_unprepare(phy->pad_clk);
++
++ return ret;
+ }
+
+ static void utmip_pad_power_on(struct tegra_usb_phy *phy)
+@@ -700,6 +766,9 @@ static void tegra_usb_phy_close(struct tegra_usb_phy *phy)
+ if (!IS_ERR(phy->vbus))
+ regulator_disable(phy->vbus);
+
++ if (!phy->is_ulpi_phy)
++ utmip_pad_close(phy);
++
+ clk_disable_unprepare(phy->pll_u);
+ }
+
+diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h
+index d641ea1660b7..0c5c3ea8b2d7 100644
+--- a/include/linux/usb/tegra_usb_phy.h
++++ b/include/linux/usb/tegra_usb_phy.h
+@@ -17,6 +17,7 @@
+ #define __TEGRA_USB_PHY_H
+
+ #include <linux/clk.h>
++#include <linux/reset.h>
+ #include <linux/usb/otg.h>
+
+ /*
+@@ -76,6 +77,7 @@ struct tegra_usb_phy {
+ bool is_legacy_phy;
+ bool is_ulpi_phy;
+ int reset_gpio;
++ struct reset_control *pad_rst;
+ };
+
+ void tegra_usb_phy_preresume(struct usb_phy *phy);
+
+From patchwork Mon Apr 9 22:02:59 2018
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v3,3/3] usb: phy: Add Kconfig entry for Tegra PHY driver
+X-Patchwork-Submitter: Dmitry Osipenko <digetx@gmail.com>
+X-Patchwork-Id: 896434
+Message-Id: <aad79a65528636ee5fd217cfb7273de10147fc13.1523307883.git.digetx@gmail.com>
+To: Thierry Reding <thierry.reding@gmail.com>,
+ Jonathan Hunter <jonathanh@nvidia.com>, Felipe Balbi <balbi@kernel.org>,
+ Alan Stern <stern@rowland.harvard.edu>,
+ Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org,
+ linux-kernel@vger.kernel.org
+Date: Tue, 10 Apr 2018 01:02:59 +0300
+From: Dmitry Osipenko <digetx@gmail.com>
+List-Id: <linux-tegra.vger.kernel.org>
+
+Tegra's EHCI driver has a build dependency on Tegra's PHY driver and
+currently Tegra's PHY driver is built only when Tegra's EHCI driver is
+built. Add own Kconfig entry for the Tegra's PHY driver so that drivers
+other than ehci-tegra (like ChipIdea UDC) could work with ehci-tegra
+driver being disabled in kernels config by allowing user to manually
+select the PHY driver.
+
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+---
+ drivers/usb/host/Kconfig | 4 +---
+ drivers/usb/phy/Kconfig | 9 +++++++++
+ drivers/usb/phy/Makefile | 2 +-
+ 3 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 5d958da8e1bc..9f0aeb068acb 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -234,9 +234,7 @@ config USB_EHCI_TEGRA
+ tristate "NVIDIA Tegra HCD support"
+ depends on ARCH_TEGRA
+ select USB_EHCI_ROOT_HUB_TT
+- select USB_PHY
+- select USB_ULPI
+- select USB_ULPI_VIEWPORT
++ select USB_TEGRA_PHY
+ help
+ This driver enables support for the internal USB Host Controllers
+ found in NVIDIA Tegra SoCs. The controllers are EHCI compliant.
+diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
+index 0f8ab981d572..b9b0a44be679 100644
+--- a/drivers/usb/phy/Kconfig
++++ b/drivers/usb/phy/Kconfig
+@@ -159,6 +159,15 @@ config USB_MXS_PHY
+
+ MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x.
+
++config USB_TEGRA_PHY
++ tristate "NVIDIA Tegra USB PHY Driver"
++ depends on ARCH_TEGRA
++ select USB_PHY
++ select USB_ULPI
++ help
++ This driver provides PHY support for the USB controllers found
++ on NVIDIA Tegra SoC's.
++
+ config USB_ULPI
+ bool "Generic ULPI Transceiver Driver"
+ depends on ARM || ARM64
+diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
+index 25e579fb92b8..df1d99010079 100644
+--- a/drivers/usb/phy/Makefile
++++ b/drivers/usb/phy/Makefile
+@@ -16,7 +16,7 @@ obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o
+ obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o
+ obj-$(CONFIG_OMAP_OTG) += phy-omap-otg.o
+ obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o
+-obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o
++obj-$(CONFIG_USB_TEGRA_PHY) += phy-tegra-usb.o
+ obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o
+ obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o
+ obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o