diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2012-04-23 13:54:36 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-23 15:05:44 -0400 |
commit | 3d9545cc375d117554a9b35dfddadf9189c62775 (patch) | |
tree | b01707d2e0901665f20bae0f0c5a0930af69651a /drivers/usb/host/ehci-q.c | |
parent | 09091a4d5f2dd378dcf71de50b48cdacc58a8ac0 (diff) |
EHCI: maintain the ehci->command value properly
The ehci-hcd driver is a little haphazard about keeping track of the
state of the USBCMD register. The ehci->command field is supposed to
hold the register's value (apart from a few special bits) at all
times, but it isn't maintained properly.
This patch (as1543) cleans up the situation. It keeps ehci->command
up-to-date, and uses that value rather than reading the register from
the hardware whenever possible.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-q.c')
-rw-r--r-- | drivers/usb/host/ehci-q.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 36ca5077cdf7..13f4f980841a 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -981,14 +981,12 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
981 | head = ehci->async; | 981 | head = ehci->async; |
982 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 982 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
983 | if (!head->qh_next.qh) { | 983 | if (!head->qh_next.qh) { |
984 | u32 cmd = ehci_readl(ehci, &ehci->regs->command); | 984 | if (!(ehci->command & CMD_ASE)) { |
985 | |||
986 | if (!(cmd & CMD_ASE)) { | ||
987 | /* in case a clear of CMD_ASE didn't take yet */ | 985 | /* in case a clear of CMD_ASE didn't take yet */ |
988 | (void)handshake(ehci, &ehci->regs->status, | 986 | (void)handshake(ehci, &ehci->regs->status, |
989 | STS_ASS, 0, 150); | 987 | STS_ASS, 0, 150); |
990 | cmd |= CMD_ASE; | 988 | ehci->command |= CMD_ASE; |
991 | ehci_writel(ehci, cmd, &ehci->regs->command); | 989 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
992 | /* posted write need not be known to HC yet ... */ | 990 | /* posted write need not be known to HC yet ... */ |
993 | } | 991 | } |
994 | } | 992 | } |
@@ -1204,7 +1202,6 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
1204 | 1202 | ||
1205 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 1203 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
1206 | { | 1204 | { |
1207 | int cmd = ehci_readl(ehci, &ehci->regs->command); | ||
1208 | struct ehci_qh *prev; | 1205 | struct ehci_qh *prev; |
1209 | 1206 | ||
1210 | #ifdef DEBUG | 1207 | #ifdef DEBUG |
@@ -1222,8 +1219,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1222 | if (ehci->rh_state != EHCI_RH_HALTED | 1219 | if (ehci->rh_state != EHCI_RH_HALTED |
1223 | && !ehci->reclaim) { | 1220 | && !ehci->reclaim) { |
1224 | /* ... and CMD_IAAD clear */ | 1221 | /* ... and CMD_IAAD clear */ |
1225 | ehci_writel(ehci, cmd & ~CMD_ASE, | 1222 | ehci->command &= ~CMD_ASE; |
1226 | &ehci->regs->command); | 1223 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
1227 | wmb (); | 1224 | wmb (); |
1228 | // handshake later, if we need to | 1225 | // handshake later, if we need to |
1229 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 1226 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
@@ -1253,8 +1250,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1253 | return; | 1250 | return; |
1254 | } | 1251 | } |
1255 | 1252 | ||
1256 | cmd |= CMD_IAAD; | 1253 | ehci_writel(ehci, ehci->command | CMD_IAAD, &ehci->regs->command); |
1257 | ehci_writel(ehci, cmd, &ehci->regs->command); | ||
1258 | (void)ehci_readl(ehci, &ehci->regs->command); | 1254 | (void)ehci_readl(ehci, &ehci->regs->command); |
1259 | iaa_watchdog_start(ehci); | 1255 | iaa_watchdog_start(ehci); |
1260 | } | 1256 | } |