aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/musb/am35x.c130
1 files changed, 45 insertions, 85 deletions
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c
index 62e65f0a7284..d5a3da37c90c 100644
--- a/drivers/usb/musb/am35x.c
+++ b/drivers/usb/musb/am35x.c
@@ -32,7 +32,6 @@
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/dma-mapping.h> 33#include <linux/dma-mapping.h>
34 34
35#include <plat/control.h>
36#include <plat/usb.h> 35#include <plat/usb.h>
37 36
38#include "musb_core.h" 37#include "musb_core.h"
@@ -90,47 +89,6 @@ struct am35x_glue {
90}; 89};
91#define glue_to_musb(g) platform_get_drvdata(g->musb) 90#define glue_to_musb(g) platform_get_drvdata(g->musb)
92 91
93static inline void phy_on(void)
94{
95 unsigned long timeout = jiffies + msecs_to_jiffies(100);
96 u32 devconf2;
97
98 /*
99 * Start the on-chip PHY and its PLL.
100 */
101 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
102
103 devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
104 devconf2 |= CONF2_PHY_PLLON;
105
106 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
107
108 DBG(1, "Waiting for PHY clock good...\n");
109 while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
110 & CONF2_PHYCLKGD)) {
111 cpu_relax();
112
113 if (time_after(jiffies, timeout)) {
114 DBG(1, "musb PHY clock good timed out\n");
115 break;
116 }
117 }
118}
119
120static inline void phy_off(void)
121{
122 u32 devconf2;
123
124 /*
125 * Power down the on-chip PHY.
126 */
127 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
128
129 devconf2 &= ~CONF2_PHY_PLLON;
130 devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
131 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
132}
133
134/* 92/*
135 * am35x_musb_enable - enable interrupts 93 * am35x_musb_enable - enable interrupts
136 */ 94 */
@@ -265,9 +223,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
265{ 223{
266 struct musb *musb = hci; 224 struct musb *musb = hci;
267 void __iomem *reg_base = musb->ctrl_base; 225 void __iomem *reg_base = musb->ctrl_base;
226 struct device *dev = musb->controller;
227 struct musb_hdrc_platform_data *plat = dev->platform_data;
228 struct omap_musb_board_data *data = plat->board_data;
268 unsigned long flags; 229 unsigned long flags;
269 irqreturn_t ret = IRQ_NONE; 230 irqreturn_t ret = IRQ_NONE;
270 u32 epintr, usbintr, lvl_intr; 231 u32 epintr, usbintr;
271 232
272 spin_lock_irqsave(&musb->lock, flags); 233 spin_lock_irqsave(&musb->lock, flags);
273 234
@@ -356,9 +317,8 @@ eoi:
356 /* EOI needs to be written for the IRQ to be re-asserted. */ 317 /* EOI needs to be written for the IRQ to be re-asserted. */
357 if (ret == IRQ_HANDLED || epintr || usbintr) { 318 if (ret == IRQ_HANDLED || epintr || usbintr) {
358 /* clear level interrupt */ 319 /* clear level interrupt */
359 lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); 320 if (data->clear_irq)
360 lvl_intr |= AM35XX_USBOTGSS_INT_CLR; 321 data->clear_irq();
361 omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR);
362 /* write EOI */ 322 /* write EOI */
363 musb_writel(reg_base, USB_END_OF_INTR_REG, 0); 323 musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
364 } 324 }
@@ -374,37 +334,26 @@ eoi:
374 334
375static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode) 335static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode)
376{ 336{
377 u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); 337 struct device *dev = musb->controller;
338 struct musb_hdrc_platform_data *plat = dev->platform_data;
339 struct omap_musb_board_data *data = plat->board_data;
340 int retval = 0;
378 341
379 devconf2 &= ~CONF2_OTGMODE; 342 if (data->set_mode)
380 switch (musb_mode) { 343 data->set_mode(musb_mode);
381#ifdef CONFIG_USB_MUSB_HDRC_HCD 344 else
382 case MUSB_HOST: /* Force VBUS valid, ID = 0 */ 345 retval = -EIO;
383 devconf2 |= CONF2_FORCE_HOST;
384 break;
385#endif
386#ifdef CONFIG_USB_GADGET_MUSB_HDRC
387 case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
388 devconf2 |= CONF2_FORCE_DEVICE;
389 break;
390#endif
391#ifdef CONFIG_USB_MUSB_OTG
392 case MUSB_OTG: /* Don't override the VBUS/ID comparators */
393 devconf2 |= CONF2_NO_OVERRIDE;
394 break;
395#endif
396 default:
397 DBG(2, "Trying to set unsupported mode %u\n", musb_mode);
398 }
399 346
400 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); 347 return retval;
401 return 0;
402} 348}
403 349
404static int am35x_musb_init(struct musb *musb) 350static int am35x_musb_init(struct musb *musb)
405{ 351{
352 struct device *dev = musb->controller;
353 struct musb_hdrc_platform_data *plat = dev->platform_data;
354 struct omap_musb_board_data *data = plat->board_data;
406 void __iomem *reg_base = musb->ctrl_base; 355 void __iomem *reg_base = musb->ctrl_base;
407 u32 rev, lvl_intr, sw_reset; 356 u32 rev;
408 357
409 musb->mregs += USB_MENTOR_CORE_OFFSET; 358 musb->mregs += USB_MENTOR_CORE_OFFSET;
410 359
@@ -421,39 +370,40 @@ static int am35x_musb_init(struct musb *musb)
421 if (is_host_enabled(musb)) 370 if (is_host_enabled(musb))
422 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); 371 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
423 372
424 /* Global reset */ 373 /* Reset the musb */
425 sw_reset = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); 374 if (data->reset)
426 375 data->reset();
427 sw_reset |= AM35XX_USBOTGSS_SW_RST;
428 omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET);
429
430 sw_reset &= ~AM35XX_USBOTGSS_SW_RST;
431 omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET);
432 376
433 /* Reset the controller */ 377 /* Reset the controller */
434 musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); 378 musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK);
435 379
436 /* Start the on-chip PHY and its PLL. */ 380 /* Start the on-chip PHY and its PLL. */
437 phy_on(); 381 if (data->set_phy_power)
382 data->set_phy_power(1);
438 383
439 msleep(5); 384 msleep(5);
440 385
441 musb->isr = am35x_musb_interrupt; 386 musb->isr = am35x_musb_interrupt;
442 387
443 /* clear level interrupt */ 388 /* clear level interrupt */
444 lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); 389 if (data->clear_irq)
445 lvl_intr |= AM35XX_USBOTGSS_INT_CLR; 390 data->clear_irq();
446 omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR);
447 391
448 return 0; 392 return 0;
449} 393}
450 394
451static int am35x_musb_exit(struct musb *musb) 395static int am35x_musb_exit(struct musb *musb)
452{ 396{
397 struct device *dev = musb->controller;
398 struct musb_hdrc_platform_data *plat = dev->platform_data;
399 struct omap_musb_board_data *data = plat->board_data;
400
453 if (is_host_enabled(musb)) 401 if (is_host_enabled(musb))
454 del_timer_sync(&otg_workaround); 402 del_timer_sync(&otg_workaround);
455 403
456 phy_off(); 404 /* Shutdown the on-chip PHY and its PLL. */
405 if (data->set_phy_power)
406 data->set_phy_power(0);
457 407
458 otg_put_transceiver(musb->xceiv); 408 otg_put_transceiver(musb->xceiv);
459 usb_nop_xceiv_unregister(); 409 usb_nop_xceiv_unregister();
@@ -630,8 +580,13 @@ static int __exit am35x_remove(struct platform_device *pdev)
630static int am35x_suspend(struct device *dev) 580static int am35x_suspend(struct device *dev)
631{ 581{
632 struct am35x_glue *glue = dev_get_drvdata(dev); 582 struct am35x_glue *glue = dev_get_drvdata(dev);
583 struct musb_hdrc_platform_data *plat = dev->platform_data;
584 struct omap_musb_board_data *data = plat->board_data;
585
586 /* Shutdown the on-chip PHY and its PLL. */
587 if (data->set_phy_power)
588 data->set_phy_power(0);
633 589
634 phy_off();
635 clk_disable(glue->phy_clk); 590 clk_disable(glue->phy_clk);
636 clk_disable(glue->clk); 591 clk_disable(glue->clk);
637 592
@@ -641,9 +596,14 @@ static int am35x_suspend(struct device *dev)
641static int am35x_resume(struct device *dev) 596static int am35x_resume(struct device *dev)
642{ 597{
643 struct am35x_glue *glue = dev_get_drvdata(dev); 598 struct am35x_glue *glue = dev_get_drvdata(dev);
599 struct musb_hdrc_platform_data *plat = dev->platform_data;
600 struct omap_musb_board_data *data = plat->board_data;
644 int ret; 601 int ret;
645 602
646 phy_on(); 603 /* Start the on-chip PHY and its PLL. */
604 if (data->set_phy_power)
605 data->set_phy_power(1);
606
647 ret = clk_enable(glue->phy_clk); 607 ret = clk_enable(glue->phy_clk);
648 if (ret) { 608 if (ret) {
649 dev_err(dev, "failed to enable PHY clock\n"); 609 dev_err(dev, "failed to enable PHY clock\n");