aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-hub.c
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2012-10-15 03:38:34 -0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2012-10-22 16:26:48 -0400
commit170ed807340b4db0a5e010c2e4da43cf5a2c9a29 (patch)
tree96747e7e36a9ff35f186c1cb9e3f0bb8d4276d9c /drivers/usb/host/xhci-hub.c
parent3b6054da68f9b0d5ed6a7ed0f42a79e61904352c (diff)
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,
809 temp = xhci_readl(xhci, port_array[wIndex]); 809 temp = xhci_readl(xhci, port_array[wIndex]);
810 xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); 810 xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);
811 811
812 spin_unlock_irqrestore(&xhci->lock, flags);
812 temp = usb_acpi_power_manageable(hcd->self.root_hub, 813 temp = usb_acpi_power_manageable(hcd->self.root_hub,
813 wIndex); 814 wIndex);
814 if (temp) 815 if (temp)
815 usb_acpi_set_power_state(hcd->self.root_hub, 816 usb_acpi_set_power_state(hcd->self.root_hub,
816 wIndex, true); 817 wIndex, true);
818 spin_lock_irqsave(&xhci->lock, flags);
817 break; 819 break;
818 case USB_PORT_FEAT_RESET: 820 case USB_PORT_FEAT_RESET:
819 temp = (temp | PORT_RESET); 821 temp = (temp | PORT_RESET);
@@ -917,11 +919,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
917 xhci_writel(xhci, temp & ~PORT_POWER, 919 xhci_writel(xhci, temp & ~PORT_POWER,
918 port_array[wIndex]); 920 port_array[wIndex]);
919 921
922 spin_unlock_irqrestore(&xhci->lock, flags);
920 temp = usb_acpi_power_manageable(hcd->self.root_hub, 923 temp = usb_acpi_power_manageable(hcd->self.root_hub,
921 wIndex); 924 wIndex);
922 if (temp) 925 if (temp)
923 usb_acpi_set_power_state(hcd->self.root_hub, 926 usb_acpi_set_power_state(hcd->self.root_hub,
924 wIndex, false); 927 wIndex, false);
928 spin_lock_irqsave(&xhci->lock, flags);
925 break; 929 break;
926 default: 930 default:
927 goto error; 931 goto error;