summaryrefslogtreecommitdiff
path: root/drivers/usb/musb/musb_dsps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 09:11:20 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 09:11:20 -0700
commite5c4ecdc55b6d824365ba7964bcd3185223f9688 (patch)
tree405556c9fe703094dd0fc07bc89d9a2fdb5ee525 /drivers/usb/musb/musb_dsps.c
parent49eb7b0750d9483c74e9c14ae6ea1e9d62481c3c (diff)
parent4a95b1fce97756d0333f8232eb7ed6974e93b054 (diff)
Merge tag 'usb-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb into next
Pull USB driver updates from Greg KH: "Here is the big USB driver pull request for 3.16-rc1. Nothing huge here, but lots of little things in the USB core, and in lots of drivers. Hopefully the USB power management will be work better now that it has been reworked to do per-port power control dynamically. There's also a raft of gadget driver updates and fixes, CONFIG_USB_DEBUG is finally gone now that everything has been converted over to the dynamic debug inteface, the last hold-out drivers were cleaned up and the config option removed. There were also other minor things all through the drivers/usb/ tree, the shortlog shows this pretty well. All have been in linux-next, including the very last patch, which came from linux-next to fix a build issue on some platforms" * tag 'usb-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (314 commits) usb: hub_handle_remote_wakeup() only exists for CONFIG_PM=y USB: orinoco_usb: remove CONFIG_USB_DEBUG support USB: media: lirc: igorplugusb: remove CONFIG_USB_DEBUG support USB: media: streamzap: remove CONFIG_USB_DEBUG USB: media: redrat3: remove CONFIG_USB_DEBUG usage USB: media: redrat3: remove unneeded tracing macro usb: qcserial: add additional Sierra Wireless QMI devices usb: host: max3421-hcd: Use module_spi_driver usb: host: max3421-hcd: Allow platform-data to specify Vbus polarity usb: host: max3421-hcd: fix "spi_rd8" uses dynamic stack allocation warning usb: host: max3421-hcd: Fix missing unlock in max3421_urb_enqueue() usb: qcserial: add Netgear AirCard 341U Documentation: dt-bindings: update xhci-platform DT binding for R-Car H2 and M2 usb: host: xhci-plat: add xhci_plat_start() usb: host: max3421-hcd: Fix potential NULL urb dereference Revert "usb: gadget: net2280: Add support for PLX USB338X" USB: usbip: remove CONFIG_USB_DEBUG reference USB: remove CONFIG_USB_DEBUG from defconfig files usb: resume child device when port is powered on usb: hub_handle_remote_wakeup() depends on CONFIG_PM_RUNTIME=y ...
Diffstat (limited to 'drivers/usb/musb/musb_dsps.c')
-rw-r--r--drivers/usb/musb/musb_dsps.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index e2fd263585de..51beb13c7e1a 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -35,7 +35,7 @@
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
-#include <linux/usb/usb_phy_gen_xceiv.h>
+#include <linux/usb/usb_phy_generic.h>
#include <linux/platform_data/usb-omap.h>
#include <linux/sizes.h>
@@ -329,9 +329,21 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
* value but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
* Also, DRVVBUS pulses for SRP (but not at 5V) ...
*/
- if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE)
+ if (is_host_active(musb) && usbintr & MUSB_INTR_BABBLE) {
pr_info("CAUTION: musb: Babble Interrupt Occurred\n");
+ /*
+ * When a babble condition occurs, the musb controller removes
+ * the session and is no longer in host mode. Hence, all
+ * devices connected to its root hub get disconnected.
+ *
+ * Hand this error down to the musb core isr, so it can
+ * recover.
+ */
+ musb->int_usb = MUSB_INTR_BABBLE | MUSB_INTR_DISCONNECT;
+ musb->int_tx = musb->int_rx = 0;
+ }
+
if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) {
int drvvbus = dsps_readl(reg_base, wrp->status);
void __iomem *mregs = musb->mregs;
@@ -524,6 +536,16 @@ static int dsps_musb_set_mode(struct musb *musb, u8 mode)
return 0;
}
+static void dsps_musb_reset(struct musb *musb)
+{
+ struct device *dev = musb->controller;
+ struct dsps_glue *glue = dev_get_drvdata(dev->parent);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+
+ dsps_writel(musb->ctrl_base, wrp->control, (1 << wrp->reset));
+ udelay(100);
+}
+
static struct musb_platform_ops dsps_ops = {
.init = dsps_musb_init,
.exit = dsps_musb_exit,
@@ -533,6 +555,7 @@ static struct musb_platform_ops dsps_ops = {
.try_idle = dsps_musb_try_idle,
.set_mode = dsps_musb_set_mode,
+ .reset = dsps_musb_reset,
};
static u64 musb_dmamask = DMA_BIT_MASK(32);
@@ -750,7 +773,7 @@ static const struct of_device_id musb_dsps_of_match[] = {
};
MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int dsps_suspend(struct device *dev)
{
struct dsps_glue *glue = dev_get_drvdata(dev);