diff options
Diffstat (limited to 'drivers/usb/host/ehci-exynos.c')
-rw-r--r-- | drivers/usb/host/ehci-exynos.c | 74 |
1 files changed, 20 insertions, 54 deletions
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 2eed9a4f89a9..7189f2e32ac2 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c | |||
@@ -21,11 +21,8 @@ | |||
21 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
22 | #include <linux/phy/phy.h> | 22 | #include <linux/phy/phy.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/usb/phy.h> | ||
25 | #include <linux/usb/samsung_usb_phy.h> | ||
26 | #include <linux/usb.h> | 24 | #include <linux/usb.h> |
27 | #include <linux/usb/hcd.h> | 25 | #include <linux/usb/hcd.h> |
28 | #include <linux/usb/otg.h> | ||
29 | 26 | ||
30 | #include "ehci.h" | 27 | #include "ehci.h" |
31 | 28 | ||
@@ -47,9 +44,7 @@ static struct hc_driver __read_mostly exynos_ehci_hc_driver; | |||
47 | 44 | ||
48 | struct exynos_ehci_hcd { | 45 | struct exynos_ehci_hcd { |
49 | struct clk *clk; | 46 | struct clk *clk; |
50 | struct usb_phy *phy; | 47 | struct phy *phy[PHY_NUMBER]; |
51 | struct usb_otg *otg; | ||
52 | struct phy *phy_g[PHY_NUMBER]; | ||
53 | }; | 48 | }; |
54 | 49 | ||
55 | #define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv) | 50 | #define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv) |
@@ -60,8 +55,9 @@ static int exynos_ehci_get_phy(struct device *dev, | |||
60 | struct device_node *child; | 55 | struct device_node *child; |
61 | struct phy *phy; | 56 | struct phy *phy; |
62 | int phy_number; | 57 | int phy_number; |
63 | int ret = 0; | 58 | int ret; |
64 | 59 | ||
60 | /* Get PHYs for the controller */ | ||
65 | for_each_available_child_of_node(dev->of_node, child) { | 61 | for_each_available_child_of_node(dev->of_node, child) { |
66 | ret = of_property_read_u32(child, "reg", &phy_number); | 62 | ret = of_property_read_u32(child, "reg", &phy_number); |
67 | if (ret) { | 63 | if (ret) { |
@@ -77,31 +73,21 @@ static int exynos_ehci_get_phy(struct device *dev, | |||
77 | } | 73 | } |
78 | 74 | ||
79 | phy = devm_of_phy_get(dev, child, NULL); | 75 | phy = devm_of_phy_get(dev, child, NULL); |
76 | exynos_ehci->phy[phy_number] = phy; | ||
80 | of_node_put(child); | 77 | of_node_put(child); |
81 | if (IS_ERR(phy)) | 78 | if (IS_ERR(phy)) { |
82 | /* Lets fallback to older USB-PHYs */ | 79 | ret = PTR_ERR(phy); |
83 | goto usb_phy_old; | 80 | if (ret == -EPROBE_DEFER) { |
84 | exynos_ehci->phy_g[phy_number] = phy; | 81 | return ret; |
85 | /* Make the older PHYs unavailable */ | 82 | } else if (ret != -ENOSYS && ret != -ENODEV) { |
86 | exynos_ehci->phy = ERR_PTR(-ENXIO); | 83 | dev_err(dev, |
87 | } | 84 | "Error retrieving usb2 phy: %d\n", ret); |
88 | 85 | return ret; | |
89 | return 0; | 86 | } |
90 | |||
91 | usb_phy_old: | ||
92 | exynos_ehci->phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
93 | if (IS_ERR(exynos_ehci->phy)) { | ||
94 | ret = PTR_ERR(exynos_ehci->phy); | ||
95 | if (ret != -ENXIO && ret != -ENODEV) { | ||
96 | dev_err(dev, "no usb2 phy configured\n"); | ||
97 | return ret; | ||
98 | } | 87 | } |
99 | dev_dbg(dev, "Failed to get usb2 phy\n"); | ||
100 | } else { | ||
101 | exynos_ehci->otg = exynos_ehci->phy->otg; | ||
102 | } | 88 | } |
103 | 89 | ||
104 | return ret; | 90 | return 0; |
105 | } | 91 | } |
106 | 92 | ||
107 | static int exynos_ehci_phy_enable(struct device *dev) | 93 | static int exynos_ehci_phy_enable(struct device *dev) |
@@ -111,16 +97,13 @@ static int exynos_ehci_phy_enable(struct device *dev) | |||
111 | int i; | 97 | int i; |
112 | int ret = 0; | 98 | int ret = 0; |
113 | 99 | ||
114 | if (!IS_ERR(exynos_ehci->phy)) | ||
115 | return usb_phy_init(exynos_ehci->phy); | ||
116 | |||
117 | for (i = 0; ret == 0 && i < PHY_NUMBER; i++) | 100 | for (i = 0; ret == 0 && i < PHY_NUMBER; i++) |
118 | if (!IS_ERR(exynos_ehci->phy_g[i])) | 101 | if (!IS_ERR(exynos_ehci->phy[i])) |
119 | ret = phy_power_on(exynos_ehci->phy_g[i]); | 102 | ret = phy_power_on(exynos_ehci->phy[i]); |
120 | if (ret) | 103 | if (ret) |
121 | for (i--; i >= 0; i--) | 104 | for (i--; i >= 0; i--) |
122 | if (!IS_ERR(exynos_ehci->phy_g[i])) | 105 | if (!IS_ERR(exynos_ehci->phy[i])) |
123 | phy_power_off(exynos_ehci->phy_g[i]); | 106 | phy_power_off(exynos_ehci->phy[i]); |
124 | 107 | ||
125 | return ret; | 108 | return ret; |
126 | } | 109 | } |
@@ -131,14 +114,9 @@ static void exynos_ehci_phy_disable(struct device *dev) | |||
131 | struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); | 114 | struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); |
132 | int i; | 115 | int i; |
133 | 116 | ||
134 | if (!IS_ERR(exynos_ehci->phy)) { | ||
135 | usb_phy_shutdown(exynos_ehci->phy); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | for (i = 0; i < PHY_NUMBER; i++) | 117 | for (i = 0; i < PHY_NUMBER; i++) |
140 | if (!IS_ERR(exynos_ehci->phy_g[i])) | 118 | if (!IS_ERR(exynos_ehci->phy[i])) |
141 | phy_power_off(exynos_ehci->phy_g[i]); | 119 | phy_power_off(exynos_ehci->phy[i]); |
142 | } | 120 | } |
143 | 121 | ||
144 | static void exynos_setup_vbus_gpio(struct device *dev) | 122 | static void exynos_setup_vbus_gpio(struct device *dev) |
@@ -231,9 +209,6 @@ skip_phy: | |||
231 | goto fail_io; | 209 | goto fail_io; |
232 | } | 210 | } |
233 | 211 | ||
234 | if (exynos_ehci->otg) | ||
235 | exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); | ||
236 | |||
237 | err = exynos_ehci_phy_enable(&pdev->dev); | 212 | err = exynos_ehci_phy_enable(&pdev->dev); |
238 | if (err) { | 213 | if (err) { |
239 | dev_err(&pdev->dev, "Failed to enable USB phy\n"); | 214 | dev_err(&pdev->dev, "Failed to enable USB phy\n"); |
@@ -273,9 +248,6 @@ static int exynos_ehci_remove(struct platform_device *pdev) | |||
273 | 248 | ||
274 | usb_remove_hcd(hcd); | 249 | usb_remove_hcd(hcd); |
275 | 250 | ||
276 | if (exynos_ehci->otg) | ||
277 | exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); | ||
278 | |||
279 | exynos_ehci_phy_disable(&pdev->dev); | 251 | exynos_ehci_phy_disable(&pdev->dev); |
280 | 252 | ||
281 | clk_disable_unprepare(exynos_ehci->clk); | 253 | clk_disable_unprepare(exynos_ehci->clk); |
@@ -298,9 +270,6 @@ static int exynos_ehci_suspend(struct device *dev) | |||
298 | if (rc) | 270 | if (rc) |
299 | return rc; | 271 | return rc; |
300 | 272 | ||
301 | if (exynos_ehci->otg) | ||
302 | exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); | ||
303 | |||
304 | exynos_ehci_phy_disable(dev); | 273 | exynos_ehci_phy_disable(dev); |
305 | 274 | ||
306 | clk_disable_unprepare(exynos_ehci->clk); | 275 | clk_disable_unprepare(exynos_ehci->clk); |
@@ -316,9 +285,6 @@ static int exynos_ehci_resume(struct device *dev) | |||
316 | 285 | ||
317 | clk_prepare_enable(exynos_ehci->clk); | 286 | clk_prepare_enable(exynos_ehci->clk); |
318 | 287 | ||
319 | if (exynos_ehci->otg) | ||
320 | exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); | ||
321 | |||
322 | ret = exynos_ehci_phy_enable(dev); | 288 | ret = exynos_ehci_phy_enable(dev); |
323 | if (ret) { | 289 | if (ret) { |
324 | dev_err(dev, "Failed to enable USB phy\n"); | 290 | dev_err(dev, "Failed to enable USB phy\n"); |