diff options
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 5728829cf6ef..118edb7bdca2 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -69,10 +69,8 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) | |||
69 | if (test_bit(port, &ehci->owned_ports)) { | 69 | if (test_bit(port, &ehci->owned_ports)) { |
70 | reg = &ehci->regs->port_status[port]; | 70 | reg = &ehci->regs->port_status[port]; |
71 | status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; | 71 | status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |
72 | if (!(status & PORT_POWER)) { | 72 | if (!(status & PORT_POWER)) |
73 | status |= PORT_POWER; | 73 | ehci_port_power(ehci, port, true); |
74 | ehci_writel(ehci, status, reg); | ||
75 | } | ||
76 | } | 74 | } |
77 | } | 75 | } |
78 | 76 | ||
@@ -952,9 +950,11 @@ int ehci_hub_control( | |||
952 | clear_bit(wIndex, &ehci->port_c_suspend); | 950 | clear_bit(wIndex, &ehci->port_c_suspend); |
953 | break; | 951 | break; |
954 | case USB_PORT_FEAT_POWER: | 952 | case USB_PORT_FEAT_POWER: |
955 | if (HCS_PPC (ehci->hcs_params)) | 953 | if (HCS_PPC(ehci->hcs_params)) { |
956 | ehci_writel(ehci, temp & ~PORT_POWER, | 954 | spin_unlock_irqrestore(&ehci->lock, flags); |
957 | status_reg); | 955 | ehci_port_power(ehci, wIndex, false); |
956 | spin_lock_irqsave(&ehci->lock, flags); | ||
957 | } | ||
958 | break; | 958 | break; |
959 | case USB_PORT_FEAT_C_CONNECTION: | 959 | case USB_PORT_FEAT_C_CONNECTION: |
960 | ehci_writel(ehci, temp | PORT_CSC, status_reg); | 960 | ehci_writel(ehci, temp | PORT_CSC, status_reg); |
@@ -1004,9 +1004,9 @@ int ehci_hub_control( | |||
1004 | */ | 1004 | */ |
1005 | if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle)) | 1005 | if (((temp & PORT_OC) || (ehci->need_oc_pp_cycle)) |
1006 | && HCS_PPC(ehci->hcs_params)) { | 1006 | && HCS_PPC(ehci->hcs_params)) { |
1007 | ehci_writel(ehci, | 1007 | spin_unlock_irqrestore(&ehci->lock, flags); |
1008 | temp & ~(PORT_RWC_BITS | PORT_POWER), | 1008 | ehci_port_power(ehci, wIndex, false); |
1009 | status_reg); | 1009 | spin_lock_irqsave(&ehci->lock, flags); |
1010 | temp = ehci_readl(ehci, status_reg); | 1010 | temp = ehci_readl(ehci, status_reg); |
1011 | } | 1011 | } |
1012 | } | 1012 | } |
@@ -1187,9 +1187,11 @@ int ehci_hub_control( | |||
1187 | set_bit(wIndex, &ehci->suspended_ports); | 1187 | set_bit(wIndex, &ehci->suspended_ports); |
1188 | break; | 1188 | break; |
1189 | case USB_PORT_FEAT_POWER: | 1189 | case USB_PORT_FEAT_POWER: |
1190 | if (HCS_PPC (ehci->hcs_params)) | 1190 | if (HCS_PPC(ehci->hcs_params)) { |
1191 | ehci_writel(ehci, temp | PORT_POWER, | 1191 | spin_unlock_irqrestore(&ehci->lock, flags); |
1192 | status_reg); | 1192 | ehci_port_power(ehci, wIndex, true); |
1193 | spin_lock_irqsave(&ehci->lock, flags); | ||
1194 | } | ||
1193 | break; | 1195 | break; |
1194 | case USB_PORT_FEAT_RESET: | 1196 | case USB_PORT_FEAT_RESET: |
1195 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | 1197 | if (temp & (PORT_SUSPEND|PORT_RESUME)) |
@@ -1297,3 +1299,20 @@ static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) | |||
1297 | reg = &ehci->regs->port_status[portnum - 1]; | 1299 | reg = &ehci->regs->port_status[portnum - 1]; |
1298 | return ehci_readl(ehci, reg) & PORT_OWNER; | 1300 | return ehci_readl(ehci, reg) & PORT_OWNER; |
1299 | } | 1301 | } |
1302 | |||
1303 | static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable) | ||
1304 | { | ||
1305 | struct usb_hcd *hcd = ehci_to_hcd(ehci); | ||
1306 | u32 __iomem *status_reg = &ehci->regs->port_status[portnum]; | ||
1307 | u32 temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS; | ||
1308 | |||
1309 | if (enable) | ||
1310 | ehci_writel(ehci, temp | PORT_POWER, status_reg); | ||
1311 | else | ||
1312 | ehci_writel(ehci, temp & ~PORT_POWER, status_reg); | ||
1313 | |||
1314 | if (hcd->driver->port_power) | ||
1315 | hcd->driver->port_power(hcd, portnum, enable); | ||
1316 | |||
1317 | return 0; | ||
1318 | } | ||