Commit 6219c047 authored by Sarah Sharp's avatar Sarah Sharp Committed by Greg Kroah-Hartman

USB: xhci: Allow roothub ports to be disabled.

Add the hub emulation code to allow ports on an xHCI root hub to be
disabled.  Add the code to clear the port enabled/disabled bit, and clear
the port enabled/disabled change bit.  Like EHCI, the port cannot be
enabled by setting the port enabled/disabled bit.  Instead, a port is
enabled by the host controller after a reset.
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 34fb562a
...@@ -129,6 +129,16 @@ static u32 xhci_port_state_to_neutral(u32 state) ...@@ -129,6 +129,16 @@ static u32 xhci_port_state_to_neutral(u32 state)
return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS);
} }
static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex,
u32 __iomem *addr, u32 port_status)
{
/* Write 1 to disable the port */
xhci_writel(xhci, port_status | PORT_PE, addr);
port_status = xhci_readl(xhci, addr);
xhci_dbg(xhci, "disable port, actual port %d status = 0x%x\n",
wIndex, port_status);
}
static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
u16 wIndex, u32 __iomem *addr, u32 port_status) u16 wIndex, u32 __iomem *addr, u32 port_status)
{ {
...@@ -148,6 +158,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, ...@@ -148,6 +158,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
status = PORT_OCC; status = PORT_OCC;
port_change_bit = "over-current"; port_change_bit = "over-current";
break; break;
case USB_PORT_FEAT_C_ENABLE:
status = PORT_PEC;
port_change_bit = "enable/disable";
break;
default: default:
/* Should never happen */ /* Should never happen */
return; return;
...@@ -260,9 +274,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -260,9 +274,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_RESET:
case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_CONNECTION:
case USB_PORT_FEAT_C_OVER_CURRENT: case USB_PORT_FEAT_C_OVER_CURRENT:
case USB_PORT_FEAT_C_ENABLE:
xhci_clear_port_change_bit(xhci, wValue, wIndex, xhci_clear_port_change_bit(xhci, wValue, wIndex,
addr, temp); addr, temp);
break; break;
case USB_PORT_FEAT_ENABLE:
xhci_disable_port(xhci, wIndex, addr, temp);
break;
default: default:
goto error; goto error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment