summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-27 13:02:57 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-27 13:02:57 -0700
commit62f4b242ca43c17d9d332de0db5a708f29bfe732 (patch)
treeec4f7c3780da0f1a8d274312eebff4326db8919e /drivers/usb
parentce26bd23d4ad180883f53709f9a2220dc771c030 (diff)
parent0730d52a86919300a39a2be37f6c140997dfb82f (diff)
downloadlinux-62f4b242ca43c17d9d332de0db5a708f29bfe732.tar.gz
linux-62f4b242ca43c17d9d332de0db5a708f29bfe732.tar.bz2
linux-62f4b242ca43c17d9d332de0db5a708f29bfe732.zip
Merge tag 'for-usb-next-2013-08-27' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-next
Sarah writes: xhci: Bug fixes for 3.12. Hi Greg, Here's three low-priority bug fixes that should be queued for 3.12. They disable runtime PM for hosts that need the XHCI_RESET_ON_RESUME quirk, fix USB 2.0 Link PM on hosts that don't have BESL support, and prevent a bunch of log spam. Please pull into usb-next for 3.12. Sarah Sharp
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-ext-caps.h2
-rw-r--r--drivers/usb/host/xhci-ring.c24
-rw-r--r--drivers/usb/host/xhci.c22
3 files changed, 31 insertions, 17 deletions
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h
index 8d7a1324e2f3..9fe3225e6c61 100644
--- a/drivers/usb/host/xhci-ext-caps.h
+++ b/drivers/usb/host/xhci-ext-caps.h
@@ -71,7 +71,7 @@
/* USB 2.0 xHCI 1.0 hardware LMP capability - section 7.2.2.1.3.2 */
#define XHCI_HLC (1 << 19)
-#define XHCI_BLC (1 << 19)
+#define XHCI_BLC (1 << 20)
/* command register values to disable interrupts and halt the HC */
/* start/stop HC execution - do not write unless HC is halted*/
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7b35af167e55..411da1fc7ae8 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3087,14 +3087,10 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
* to set the polling interval (once the API is added).
*/
if (xhci_interval != ep_interval) {
- if (printk_ratelimit())
- dev_dbg(&urb->dev->dev, "Driver uses different interval"
- " (%d microframe%s) than xHCI "
- "(%d microframe%s)\n",
- ep_interval,
- ep_interval == 1 ? "" : "s",
- xhci_interval,
- xhci_interval == 1 ? "" : "s");
+ dev_dbg_ratelimited(&urb->dev->dev,
+ "Driver uses different interval (%d microframe%s) than xHCI (%d microframe%s)\n",
+ ep_interval, ep_interval == 1 ? "" : "s",
+ xhci_interval, xhci_interval == 1 ? "" : "s");
urb->interval = xhci_interval;
/* Convert back to frames for LS/FS devices */
if (urb->dev->speed == USB_SPEED_LOW ||
@@ -3876,14 +3872,10 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
* to set the polling interval (once the API is added).
*/
if (xhci_interval != ep_interval) {
- if (printk_ratelimit())
- dev_dbg(&urb->dev->dev, "Driver uses different interval"
- " (%d microframe%s) than xHCI "
- "(%d microframe%s)\n",
- ep_interval,
- ep_interval == 1 ? "" : "s",
- xhci_interval,
- xhci_interval == 1 ? "" : "s");
+ dev_dbg_ratelimited(&urb->dev->dev,
+ "Driver uses different interval (%d microframe%s) than xHCI (%d microframe%s)\n",
+ ep_interval, ep_interval == 1 ? "" : "s",
+ xhci_interval, xhci_interval == 1 ? "" : "s");
urb->interval = xhci_interval;
/* Convert back to frames for LS/FS devices */
if (urb->dev->speed == USB_SPEED_LOW ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ba0ec0a96481..349d3460a17a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3557,10 +3557,21 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_virt_device *virt_dev;
+ struct device *dev = hcd->self.controller;
unsigned long flags;
u32 state;
int i, ret;
+#ifndef CONFIG_USB_DEFAULT_PERSIST
+ /*
+ * We called pm_runtime_get_noresume when the device was attached.
+ * Decrement the counter here to allow controller to runtime suspend
+ * if no devices remain.
+ */
+ if (xhci->quirks & XHCI_RESET_ON_RESUME)
+ pm_runtime_put_noidle(dev);
+#endif
+
ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
/* If the host is halted due to driver unload, we still need to free the
* device.
@@ -3634,6 +3645,7 @@ static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci)
int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ struct device *dev = hcd->self.controller;
unsigned long flags;
int timeleft;
int ret;
@@ -3686,6 +3698,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
goto disable_slot;
}
udev->slot_id = xhci->slot_id;
+
+#ifndef CONFIG_USB_DEFAULT_PERSIST
+ /*
+ * If resetting upon resume, we can't put the controller into runtime
+ * suspend if there is a device attached.
+ */
+ if (xhci->quirks & XHCI_RESET_ON_RESUME)
+ pm_runtime_get_noresume(dev);
+#endif
+
/* Is this a LS or FS device under a HS hub? */
/* Hub or peripherial? */
return 1;