summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2012-10-15 15:38:34 +0800
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2012-10-22 13:26:48 -0700
commit170ed807340b4db0a5e010c2e4da43cf5a2c9a29 (patch)
tree96747e7e36a9ff35f186c1cb9e3f0bb8d4276d9c /drivers/usb/host/xhci-hub.c
parent3b6054da68f9b0d5ed6a7ed0f42a79e61904352c (diff)
downloadtalos-op-linux-170ed807340b4db0a5e010c2e4da43cf5a2c9a29.tar.gz
talos-op-linux-170ed807340b4db0a5e010c2e4da43cf5a2c9a29.zip
usb/xhci: release xhci->lock during turning on/off usb port's acpi power resource and checking the existence of port's power resource
When setting usb port's acpi power resource, there will be some xhci hub requests. This will cause dead lock since xhci->lock has been held before setting acpi power resource in the xhci_hub_control(). The usb_acpi_power_manageable() function might fall into sleep so release xhci->lock before invoking it. Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci-hub.c')
-rw-r--r--drivers/usb/host/xhci-hub.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index aa90ad4d4fd5..65d416c08cef 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -809,11 +809,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_readl(xhci, port_array[wIndex]);
xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);
+ spin_unlock_irqrestore(&xhci->lock, flags);
temp = usb_acpi_power_manageable(hcd->self.root_hub,
wIndex);
if (temp)
usb_acpi_set_power_state(hcd->self.root_hub,
wIndex, true);
+ spin_lock_irqsave(&xhci->lock, flags);
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
@@ -917,11 +919,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_writel(xhci, temp & ~PORT_POWER,
port_array[wIndex]);
+ spin_unlock_irqrestore(&xhci->lock, flags);
temp = usb_acpi_power_manageable(hcd->self.root_hub,
wIndex);
if (temp)
usb_acpi_set_power_state(hcd->self.root_hub,
wIndex, false);
+ spin_lock_irqsave(&xhci->lock, flags);
break;
default:
goto error;
OpenPOWER on IntegriCloud