aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorVivek Gautam <gautam.vivek@samsung.com>2013-01-22 08:00:43 -0500
committerFelipe Balbi <balbi@ti.com>2013-01-23 06:39:22 -0500
commited993bf19b98fdb0d364913174b5001fc3ac199b (patch)
tree61c2426b760ab6c4993204da7c4ccfaeb6042711 /drivers/usb/host
parentd233c196ce1a3a33901b75ca818c85825683afba (diff)
USB: ohci-exynos: Add phy driver support
Adding the phy-driver to ohci-exynos. Keeping the platform data for continuing the smooth operation for boards which still uses it Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com> Acked-by: Jingoo Han <jg1.han@samsung.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ohci-exynos.c84
1 files changed, 63 insertions, 21 deletions
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 804fb62a888c..1b3840980177 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -15,6 +15,7 @@
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/platform_data/usb-exynos.h> 17#include <linux/platform_data/usb-exynos.h>
18#include <linux/usb/phy.h>
18#include <linux/usb/samsung_usb_phy.h> 19#include <linux/usb/samsung_usb_phy.h>
19#include <plat/usb-phy.h> 20#include <plat/usb-phy.h>
20 21
@@ -22,8 +23,31 @@ struct exynos_ohci_hcd {
22 struct device *dev; 23 struct device *dev;
23 struct usb_hcd *hcd; 24 struct usb_hcd *hcd;
24 struct clk *clk; 25 struct clk *clk;
26 struct usb_phy *phy;
27 struct usb_otg *otg;
28 struct exynos4_ohci_platdata *pdata;
25}; 29};
26 30
31static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
32{
33 struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
34
35 if (exynos_ohci->phy)
36 usb_phy_init(exynos_ohci->phy);
37 else if (exynos_ohci->pdata->phy_init)
38 exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
39}
40
41static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
42{
43 struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
44
45 if (exynos_ohci->phy)
46 usb_phy_shutdown(exynos_ohci->phy);
47 else if (exynos_ohci->pdata->phy_exit)
48 exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
49}
50
27static int ohci_exynos_reset(struct usb_hcd *hcd) 51static int ohci_exynos_reset(struct usb_hcd *hcd)
28{ 52{
29 return ohci_init(hcd_to_ohci(hcd)); 53 return ohci_init(hcd_to_ohci(hcd));
@@ -79,20 +103,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
79 103
80static int exynos_ohci_probe(struct platform_device *pdev) 104static int exynos_ohci_probe(struct platform_device *pdev)
81{ 105{
82 struct exynos4_ohci_platdata *pdata; 106 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
83 struct exynos_ohci_hcd *exynos_ohci; 107 struct exynos_ohci_hcd *exynos_ohci;
84 struct usb_hcd *hcd; 108 struct usb_hcd *hcd;
85 struct ohci_hcd *ohci; 109 struct ohci_hcd *ohci;
86 struct resource *res; 110 struct resource *res;
111 struct usb_phy *phy;
87 int irq; 112 int irq;
88 int err; 113 int err;
89 114
90 pdata = pdev->dev.platform_data;
91 if (!pdata) {
92 dev_err(&pdev->dev, "No platform data defined\n");
93 return -EINVAL;
94 }
95
96 /* 115 /*
97 * Right now device-tree probed devices don't get dma_mask set. 116 * Right now device-tree probed devices don't get dma_mask set.
98 * Since shared usb code relies on it, set it here for now. 117 * Since shared usb code relies on it, set it here for now.
@@ -108,6 +127,20 @@ static int exynos_ohci_probe(struct platform_device *pdev)
108 if (!exynos_ohci) 127 if (!exynos_ohci)
109 return -ENOMEM; 128 return -ENOMEM;
110 129
130 phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
131 if (IS_ERR_OR_NULL(phy)) {
132 /* Fallback to pdata */
133 if (!pdata) {
134 dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
135 return -EPROBE_DEFER;
136 } else {
137 exynos_ohci->pdata = pdata;
138 }
139 } else {
140 exynos_ohci->phy = phy;
141 exynos_ohci->otg = phy->otg;
142 }
143
111 exynos_ohci->dev = &pdev->dev; 144 exynos_ohci->dev = &pdev->dev;
112 145
113 hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, 146 hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
@@ -153,8 +186,11 @@ static int exynos_ohci_probe(struct platform_device *pdev)
153 goto fail_io; 186 goto fail_io;
154 } 187 }
155 188
156 if (pdata->phy_init) 189 if (exynos_ohci->otg)
157 pdata->phy_init(pdev, USB_PHY_TYPE_HOST); 190 exynos_ohci->otg->set_host(exynos_ohci->otg,
191 &exynos_ohci->hcd->self);
192
193 exynos_ohci_phy_enable(exynos_ohci);
158 194
159 ohci = hcd_to_ohci(hcd); 195 ohci = hcd_to_ohci(hcd);
160 ohci_hcd_init(ohci); 196 ohci_hcd_init(ohci);
@@ -162,13 +198,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
162 err = usb_add_hcd(hcd, irq, IRQF_SHARED); 198 err = usb_add_hcd(hcd, irq, IRQF_SHARED);
163 if (err) { 199 if (err) {
164 dev_err(&pdev->dev, "Failed to add USB HCD\n"); 200 dev_err(&pdev->dev, "Failed to add USB HCD\n");
165 goto fail_io; 201 goto fail_add_hcd;
166 } 202 }
167 203
168 platform_set_drvdata(pdev, exynos_ohci); 204 platform_set_drvdata(pdev, exynos_ohci);
169 205
170 return 0; 206 return 0;
171 207
208fail_add_hcd:
209 exynos_ohci_phy_disable(exynos_ohci);
172fail_io: 210fail_io:
173 clk_disable_unprepare(exynos_ohci->clk); 211 clk_disable_unprepare(exynos_ohci->clk);
174fail_clk: 212fail_clk:
@@ -178,14 +216,16 @@ fail_clk:
178 216
179static int exynos_ohci_remove(struct platform_device *pdev) 217static int exynos_ohci_remove(struct platform_device *pdev)
180{ 218{
181 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
182 struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); 219 struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
183 struct usb_hcd *hcd = exynos_ohci->hcd; 220 struct usb_hcd *hcd = exynos_ohci->hcd;
184 221
185 usb_remove_hcd(hcd); 222 usb_remove_hcd(hcd);
186 223
187 if (pdata && pdata->phy_exit) 224 if (exynos_ohci->otg)
188 pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); 225 exynos_ohci->otg->set_host(exynos_ohci->otg,
226 &exynos_ohci->hcd->self);
227
228 exynos_ohci_phy_disable(exynos_ohci);
189 229
190 clk_disable_unprepare(exynos_ohci->clk); 230 clk_disable_unprepare(exynos_ohci->clk);
191 231
@@ -209,8 +249,6 @@ static int exynos_ohci_suspend(struct device *dev)
209 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); 249 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
210 struct usb_hcd *hcd = exynos_ohci->hcd; 250 struct usb_hcd *hcd = exynos_ohci->hcd;
211 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 251 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
212 struct platform_device *pdev = to_platform_device(dev);
213 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
214 unsigned long flags; 252 unsigned long flags;
215 int rc = 0; 253 int rc = 0;
216 254
@@ -229,8 +267,11 @@ static int exynos_ohci_suspend(struct device *dev)
229 267
230 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 268 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
231 269
232 if (pdata && pdata->phy_exit) 270 if (exynos_ohci->otg)
233 pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); 271 exynos_ohci->otg->set_host(exynos_ohci->otg,
272 &exynos_ohci->hcd->self);
273
274 exynos_ohci_phy_disable(exynos_ohci);
234 275
235 clk_disable_unprepare(exynos_ohci->clk); 276 clk_disable_unprepare(exynos_ohci->clk);
236 277
@@ -244,13 +285,14 @@ static int exynos_ohci_resume(struct device *dev)
244{ 285{
245 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); 286 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
246 struct usb_hcd *hcd = exynos_ohci->hcd; 287 struct usb_hcd *hcd = exynos_ohci->hcd;
247 struct platform_device *pdev = to_platform_device(dev);
248 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
249 288
250 clk_prepare_enable(exynos_ohci->clk); 289 clk_prepare_enable(exynos_ohci->clk);
251 290
252 if (pdata && pdata->phy_init) 291 if (exynos_ohci->otg)
253 pdata->phy_init(pdev, USB_PHY_TYPE_HOST); 292 exynos_ohci->otg->set_host(exynos_ohci->otg,
293 &exynos_ohci->hcd->self);
294
295 exynos_ohci_phy_enable(exynos_ohci);
254 296
255 ohci_resume(hcd, false); 297 ohci_resume(hcd, false);
256 298