aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-pci.c20
-rw-r--r--drivers/usb/host/ohci-q.c18
-rw-r--r--drivers/usb/host/ohci.h9
4 files changed, 46 insertions, 6 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 78bb7710f36d..24eb74781919 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd *ohci);
87#ifdef CONFIG_PCI 87#ifdef CONFIG_PCI
88static void quirk_amd_pll(int state); 88static void quirk_amd_pll(int state);
89static void amd_iso_dev_put(void); 89static void amd_iso_dev_put(void);
90static void sb800_prefetch(struct ohci_hcd *ohci, int on);
90#else 91#else
91static inline void quirk_amd_pll(int state) 92static inline void quirk_amd_pll(int state)
92{ 93{
@@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void)
96{ 97{
97 return; 98 return;
98} 99}
100static inline void sb800_prefetch(struct ohci_hcd *ohci, int on)
101{
102 return;
103}
99#endif 104#endif
100 105
101 106
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index d2ba04dd785e..b8a1148f248e 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
177 return 0; 177 return 0;
178 178
179 pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); 179 pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
180
181 /* SB800 needs pre-fetch fix */
182 if ((rev >= 0x40) && (rev <= 0x4f)) {
183 ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;
184 ohci_dbg(ohci, "enabled AMD prefetch quirk\n");
185 }
186
180 if ((rev > 0x3b) || (rev < 0x30)) { 187 if ((rev > 0x3b) || (rev < 0x30)) {
181 pci_dev_put(amd_smbus_dev); 188 pci_dev_put(amd_smbus_dev);
182 amd_smbus_dev = NULL; 189 amd_smbus_dev = NULL;
@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void)
262 269
263} 270}
264 271
272static void sb800_prefetch(struct ohci_hcd *ohci, int on)
273{
274 struct pci_dev *pdev;
275 u16 misc;
276
277 pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller);
278 pci_read_config_word(pdev, 0x50, &misc);
279 if (on == 0)
280 pci_write_config_word(pdev, 0x50, misc & 0xfcff);
281 else
282 pci_write_config_word(pdev, 0x50, misc | 0x0300);
283}
284
265/* List of quirks for OHCI */ 285/* List of quirks for OHCI */
266static const struct pci_device_id ohci_pci_quirks[] = { 286static const struct pci_device_id ohci_pci_quirks[] = {
267 { 287 {
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 16fecb8ecc39..35288bcae0db 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -49,9 +49,12 @@ __acquires(ohci->lock)
49 switch (usb_pipetype (urb->pipe)) { 49 switch (usb_pipetype (urb->pipe)) {
50 case PIPE_ISOCHRONOUS: 50 case PIPE_ISOCHRONOUS:
51 ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; 51 ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
52 if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 52 if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
53 && quirk_amdiso(ohci)) 53 if (quirk_amdiso(ohci))
54 quirk_amd_pll(1); 54 quirk_amd_pll(1);
55 if (quirk_amdprefetch(ohci))
56 sb800_prefetch(ohci, 0);
57 }
55 break; 58 break;
56 case PIPE_INTERRUPT: 59 case PIPE_INTERRUPT:
57 ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; 60 ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
@@ -680,9 +683,12 @@ static void td_submit_urb (
680 data + urb->iso_frame_desc [cnt].offset, 683 data + urb->iso_frame_desc [cnt].offset,
681 urb->iso_frame_desc [cnt].length, urb, cnt); 684 urb->iso_frame_desc [cnt].length, urb, cnt);
682 } 685 }
683 if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 686 if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
684 && quirk_amdiso(ohci)) 687 if (quirk_amdiso(ohci))
685 quirk_amd_pll(0); 688 quirk_amd_pll(0);
689 if (quirk_amdprefetch(ohci))
690 sb800_prefetch(ohci, 1);
691 }
686 periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 692 periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
687 && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; 693 && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
688 break; 694 break;
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 222011f6172c..5bf15fed0d9f 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -402,6 +402,7 @@ struct ohci_hcd {
402#define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ 402#define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */
403#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ 403#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
404#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ 404#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/
405#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
405 // there are also chip quirks/bugs in init logic 406 // there are also chip quirks/bugs in init logic
406 407
407 struct work_struct nec_work; /* Worker for NEC quirk */ 408 struct work_struct nec_work; /* Worker for NEC quirk */
@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
433{ 434{
434 return ohci->flags & OHCI_QUIRK_AMD_ISO; 435 return ohci->flags & OHCI_QUIRK_AMD_ISO;
435} 436}
437static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
438{
439 return ohci->flags & OHCI_QUIRK_AMD_PREFETCH;
440}
436#else 441#else
437static inline int quirk_nec(struct ohci_hcd *ohci) 442static inline int quirk_nec(struct ohci_hcd *ohci)
438{ 443{
@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
446{ 451{
447 return 0; 452 return 0;
448} 453}
454static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
455{
456 return 0;
457}
449#endif 458#endif
450 459
451/* convert between an hcd pointer and the corresponding ohci_hcd */ 460/* convert between an hcd pointer and the corresponding ohci_hcd */