提交 34fb562a 编写于 作者: S Sarah Sharp 提交者: Greg Kroah-Hartman

USB: xhci: Refactor code to clear port change bits.

Refactor the code to clear the port change bits in the port status
register.  All port status change bits are write one to clear.

Remove a redundant port status read that was supposed to unblock any
posted writes.  We read the port after the write to get the updated status
for debugging, so the port read after that is unnecessary.
Signed-off-by: NSarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 b45b5069
...@@ -129,6 +129,36 @@ static u32 xhci_port_state_to_neutral(u32 state) ...@@ -129,6 +129,36 @@ 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_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
u16 wIndex, u32 __iomem *addr, u32 port_status)
{
char *port_change_bit;
u32 status;
switch (wValue) {
case USB_PORT_FEAT_C_RESET:
status = PORT_RC;
port_change_bit = "reset";
break;
case USB_PORT_FEAT_C_CONNECTION:
status = PORT_CSC;
port_change_bit = "connect";
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
status = PORT_OCC;
port_change_bit = "over-current";
break;
default:
/* Should never happen */
return;
}
/* Change bits are all write 1 to clear */
xhci_writel(xhci, port_status | status, addr);
port_status = xhci_readl(xhci, addr);
xhci_dbg(xhci, "clear port %s change, actual port %d status = 0x%x\n",
port_change_bit, wIndex, port_status);
}
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 wIndex, char *buf, u16 wLength) u16 wIndex, char *buf, u16 wLength)
{ {
...@@ -138,7 +168,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -138,7 +168,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u32 temp, status; u32 temp, status;
int retval = 0; int retval = 0;
u32 __iomem *addr; u32 __iomem *addr;
char *port_change_bit;
ports = HCS_MAX_PORTS(xhci->hcs_params1); ports = HCS_MAX_PORTS(xhci->hcs_params1);
...@@ -229,26 +258,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -229,26 +258,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_port_state_to_neutral(temp); temp = xhci_port_state_to_neutral(temp);
switch (wValue) { switch (wValue) {
case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_RESET:
status = PORT_RC;
port_change_bit = "reset";
break;
case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_CONNECTION:
status = PORT_CSC;
port_change_bit = "connect";
break;
case USB_PORT_FEAT_C_OVER_CURRENT: case USB_PORT_FEAT_C_OVER_CURRENT:
status = PORT_OCC; xhci_clear_port_change_bit(xhci, wValue, wIndex,
port_change_bit = "over-current"; addr, temp);
break; break;
default: default:
goto error; goto error;
} }
/* Change bits are all write 1 to clear */
xhci_writel(xhci, temp | status, addr);
temp = xhci_readl(xhci, addr);
xhci_dbg(xhci, "clear port %s change, actual port %d status = 0x%x\n",
port_change_bit, wIndex, temp);
temp = xhci_readl(xhci, addr); /* unblock any posted writes */
break; break;
default: default:
error: error:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册