aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-exynos.c129
1 files changed, 109 insertions, 20 deletions
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 4d763dc91f70..c7081c75de8a 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_gpio.h> 21#include <linux/of_gpio.h>
22#include <linux/phy/phy.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/usb/phy.h> 24#include <linux/usb/phy.h>
24#include <linux/usb/samsung_usb_phy.h> 25#include <linux/usb/samsung_usb_phy.h>
@@ -42,14 +43,104 @@
42static const char hcd_name[] = "ehci-exynos"; 43static const char hcd_name[] = "ehci-exynos";
43static struct hc_driver __read_mostly exynos_ehci_hc_driver; 44static struct hc_driver __read_mostly exynos_ehci_hc_driver;
44 45
46#define PHY_NUMBER 3
47
45struct exynos_ehci_hcd { 48struct exynos_ehci_hcd {
46 struct clk *clk; 49 struct clk *clk;
47 struct usb_phy *phy; 50 struct usb_phy *phy;
48 struct usb_otg *otg; 51 struct usb_otg *otg;
52 struct phy *phy_g[PHY_NUMBER];
49}; 53};
50 54
51#define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv) 55#define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
52 56
57static int exynos_ehci_get_phy(struct device *dev,
58 struct exynos_ehci_hcd *exynos_ehci)
59{
60 struct device_node *child;
61 struct phy *phy;
62 int phy_number;
63 int ret = 0;
64
65 exynos_ehci->phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
66 if (IS_ERR(exynos_ehci->phy)) {
67 ret = PTR_ERR(exynos_ehci->phy);
68 if (ret != -ENXIO && ret != -ENODEV) {
69 dev_err(dev, "no usb2 phy configured\n");
70 return ret;
71 }
72 dev_dbg(dev, "Failed to get usb2 phy\n");
73 } else {
74 exynos_ehci->otg = exynos_ehci->phy->otg;
75 }
76
77 for_each_available_child_of_node(dev->of_node, child) {
78 ret = of_property_read_u32(child, "reg", &phy_number);
79 if (ret) {
80 dev_err(dev, "Failed to parse device tree\n");
81 of_node_put(child);
82 return ret;
83 }
84
85 if (phy_number >= PHY_NUMBER) {
86 dev_err(dev, "Invalid number of PHYs\n");
87 of_node_put(child);
88 return -EINVAL;
89 }
90
91 phy = devm_of_phy_get(dev, child, 0);
92 of_node_put(child);
93 if (IS_ERR(phy)) {
94 ret = PTR_ERR(phy);
95 if (ret != -ENOSYS && ret != -ENODEV) {
96 dev_err(dev, "no usb2 phy configured\n");
97 return ret;
98 }
99 dev_dbg(dev, "Failed to get usb2 phy\n");
100 }
101 exynos_ehci->phy_g[phy_number] = phy;
102 }
103
104 return ret;
105}
106
107static int exynos_ehci_phy_enable(struct device *dev)
108{
109 struct usb_hcd *hcd = dev_get_drvdata(dev);
110 struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
111 int i;
112 int ret = 0;
113
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++)
118 if (!IS_ERR(exynos_ehci->phy_g[i]))
119 ret = phy_power_on(exynos_ehci->phy_g[i]);
120 if (ret)
121 for (i--; i >= 0; i--)
122 if (!IS_ERR(exynos_ehci->phy_g[i]))
123 phy_power_off(exynos_ehci->phy_g[i]);
124
125 return ret;
126}
127
128static void exynos_ehci_phy_disable(struct device *dev)
129{
130 struct usb_hcd *hcd = dev_get_drvdata(dev);
131 struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
132 int i;
133
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++)
140 if (!IS_ERR(exynos_ehci->phy_g[i]))
141 phy_power_off(exynos_ehci->phy_g[i]);
142}
143
53static void exynos_setup_vbus_gpio(struct device *dev) 144static void exynos_setup_vbus_gpio(struct device *dev)
54{ 145{
55 int err; 146 int err;
@@ -74,7 +165,6 @@ static int exynos_ehci_probe(struct platform_device *pdev)
74 struct usb_hcd *hcd; 165 struct usb_hcd *hcd;
75 struct ehci_hcd *ehci; 166 struct ehci_hcd *ehci;
76 struct resource *res; 167 struct resource *res;
77 struct usb_phy *phy;
78 int irq; 168 int irq;
79 int err; 169 int err;
80 170
@@ -101,15 +191,9 @@ static int exynos_ehci_probe(struct platform_device *pdev)
101 "samsung,exynos5440-ehci")) 191 "samsung,exynos5440-ehci"))
102 goto skip_phy; 192 goto skip_phy;
103 193
104 phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); 194 err = exynos_ehci_get_phy(&pdev->dev, exynos_ehci);
105 if (IS_ERR(phy)) { 195 if (err)
106 usb_put_hcd(hcd); 196 goto fail_clk;
107 dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
108 return -EPROBE_DEFER;
109 } else {
110 exynos_ehci->phy = phy;
111 exynos_ehci->otg = phy->otg;
112 }
113 197
114skip_phy: 198skip_phy:
115 199
@@ -151,8 +235,11 @@ skip_phy:
151 if (exynos_ehci->otg) 235 if (exynos_ehci->otg)
152 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); 236 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
153 237
154 if (exynos_ehci->phy) 238 err = exynos_ehci_phy_enable(&pdev->dev);
155 usb_phy_init(exynos_ehci->phy); 239 if (err) {
240 dev_err(&pdev->dev, "Failed to enable USB phy\n");
241 goto fail_io;
242 }
156 243
157 ehci = hcd_to_ehci(hcd); 244 ehci = hcd_to_ehci(hcd);
158 ehci->caps = hcd->regs; 245 ehci->caps = hcd->regs;
@@ -172,8 +259,7 @@ skip_phy:
172 return 0; 259 return 0;
173 260
174fail_add_hcd: 261fail_add_hcd:
175 if (exynos_ehci->phy) 262 exynos_ehci_phy_disable(&pdev->dev);
176 usb_phy_shutdown(exynos_ehci->phy);
177fail_io: 263fail_io:
178 clk_disable_unprepare(exynos_ehci->clk); 264 clk_disable_unprepare(exynos_ehci->clk);
179fail_clk: 265fail_clk:
@@ -191,8 +277,7 @@ static int exynos_ehci_remove(struct platform_device *pdev)
191 if (exynos_ehci->otg) 277 if (exynos_ehci->otg)
192 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); 278 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
193 279
194 if (exynos_ehci->phy) 280 exynos_ehci_phy_disable(&pdev->dev);
195 usb_phy_shutdown(exynos_ehci->phy);
196 281
197 clk_disable_unprepare(exynos_ehci->clk); 282 clk_disable_unprepare(exynos_ehci->clk);
198 283
@@ -217,8 +302,7 @@ static int exynos_ehci_suspend(struct device *dev)
217 if (exynos_ehci->otg) 302 if (exynos_ehci->otg)
218 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); 303 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
219 304
220 if (exynos_ehci->phy) 305 exynos_ehci_phy_disable(dev);
221 usb_phy_shutdown(exynos_ehci->phy);
222 306
223 clk_disable_unprepare(exynos_ehci->clk); 307 clk_disable_unprepare(exynos_ehci->clk);
224 308
@@ -229,14 +313,19 @@ static int exynos_ehci_resume(struct device *dev)
229{ 313{
230 struct usb_hcd *hcd = dev_get_drvdata(dev); 314 struct usb_hcd *hcd = dev_get_drvdata(dev);
231 struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); 315 struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
316 int ret;
232 317
233 clk_prepare_enable(exynos_ehci->clk); 318 clk_prepare_enable(exynos_ehci->clk);
234 319
235 if (exynos_ehci->otg) 320 if (exynos_ehci->otg)
236 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); 321 exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
237 322
238 if (exynos_ehci->phy) 323 ret = exynos_ehci_phy_enable(dev);
239 usb_phy_init(exynos_ehci->phy); 324 if (ret) {
325 dev_err(dev, "Failed to enable USB phy\n");
326 clk_disable_unprepare(exynos_ehci->clk);
327 return ret;
328 }
240 329
241 /* DMA burst Enable */ 330 /* DMA burst Enable */
242 writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); 331 writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));