diff options
author | Jan Andersson <jan@gaisler.com> | 2011-05-06 12:00:16 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-06 18:24:01 -0700 |
commit | 9faa091a409851ac6b3812164d53644074bc89b1 (patch) | |
tree | c7d95c20e9b476261a1ccd7a5f02286be5b7502d /drivers | |
parent | c31a65f869f7b8a7039007411c76d7b6f9a63323 (diff) | |
download | linux-9faa091a409851ac6b3812164d53644074bc89b1.tar.bz2 |
USB: UHCI: Wrap I/O register accesses
This patch is part of a series that extend the UHCI HCD to support
non-PCI controllers.
This patch replaces in{b,w,l} and out{b,wl} with calls to local inline
functions. This is done so that the register access functions can be
extended to support register areas not mapped in PCI I/O space.
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/uhci-debug.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 42 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 30 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hub.c | 35 |
4 files changed, 77 insertions, 47 deletions
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index ee60cd3ea642..f882a84b1bbb 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -285,7 +285,6 @@ static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len) static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) { char *out = buf; - unsigned long io_addr = uhci->io_addr; unsigned short usbcmd, usbstat, usbint, usbfrnum; unsigned int flbaseadd; unsigned char sof; @@ -295,14 +294,14 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len) if (len < 80 * 9) return 0; - usbcmd = inw(io_addr + 0); - usbstat = inw(io_addr + 2); - usbint = inw(io_addr + 4); - usbfrnum = inw(io_addr + 6); - flbaseadd = inl(io_addr + 8); - sof = inb(io_addr + 12); - portsc1 = inw(io_addr + 16); - portsc2 = inw(io_addr + 18); + usbcmd = uhci_readw(uhci, 0); + usbstat = uhci_readw(uhci, 2); + usbint = uhci_readw(uhci, 4); + usbfrnum = uhci_readw(uhci, 6); + flbaseadd = uhci_readl(uhci, 8); + sof = uhci_readb(uhci, 12); + portsc1 = uhci_readw(uhci, 16); + portsc2 = uhci_readw(uhci, 18); out += sprintf(out, " usbcmd = %04x %s%s%s%s%s%s%s%s\n", usbcmd, diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 3d2a10563be8..5176c537b95a 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -133,7 +133,7 @@ static void finish_reset(struct uhci_hcd *uhci) * We have to clear them by hand. */ for (port = 0; port < uhci->rh_numports; ++port) - outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); + uhci_writew(uhci, 0, USBPORTSC1 + (port * 2)); uhci->port_c_suspend = uhci->resuming_ports = 0; uhci->rh_state = UHCI_RH_RESET; @@ -173,14 +173,14 @@ static void check_and_reset_hc(struct uhci_hcd *uhci) static void configure_hc(struct uhci_hcd *uhci) { /* Set the frame length to the default: 1 ms exactly */ - outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); + uhci_writeb(uhci, USBSOF_DEFAULT, USBSOF); /* Store the frame list base address */ - outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); + uhci_writel(uhci, uhci->frame_dma_handle, USBFLBASEADD); /* Set the current frame number */ - outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER, - uhci->io_addr + USBFRNUM); + uhci_writew(uhci, uhci->frame_number & UHCI_MAX_SOF_NUMBER, + USBFRNUM); /* perform any arch/bus specific configuration */ if (uhci->configure_hc) @@ -264,8 +264,8 @@ __acquires(uhci->lock) !int_enable) uhci->RD_enable = int_enable = 0; - outw(int_enable, uhci->io_addr + USBINTR); - outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); + uhci_writew(uhci, int_enable, USBINTR); + uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD); mb(); udelay(5); @@ -274,7 +274,7 @@ __acquires(uhci->lock) * controller should stop after a few microseconds. Otherwise * we will give the controller one frame to stop. */ - if (!auto_stop && !(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) { + if (!auto_stop && !(uhci_readw(uhci, USBSTS) & USBSTS_HCH)) { uhci->rh_state = UHCI_RH_SUSPENDING; spin_unlock_irq(&uhci->lock); msleep(1); @@ -282,7 +282,7 @@ __acquires(uhci->lock) if (uhci->dead) return; } - if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) + if (!(uhci_readw(uhci, USBSTS) & USBSTS_HCH)) dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n"); uhci_get_current_frame_number(uhci); @@ -309,9 +309,9 @@ static void start_rh(struct uhci_hcd *uhci) /* Mark it configured and running with a 64-byte max packet. * All interrupts are enabled, even though RESUME won't do anything. */ - outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD); - outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, - uhci->io_addr + USBINTR); + uhci_writew(uhci, USBCMD_RS | USBCMD_CF | USBCMD_MAXP, USBCMD); + uhci_writew(uhci, USBINTR_TIMEOUT | USBINTR_RESUME | + USBINTR_IOC | USBINTR_SP, USBINTR); mb(); uhci->rh_state = UHCI_RH_RUNNING; set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); @@ -334,9 +334,9 @@ __acquires(uhci->lock) unsigned egsm; /* Keep EGSM on if it was set before */ - egsm = inw(uhci->io_addr + USBCMD) & USBCMD_EGSM; + egsm = uhci_readw(uhci, USBCMD) & USBCMD_EGSM; uhci->rh_state = UHCI_RH_RESUMING; - outw(USBCMD_FGR | USBCMD_CF | egsm, uhci->io_addr + USBCMD); + uhci_writew(uhci, USBCMD_FGR | USBCMD_CF | egsm, USBCMD); spin_unlock_irq(&uhci->lock); msleep(20); spin_lock_irq(&uhci->lock); @@ -344,10 +344,10 @@ __acquires(uhci->lock) return; /* End Global Resume and wait for EOP to be sent */ - outw(USBCMD_CF, uhci->io_addr + USBCMD); + uhci_writew(uhci, USBCMD_CF, USBCMD); mb(); udelay(4); - if (inw(uhci->io_addr + USBCMD) & USBCMD_FGR) + if (uhci_readw(uhci, USBCMD) & USBCMD_FGR) dev_warn(uhci_dev(uhci), "FGR not stopped yet!\n"); } @@ -367,10 +367,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd) * interrupt cause. Contrary to the UHCI specification, the * "HC Halted" status bit is persistent: it is RO, not R/WC. */ - status = inw(uhci->io_addr + USBSTS); + status = uhci_readw(uhci, USBSTS); if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ return IRQ_NONE; - outw(status, uhci->io_addr + USBSTS); /* Clear it */ + uhci_writew(uhci, status, USBSTS); /* Clear it */ if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { if (status & USBSTS_HSE) @@ -426,7 +426,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci) if (!uhci->is_stopped) { unsigned delta; - delta = (inw(uhci->io_addr + USBFRNUM) - uhci->frame_number) & + delta = (uhci_readw(uhci, USBFRNUM) - uhci->frame_number) & (UHCI_NUMFRAMES - 1); uhci->frame_number += delta; } @@ -716,7 +716,7 @@ static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) /* Minimize latency by avoiding the spinlock */ frame_number = uhci->frame_number; barrier(); - delta = (inw(uhci->io_addr + USBFRNUM) - frame_number) & + delta = (uhci_readw(uhci, USBFRNUM) - frame_number) & (UHCI_NUMFRAMES - 1); return frame_number + delta; } @@ -739,7 +739,7 @@ static int uhci_count_ports(struct usb_hcd *hcd) for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { unsigned int portstatus; - portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2)); + portstatus = uhci_readw(uhci, USBPORTSC1 + (port * 2)); if (!(portstatus & 0x0080) || portstatus == 0xffff) break; } diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 569437954578..a6de241bf966 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -481,4 +481,34 @@ struct urb_priv { #define PCI_VENDOR_ID_GENESYS 0x17a0 #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 +static inline u32 uhci_readl(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) +{ + outl(val, uhci->io_addr + reg); +} + +static inline u16 uhci_readw(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) +{ + outw(val, uhci->io_addr + reg); +} + +static inline u8 uhci_readb(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) +{ + outb(val, uhci->io_addr + reg); +} + #endif diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 75418265488d..045cde4cbc3d 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -44,7 +44,7 @@ static int any_ports_active(struct uhci_hcd *uhci) int port; for (port = 0; port < uhci->rh_numports; ++port) { - if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & + if ((uhci_readw(uhci, USBPORTSC1 + port * 2) & (USBPORTSC_CCS | RWC_BITS)) || test_bit(port, &uhci->port_c_suspend)) return 1; @@ -68,7 +68,7 @@ static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) *buf = 0; for (port = 0; port < uhci->rh_numports; ++port) { - if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) || + if ((uhci_readw(uhci, USBPORTSC1 + port * 2) & mask) || test_bit(port, &uhci->port_c_suspend)) *buf |= (1 << (port + 1)); } @@ -78,17 +78,17 @@ static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) #define OK(x) len = (x); break #define CLR_RH_PORTSTAT(x) \ - status = inw(port_addr); \ + status = uhci_readw(uhci, port_addr); \ status &= ~(RWC_BITS|WZ_BITS); \ status &= ~(x); \ status |= RWC_BITS & (x); \ - outw(status, port_addr) + uhci_writew(uhci, status, port_addr) #define SET_RH_PORTSTAT(x) \ - status = inw(port_addr); \ + status = uhci_readw(uhci, port_addr); \ status |= (x); \ status &= ~(RWC_BITS|WZ_BITS); \ - outw(status, port_addr) + uhci_writew(uhci, status, port_addr) /* UHCI controllers don't automatically stop resume signalling after 20 msec, * so we have to poll and check timeouts in order to take care of it. @@ -99,7 +99,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, int status; int i; - if (inw(port_addr) & SUSPEND_BITS) { + if (uhci_readw(uhci, port_addr) & SUSPEND_BITS) { CLR_RH_PORTSTAT(SUSPEND_BITS); if (test_bit(port, &uhci->resuming_ports)) set_bit(port, &uhci->port_c_suspend); @@ -110,7 +110,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, * Experiments show that some controllers take longer, so * we'll poll for completion. */ for (i = 0; i < 10; ++i) { - if (!(inw(port_addr) & SUSPEND_BITS)) + if (!(uhci_readw(uhci, port_addr) & SUSPEND_BITS)) break; udelay(1); } @@ -121,12 +121,12 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, /* Wait for the UHCI controller in HP's iLO2 server management chip. * It can take up to 250 us to finish a reset and set the CSC bit. */ -static void wait_for_HP(unsigned long port_addr) +static void wait_for_HP(struct uhci_hcd *uhci, unsigned long port_addr) { int i; for (i = 10; i < 250; i += 10) { - if (inw(port_addr) & USBPORTSC_CSC) + if (uhci_readw(uhci, port_addr) & USBPORTSC_CSC) return; udelay(10); } @@ -140,8 +140,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci) int status; for (port = 0; port < uhci->rh_numports; ++port) { - port_addr = uhci->io_addr + USBPORTSC1 + 2 * port; - status = inw(port_addr); + port_addr = USBPORTSC1 + 2 * port; + status = uhci_readw(uhci, port_addr); if (unlikely(status & USBPORTSC_PR)) { if (time_after_eq(jiffies, uhci->ports_timeout)) { CLR_RH_PORTSTAT(USBPORTSC_PR); @@ -150,7 +150,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci) /* HP's server management chip requires * a longer delay. */ if (uhci->wait_for_hp) - wait_for_HP(port_addr); + wait_for_HP(uhci, port_addr); /* If the port was enabled before, turning * reset on caused a port enable change. @@ -241,7 +241,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, struct uhci_hcd *uhci = hcd_to_uhci(hcd); int status, lstatus, retval = 0, len = 0; unsigned int port = wIndex - 1; - unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * port; + unsigned long port_addr = USBPORTSC1 + 2 * port; u16 wPortChange, wPortStatus; unsigned long flags; @@ -259,7 +259,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto err; uhci_check_ports(uhci); - status = inw(port_addr); + status = uhci_readw(uhci, port_addr); /* Intel controllers report the OverCurrent bit active on. * VIA controllers report it active off, so we'll adjust the @@ -356,7 +356,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, CLR_RH_PORTSTAT(USBPORTSC_PEC); OK(0); case USB_PORT_FEAT_SUSPEND: - if (!(inw(port_addr) & USBPORTSC_SUSP)) { + if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) { /* Make certain the port isn't suspended */ uhci_finish_suspend(uhci, port, port_addr); @@ -368,7 +368,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, * if the port is disabled. When this happens * just skip the Resume signalling. */ - if (!(inw(port_addr) & USBPORTSC_RD)) + if (!(uhci_readw(uhci, port_addr) & + USBPORTSC_RD)) uhci_finish_suspend(uhci, port, port_addr); else |