aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-14 14:54:03 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:31 -0500
commit11d1a4aa8d657478cb2e5d33f203ba8f01b9ac24 (patch)
treeb433927494c87f5f4d4ee03b78a35b894705037d /drivers/usb
parent4302a595cd9c6363b495460497ecbda49fa16858 (diff)
USB: Implement support for "split" endian OHCI
This patch separates support for big endian MMIO register access and big endian descriptors in order to support the Toshiba SCC implementation which has big endian registers but little endian in-memory descriptors. It simplifies the access functions a bit in ohci.h while at it. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Acked-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/Kconfig10
-rw-r--r--drivers/usb/host/ohci-pci.c26
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c2
-rw-r--r--drivers/usb/host/ohci.h147
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
118config USB_OHCI_BIG_ENDIAN 119config USB_OHCI_BIG_ENDIAN_DESC
120 bool
121 depends on USB_OHCI_HCD
122 default n
123
124config 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 */
91static 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 */
90static const struct pci_device_id ohci_pci_quirks[] = { 111static 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
464static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, 505static 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
470static inline void ohci_writel (const struct ohci_hcd *ohci, 513static 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 */
487static inline unsigned int 527#define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r))
488ohci_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)
496static inline unsigned int
497ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs)
498{
499 return readl(regs);
500}
501#endif 532#endif
502 533
503static 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 */
514static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) 538static 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
519static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) 545static 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
524static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) 552static 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
529static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) 559static 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 */
535static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) 567static 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
540static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) 574static 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
545static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) 581static 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
550static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) 588static 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)
568static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) 611static 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)
580static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, 623static 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