summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c19
-rwxr-xr-xdrivers/usb/gadget/arcotg_udc.c12
-rwxr-xr-xdrivers/usb/host/ehci-arc.c51
-rw-r--r--drivers/usb/host/ehci-hub.c11
4 files changed, 46 insertions, 47 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 694476ea22ac..f056707d0986 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -42,6 +42,11 @@ extern void fsl_platform_set_usb_phy_dis(struct fsl_usb2_platform_data *pdata,
#ifdef CONFIG_ARCH_MVF
#define MVF_USB_HOST_HACK
#include <linux/fsl_devices.h>
+
+extern void fsl_platform_set_usb0_phy_dis(struct fsl_usb2_platform_data *pdata,
+ bool enable);
+extern void fsl_platform_set_usb1_phy_dis(struct fsl_usb2_platform_data *pdata,
+ bool enable);
#endif
/* if we are in debug mode, always announce new devices */
#ifdef DEBUG
@@ -1669,8 +1674,15 @@ void usb_disconnect(struct usb_device **pdev)
udev->devnum);
#ifdef MVF_USB_HOST_HACK
if (udev->speed == USB_SPEED_HIGH && udev->level == 1)
+#ifdef CONFIG_MACH_PCM052
+ {
+ fsl_platform_set_usb0_phy_dis(NULL, 0);
+ fsl_platform_set_usb1_phy_dis(NULL, 0);
+ }
+#else
fsl_platform_set_usb_phy_dis(NULL, 0);
#endif
+#endif
usb_lock_device(udev);
/* Free up all the children before we remove this device */
@@ -2917,8 +2929,15 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
}
#ifdef MVF_USB_HOST_HACK
if (udev->speed == USB_SPEED_HIGH && udev->level == 1)
+#ifdef CONFIG_MACH_PCM052
+ {
+ fsl_platform_set_usb0_phy_dis(NULL, 1);
+ fsl_platform_set_usb1_phy_dis(NULL, 1);
+ }
+#else
fsl_platform_set_usb_phy_dis(NULL, 1);
#endif
+#endif
/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
* Because device hardware and firmware is sometimes buggy in
* this area, and this is how Linux has done it for ages.
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index 5a1aab94b405..c7c99cd9f3cb 100755
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -3356,9 +3356,15 @@ static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state)
(udc_controller->usb_state > USB_STATE_POWERED) &&
(udc_controller->usb_state < USB_STATE_SUSPENDED)) {
return -EBUSY;/* keep the clk on */
- } else
+ } else {
+ if (udc_controller->pdata->wake_up_enable)
+ udc_controller->pdata->wake_up_enable(
+ udc_controller->pdata, true);
ret = udc_suspend(udc_controller);
- dr_clk_gate(false);
+ }
+
+ if (udc_controller->stopped)
+ dr_clk_gate(false);
printk(KERN_DEBUG "USB Gadget suspend ends\n");
return ret;
@@ -3408,6 +3414,8 @@ static int fsl_udc_resume(struct platform_device *pdev)
/* prevent the quirk interrupts from resuming */
disable_irq_nosync(udc_controller->irq);
+ if (pdata->wake_up_enable)
+ pdata->wake_up_enable(pdata, false);
/*
* If the controller was stopped at suspend time, then
* don't resume it now.
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index 81ab1cffe374..0f5335d6381e 100755
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -670,28 +670,7 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
printk(KERN_DEBUG "USB Host suspend begins\n");
-#ifdef CONFIG_ARCH_MVF
- if (pdata->suspended) {
- pr_debug("%s: already suspended, leaving early\n", __func__);
- pdata->already_suspended = 1;
- return 0;
- }
-
- pr_debug("%s: suspending...\n", __func__);
-
- hcd->state = HC_STATE_SUSPENDED;
- pdev->dev.power.power_state = PMSG_SUSPEND;
-
- /* ignore non-host interrupts */
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- /* stop the controller */
- tmp = ehci_readl(ehci, &ehci->regs->command);
- tmp &= ~CMD_RUN;
- ehci_writel(ehci, tmp, &ehci->regs->command);
- pdata->suspended = 1;
-#else
/* Only handles OTG mode switch event, system suspend event will be done in bus suspend */
if (pdata->pmflags == 0) {
printk(KERN_DEBUG "%s, pm event\n", __func__);
@@ -706,7 +685,7 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
printk(KERN_DEBUG "host suspend ends\n");
return 0;
}
-
+#ifndef CONFIG_ARCH_MVF
/* only the otg host can go here */
/* wait for all usb device on the hcd dettached */
usb_lock_device(roothub);
@@ -740,7 +719,7 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
}
-#endif
+
port_status = ehci_readl(ehci, &ehci->regs->port_status[0]);
/* save EHCI registers */
pdata->pm_command = ehci_readl(ehci, &ehci->regs->command);
@@ -772,6 +751,7 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
}
pdata->pmflags = 0;
printk(KERN_DEBUG "host suspend ends\n");
+#endif
return 0;
}
@@ -786,27 +766,13 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
struct fsl_usb2_wakeup_platform_data *wake_up_pdata = pdata->wakeup_pdata;
/* Only handles OTG mode switch event */
printk(KERN_DEBUG "ehci fsl drv resume begins: %s\n", pdata->name);
-#ifdef CONFIG_ARCH_MVF
- if (pdata->already_suspended) {
- pr_debug("already suspended, leaving early\n");
- pdata->already_suspended = 0;
- return 0;
- }
- if (!pdata->suspended) {
- pr_debug("not suspended, leaving early\n");
- return 0;
- }
-
- pdata->suspended = 0;
-
- pr_debug("%s resuming...\n", __func__);
-#else
if (pdata->pmflags == 0) {
printk(KERN_DEBUG "%s,pm event, wait for wakeup irq if needed\n", __func__);
wait_event_interruptible(wake_up_pdata->wq, !wake_up_pdata->usb_wakeup_is_pending);
return 0;
}
+#ifndef CONFIG_ARCH_MVF
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
@@ -815,7 +781,7 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
fsl_usb_lowpower_mode(pdata, false);
spin_unlock_irqrestore(&ehci->lock, flags);
}
-#endif
+
spin_lock_irqsave(&ehci->lock, flags);
/* set host mode */
fsl_platform_set_host_mode(hcd);
@@ -837,19 +803,16 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
ehci_writel(ehci, tmp, &ehci->regs->command);
spin_unlock_irqrestore(&ehci->lock, flags);
-#ifdef CONFIG_ARCH_MVF
- usb_hcd_resume_root_hub(hcd);
-#else
if ((hcd->state & HC_STATE_SUSPENDED)) {
printk(KERN_DEBUG "will resume roothub and its children\n");
usb_lock_device(roothub);
usb_resume(&roothub->dev, PMSG_USER_RESUME);
usb_unlock_device(roothub);
}
-#endif
+
pdata->pmflags = 0;
printk(KERN_DEBUG "ehci fsl drv resume ends: %s\n", pdata->name);
-
+#endif
return 0;
}
#endif
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index d6a80d9731a2..544ed44ef28c 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -29,8 +29,9 @@
/*-------------------------------------------------------------------------*/
#include <linux/usb/otg.h>
-#ifdef CONFIG_ARCH_MX6
+#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MVF)
#define MX6_USB_HOST_HACK
+#define MVF_USB_HOST_HACK
#include <linux/fsl_devices.h>
#endif
#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
@@ -1081,6 +1082,14 @@ static int ehci_hub_control (
pdata = hcd->self.controller->platform_data;
if (pdata->platform_suspend)
pdata->platform_suspend(pdata);
+#ifdef MVF_USB_HOST_HACK
+ /* workaround:
+ * Toggle HW_USBPHY_PWD to flag controller
+ * generating LS-SE0/LS-EOP after resume
+ */
+ if (pdata->platform_resume)
+ pdata->platform_resume(pdata);
+#endif
}
#endif
if (hostpc_reg) {