This patch changes the uhci_{read,write}* functions into using function pointers from the uhci_hcd struct when accessing registers. This is done in order to reduce the amount of code that need to be ifdef:ed around uhci_{read,write}* when later adding (dynamic) support for big endian mmio. This change leads to a bit more work for the processor when running with a PCI-only UHCI kernel. Considering how relatively slow PCI accesses are it should not matter much, and it saves us the trouble of having a special case for PCI-only configurations in uhci-hcd.h. Also added 'const' to uhci_hcd argument. Signed-off-by: Jan Andersson <jan@xxxxxxxxxxx> --- My guess is that the change in this patch may not be to everyones (anyones?) liking. Another solution would be to use someting more similar to the previous version, like: #if !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) { return inl(uhci->io_addr + reg); } #else #define uhci_has_pci_registers(u) ((u)->io_addr != 0) static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) { if (uhci_has_pci_registers(uhci)) return inl(uhci->io_addr + reg); else return uhci->ureadl(uhci->regs, reg); } #endif ... or more similar to the solution in used for the EHCI HCD (leads to the largest amount of special case ifdefs, at least in my attempts, but no extra function call): #if !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) { return inl(uhci->io_addr + reg); } #else #define uhci_has_pci_registers(u) ((u)->io_addr != 0) static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) { if (uhci_has_pci_registers(uhci)) return inl(uhci->io_addr + reg); #if defined(CONFIG_USB_UHCI_BIG_ENDIAN_MMIO) elsif uhci_big_endian_mmio(uhci) return readl_be(uhci->regs, reg); #endif else return readl(uhci->regs, reg); } #endif The last example shows how the code would later look like with support for BE. BE support is not added by this patch. --- drivers/usb/host/uhci-grlib.c | 8 +++ drivers/usb/host/uhci-hcd.h | 103 ++++++++++++++++++++++++----------------- drivers/usb/host/uhci-pci.c | 8 +++ 3 files changed, 76 insertions(+), 43 deletions(-) diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index b1addd6..004c65a 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -25,6 +25,14 @@ static int uhci_grlib_init(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); + /* Assign function pointers that will be used for register accesses */ + uhci->ureadl = uhci_mmio_readl; + uhci->uwritel = uhci_mmio_writel; + uhci->ureadw = uhci_mmio_readw; + uhci->uwritew = uhci_mmio_writew; + uhci->ureadb = uhci_mmio_readb; + uhci->uwriteb = uhci_mmio_writeb; + uhci->rh_numports = uhci_count_ports(hcd); /* Set up pointers to to generic functions */ diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index a4e64d0..c73edd6 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -446,6 +446,14 @@ struct uhci_hcd { int (*resume_detect_interrupts_are_broken) (struct uhci_hcd *uhci); /* Check for broken global suspend */ int (*global_suspend_mode_is_broken) (struct uhci_hcd *uhci); + + /* Functions used for accessing host controller registers */ + u32 (*ureadl) (const struct uhci_hcd *uhci, int reg); + void (*uwritel) (const struct uhci_hcd *uhci, u32 val, int reg); + u16 (*ureadw) (const struct uhci_hcd *uhci, int reg); + void (*uwritew) (const struct uhci_hcd *uhci, u16 val, int reg); + u8 (*ureadb) (const struct uhci_hcd *uhci, int reg); + void (*uwriteb) (const struct uhci_hcd *uhci, u8 val, int reg); }; /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ @@ -489,90 +497,99 @@ struct urb_priv { * controller I/O registers are mapped into PCI I/O space. For non-PCI hosts * we use memory mapped registers. */ +static inline u32 uhci_readl(const struct uhci_hcd *uhci, int reg) +{ + return uhci->ureadl(uhci, reg); +} + +static inline void uhci_writel(const struct uhci_hcd *uhci, u32 val, int reg) +{ + uhci->uwritel(uhci, val, reg); +} + +static inline u16 uhci_readw(const struct uhci_hcd *uhci, int reg) +{ + return uhci->ureadw(uhci, reg); +} + +static inline void uhci_writew(const struct uhci_hcd *uhci, u16 val, int reg) +{ + uhci->uwritew(uhci, val, reg); +} + +static inline u8 uhci_readb(const struct uhci_hcd *uhci, int reg) +{ + return uhci->ureadb(uhci, reg); +} -#if !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) -/* Support PCI only */ -static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) +static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) +{ + uhci->uwriteb(uhci, val, reg); +} + +#if defined(CONFIG_PCI) +/* Functions for accessing registers in PCI I/O space */ +static u32 uhci_pciio_readl(const struct uhci_hcd *uhci, int reg) { return inl(uhci->io_addr + reg); } -static inline void uhci_writel(struct uhci_hcd *uhci, u32 val, int reg) +static void uhci_pciio_writel(const struct uhci_hcd *uhci, u32 val, int reg) { outl(val, uhci->io_addr + reg); } -static inline u16 uhci_readw(struct uhci_hcd *uhci, int reg) +static u16 uhci_pciio_readw(const struct uhci_hcd *uhci, int reg) { return inw(uhci->io_addr + reg); } -static inline void uhci_writew(struct uhci_hcd *uhci, u16 val, int reg) +static void uhci_pciio_writew(const struct uhci_hcd *uhci, u16 val, int reg) { outw(val, uhci->io_addr + reg); } -static inline u8 uhci_readb(struct uhci_hcd *uhci, int reg) +static u8 uhci_pciio_readb(const struct uhci_hcd *uhci, int reg) { return inb(uhci->io_addr + reg); } -static inline void uhci_writeb(struct uhci_hcd *uhci, u8 val, int reg) +static void uhci_pciio_writeb(const struct uhci_hcd *uhci, u8 val, int reg) { outb(val, uhci->io_addr + reg); } +#endif /* defined(CONFIG_PCI) */ -#else -/* Support PCI and non-PCI host controllers */ - -#define uhci_has_pci_registers(u) ((u)->io_addr != 0) - -static inline u32 uhci_readl(struct uhci_hcd *uhci, int reg) +#if defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) +/* Functions for memory mapped I/O */ +static u32 uhci_mmio_readl(const struct uhci_hcd *uhci, int reg) { - if (uhci_has_pci_registers(uhci)) - return inl(uhci->io_addr + reg); - else - return readl(uhci->regs + reg); + return readl(uhci->regs + reg); } -static inline void uhci_writel(struct uhci_hcd *uhci, u32 val, int reg) +static void uhci_mmio_writel(const struct uhci_hcd *uhci, u32 val, int reg) { - if (uhci_has_pci_registers(uhci)) - outl(val, uhci->io_addr + reg); - else - writel(val, uhci->regs + reg); + writel(val, uhci->regs + reg); } -static inline u16 uhci_readw(struct uhci_hcd *uhci, int reg) +static u16 uhci_mmio_readw(const struct uhci_hcd *uhci, int reg) { - if (uhci_has_pci_registers(uhci)) - return inw(uhci->io_addr + reg); - else - return readw(uhci->regs + reg); + return readw(uhci->regs + reg); } -static inline void uhci_writew(struct uhci_hcd *uhci, u16 val, int reg) +static void uhci_mmio_writew(const struct uhci_hcd *uhci, u16 val, int reg) { - if (uhci_has_pci_registers(uhci)) - outw(val, uhci->io_addr + reg); - else - writew(val, uhci->regs + reg); + writew(val, uhci->regs + reg); } -static inline u8 uhci_readb(struct uhci_hcd *uhci, int reg) +static u8 uhci_mmio_readb(const struct uhci_hcd *uhci, int reg) { - if (uhci_has_pci_registers(uhci)) - return inb(uhci->io_addr + reg); - else - return readb(uhci->regs + reg); + return readb(uhci->regs + reg); } -static inline void uhci_writeb(struct uhci_hcd *uhci, u8 val, int reg) +static void uhci_mmio_writeb(const struct uhci_hcd *uhci, u8 val, int reg) { - if (uhci_has_pci_registers(uhci)) - outb(val, uhci->io_addr + reg); - else - writeb(val, uhci->regs + reg); + writeb(val, uhci->regs + reg); } #endif /* !defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) */ diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index c300bd2..0f61760 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -116,6 +116,14 @@ static int uhci_pci_init(struct usb_hcd *hcd) uhci->io_addr = (unsigned long) hcd->rsrc_start; + /* Assign function pointers that will be used for register accesses */ + uhci->ureadl = uhci_pciio_readl; + uhci->uwritel = uhci_pciio_writel; + uhci->ureadw = uhci_pciio_readw; + uhci->uwritew = uhci_pciio_writew; + uhci->ureadb = uhci_pciio_readb; + uhci->uwriteb = uhci_pciio_writeb; + uhci->rh_numports = uhci_count_ports(hcd); /* Intel controllers report the OverCurrent bit active on. -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html