diff options
-rw-r--r-- | drivers/usb/host/Kconfig | 10 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 26 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ppc-soc.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 147 |
4 files changed, 130 insertions, 55 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cc60759083bf..faabce8bf39f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -101,7 +101,8 @@ config USB_OHCI_HCD_PPC_SOC | |||
101 | bool "OHCI support for on-chip PPC USB controller" | 101 | bool "OHCI support for on-chip PPC USB controller" |
102 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) | 102 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) |
103 | default y | 103 | default y |
104 | select USB_OHCI_BIG_ENDIAN | 104 | select USB_OHCI_BIG_ENDIAN_DESC |
105 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
105 | ---help--- | 106 | ---help--- |
106 | Enables support for the USB controller on the MPC52xx or | 107 | Enables support for the USB controller on the MPC52xx or |
107 | STB03xxx processor chip. If unsure, say Y. | 108 | STB03xxx processor chip. If unsure, say Y. |
@@ -115,7 +116,12 @@ config USB_OHCI_HCD_PCI | |||
115 | Enables support for PCI-bus plug-in USB controller cards. | 116 | Enables support for PCI-bus plug-in USB controller cards. |
116 | If unsure, say Y. | 117 | If unsure, say Y. |
117 | 118 | ||
118 | config USB_OHCI_BIG_ENDIAN | 119 | config USB_OHCI_BIG_ENDIAN_DESC |
120 | bool | ||
121 | depends on USB_OHCI_HCD | ||
122 | default n | ||
123 | |||
124 | config USB_OHCI_BIG_ENDIAN_MMIO | ||
119 | bool | 125 | bool |
120 | depends on USB_OHCI_HCD | 126 | depends on USB_OHCI_HCD |
121 | default n | 127 | default n |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 82fbec305a66..292daf044b62 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -85,6 +85,27 @@ static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) | |||
85 | return 0; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | /* Check for Toshiba SCC OHCI which has big endian registers | ||
89 | * and little endian in memory data structures | ||
90 | */ | ||
91 | static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | ||
92 | { | ||
93 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
94 | |||
95 | /* That chip is only present in the southbridge of some | ||
96 | * cell based platforms which are supposed to select | ||
97 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if | ||
98 | * that was the case though. | ||
99 | */ | ||
100 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
101 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
102 | ohci_dbg (ohci, "enabled big endian Toshiba quirk\n"); | ||
103 | return 0; | ||
104 | #else | ||
105 | ohci_err (ohci, "unsupported big endian Toshiba quirk\n"); | ||
106 | return -ENXIO; | ||
107 | #endif | ||
108 | } | ||
88 | 109 | ||
89 | /* List of quirks for OHCI */ | 110 | /* List of quirks for OHCI */ |
90 | static const struct pci_device_id ohci_pci_quirks[] = { | 111 | static const struct pci_device_id ohci_pci_quirks[] = { |
@@ -104,9 +125,14 @@ static const struct pci_device_id ohci_pci_quirks[] = { | |||
104 | PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), | 125 | PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), |
105 | .driver_data = (unsigned long)ohci_quirk_zfmicro, | 126 | .driver_data = (unsigned long)ohci_quirk_zfmicro, |
106 | }, | 127 | }, |
128 | { | ||
129 | PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), | ||
130 | .driver_data = (unsigned long)ohci_quirk_toshiba_scc, | ||
131 | }, | ||
107 | /* FIXME for some of the early AMD 760 southbridges, OHCI | 132 | /* FIXME for some of the early AMD 760 southbridges, OHCI |
108 | * won't work at all. blacklist them. | 133 | * won't work at all. blacklist them. |
109 | */ | 134 | */ |
135 | |||
110 | {}, | 136 | {}, |
111 | }; | 137 | }; |
112 | 138 | ||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index e1a7eb817313..c7ce8e638a25 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -72,7 +72,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | ohci = hcd_to_ohci(hcd); | 74 | ohci = hcd_to_ohci(hcd); |
75 | ohci->flags |= OHCI_BIG_ENDIAN; | 75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
76 | ohci_hcd_init(ohci); | 76 | ohci_hcd_init(ohci); |
77 | 77 | ||
78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 405257f3e853..fc7c1614cf9e 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -394,8 +394,9 @@ struct ohci_hcd { | |||
394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ | 394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ |
395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ | 395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ |
396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ | 396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ |
397 | #define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ | 397 | #define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ |
398 | #define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ | 398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ |
399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ | ||
399 | // there are also chip quirks/bugs in init logic | 400 | // there are also chip quirks/bugs in init logic |
400 | 401 | ||
401 | }; | 402 | }; |
@@ -439,117 +440,156 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) | |||
439 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 | 440 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 |
440 | * processors) implement them in big endian format. | 441 | * processors) implement them in big endian format. |
441 | * | 442 | * |
443 | * In addition some more exotic implementations like the Toshiba | ||
444 | * Spider (aka SCC) cell southbridge are "mixed" endian, that is, | ||
445 | * they have a different endianness for registers vs. in-memory | ||
446 | * descriptors. | ||
447 | * | ||
442 | * This attempts to support either format at compile time without a | 448 | * This attempts to support either format at compile time without a |
443 | * runtime penalty, or both formats with the additional overhead | 449 | * runtime penalty, or both formats with the additional overhead |
444 | * of checking a flag bit. | 450 | * of checking a flag bit. |
451 | * | ||
452 | * That leads to some tricky Kconfig rules howevber. There are | ||
453 | * different defaults based on some arch/ppc platforms, though | ||
454 | * the basic rules are: | ||
455 | * | ||
456 | * Controller type Kconfig options needed | ||
457 | * --------------- ---------------------- | ||
458 | * little endian CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
459 | * | ||
460 | * fully big endian CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_ | ||
461 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
462 | * | ||
463 | * mixed endian CONFIG_USB_OHCI_LITTLE_ENDIAN _and_ | ||
464 | * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} | ||
465 | * | ||
466 | * (If you have a mixed endian controller, you -must- also define | ||
467 | * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building | ||
468 | * both your mixed endian and a fully big endian controller support in | ||
469 | * the same kernel image). | ||
445 | */ | 470 | */ |
446 | 471 | ||
447 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN | 472 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC |
473 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
474 | #define big_endian_desc(ohci) (ohci->flags & OHCI_QUIRK_BE_DESC) | ||
475 | #else | ||
476 | #define big_endian_desc(ohci) 1 /* only big endian */ | ||
477 | #endif | ||
478 | #else | ||
479 | #define big_endian_desc(ohci) 0 /* only little endian */ | ||
480 | #endif | ||
448 | 481 | ||
482 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
449 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | 483 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN |
450 | #define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */ | 484 | #define big_endian_mmio(ohci) (ohci->flags & OHCI_QUIRK_BE_MMIO) |
485 | #else | ||
486 | #define big_endian_mmio(ohci) 1 /* only big endian */ | ||
487 | #endif | ||
451 | #else | 488 | #else |
452 | #define big_endian(ohci) 1 /* only big endian */ | 489 | #define big_endian_mmio(ohci) 0 /* only little endian */ |
453 | #endif | 490 | #endif |
454 | 491 | ||
455 | /* | 492 | /* |
456 | * Big-endian read/write functions are arch-specific. | 493 | * Big-endian read/write functions are arch-specific. |
457 | * Other arches can be added if/when they're needed. | 494 | * Other arches can be added if/when they're needed. |
495 | * | ||
496 | * REVISIT: arch/powerpc now has readl/writel_be, so the | ||
497 | * definition below can die once the STB04xxx support is | ||
498 | * finally ported over. | ||
458 | */ | 499 | */ |
459 | #if defined(CONFIG_PPC) | 500 | #if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) |
460 | #define readl_be(addr) in_be32((__force unsigned *)addr) | 501 | #define readl_be(addr) in_be32((__force unsigned *)addr) |
461 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) | 502 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) |
462 | #endif | 503 | #endif |
463 | 504 | ||
464 | static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, | 505 | static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, |
465 | __hc32 __iomem * regs) | 506 | __hc32 __iomem * regs) |
466 | { | 507 | { |
467 | return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs); | 508 | return big_endian_mmio(ohci) ? |
509 | readl_be ((__force u32 *)regs) : | ||
510 | readl ((__force u32 *)regs); | ||
468 | } | 511 | } |
469 | 512 | ||
470 | static inline void ohci_writel (const struct ohci_hcd *ohci, | 513 | static inline void _ohci_writel (const struct ohci_hcd *ohci, |
471 | const unsigned int val, __hc32 __iomem *regs) | 514 | const unsigned int val, __hc32 __iomem *regs) |
472 | { | 515 | { |
473 | big_endian(ohci) ? writel_be (val, regs) : | 516 | big_endian_mmio(ohci) ? |
474 | writel (val, (__force u32 *)regs); | 517 | writel_be (val, (__force u32 *)regs) : |
518 | writel (val, (__force u32 *)regs); | ||
475 | } | 519 | } |
476 | 520 | ||
477 | #else /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
478 | |||
479 | #define big_endian(ohci) 0 /* only little endian */ | ||
480 | |||
481 | #ifdef CONFIG_ARCH_LH7A404 | 521 | #ifdef CONFIG_ARCH_LH7A404 |
482 | /* Marc Singer: at the time this code was written, the LH7A404 | 522 | /* Marc Singer: at the time this code was written, the LH7A404 |
483 | * had a problem reading the USB host registers. This | 523 | * had a problem reading the USB host registers. This |
484 | * implementation of the ohci_readl function performs the read | 524 | * implementation of the ohci_readl function performs the read |
485 | * twice as a work-around. | 525 | * twice as a work-around. |
486 | */ | 526 | */ |
487 | static inline unsigned int | 527 | #define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) |
488 | ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs) | 528 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
489 | { | ||
490 | *(volatile __force unsigned int*) regs; | ||
491 | return *(volatile __force unsigned int*) regs; | ||
492 | } | ||
493 | #else | 529 | #else |
494 | /* Standard version of ohci_readl uses standard, platform | 530 | #define ohci_readl(o,r) _ohci_readl(o,r) |
495 | * specific implementation. */ | 531 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
496 | static inline unsigned int | ||
497 | ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) | ||
498 | { | ||
499 | return readl(regs); | ||
500 | } | ||
501 | #endif | 532 | #endif |
502 | 533 | ||
503 | static inline void ohci_writel (const struct ohci_hcd *ohci, | ||
504 | const unsigned int val, __hc32 __iomem *regs) | ||
505 | { | ||
506 | writel (val, regs); | ||
507 | } | ||
508 | |||
509 | #endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
510 | 534 | ||
511 | /*-------------------------------------------------------------------------*/ | 535 | /*-------------------------------------------------------------------------*/ |
512 | 536 | ||
513 | /* cpu to ohci */ | 537 | /* cpu to ohci */ |
514 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) | 538 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) |
515 | { | 539 | { |
516 | return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x); | 540 | return big_endian_desc(ohci) ? |
541 | (__force __hc16)cpu_to_be16(x) : | ||
542 | (__force __hc16)cpu_to_le16(x); | ||
517 | } | 543 | } |
518 | 544 | ||
519 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) | 545 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) |
520 | { | 546 | { |
521 | return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x); | 547 | return big_endian_desc(ohci) ? |
548 | cpu_to_be16p(x) : | ||
549 | cpu_to_le16p(x); | ||
522 | } | 550 | } |
523 | 551 | ||
524 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) | 552 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) |
525 | { | 553 | { |
526 | return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); | 554 | return big_endian_desc(ohci) ? |
555 | (__force __hc32)cpu_to_be32(x) : | ||
556 | (__force __hc32)cpu_to_le32(x); | ||
527 | } | 557 | } |
528 | 558 | ||
529 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) | 559 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) |
530 | { | 560 | { |
531 | return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x); | 561 | return big_endian_desc(ohci) ? |
562 | cpu_to_be32p(x) : | ||
563 | cpu_to_le32p(x); | ||
532 | } | 564 | } |
533 | 565 | ||
534 | /* ohci to cpu */ | 566 | /* ohci to cpu */ |
535 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) | 567 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) |
536 | { | 568 | { |
537 | return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x); | 569 | return big_endian_desc(ohci) ? |
570 | be16_to_cpu((__force __be16)x) : | ||
571 | le16_to_cpu((__force __le16)x); | ||
538 | } | 572 | } |
539 | 573 | ||
540 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) | 574 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) |
541 | { | 575 | { |
542 | return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x); | 576 | return big_endian_desc(ohci) ? |
577 | be16_to_cpup((__force __be16 *)x) : | ||
578 | le16_to_cpup((__force __le16 *)x); | ||
543 | } | 579 | } |
544 | 580 | ||
545 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) | 581 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) |
546 | { | 582 | { |
547 | return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); | 583 | return big_endian_desc(ohci) ? |
584 | be32_to_cpu((__force __be32)x) : | ||
585 | le32_to_cpu((__force __le32)x); | ||
548 | } | 586 | } |
549 | 587 | ||
550 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | 588 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) |
551 | { | 589 | { |
552 | return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); | 590 | return big_endian_desc(ohci) ? |
591 | be32_to_cpup((__force __be32 *)x) : | ||
592 | le32_to_cpup((__force __le32 *)x); | ||
553 | } | 593 | } |
554 | 594 | ||
555 | /*-------------------------------------------------------------------------*/ | 595 | /*-------------------------------------------------------------------------*/ |
@@ -557,6 +597,9 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
557 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all | 597 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all |
558 | * hardware handles 16 bit reads. That creates a different confusion on | 598 | * hardware handles 16 bit reads. That creates a different confusion on |
559 | * some big-endian SOC implementations. Same thing happens with PSW access. | 599 | * some big-endian SOC implementations. Same thing happens with PSW access. |
600 | * | ||
601 | * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over | ||
602 | * to arch/powerpc | ||
560 | */ | 603 | */ |
561 | 604 | ||
562 | #ifdef CONFIG_STB03xxx | 605 | #ifdef CONFIG_STB03xxx |
@@ -568,7 +611,7 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
568 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | 611 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) |
569 | { | 612 | { |
570 | u32 tmp; | 613 | u32 tmp; |
571 | if (big_endian(ohci)) { | 614 | if (big_endian_desc(ohci)) { |
572 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); | 615 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); |
573 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; | 616 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; |
574 | } else | 617 | } else |
@@ -580,7 +623,7 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | |||
580 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, | 623 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, |
581 | const struct td *td, int index) | 624 | const struct td *td, int index) |
582 | { | 625 | { |
583 | return (__hc16 *)(big_endian(ohci) ? | 626 | return (__hc16 *)(big_endian_desc(ohci) ? |
584 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); | 627 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); |
585 | } | 628 | } |
586 | 629 | ||