diff options
author | Stuart_Hayes@Dell.com <Stuart_Hayes@Dell.com> | 2007-05-03 11:58:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:29:45 -0400 |
commit | 196705c9bbc03540429b0f7cf9ee35c2f928a534 (patch) | |
tree | 37ddc23737bced60a8defc52f643f362e2744908 /drivers/usb/host/ehci.h | |
parent | ec22559e0b7a05283a3413bda5d177e42c950e23 (diff) |
USB: EHCI cpufreq fix
EHCI controllers that don't cache enough microframes can get MMF errors
when CPU frequency changes occur between the start and completion of
split interrupt transactions, due to delays in reading main memory
(caused by CPU cache snoop delays).
This patch adds a cpufreq notifier to the EHCI driver that will
inactivate split interrupt transactions during frequency transitions.
It was tested on Intel ICH7 and Serverworks/Broadcom HT1000 EHCI
controllers.
Signed-off-by: Stuart Hayes <stuart_hayes@dell.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci.h')
-rw-r--r-- | drivers/usb/host/ehci.h | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 46fa57a520d0..a9ba5d28cdc2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -55,6 +55,12 @@ struct ehci_hcd { /* one per controller */ | |||
55 | __u32 hcs_params; /* cached register copy */ | 55 | __u32 hcs_params; /* cached register copy */ |
56 | spinlock_t lock; | 56 | spinlock_t lock; |
57 | 57 | ||
58 | #ifdef CONFIG_CPU_FREQ | ||
59 | struct notifier_block cpufreq_transition; | ||
60 | int cpufreq_changing; | ||
61 | struct list_head split_intr_qhs; | ||
62 | #endif | ||
63 | |||
58 | /* async schedule support */ | 64 | /* async schedule support */ |
59 | struct ehci_qh *async; | 65 | struct ehci_qh *async; |
60 | struct ehci_qh *reclaim; | 66 | struct ehci_qh *reclaim; |
@@ -395,6 +401,7 @@ struct ehci_qh { | |||
395 | __le32 hw_next; /* see EHCI 3.6.1 */ | 401 | __le32 hw_next; /* see EHCI 3.6.1 */ |
396 | __le32 hw_info1; /* see EHCI 3.6.2 */ | 402 | __le32 hw_info1; /* see EHCI 3.6.2 */ |
397 | #define QH_HEAD 0x00008000 | 403 | #define QH_HEAD 0x00008000 |
404 | #define QH_INACTIVATE 0x00000080 | ||
398 | __le32 hw_info2; /* see EHCI 3.6.2 */ | 405 | __le32 hw_info2; /* see EHCI 3.6.2 */ |
399 | #define QH_SMASK 0x000000ff | 406 | #define QH_SMASK 0x000000ff |
400 | #define QH_CMASK 0x0000ff00 | 407 | #define QH_CMASK 0x0000ff00 |
@@ -437,6 +444,10 @@ struct ehci_qh { | |||
437 | unsigned short start; /* where polling starts */ | 444 | unsigned short start; /* where polling starts */ |
438 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ | 445 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
439 | struct usb_device *dev; /* access to TT */ | 446 | struct usb_device *dev; /* access to TT */ |
447 | #ifdef CONFIG_CPU_FREQ | ||
448 | struct list_head split_intr_qhs; /* list of split qhs */ | ||
449 | __le32 was_active; /* active bit before "i" set */ | ||
450 | #endif | ||
440 | } __attribute__ ((aligned (32))); | 451 | } __attribute__ ((aligned (32))); |
441 | 452 | ||
442 | /*-------------------------------------------------------------------------*/ | 453 | /*-------------------------------------------------------------------------*/ |