aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/usb/host/ohci-exynos.c
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2019-05-20 11:08:23 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-21 08:34:49 +0200
commit01d4071486fe18ec91f78725d81c7e46557c629a (patch)
treecd7dd0cbccbfeace82a48d4b4f0135babafcbf5d /drivers/usb/host/ohci-exynos.c
parentusbip: usbip_host: cleanup do_rebind() return path (diff)
downloadwireguard-linux-01d4071486fe18ec91f78725d81c7e46557c629a.tar.xz
wireguard-linux-01d4071486fe18ec91f78725d81c7e46557c629a.zip
usb: exynos: add workaround for the USB device bindings conflict
Commit 69bec7259853 ("USB: core: let USB device know device node") added support for attaching devicetree node for USB devices. Those nodes are children of their USB host controller. However Exynos EHCI and OHCI driver bindings already define child-nodes for each physical root hub port and assigns respective PHY controller and parameters to them. Those bindings predates support for USB device tree nodes. To mitigate the side-effects of the conflict between those bindings, lets reset Exynos host controller of_node pointer before registering it to USB subsystem. This fixes the issue raised by the commit 01fdf179f4b0 ("usb: core: skip interfaces disabled in devicetree"), which incorrectly disabled some devices on Exynos based boards. Reported-by: Markus Reichl <m.reichl@fivetechno.de> Suggested-by: Måns Rullgård <mans@mansr.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ohci-exynos.c')
-rw-r--r--drivers/usb/host/ohci-exynos.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index c0c4dcca6f3c..905c6317e0c3 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -30,6 +30,7 @@ static struct hc_driver __read_mostly exynos_ohci_hc_driver;
struct exynos_ohci_hcd {
struct clk *clk;
+ struct device_node *of_node;
struct phy *phy[PHY_NUMBER];
};
@@ -170,6 +171,13 @@ static int exynos_ohci_probe(struct platform_device *pdev)
goto fail_io;
}
+ /*
+ * Workaround: reset of_node pointer to avoid conflict between Exynos
+ * OHCI port subnodes and generic USB device bindings
+ */
+ exynos_ohci->of_node = pdev->dev.of_node;
+ pdev->dev.of_node = NULL;
+
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err) {
dev_err(&pdev->dev, "Failed to add USB HCD\n");
@@ -180,6 +188,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
fail_add_hcd:
exynos_ohci_phy_disable(&pdev->dev);
+ pdev->dev.of_node = exynos_ohci->of_node;
fail_io:
clk_disable_unprepare(exynos_ohci->clk);
fail_clk:
@@ -192,6 +201,8 @@ static int exynos_ohci_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
+ pdev->dev.of_node = exynos_ohci->of_node;
+
usb_remove_hcd(hcd);
exynos_ohci_phy_disable(&pdev->dev);