diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci.h | 19 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 15 | ||||
-rw-r--r-- | drivers/usb/host/ohci-q.c | 12 |
3 files changed, 36 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 35a03095757e..90245fd8bac4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -177,6 +177,15 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
177 | static inline void | 177 | static inline void |
178 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | 178 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) |
179 | { | 179 | { |
180 | /* Don't override timeouts which shrink or (later) disable | ||
181 | * the async ring; just the I/O watchdog. Note that if a | ||
182 | * SHRINK were pending, OFF would never be requested. | ||
183 | */ | ||
184 | if (timer_pending(&ehci->watchdog) | ||
185 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
186 | & ehci->actions)) | ||
187 | return; | ||
188 | |||
180 | if (!test_and_set_bit (action, &ehci->actions)) { | 189 | if (!test_and_set_bit (action, &ehci->actions)) { |
181 | unsigned long t; | 190 | unsigned long t; |
182 | 191 | ||
@@ -192,15 +201,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
192 | t = EHCI_SHRINK_JIFFIES; | 201 | t = EHCI_SHRINK_JIFFIES; |
193 | break; | 202 | break; |
194 | } | 203 | } |
195 | t += jiffies; | 204 | mod_timer(&ehci->watchdog, t + jiffies); |
196 | // all timings except IAA watchdog can be overridden. | ||
197 | // async queue SHRINK often precedes IAA. while it's ready | ||
198 | // to go OFF neither can matter, and afterwards the IO | ||
199 | // watchdog stops unless there's still periodic traffic. | ||
200 | if (time_before_eq(t, ehci->watchdog.expires) | ||
201 | && timer_pending (&ehci->watchdog)) | ||
202 | return; | ||
203 | mod_timer (&ehci->watchdog, t); | ||
204 | } | 205 | } |
205 | } | 206 | } |
206 | 207 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 33f1c1c32edf..a8160d65f32b 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1054,7 +1054,7 @@ MODULE_LICENSE ("GPL"); | |||
1054 | 1054 | ||
1055 | #ifdef CONFIG_MFD_SM501 | 1055 | #ifdef CONFIG_MFD_SM501 |
1056 | #include "ohci-sm501.c" | 1056 | #include "ohci-sm501.c" |
1057 | #define PLATFORM_DRIVER ohci_hcd_sm501_driver | 1057 | #define SM501_OHCI_DRIVER ohci_hcd_sm501_driver |
1058 | #endif | 1058 | #endif |
1059 | 1059 | ||
1060 | #if !defined(PCI_DRIVER) && \ | 1060 | #if !defined(PCI_DRIVER) && \ |
@@ -1062,6 +1062,7 @@ MODULE_LICENSE ("GPL"); | |||
1062 | !defined(OF_PLATFORM_DRIVER) && \ | 1062 | !defined(OF_PLATFORM_DRIVER) && \ |
1063 | !defined(SA1111_DRIVER) && \ | 1063 | !defined(SA1111_DRIVER) && \ |
1064 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ | 1064 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ |
1065 | !defined(SM501_OHCI_DRIVER) && \ | ||
1065 | !defined(SSB_OHCI_DRIVER) | 1066 | !defined(SSB_OHCI_DRIVER) |
1066 | #error "missing bus glue for ohci-hcd" | 1067 | #error "missing bus glue for ohci-hcd" |
1067 | #endif | 1068 | #endif |
@@ -1121,9 +1122,18 @@ static int __init ohci_hcd_mod_init(void) | |||
1121 | goto error_ssb; | 1122 | goto error_ssb; |
1122 | #endif | 1123 | #endif |
1123 | 1124 | ||
1125 | #ifdef SM501_OHCI_DRIVER | ||
1126 | retval = platform_driver_register(&SM501_OHCI_DRIVER); | ||
1127 | if (retval < 0) | ||
1128 | goto error_sm501; | ||
1129 | #endif | ||
1130 | |||
1124 | return retval; | 1131 | return retval; |
1125 | 1132 | ||
1126 | /* Error path */ | 1133 | /* Error path */ |
1134 | #ifdef SM501_OHCI_DRIVER | ||
1135 | error_sm501: | ||
1136 | #endif | ||
1127 | #ifdef SSB_OHCI_DRIVER | 1137 | #ifdef SSB_OHCI_DRIVER |
1128 | error_ssb: | 1138 | error_ssb: |
1129 | #endif | 1139 | #endif |
@@ -1159,6 +1169,9 @@ module_init(ohci_hcd_mod_init); | |||
1159 | 1169 | ||
1160 | static void __exit ohci_hcd_mod_exit(void) | 1170 | static void __exit ohci_hcd_mod_exit(void) |
1161 | { | 1171 | { |
1172 | #ifdef SM501_OHCI_DRIVER | ||
1173 | platform_driver_unregister(&SM501_OHCI_DRIVER); | ||
1174 | #endif | ||
1162 | #ifdef SSB_OHCI_DRIVER | 1175 | #ifdef SSB_OHCI_DRIVER |
1163 | ssb_driver_unregister(&SSB_OHCI_DRIVER); | 1176 | ssb_driver_unregister(&SSB_OHCI_DRIVER); |
1164 | #endif | 1177 | #endif |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 9c9f3b59186f..9b547407c934 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -952,6 +952,7 @@ rescan_this: | |||
952 | struct urb *urb; | 952 | struct urb *urb; |
953 | urb_priv_t *urb_priv; | 953 | urb_priv_t *urb_priv; |
954 | __hc32 savebits; | 954 | __hc32 savebits; |
955 | u32 tdINFO; | ||
955 | 956 | ||
956 | td = list_entry (entry, struct td, td_list); | 957 | td = list_entry (entry, struct td, td_list); |
957 | urb = td->urb; | 958 | urb = td->urb; |
@@ -966,6 +967,17 @@ rescan_this: | |||
966 | savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK); | 967 | savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK); |
967 | *prev = td->hwNextTD | savebits; | 968 | *prev = td->hwNextTD | savebits; |
968 | 969 | ||
970 | /* If this was unlinked, the TD may not have been | ||
971 | * retired ... so manually save the data toggle. | ||
972 | * The controller ignores the value we save for | ||
973 | * control and ISO endpoints. | ||
974 | */ | ||
975 | tdINFO = hc32_to_cpup(ohci, &td->hwINFO); | ||
976 | if ((tdINFO & TD_T) == TD_T_DATA0) | ||
977 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_C); | ||
978 | else if ((tdINFO & TD_T) == TD_T_DATA1) | ||
979 | ed->hwHeadP |= cpu_to_hc32(ohci, ED_C); | ||
980 | |||
969 | /* HC may have partly processed this TD */ | 981 | /* HC may have partly processed this TD */ |
970 | td_done (ohci, urb, td); | 982 | td_done (ohci, urb, td); |
971 | urb_priv->td_cnt++; | 983 | urb_priv->td_cnt++; |