mirror of
https://github.com/armbian/build.git
synced 2025-08-14 15:16:58 +02:00
178 lines
6.4 KiB
Diff
178 lines
6.4 KiB
Diff
From ed02ac606b91990e9417d5a91dc7c905a115cf6d Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 3 Mar 2018 22:43:03 +0100
|
|
Subject: [PATCH] usb: add a flag to skip PHY initialization to struct usb_hcd
|
|
|
|
The USB HCD core driver parses the device-tree node for "phys" and
|
|
"usb-phys" properties. It also manages the power state of these PHYs
|
|
automatically.
|
|
However, drivers may opt-out of this behavior by setting "phy" or
|
|
"usb_phy" in struct usb_hcd to a non-null value. An example where this
|
|
is required is the "Qualcomm USB2 controller", implemented by the
|
|
chipidea driver. The hardware requires that the PHY is only powered on
|
|
after the "reset completed" event from the controller is received.
|
|
|
|
A follow-up patch will allow the USB HCD core driver to manage more than
|
|
one PHY. Add a new "skip_phy_initialization" bitflag to struct usb_hcd
|
|
so drivers can opt-out of any PHY management provided by the USB HCD
|
|
core driver.
|
|
|
|
This also updates the existing drivers so they use the new flag if they
|
|
want to opt out of the PHY management provided by the USB HCD core
|
|
driver. This means that for these drivers the new "multiple PHY"
|
|
handling (which will be added in a follow-up patch) will be disabled as
|
|
well.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Acked-by: Peter Chen <peter.chen@nxp.com>
|
|
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
|
---
|
|
drivers/usb/chipidea/host.c | 6 ++----
|
|
drivers/usb/core/hcd.c | 4 ++--
|
|
drivers/usb/host/ehci-fsl.c | 2 ++
|
|
drivers/usb/host/ehci-platform.c | 4 ++--
|
|
drivers/usb/host/ehci-tegra.c | 1 +
|
|
drivers/usb/host/ohci-omap.c | 1 +
|
|
drivers/usb/host/ohci-platform.c | 4 ++--
|
|
drivers/usb/host/xhci-plat.c | 1 +
|
|
include/linux/usb/hcd.h | 6 ++++++
|
|
9 files changed, 19 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
|
|
index 19d60ed..af45aa32 100644
|
|
--- a/drivers/usb/chipidea/host.c
|
|
+++ b/drivers/usb/chipidea/host.c
|
|
@@ -124,10 +124,8 @@ static int host_start(struct ci_hdrc *ci)
|
|
|
|
hcd->power_budget = ci->platdata->power_budget;
|
|
hcd->tpl_support = ci->platdata->tpl_support;
|
|
- if (ci->phy)
|
|
- hcd->phy = ci->phy;
|
|
- else
|
|
- hcd->usb_phy = ci->usb_phy;
|
|
+ if (ci->phy || ci->usb_phy)
|
|
+ hcd->skip_phy_initialization = 1;
|
|
|
|
ehci = hcd_to_ehci(hcd);
|
|
ehci->caps = ci->hw_bank.cap;
|
|
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
|
|
index fc32391..f230747 100644
|
|
--- a/drivers/usb/core/hcd.c
|
|
+++ b/drivers/usb/core/hcd.c
|
|
@@ -2727,7 +2727,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
|
int retval;
|
|
struct usb_device *rhdev;
|
|
|
|
- if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->usb_phy) {
|
|
+ if (IS_ENABLED(CONFIG_USB_PHY) && !hcd->skip_phy_initialization) {
|
|
struct usb_phy *phy = usb_get_phy_dev(hcd->self.sysdev, 0);
|
|
|
|
if (IS_ERR(phy)) {
|
|
@@ -2745,7 +2745,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
|
}
|
|
}
|
|
|
|
- if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->phy) {
|
|
+ if (IS_ENABLED(CONFIG_GENERIC_PHY) && !hcd->skip_phy_initialization) {
|
|
struct phy *phy = phy_get(hcd->self.sysdev, "usb");
|
|
|
|
if (IS_ERR(phy)) {
|
|
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
|
|
index c5094cb..0a9fd20 100644
|
|
--- a/drivers/usb/host/ehci-fsl.c
|
|
+++ b/drivers/usb/host/ehci-fsl.c
|
|
@@ -155,6 +155,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
|
|
retval = -ENODEV;
|
|
goto err2;
|
|
}
|
|
+
|
|
+ hcd->skip_phy_initialization = 1;
|
|
}
|
|
#endif
|
|
return retval;
|
|
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
|
|
index b065a96..b91eea8 100644
|
|
--- a/drivers/usb/host/ehci-platform.c
|
|
+++ b/drivers/usb/host/ehci-platform.c
|
|
@@ -219,9 +219,9 @@ static int ehci_platform_probe(struct platform_device *dev)
|
|
if (IS_ERR(priv->phys[phy_num])) {
|
|
err = PTR_ERR(priv->phys[phy_num]);
|
|
goto err_put_hcd;
|
|
- } else if (!hcd->phy) {
|
|
+ } else {
|
|
/* Avoiding phy_get() in usb_add_hcd() */
|
|
- hcd->phy = priv->phys[phy_num];
|
|
+ hcd->skip_phy_initialization = 1;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
|
|
index c809f7d..a6f4389 100644
|
|
--- a/drivers/usb/host/ehci-tegra.c
|
|
+++ b/drivers/usb/host/ehci-tegra.c
|
|
@@ -461,6 +461,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)
|
|
goto cleanup_clk_en;
|
|
}
|
|
hcd->usb_phy = u_phy;
|
|
+ hcd->skip_phy_initialization = 1;
|
|
|
|
tegra->needs_double_reset = of_property_read_bool(pdev->dev.of_node,
|
|
"nvidia,needs-double-reset");
|
|
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
|
|
index 0201c49..d8d35d4 100644
|
|
--- a/drivers/usb/host/ohci-omap.c
|
|
+++ b/drivers/usb/host/ohci-omap.c
|
|
@@ -230,6 +230,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
|
|
} else {
|
|
return -EPROBE_DEFER;
|
|
}
|
|
+ hcd->skip_phy_initialization = 1;
|
|
ohci->start_hnp = start_hnp;
|
|
}
|
|
#endif
|
|
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
|
|
index 1e6c954..62ef36a 100644
|
|
--- a/drivers/usb/host/ohci-platform.c
|
|
+++ b/drivers/usb/host/ohci-platform.c
|
|
@@ -186,9 +186,9 @@ static int ohci_platform_probe(struct platform_device *dev)
|
|
if (IS_ERR(priv->phys[phy_num])) {
|
|
err = PTR_ERR(priv->phys[phy_num]);
|
|
goto err_put_hcd;
|
|
- } else if (!hcd->phy) {
|
|
+ } else {
|
|
/* Avoiding phy_get() in usb_add_hcd() */
|
|
- hcd->phy = priv->phys[phy_num];
|
|
+ hcd->skip_phy_initialization = 1;
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
|
|
index 6652e2d..df327dc 100644
|
|
--- a/drivers/usb/host/xhci-plat.c
|
|
+++ b/drivers/usb/host/xhci-plat.c
|
|
@@ -284,6 +284,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
|
ret = usb_phy_init(hcd->usb_phy);
|
|
if (ret)
|
|
goto put_usb3_hcd;
|
|
+ hcd->skip_phy_initialization = 1;
|
|
}
|
|
|
|
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
|
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
|
|
index 1769005..693502c 100644
|
|
--- a/include/linux/usb/hcd.h
|
|
+++ b/include/linux/usb/hcd.h
|
|
@@ -151,6 +151,12 @@ struct usb_hcd {
|
|
unsigned msix_enabled:1; /* driver has MSI-X enabled? */
|
|
unsigned msi_enabled:1; /* driver has MSI enabled? */
|
|
unsigned remove_phy:1; /* auto-remove USB phy */
|
|
+ /*
|
|
+ * do not manage the PHY state in the HCD core, instead let the driver
|
|
+ * handle this (for example if the PHY can only be turned on after a
|
|
+ * specific event)
|
|
+ */
|
|
+ unsigned skip_phy_initialization:1;
|
|
|
|
/* The next flag is a stopgap, to be removed when all the HCDs
|
|
* support the new root-hub polling mechanism. */
|