diff options
author | Jan Andersson <jan@gaisler.com> | 2011-05-18 04:44:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-19 19:43:19 -0400 |
commit | 8452c6745e74384e7e434144f989ada3eae41170 (patch) | |
tree | 4ead646def1a541b4ca7062b5dab2b4a3e737a2d | |
parent | 5116901d8596a52598364d41581c0a745da003bc (diff) |
USB: UHCI: Add support for big endian mmio
This patch adds support for big endian mmio to the UHCI HCD. Big endian
mmio is supported by adding a flag bit to the UHCI HCD replicating the
solution used in the EHCI HCD.
When adding big endian support this patch also adds a check to see if we
need to support HCs with PCI I/O registers when we support HCs with MMIO.
This patch also adds 'const' to the register access functions' uhci_hcd
argument.
Signed-off-by: Jan Andersson <jan@gaisler.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/host/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 67 |
2 files changed, 56 insertions, 15 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 8898505af429..ce9e22bf211c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -416,6 +416,10 @@ config USB_UHCI_SUPPORT_NON_PCI_HC | |||
416 | depends on USB_UHCI_HCD | 416 | depends on USB_UHCI_HCD |
417 | default y if SPARC_LEON | 417 | default y if SPARC_LEON |
418 | 418 | ||
419 | config USB_UHCI_BIG_ENDIAN_MMIO | ||
420 | bool | ||
421 | depends on USB_UHCI_SUPPORT_NON_PCI_HC | ||
422 | |||
419 | config USB_FHCI_HCD | 423 | config USB_FHCI_HCD |
420 | tristate "Freescale QE USB Host Controller support" | 424 | tristate "Freescale QE USB Host Controller support" |
421 | depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE | 425 | depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index a4e64d08f020..10b68a846f65 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -421,6 +421,7 @@ struct uhci_hcd { | |||
421 | /* Silicon quirks */ | 421 | /* Silicon quirks */ |
422 | unsigned int oc_low:1; /* OverCurrent bit active low */ | 422 | unsigned int oc_low:1; /* OverCurrent bit active low */ |
423 | unsigned int wait_for_hp:1; /* Wait for HP port reset */ | 423 | unsigned int wait_for_hp:1; /* Wait for HP port reset */ |
424 | unsigned int big_endian_mmio:1; /* Big endian registers */ | ||
424 | 425 | ||
425 | /* Support for port suspend/resume/reset */ | 426 | /* Support for port suspend/resume/reset */ |
426 | unsigned long port_c_suspend; /* Bit-arrays of ports */ | 427 | unsigned long port_c_suspend; /* Bit-arrays of ports */ |
@@ -490,90 +491,126 @@ struct urb_priv { | |||
490 | * we use memory mapped registers. | 491 | * we use memory mapped registers. |
491 | */ | 492 | */ |
492 | 493 | ||
493 | #if !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) | 494 | #ifndef CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC |
494 | /* Support PCI only */ | 495 | /* Support PCI only */ |
495 | static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) | 496 | static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) |
496 | { | 497 | { |
497 | return inl(uhci->io_addr + reg); | 498 | return inl(uhci->io_addr + reg); |
498 | } | 499 | } |
499 | 500 | ||
500 | static inline void uhci_writel(struct uhci_hcd *uhci, u32 val, int reg) | 501 | static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) |
501 | { | 502 | { |
502 | outl(val, uhci->io_addr + reg); | 503 | outl(val, uhci->io_addr + reg); |
503 | } | 504 | } |
504 | 505 | ||
505 | static inline u16 uhci_readw(struct uhci_hcd *uhci, int reg) | 506 | static inline u16 uhci_readw(const struct uhci_hcd *uhci, int reg) |
506 | { | 507 | { |
507 | return inw(uhci->io_addr + reg); | 508 | return inw(uhci->io_addr + reg); |
508 | } | 509 | } |
509 | 510 | ||
510 | static inline void uhci_writew(struct uhci_hcd *uhci, u16 val, int reg) | 511 | static inline void uhci_writew(const struct uhci_hcd *uhci, u16 val, int reg) |
511 | { | 512 | { |
512 | outw(val, uhci->io_addr + reg); | 513 | outw(val, uhci->io_addr + reg); |
513 | } | 514 | } |
514 | 515 | ||
515 | static inline u8 uhci_readb(struct uhci_hcd *uhci, int reg) | 516 | static inline u8 uhci_readb(const struct uhci_hcd *uhci, int reg) |
516 | { | 517 | { |
517 | return inb(uhci->io_addr + reg); | 518 | return inb(uhci->io_addr + reg); |
518 | } | 519 | } |
519 | 520 | ||
520 | static inline void uhci_writeb(struct uhci_hcd *uhci, u8 val, int reg) | 521 | static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) |
521 | { | 522 | { |
522 | outb(val, uhci->io_addr + reg); | 523 | outb(val, uhci->io_addr + reg); |
523 | } | 524 | } |
524 | 525 | ||
525 | #else | 526 | #else |
527 | /* Support non-PCI host controllers */ | ||
528 | #ifdef CONFIG_PCI | ||
526 | /* Support PCI and non-PCI host controllers */ | 529 | /* Support PCI and non-PCI host controllers */ |
527 | |||
528 | #define uhci_has_pci_registers(u) ((u)->io_addr != 0) | 530 | #define uhci_has_pci_registers(u) ((u)->io_addr != 0) |
531 | #else | ||
532 | /* Support non-PCI host controllers only */ | ||
533 | #define uhci_has_pci_registers(u) 0 | ||
534 | #endif | ||
535 | |||
536 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
537 | /* Support (non-PCI) big endian host controllers */ | ||
538 | #define uhci_big_endian_mmio(u) ((u)->big_endian_mmio) | ||
539 | #else | ||
540 | #define uhci_big_endian_mmio(u) 0 | ||
541 | #endif | ||
529 | 542 | ||
530 | static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) | 543 | static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) |
531 | { | 544 | { |
532 | if (uhci_has_pci_registers(uhci)) | 545 | if (uhci_has_pci_registers(uhci)) |
533 | return inl(uhci->io_addr + reg); | 546 | return inl(uhci->io_addr + reg); |
547 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
548 | else if (uhci_big_endian_mmio(uhci)) | ||
549 | return readl_be(uhci->regs + reg); | ||
550 | #endif | ||
534 | else | 551 | else |
535 | return readl(uhci->regs + reg); | 552 | return readl(uhci->regs + reg); |
536 | } | 553 | } |
537 | 554 | ||
538 | static inline void uhci_writel(struct uhci_hcd *uhci, u32 val, int reg) | 555 | static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) |
539 | { | 556 | { |
540 | if (uhci_has_pci_registers(uhci)) | 557 | if (uhci_has_pci_registers(uhci)) |
541 | outl(val, uhci->io_addr + reg); | 558 | outl(val, uhci->io_addr + reg); |
559 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
560 | else if (uhci_big_endian_mmio(uhci)) | ||
561 | writel_be(val, uhci->regs + reg); | ||
562 | #endif | ||
542 | else | 563 | else |
543 | writel(val, uhci->regs + reg); | 564 | writel(val, uhci->regs + reg); |
544 | } | 565 | } |
545 | 566 | ||
546 | static inline u16 uhci_readw(struct uhci_hcd *uhci, int reg) | 567 | static inline u16 uhci_readw(const struct uhci_hcd *uhci, int reg) |
547 | { | 568 | { |
548 | if (uhci_has_pci_registers(uhci)) | 569 | if (uhci_has_pci_registers(uhci)) |
549 | return inw(uhci->io_addr + reg); | 570 | return inw(uhci->io_addr + reg); |
571 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
572 | else if (uhci_big_endian_mmio(uhci)) | ||
573 | return readw_be(uhci->regs + reg); | ||
574 | #endif | ||
550 | else | 575 | else |
551 | return readw(uhci->regs + reg); | 576 | return readw(uhci->regs + reg); |
552 | } | 577 | } |
553 | 578 | ||
554 | static inline void uhci_writew(struct uhci_hcd *uhci, u16 val, int reg) | 579 | static inline void uhci_writew(const struct uhci_hcd *uhci, u16 val, int reg) |
555 | { | 580 | { |
556 | if (uhci_has_pci_registers(uhci)) | 581 | if (uhci_has_pci_registers(uhci)) |
557 | outw(val, uhci->io_addr + reg); | 582 | outw(val, uhci->io_addr + reg); |
583 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
584 | else if (uhci_big_endian_mmio(uhci)) | ||
585 | writew_be(val, uhci->regs + reg); | ||
586 | #endif | ||
558 | else | 587 | else |
559 | writew(val, uhci->regs + reg); | 588 | writew(val, uhci->regs + reg); |
560 | } | 589 | } |
561 | 590 | ||
562 | static inline u8 uhci_readb(struct uhci_hcd *uhci, int reg) | 591 | static inline u8 uhci_readb(const struct uhci_hcd *uhci, int reg) |
563 | { | 592 | { |
564 | if (uhci_has_pci_registers(uhci)) | 593 | if (uhci_has_pci_registers(uhci)) |
565 | return inb(uhci->io_addr + reg); | 594 | return inb(uhci->io_addr + reg); |
595 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
596 | else if (uhci_big_endian_mmio(uhci)) | ||
597 | return readb_be(uhci->regs + reg); | ||
598 | #endif | ||
566 | else | 599 | else |
567 | return readb(uhci->regs + reg); | 600 | return readb(uhci->regs + reg); |
568 | } | 601 | } |
569 | 602 | ||
570 | static inline void uhci_writeb(struct uhci_hcd *uhci, u8 val, int reg) | 603 | static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) |
571 | { | 604 | { |
572 | if (uhci_has_pci_registers(uhci)) | 605 | if (uhci_has_pci_registers(uhci)) |
573 | outb(val, uhci->io_addr + reg); | 606 | outb(val, uhci->io_addr + reg); |
607 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_MMIO | ||
608 | else if (uhci_big_endian_mmio(uhci)) | ||
609 | writeb_be(val, uhci->regs + reg); | ||
610 | #endif | ||
574 | else | 611 | else |
575 | writeb(val, uhci->regs + reg); | 612 | writeb(val, uhci->regs + reg); |
576 | } | 613 | } |
577 | #endif /* !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) */ | 614 | #endif /* CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC */ |
578 | 615 | ||
579 | #endif | 616 | #endif |