diff options
author | Roger Quadros <rogerq@ti.com> | 2013-03-12 06:44:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-15 14:51:46 -0400 |
commit | dcd64063fd917b5c79f99cae218e1df3ed1b62a2 (patch) | |
tree | 0b3cb3f51224336fc9f40ffeef0040235764f0eb /drivers/usb/host/ehci-omap.c | |
parent | 18c2bb1b8c1571f4c1fa33cc1f4525b282059455 (diff) |
USB: ehci-omap: Use PHY APIs to get the PHY device and put it out of suspend
For each port that is in PHY mode we obtain a PHY device using the USB PHY
library and put it out of suspend.
It is up to platform code to associate the PHY to the controller's
port and it is up to the PHY driver to manage the PHY's resources.
Also remove weird spacing around declarations we come across.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-omap.c')
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 76 |
1 files changed, 62 insertions, 14 deletions
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 70e8e6f33d42..6b8b7e5358a6 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -4,10 +4,11 @@ | |||
4 | * Bus Glue for the EHCI controllers in OMAP3/4 | 4 | * Bus Glue for the EHCI controllers in OMAP3/4 |
5 | * Tested on several OMAP3 boards, and OMAP4 Pandaboard | 5 | * Tested on several OMAP3 boards, and OMAP4 Pandaboard |
6 | * | 6 | * |
7 | * Copyright (C) 2007-2011 Texas Instruments, Inc. | 7 | * Copyright (C) 2007-2013 Texas Instruments, Inc. |
8 | * Author: Vikram Pandita <vikram.pandita@ti.com> | 8 | * Author: Vikram Pandita <vikram.pandita@ti.com> |
9 | * Author: Anand Gadiyar <gadiyar@ti.com> | 9 | * Author: Anand Gadiyar <gadiyar@ti.com> |
10 | * Author: Keshava Munegowda <keshava_mgowda@ti.com> | 10 | * Author: Keshava Munegowda <keshava_mgowda@ti.com> |
11 | * Author: Roger Quadros <rogerq@ti.com> | ||
11 | * | 12 | * |
12 | * Copyright (C) 2009 Nokia Corporation | 13 | * Copyright (C) 2009 Nokia Corporation |
13 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> | 14 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> |
@@ -70,6 +71,10 @@ static const char hcd_name[] = "ehci-omap"; | |||
70 | 71 | ||
71 | /*-------------------------------------------------------------------------*/ | 72 | /*-------------------------------------------------------------------------*/ |
72 | 73 | ||
74 | struct omap_hcd { | ||
75 | struct usb_phy *phy[OMAP3_HS_USB_PORTS]; /* one PHY for each port */ | ||
76 | int nports; | ||
77 | }; | ||
73 | 78 | ||
74 | static inline void ehci_write(void __iomem *base, u32 reg, u32 val) | 79 | static inline void ehci_write(void __iomem *base, u32 reg, u32 val) |
75 | { | 80 | { |
@@ -178,7 +183,8 @@ static void disable_put_regulator( | |||
178 | static struct hc_driver __read_mostly ehci_omap_hc_driver; | 183 | static struct hc_driver __read_mostly ehci_omap_hc_driver; |
179 | 184 | ||
180 | static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { | 185 | static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { |
181 | .reset = omap_ehci_init, | 186 | .reset = omap_ehci_init, |
187 | .extra_priv_size = sizeof(struct omap_hcd), | ||
182 | }; | 188 | }; |
183 | 189 | ||
184 | /** | 190 | /** |
@@ -190,15 +196,16 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { | |||
190 | */ | 196 | */ |
191 | static int ehci_hcd_omap_probe(struct platform_device *pdev) | 197 | static int ehci_hcd_omap_probe(struct platform_device *pdev) |
192 | { | 198 | { |
193 | struct device *dev = &pdev->dev; | 199 | struct device *dev = &pdev->dev; |
194 | struct usbhs_omap_platform_data *pdata = dev->platform_data; | 200 | struct usbhs_omap_platform_data *pdata = dev->platform_data; |
195 | struct resource *res; | 201 | struct resource *res; |
196 | struct usb_hcd *hcd; | 202 | struct usb_hcd *hcd; |
197 | void __iomem *regs; | 203 | void __iomem *regs; |
198 | int ret = -ENODEV; | 204 | int ret = -ENODEV; |
199 | int irq; | 205 | int irq; |
200 | int i; | 206 | int i; |
201 | char supply[7]; | 207 | char supply[7]; |
208 | struct omap_hcd *omap; | ||
202 | 209 | ||
203 | if (usb_disabled()) | 210 | if (usb_disabled()) |
204 | return -ENODEV; | 211 | return -ENODEV; |
@@ -231,6 +238,33 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
231 | hcd->rsrc_len = resource_size(res); | 238 | hcd->rsrc_len = resource_size(res); |
232 | hcd->regs = regs; | 239 | hcd->regs = regs; |
233 | 240 | ||
241 | omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv; | ||
242 | omap->nports = pdata->nports; | ||
243 | |||
244 | platform_set_drvdata(pdev, hcd); | ||
245 | |||
246 | /* get the PHY devices if needed */ | ||
247 | for (i = 0 ; i < omap->nports ; i++) { | ||
248 | struct usb_phy *phy; | ||
249 | |||
250 | if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) | ||
251 | continue; | ||
252 | |||
253 | /* get the PHY device */ | ||
254 | phy = devm_usb_get_phy_dev(dev, i); | ||
255 | if (IS_ERR(phy) || !phy) { | ||
256 | ret = IS_ERR(phy) ? PTR_ERR(phy) : -ENODEV; | ||
257 | dev_err(dev, "Can't get PHY device for port %d: %d\n", | ||
258 | i, ret); | ||
259 | goto err_phy; | ||
260 | } | ||
261 | |||
262 | omap->phy[i] = phy; | ||
263 | usb_phy_init(omap->phy[i]); | ||
264 | /* bring PHY out of suspend */ | ||
265 | usb_phy_set_suspend(omap->phy[i], 0); | ||
266 | } | ||
267 | |||
234 | /* get ehci regulator and enable */ | 268 | /* get ehci regulator and enable */ |
235 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | 269 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { |
236 | if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { | 270 | if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { |
@@ -275,6 +309,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
275 | err_pm_runtime: | 309 | err_pm_runtime: |
276 | disable_put_regulator(pdata); | 310 | disable_put_regulator(pdata); |
277 | pm_runtime_put_sync(dev); | 311 | pm_runtime_put_sync(dev); |
312 | |||
313 | err_phy: | ||
314 | for (i = 0; i < omap->nports; i++) { | ||
315 | if (omap->phy[i]) | ||
316 | usb_phy_shutdown(omap->phy[i]); | ||
317 | } | ||
318 | |||
278 | usb_put_hcd(hcd); | 319 | usb_put_hcd(hcd); |
279 | 320 | ||
280 | return ret; | 321 | return ret; |
@@ -291,13 +332,20 @@ err_pm_runtime: | |||
291 | */ | 332 | */ |
292 | static int ehci_hcd_omap_remove(struct platform_device *pdev) | 333 | static int ehci_hcd_omap_remove(struct platform_device *pdev) |
293 | { | 334 | { |
294 | struct device *dev = &pdev->dev; | 335 | struct device *dev = &pdev->dev; |
295 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 336 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
337 | struct omap_hcd *omap = (struct omap_hcd *)hcd_to_ehci(hcd)->priv; | ||
338 | int i; | ||
296 | 339 | ||
297 | usb_remove_hcd(hcd); | 340 | usb_remove_hcd(hcd); |
298 | disable_put_regulator(dev->platform_data); | 341 | disable_put_regulator(dev->platform_data); |
299 | usb_put_hcd(hcd); | ||
300 | 342 | ||
343 | for (i = 0; i < omap->nports; i++) { | ||
344 | if (omap->phy[i]) | ||
345 | usb_phy_shutdown(omap->phy[i]); | ||
346 | } | ||
347 | |||
348 | usb_put_hcd(hcd); | ||
301 | pm_runtime_put_sync(dev); | 349 | pm_runtime_put_sync(dev); |
302 | pm_runtime_disable(dev); | 350 | pm_runtime_disable(dev); |
303 | 351 | ||