git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
usb: musb: omap2430: fix occasional musb breakage on boot
[pandora-kernel.git]
/
drivers
/
usb
/
musb
/
omap2430.c
diff --git
a/drivers/usb/musb/omap2430.c
b/drivers/usb/musb/omap2430.c
index
ba85f27
..
58ca5e4
100644
(file)
--- a/
drivers/usb/musb/omap2430.c
+++ b/
drivers/usb/musb/omap2430.c
@@
-35,6
+35,7
@@
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/err.h>
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/err.h>
+#include <linux/delay.h>
#include "musb_core.h"
#include "omap2430.h"
#include "musb_core.h"
#include "omap2430.h"
@@
-145,6
+146,7
@@
static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
if (is_on) {
if (musb->xceiv->state == OTG_STATE_A_IDLE) {
if (is_on) {
if (musb->xceiv->state == OTG_STATE_A_IDLE) {
+ int loops = 100;
/* start the session */
devctl |= MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
/* start the session */
devctl |= MUSB_DEVCTL_SESSION;
musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
@@
-154,9
+156,11
@@
static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
*/
while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
*/
while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
+ mdelay(5);
cpu_relax();
cpu_relax();
- if (time_after(jiffies, timeout)) {
+ if (time_after(jiffies, timeout)
+ || loops-- <= 0) {
dev_err(musb->controller,
"configured as A device timeout");
ret = -EINVAL;
dev_err(musb->controller,
"configured as A device timeout");
ret = -EINVAL;
@@
-262,6
+266,8
@@
static int musb_otg_notifications(struct notifier_block *nb,
if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
if (musb->gadget_driver) {
if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
if (musb->gadget_driver) {
+ omap2430_musb_set_vbus(musb, 0);
+
pm_runtime_mark_last_busy(musb->controller);
pm_runtime_put_autosuspend(musb->controller);
}
pm_runtime_mark_last_busy(musb->controller);
pm_runtime_put_autosuspend(musb->controller);
}
@@
-282,7
+288,8
@@
static int musb_otg_notifications(struct notifier_block *nb,
static int omap2430_musb_init(struct musb *musb)
{
static int omap2430_musb_init(struct musb *musb)
{
- u32 l, status = 0;
+ u32 l;
+ int status = 0;
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev->platform_data;
struct omap_musb_board_data *data = plat->board_data;
struct device *dev = musb->controller;
struct musb_hdrc_platform_data *plat = dev->platform_data;
struct omap_musb_board_data *data = plat->board_data;
@@
-299,7
+306,7
@@
static int omap2430_musb_init(struct musb *musb)
status = pm_runtime_get_sync(dev);
if (status < 0) {
status = pm_runtime_get_sync(dev);
if (status < 0) {
- dev_err(dev, "pm_runtime_get_sync FAILED
"
);
+ dev_err(dev, "pm_runtime_get_sync FAILED
%d\n", status
);
goto err1;
}
goto err1;
}
@@
-451,14
+458,14
@@
static int __init omap2430_probe(struct platform_device *pdev)
goto err2;
}
goto err2;
}
+ pm_runtime_enable(&pdev->dev);
+
ret = platform_device_add(musb);
if (ret) {
dev_err(&pdev->dev, "failed to register musb device\n");
goto err2;
}
ret = platform_device_add(musb);
if (ret) {
dev_err(&pdev->dev, "failed to register musb device\n");
goto err2;
}
- pm_runtime_enable(&pdev->dev);
-
return 0;
err2:
return 0;
err2:
@@
-491,6
+498,9
@@
static int omap2430_runtime_suspend(struct device *dev)
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
struct omap2430_glue *glue = dev_get_drvdata(dev);
struct musb *musb = glue_to_musb(glue);
+ musb->context.otg_interfsel = musb_readl(musb->mregs,
+ OTG_INTERFSEL);
+
omap2430_low_level_exit(musb);
otg_set_suspend(musb->xceiv, 1);
omap2430_low_level_exit(musb);
otg_set_suspend(musb->xceiv, 1);
@@
-503,6
+513,10
@@
static int omap2430_runtime_resume(struct device *dev)
struct musb *musb = glue_to_musb(glue);
omap2430_low_level_init(musb);
struct musb *musb = glue_to_musb(glue);
omap2430_low_level_init(musb);
+ if (musb->context.otg_interfsel != 0)
+ musb_writel(musb->mregs, OTG_INTERFSEL,
+ musb->context.otg_interfsel);
+
otg_set_suspend(musb->xceiv, 0);
return 0;
otg_set_suspend(musb->xceiv, 0);
return 0;