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: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
34fb562a43
commit
6219c047d3
@@ -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,
|
|||||||
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,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user