From c8476fb855434c733099079063990e5bfa7ecad6 Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Mon, 19 Aug 2013 10:36:13 -0700 Subject: usb: xhci: Disable runtime PM suspend for quirky controllers If a USB controller with XHCI_RESET_ON_RESUME goes to runtime suspend, a reset will be performed upon runtime resume. Any previously suspended devices attached to the controller will be re-enumerated at this time. This will cause problems, for example, if an open system call on the device triggered the resume (the open call will fail). Note that this change is only relevant when persist_enabled is not set for USB devices. This patch should be backported to kernels as old as 3.0, that contain the commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 "xhci: Add reset on resume quirk for asrock p67 host". Signed-off-by: Shawn Nematbakhsh Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/usb') 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; -- cgit v1.2.2 From dcf06a036848b4e8e6c8220f2e00b9adf6f84918 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 21 Aug 2013 18:50:09 +0300 Subject: xhci: fix port BESL LPM capability checking Wrong capability bit was checked for best effort service latency. bit 20 indicate port is BESL LPM capable (BLC), bit 19 is hardware LPM capable (HLC) This patch should be backported to kernels as old as 3.11, that contain the commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09 "usb: xhci: add USB2 Link power management BESL support" Signed-off-by: Mathias Nyman Signed-off-by: Sarah Sharp Reported-by: Steve Cotton Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-ext-caps.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb') 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*/ -- cgit v1.2.2 From 0730d52a86919300a39a2be37f6c140997dfb82f Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 27 Aug 2013 17:47:35 +0300 Subject: xhci:prevent "callbacks suppressed" when debug is not enabled When debug is not enabled and dev_dbg() will expand to nothing, log might be flooded with "callbacks suppressed". If it was not done on purpose, better to use dev_dbg_ratelimited() instead. Signed-off-by: Dmitry Kasatkin Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers/usb') 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 || -- cgit v1.2.2