Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[cascardo/linux.git] / drivers / staging / octeon-usb / octeon-hcd.c
index 1daeb31..9e5476e 100644 (file)
@@ -214,15 +214,14 @@ enum cvmx_usb_initialize_flags {
 /**
  * enum cvmx_usb_pipe_flags - internal flags for a pipe.
  *
- * @__CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
- *                                  actively using hardware. Do not use.
- * @__CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high
- *                                  speed pipe is in the ping state. Do not
- *                                  use.
+ * @CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
+ *                                actively using hardware.
+ * @CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high speed
+ *                                pipe is in the ping state.
  */
 enum cvmx_usb_pipe_flags {
-       __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
-       __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
+       CVMX_USB_PIPE_FLAGS_SCHEDULED   = 1 << 17,
+       CVMX_USB_PIPE_FLAGS_NEED_PING   = 1 << 18,
 };
 
 /* Maximum number of times to retry failed transactions */
@@ -231,15 +230,6 @@ enum cvmx_usb_pipe_flags {
 /* Maximum number of hardware channels supported by the USB block */
 #define MAX_CHANNELS           8
 
-/* The highest valid USB device address */
-#define MAX_USB_ADDRESS                127
-
-/* The highest valid USB endpoint number */
-#define MAX_USB_ENDPOINT       15
-
-/* The highest valid port number on a hub */
-#define MAX_USB_HUB_PORT       15
-
 /*
  * The low level hardware can transfer a maximum of this number of bytes in each
  * transfer. The field is 19 bits wide
@@ -403,16 +393,18 @@ struct octeon_hcd {
        struct cvmx_usb_state usb;
 };
 
-/* This macro spins on a field waiting for it to reach a value */
-#define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
+/* This macro spins on a register waiting for it to reach a condition. */
+#define CVMX_WAIT_FOR_FIELD32(address, _union, cond, timeout_usec)         \
        ({int result;                                                       \
        do {                                                                \
                uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
                        octeon_get_clock_rate() / 1000000;                  \
-               type c;                                                     \
+               union _union c;                                             \
+                                                                           \
                while (1) {                                                 \
-                       c.u32 = __cvmx_usb_read_csr32(usb, address);        \
-                       if (c.s.field op (value)) {                         \
+                       c.u32 = cvmx_usb_read_csr32(usb, address);          \
+                                                                           \
+                       if (cond) {                                         \
                                result = 0;                                 \
                                break;                                      \
                        } else if (cvmx_get_cycle() > done) {               \
@@ -428,12 +420,13 @@ struct octeon_hcd {
  * This macro logically sets a single field in a CSR. It does the sequence
  * read, modify, and write
  */
-#define USB_SET_FIELD32(address, type, field, value)           \
+#define USB_SET_FIELD32(address, _union, field, value)         \
        do {                                                    \
-               type c;                                         \
-               c.u32 = __cvmx_usb_read_csr32(usb, address);    \
+               union _union c;                                 \
+                                                               \
+               c.u32 = cvmx_usb_read_csr32(usb, address);      \
                c.s.field = value;                              \
-               __cvmx_usb_write_csr32(usb, address, c.u32);    \
+               cvmx_usb_write_csr32(usb, address, c.u32);      \
        } while (0)
 
 /* Returns the IO address to push/pop stuff data from the FIFOs */
@@ -442,7 +435,6 @@ struct octeon_hcd {
 
 /**
  * struct octeon_temp_buffer - a bounce buffer for USB transfers
- * @temp_buffer: the newly allocated temporary buffer (including meta-data)
  * @orig_buffer: the original buffer passed by the USB stack
  * @data:       the newly allocated temporary buffer (excluding meta-data)
  *
@@ -451,7 +443,6 @@ struct octeon_hcd {
  * represents it.
  */
 struct octeon_temp_buffer {
-       void *temp_buffer;
        void *orig_buffer;
        u8 data[0];
 };
@@ -489,7 +480,6 @@ static int octeon_alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
        if (!temp)
                return -ENOMEM;
 
-       temp->temp_buffer = temp;
        temp->orig_buffer = urb->transfer_buffer;
        if (usb_urb_dir_out(urb))
                memcpy(temp->data, urb->transfer_buffer,
@@ -520,7 +510,7 @@ static void octeon_free_temp_buffer(struct urb *urb)
                       urb->actual_length);
        urb->transfer_buffer = temp->orig_buffer;
        urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
-       kfree(temp->temp_buffer);
+       kfree(temp);
 }
 
 /**
@@ -566,8 +556,8 @@ static void octeon_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
  *
  * Returns: Result of the read
  */
-static inline uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_state *usb,
-                                            uint64_t address)
+static inline uint32_t cvmx_usb_read_csr32(struct cvmx_usb_state *usb,
+                                          uint64_t address)
 {
        uint32_t result = cvmx_read64_uint32(address ^ 4);
        return result;
@@ -583,45 +573,13 @@ static inline uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_state *usb,
  * @address: 64bit address to write
  * @value:   Value to write
  */
-static inline void __cvmx_usb_write_csr32(struct cvmx_usb_state *usb,
-                                         uint64_t address, uint32_t value)
+static inline void cvmx_usb_write_csr32(struct cvmx_usb_state *usb,
+                                       uint64_t address, uint32_t value)
 {
        cvmx_write64_uint32(address ^ 4, value);
        cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
 }
 
-
-/**
- * Read a USB 64bit CSR. It logs the value in a readable format if
- * debugging is on.
- *
- * @usb:     USB block this access is for
- * @address: 64bit address to read
- *
- * Returns: Result of the read
- */
-static inline uint64_t __cvmx_usb_read_csr64(struct cvmx_usb_state *usb,
-                                            uint64_t address)
-{
-       uint64_t result = cvmx_read64_uint64(address);
-       return result;
-}
-
-
-/**
- * Write a USB 64bit CSR. It logs the value in a readable format
- * if debugging is on.
- *
- * @usb:     USB block this access is for
- * @address: 64bit address to write
- * @value:   Value to write
- */
-static inline void __cvmx_usb_write_csr64(struct cvmx_usb_state *usb,
-                                         uint64_t address, uint64_t value)
-{
-       cvmx_write64_uint64(address, value);
-}
-
 /**
  * Return non zero if this pipe connects to a non HIGH speed
  * device through a high speed hub.
@@ -631,8 +589,8 @@ static inline void __cvmx_usb_write_csr64(struct cvmx_usb_state *usb,
  *
  * Returns: Non zero if we need to do split transactions
  */
-static inline int __cvmx_usb_pipe_needs_split(struct cvmx_usb_state *usb,
-                                             struct cvmx_usb_pipe *pipe)
+static inline int cvmx_usb_pipe_needs_split(struct cvmx_usb_state *usb,
+                                           struct cvmx_usb_pipe *pipe)
 {
        return pipe->device_speed != CVMX_USB_SPEED_HIGH &&
               usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH;
@@ -646,48 +604,119 @@ static inline int __cvmx_usb_pipe_needs_split(struct cvmx_usb_state *usb,
  *
  * Returns: PID for pipe
  */
-static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
+static inline int cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
 {
        if (pipe->pid_toggle)
                return 2; /* Data1 */
        return 0; /* Data0 */
 }
 
+static void cvmx_fifo_setup(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
+       union cvmx_usbcx_gnptxfsiz npsiz;
+       union cvmx_usbcx_hptxfsiz psiz;
+
+       usbcx_ghwcfg3.u32 = cvmx_usb_read_csr32(usb,
+                                               CVMX_USBCX_GHWCFG3(usb->index));
+
+       /*
+        * Program the USBC_GRXFSIZ register to select the size of the receive
+        * FIFO (25%).
+        */
+       USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), cvmx_usbcx_grxfsiz,
+                       rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
+
+       /*
+        * Program the USBC_GNPTXFSIZ register to select the size and the start
+        * address of the non-periodic transmit FIFO for nonperiodic
+        * transactions (50%).
+        */
+       npsiz.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
+       npsiz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
+       npsiz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), npsiz.u32);
+
+       /*
+        * Program the USBC_HPTXFSIZ register to select the size and start
+        * address of the periodic transmit FIFO for periodic transactions
+        * (25%).
+        */
+       psiz.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
+       psiz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
+       psiz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), psiz.u32);
+
+       /* Flush all FIFOs */
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
+                       cvmx_usbcx_grstctl, txfnum, 0x10);
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
+                       cvmx_usbcx_grstctl, txfflsh, 1);
+       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
+                             cvmx_usbcx_grstctl, c.s.txfflsh == 0, 100);
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
+                       cvmx_usbcx_grstctl, rxfflsh, 1);
+       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
+                             cvmx_usbcx_grstctl, c.s.rxfflsh == 0, 100);
+}
+
+/**
+ * Shutdown a USB port after a call to cvmx_usb_initialize().
+ * The port should be disabled with all pipes closed when this
+ * function is called.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_shutdown(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
+
+       /* Make sure all pipes are closed */
+       if (!list_empty(&usb->idle_pipes) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS]) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT]) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_CONTROL]) ||
+           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_BULK]))
+               return -EBUSY;
+
+       /* Disable the clocks and put them in power on reset */
+       usbn_clk_ctl.u64 = cvmx_read64_uint64(CVMX_USBNX_CLK_CTL(usb->index));
+       usbn_clk_ctl.s.enable = 1;
+       usbn_clk_ctl.s.por = 1;
+       usbn_clk_ctl.s.hclk_rst = 1;
+       usbn_clk_ctl.s.prst = 0;
+       usbn_clk_ctl.s.hrst = 0;
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
+       return 0;
+}
+
 /**
  * Initialize a USB port for use. This must be called before any
  * other access to the Octeon USB port is made. The port starts
  * off in the disabled state.
  *
- * @usb:        Pointer to an empty struct cvmx_usb_state
- *              that will be populated by the initialize call.
- *              This structure is then passed to all other USB
- *              functions.
- * @usb_port_number:
- *              Which Octeon USB port to initialize.
+ * @dev:        Pointer to struct device for logging purposes.
+ * @usb:        Pointer to struct cvmx_usb_state.
  *
  * Returns: 0 or a negative error code.
  */
-static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
-                              int usb_port_number,
-                              enum cvmx_usb_initialize_flags flags)
+static int cvmx_usb_initialize(struct device *dev,
+                              struct cvmx_usb_state *usb)
 {
+       int channel;
+       int divisor;
+       int retries = 0;
+       union cvmx_usbcx_hcfg usbcx_hcfg;
        union cvmx_usbnx_clk_ctl usbn_clk_ctl;
+       union cvmx_usbcx_gintsts usbc_gintsts;
+       union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
+       union cvmx_usbcx_gintmsk usbcx_gintmsk;
+       union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
        union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
-       int i;
-
-       /* At first allow 0-1 for the usb port number */
-       if ((usb_port_number < 0) || (usb_port_number > 1))
-               return -EINVAL;
-
-       memset(usb, 0, sizeof(*usb));
-       usb->init_flags = flags;
-
-       /* Initialize the USB state structure */
-       usb->index = usb_port_number;
-       INIT_LIST_HEAD(&usb->idle_pipes);
-       for (i = 0; i < ARRAY_SIZE(usb->active_pipes); i++)
-               INIT_LIST_HEAD(&usb->active_pipes[i]);
 
+retry:
        /*
         * Power On Reset and PHY Initialization
         *
@@ -696,8 +725,7 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         * 2a. Write USBN0/1_CLK_CTL[POR] = 1 and
         *     USBN0/1_CLK_CTL[HRST,PRST,HCLK_RST] = 0
         */
-       usbn_clk_ctl.u64 =
-               __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
+       usbn_clk_ctl.u64 = cvmx_read64_uint64(CVMX_USBNX_CLK_CTL(usb->index));
        usbn_clk_ctl.s.por = 1;
        usbn_clk_ctl.s.hrst = 0;
        usbn_clk_ctl.s.prst = 0;
@@ -722,7 +750,8 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
                        /* From CN52XX manual */
                        usbn_clk_ctl.s.p_rtype = 1;
 
-               switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
+               switch (usb->init_flags &
+                       CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
                case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
                        usbn_clk_ctl.s.p_c_sel = 0;
                        break;
@@ -752,20 +781,17 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *     setting USBN0/1_CLK_CTL[ENABLE] = 1. Divide the core clock down
         *     such that USB is as close as possible to 125Mhz
         */
-       {
-               int divisor = DIV_ROUND_UP(octeon_get_clock_rate(), 125000000);
-               /* Lower than 4 doesn't seem to work properly */
-               if (divisor < 4)
-                       divisor = 4;
-               usbn_clk_ctl.s.divide = divisor;
-               usbn_clk_ctl.s.divide2 = 0;
-       }
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
+       divisor = DIV_ROUND_UP(octeon_get_clock_rate(), 125000000);
+       /* Lower than 4 doesn't seem to work properly */
+       if (divisor < 4)
+               divisor = 4;
+       usbn_clk_ctl.s.divide = divisor;
+       usbn_clk_ctl.s.divide2 = 0;
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
+
        /* 2d. Write USBN0/1_CLK_CTL[HCLK_RST] = 1 */
        usbn_clk_ctl.s.hclk_rst = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
        /* 2e.  Wait 64 core-clock cycles for HCLK to stabilize */
        cvmx_wait(64);
        /*
@@ -774,8 +800,7 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *    USBN_CLK_CTL[POR] = 0
         */
        usbn_clk_ctl.s.por = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
        /* 4. Wait 1 ms for PHY clock to start */
        mdelay(1);
        /*
@@ -783,11 +808,11 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *    USBP control and status register:
         *    USBN_USBP_CTL_STATUS[ATE_RESET] = 1
         */
-       usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb,
-                       CVMX_USBNX_USBP_CTL_STATUS(usb->index));
+       usbn_usbp_ctl_status.u64 =
+               cvmx_read64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index));
        usbn_usbp_ctl_status.s.ate_reset = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
+       cvmx_write64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                           usbn_usbp_ctl_status.u64);
        /* 6. Wait 10 cycles */
        cvmx_wait(10);
        /*
@@ -795,23 +820,22 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *    USBN_USBP_CTL_STATUS[ATE_RESET] = 0
         */
        usbn_usbp_ctl_status.s.ate_reset = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
+       cvmx_write64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                           usbn_usbp_ctl_status.u64);
        /*
         * 8. Program the PHY reset field in the USBN clock-control register:
         *    USBN_CLK_CTL[PRST] = 1
         */
        usbn_clk_ctl.s.prst = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
        /*
         * 9. Program the USBP control and status register to select host or
         *    device mode. USBN_USBP_CTL_STATUS[HST_MODE] = 0 for host, = 1 for
         *    device
         */
        usbn_usbp_ctl_status.s.hst_mode = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
+       cvmx_write64_uint64(CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                           usbn_usbp_ctl_status.u64);
        /* 10. Wait 1 us */
        udelay(1);
        /*
@@ -819,12 +843,10 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *     USBN_CLK_CTL[HRST] = 1
         */
        usbn_clk_ctl.s.hrst = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
        /* 12. Proceed to USB core initialization */
        usbn_clk_ctl.s.enable = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
+       cvmx_write64_uint64(CVMX_USBNX_CLK_CTL(usb->index), usbn_clk_ctl.u64);
        udelay(1);
 
        /*
@@ -845,29 +867,16 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *    USBC_GAHBCFG[PTXFEMPLVL]
         *    Global interrupt mask, USBC_GAHBCFG[GLBLINTRMSK] = 1
         */
-       {
-               union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
-               /* Due to an errata, CN31XX doesn't support DMA */
-               if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-                       usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
-               usbcx_gahbcfg.u32 = 0;
-               usbcx_gahbcfg.s.dmaen = !(usb->init_flags &
-                                         CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       /* Only use one channel with non DMA */
-                       usb->idle_hardware_channels = 0x1;
-               else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
-                       /* CN5XXX have an errata with channel 3 */
-                       usb->idle_hardware_channels = 0xf7;
-               else
-                       usb->idle_hardware_channels = 0xff;
-               usbcx_gahbcfg.s.hbstlen = 0;
-               usbcx_gahbcfg.s.nptxfemplvl = 1;
-               usbcx_gahbcfg.s.ptxfemplvl = 1;
-               usbcx_gahbcfg.s.glblintrmsk = 1;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
-                                      usbcx_gahbcfg.u32);
-       }
+       usbcx_gahbcfg.u32 = 0;
+       usbcx_gahbcfg.s.dmaen = !(usb->init_flags &
+                                 CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
+       usbcx_gahbcfg.s.hbstlen = 0;
+       usbcx_gahbcfg.s.nptxfemplvl = 1;
+       usbcx_gahbcfg.s.ptxfemplvl = 1;
+       usbcx_gahbcfg.s.glblintrmsk = 1;
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
+                            usbcx_gahbcfg.u32);
+
        /*
         * 3. Program the following fields in USBC_GUSBCFG register.
         *    HS/FS timeout calibration, USBC_GUSBCFG[TOUTCAL] = 0
@@ -875,154 +884,98 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
         *    USB turnaround time, USBC_GUSBCFG[USBTRDTIM] = 0x5
         *    PHY low-power clock select, USBC_GUSBCFG[PHYLPWRCLKSEL] = 0
         */
-       {
-               union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
-
-               usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_GUSBCFG(usb->index));
-               usbcx_gusbcfg.s.toutcal = 0;
-               usbcx_gusbcfg.s.ddrsel = 0;
-               usbcx_gusbcfg.s.usbtrdtim = 0x5;
-               usbcx_gusbcfg.s.phylpwrclksel = 0;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
-                                      usbcx_gusbcfg.u32);
-       }
+       usbcx_gusbcfg.u32 = cvmx_usb_read_csr32(usb,
+                                               CVMX_USBCX_GUSBCFG(usb->index));
+       usbcx_gusbcfg.s.toutcal = 0;
+       usbcx_gusbcfg.s.ddrsel = 0;
+       usbcx_gusbcfg.s.usbtrdtim = 0x5;
+       usbcx_gusbcfg.s.phylpwrclksel = 0;
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
+                            usbcx_gusbcfg.u32);
+
        /*
         * 4. The software must unmask the following bits in the USBC_GINTMSK
         *    register.
         *    OTG interrupt mask, USBC_GINTMSK[OTGINTMSK] = 1
         *    Mode mismatch interrupt mask, USBC_GINTMSK[MODEMISMSK] = 1
         */
-       {
-               union cvmx_usbcx_gintmsk usbcx_gintmsk;
-               int channel;
-
-               usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_GINTMSK(usb->index));
-               usbcx_gintmsk.s.otgintmsk = 1;
-               usbcx_gintmsk.s.modemismsk = 1;
-               usbcx_gintmsk.s.hchintmsk = 1;
-               usbcx_gintmsk.s.sofmsk = 0;
-               /* We need RX FIFO interrupts if we don't have DMA */
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       usbcx_gintmsk.s.rxflvlmsk = 1;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
-                                      usbcx_gintmsk.u32);
-
-               /*
-                * Disable all channel interrupts. We'll enable them per channel
-                * later.
-                */
-               for (channel = 0; channel < 8; channel++)
-                       __cvmx_usb_write_csr32(usb,
-                               CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
-       }
-
-       {
-               /*
-                * Host Port Initialization
-                *
-                * 1. Program the host-port interrupt-mask field to unmask,
-                *    USBC_GINTMSK[PRTINT] = 1
-                */
-               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                               union cvmx_usbcx_gintmsk, prtintmsk, 1);
-               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                               union cvmx_usbcx_gintmsk, disconnintmsk, 1);
-               /*
-                * 2. Program the USBC_HCFG register to select full-speed host
-                *    or high-speed host.
-                */
-               {
-                       union cvmx_usbcx_hcfg usbcx_hcfg;
-
-                       usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb,
-                                       CVMX_USBCX_HCFG(usb->index));
-                       usbcx_hcfg.s.fslssupp = 0;
-                       usbcx_hcfg.s.fslspclksel = 0;
-                       __cvmx_usb_write_csr32(usb,
-                                       CVMX_USBCX_HCFG(usb->index),
-                                       usbcx_hcfg.u32);
-               }
-               /*
-                * 3. Program the port power bit to drive VBUS on the USB,
-                *    USBC_HPRT[PRTPWR] = 1
-                */
-               USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index),
-                               union cvmx_usbcx_hprt, prtpwr, 1);
-
-               /*
-                * Steps 4-15 from the manual are done later in the port enable
-                */
-       }
+       usbcx_gintmsk.u32 = cvmx_usb_read_csr32(usb,
+                                               CVMX_USBCX_GINTMSK(usb->index));
+       usbcx_gintmsk.s.otgintmsk = 1;
+       usbcx_gintmsk.s.modemismsk = 1;
+       usbcx_gintmsk.s.hchintmsk = 1;
+       usbcx_gintmsk.s.sofmsk = 0;
+       /* We need RX FIFO interrupts if we don't have DMA */
+       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+               usbcx_gintmsk.s.rxflvlmsk = 1;
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
+                            usbcx_gintmsk.u32);
 
-       return 0;
-}
+       /*
+        * Disable all channel interrupts. We'll enable them per channel later.
+        */
+       for (channel = 0; channel < 8; channel++)
+               cvmx_usb_write_csr32(usb,
+                                    CVMX_USBCX_HCINTMSKX(channel, usb->index),
+                                    0);
 
+       /*
+        * Host Port Initialization
+        *
+        * 1. Program the host-port interrupt-mask field to unmask,
+        *    USBC_GINTMSK[PRTINT] = 1
+        */
+       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
+                       cvmx_usbcx_gintmsk, prtintmsk, 1);
+       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
+                       cvmx_usbcx_gintmsk, disconnintmsk, 1);
 
-/**
- * Shutdown a USB port after a call to cvmx_usb_initialize().
- * The port should be disabled with all pipes closed when this
- * function is called.
- *
- * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-static int cvmx_usb_shutdown(struct cvmx_usb_state *usb)
-{
-       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
+       /*
+        * 2. Program the USBC_HCFG register to select full-speed host
+        *    or high-speed host.
+        */
+       usbcx_hcfg.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
+       usbcx_hcfg.s.fslssupp = 0;
+       usbcx_hcfg.s.fslspclksel = 0;
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
 
-       /* Make sure all pipes are closed */
-       if (!list_empty(&usb->idle_pipes) ||
-           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS]) ||
-           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT]) ||
-           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_CONTROL]) ||
-           !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_BULK]))
-               return -EBUSY;
+       cvmx_fifo_setup(usb);
 
-       /* Disable the clocks and put them in power on reset */
-       usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb,
-                       CVMX_USBNX_CLK_CTL(usb->index));
-       usbn_clk_ctl.s.enable = 1;
-       usbn_clk_ctl.s.por = 1;
-       usbn_clk_ctl.s.hclk_rst = 1;
-       usbn_clk_ctl.s.prst = 0;
-       usbn_clk_ctl.s.hrst = 0;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       return 0;
+       /*
+        * If the controller is getting port events right after the reset, it
+        * means the initialization failed. Try resetting the controller again
+        * in such case. This is seen to happen after cold boot on DSR-1000N.
+        */
+       usbc_gintsts.u32 = cvmx_usb_read_csr32(usb,
+                                              CVMX_USBCX_GINTSTS(usb->index));
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index),
+                            usbc_gintsts.u32);
+       dev_dbg(dev, "gintsts after reset: 0x%x\n", (int)usbc_gintsts.u32);
+       if (!usbc_gintsts.s.disconnint && !usbc_gintsts.s.prtint)
+               return 0;
+       if (retries++ >= 5)
+               return -EAGAIN;
+       dev_info(dev, "controller reset failed (gintsts=0x%x) - retrying\n",
+                (int)usbc_gintsts.u32);
+       msleep(50);
+       cvmx_usb_shutdown(usb);
+       msleep(50);
+       goto retry;
 }
 
-
 /**
- * Enable a USB port. After this call succeeds, the USB port is
+ * Reset a USB port. After this call succeeds, the USB port is
  * online and servicing requests.
  *
  * @usb: USB device state populated by cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
  */
-static int cvmx_usb_enable(struct cvmx_usb_state *usb)
+static void cvmx_usb_reset_port(struct cvmx_usb_state *usb)
 {
-       union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
-
-       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HPRT(usb->index));
-
-       /*
-        * If the port is already enabled the just return. We don't need to do
-        * anything
-        */
-       if (usb->usbcx_hprt.s.prtena)
-               return 0;
-
-       /* If there is nothing plugged into the port then fail immediately */
-       if (!usb->usbcx_hprt.s.prtconnsts)
-               return -ETIMEDOUT;
+       usb->usbcx_hprt.u32 = cvmx_usb_read_csr32(usb,
+                                                 CVMX_USBCX_HPRT(usb->index));
 
        /* Program the port reset bit to start the reset process */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt,
                        prtrst, 1);
 
        /*
@@ -1032,75 +985,15 @@ static int cvmx_usb_enable(struct cvmx_usb_state *usb)
        mdelay(50);
 
        /* Program the port reset bit to 0, USBC_HPRT[PRTRST] = 0 */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt,
                        prtrst, 0);
 
-       /* Wait for the USBC_HPRT[PRTENA]. */
-       if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index),
-                               union cvmx_usbcx_hprt, prtena, ==, 1, 100000))
-               return -ETIMEDOUT;
-
        /*
         * Read the port speed field to get the enumerated speed,
         * USBC_HPRT[PRTSPD].
         */
-       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HPRT(usb->index));
-       usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_GHWCFG3(usb->index));
-
-       /*
-        * 13. Program the USBC_GRXFSIZ register to select the size of the
-        *     receive FIFO (25%).
-        */
-       USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index),
-                       union cvmx_usbcx_grxfsiz, rxfdep,
-                       usbcx_ghwcfg3.s.dfifodepth / 4);
-       /*
-        * 14. Program the USBC_GNPTXFSIZ register to select the size and the
-        *     start address of the non- periodic transmit FIFO for nonperiodic
-        *     transactions (50%).
-        */
-       {
-               union cvmx_usbcx_gnptxfsiz siz;
-
-               siz.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_GNPTXFSIZ(usb->index));
-               siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
-               siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index),
-                                      siz.u32);
-       }
-       /*
-        * 15. Program the USBC_HPTXFSIZ register to select the size and start
-        *     address of the periodic transmit FIFO for periodic transactions
-        *     (25%).
-        */
-       {
-               union cvmx_usbcx_hptxfsiz siz;
-
-               siz.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_HPTXFSIZ(usb->index));
-               siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
-               siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index),
-                                      siz.u32);
-       }
-       /* Flush all FIFOs */
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                       union cvmx_usbcx_grstctl, txfnum, 0x10);
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                       union cvmx_usbcx_grstctl, txfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                             union cvmx_usbcx_grstctl,
-                             txfflsh, ==, 0, 100);
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                       union cvmx_usbcx_grstctl, rxfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index),
-                             union cvmx_usbcx_grstctl,
-                             rxfflsh, ==, 0, 100);
-
-       return 0;
+       usb->usbcx_hprt.u32 = cvmx_usb_read_csr32(usb,
+                                                 CVMX_USBCX_HPRT(usb->index));
 }
 
 
@@ -1117,7 +1010,7 @@ static int cvmx_usb_enable(struct cvmx_usb_state *usb)
 static int cvmx_usb_disable(struct cvmx_usb_state *usb)
 {
        /* Disable the port */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), cvmx_usbcx_hprt,
                        prtena, 1);
        return 0;
 }
@@ -1142,8 +1035,7 @@ static struct cvmx_usb_port_status cvmx_usb_get_status(
 
        memset(&result, 0, sizeof(result));
 
-       usbc_hprt.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HPRT(usb->index));
+       usbc_hprt.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
        result.port_enabled = usbc_hprt.s.prtena;
        result.port_over_current = usbc_hprt.s.prtovrcurract;
        result.port_powered = usbc_hprt.s.prtpwr;
@@ -1223,41 +1115,13 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
 {
        struct cvmx_usb_pipe *pipe;
 
-       if (unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
-               return NULL;
-       if (unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
-               return NULL;
-       if (unlikely(device_speed > CVMX_USB_SPEED_LOW))
-               return NULL;
-       if (unlikely((max_packet <= 0) || (max_packet > 1024)))
-               return NULL;
-       if (unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
-               return NULL;
-       if (unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
-               (transfer_dir != CVMX_USB_DIRECTION_IN)))
-               return NULL;
-       if (unlikely(interval < 0))
-               return NULL;
-       if (unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
-               return NULL;
-       if (unlikely(multi_count < 0))
-               return NULL;
-       if (unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
-               (multi_count != 0)))
-               return NULL;
-       if (unlikely((hub_device_addr < 0) ||
-               (hub_device_addr > MAX_USB_ADDRESS)))
-               return NULL;
-       if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
-               return NULL;
-
        pipe = kzalloc(sizeof(*pipe), GFP_ATOMIC);
        if (!pipe)
                return NULL;
        if ((device_speed == CVMX_USB_SPEED_HIGH) &&
                (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
                (transfer_type == CVMX_USB_TRANSFER_BULK))
-               pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
+               pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING;
        pipe->device_addr = device_addr;
        pipe->endpoint_num = endpoint_num;
        pipe->device_speed = device_speed;
@@ -1272,7 +1136,7 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
         */
        if (!interval)
                interval = 1;
-       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+       if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                pipe->interval = interval*8;
                /* Force start splits to be schedule on uFrame 0 */
                pipe->next_tx_frame = ((usb->frame_number+7)&~7) +
@@ -1304,7 +1168,7 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
  *
  * @usb:       USB device state populated by cvmx_usb_initialize().
  */
-static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
+static void cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
 {
        union cvmx_usbcx_grxstsph rx_status;
        int channel;
@@ -1312,8 +1176,8 @@ static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
        uint64_t address;
        uint32_t *ptr;
 
-       rx_status.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_GRXSTSPH(usb->index));
+       rx_status.u32 = cvmx_usb_read_csr32(usb,
+                                           CVMX_USBCX_GRXSTSPH(usb->index));
        /* Only read data if IN data is there */
        if (rx_status.s.pktsts != 2)
                return;
@@ -1327,18 +1191,17 @@ static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
                return;
 
        /* Get where the DMA engine would have written this data */
-       address = __cvmx_usb_read_csr64(usb,
-                       CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
+       address = cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index) +
+                                    channel * 8);
 
        ptr = cvmx_phys_to_ptr(address);
-       __cvmx_usb_write_csr64(usb,
-                              CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8,
-                              address + bytes);
+       cvmx_write64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel * 8,
+                           address + bytes);
 
        /* Loop writing the FIFO data for this packet into memory */
        while (bytes > 0) {
-               *ptr++ = __cvmx_usb_read_csr32(usb,
-                               USB_FIFO_ADDRESS(channel, usb->index));
+               *ptr++ = cvmx_usb_read_csr32(usb,
+                                       USB_FIFO_ADDRESS(channel, usb->index));
                bytes -= 4;
        }
        CVMX_SYNCW;
@@ -1356,8 +1219,8 @@ static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
  * Returns: Non zero if the hardware fifo was too small and needs
  *         to be serviced again.
  */
-static int __cvmx_usb_fill_tx_hw(struct cvmx_usb_state *usb,
-                                struct cvmx_usb_tx_fifo *fifo, int available)
+static int cvmx_usb_fill_tx_hw(struct cvmx_usb_state *usb,
+                              struct cvmx_usb_tx_fifo *fifo, int available)
 {
        /*
         * We're done either when there isn't anymore space or the software FIFO
@@ -1412,38 +1275,34 @@ static int __cvmx_usb_fill_tx_hw(struct cvmx_usb_state *usb,
  *
  * @usb:       USB device state populated by cvmx_usb_initialize().
  */
-static void __cvmx_usb_poll_tx_fifo(struct cvmx_usb_state *usb)
+static void cvmx_usb_poll_tx_fifo(struct cvmx_usb_state *usb)
 {
        if (usb->periodic.head != usb->periodic.tail) {
                union cvmx_usbcx_hptxsts tx_status;
 
-               tx_status.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_HPTXSTS(usb->index));
-               if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic,
-                                         tx_status.s.ptxfspcavail))
+               tx_status.u32 = cvmx_usb_read_csr32(usb,
+                                       CVMX_USBCX_HPTXSTS(usb->index));
+               if (cvmx_usb_fill_tx_hw(usb, &usb->periodic,
+                                       tx_status.s.ptxfspcavail))
                        USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                                       union cvmx_usbcx_gintmsk,
-                                       ptxfempmsk, 1);
+                                       cvmx_usbcx_gintmsk, ptxfempmsk, 1);
                else
                        USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                                       union cvmx_usbcx_gintmsk,
-                                       ptxfempmsk, 0);
+                                       cvmx_usbcx_gintmsk, ptxfempmsk, 0);
        }
 
        if (usb->nonperiodic.head != usb->nonperiodic.tail) {
                union cvmx_usbcx_gnptxsts tx_status;
 
-               tx_status.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_GNPTXSTS(usb->index));
-               if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic,
-                                         tx_status.s.nptxfspcavail))
+               tx_status.u32 = cvmx_usb_read_csr32(usb,
+                                       CVMX_USBCX_GNPTXSTS(usb->index));
+               if (cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic,
+                                       tx_status.s.nptxfspcavail))
                        USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                                       union cvmx_usbcx_gintmsk,
-                                       nptxfempmsk, 1);
+                                       cvmx_usbcx_gintmsk, nptxfempmsk, 1);
                else
                        USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                                       union cvmx_usbcx_gintmsk,
-                                       nptxfempmsk, 0);
+                                       cvmx_usbcx_gintmsk, nptxfempmsk, 0);
        }
 }
 
@@ -1454,7 +1313,7 @@ static void __cvmx_usb_poll_tx_fifo(struct cvmx_usb_state *usb)
  * @usb:         USB device state populated by cvmx_usb_initialize().
  * @channel:     Channel number to get packet from
  */
-static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
+static void cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
 {
        union cvmx_usbcx_hccharx hcchar;
        union cvmx_usbcx_hcspltx usbc_hcsplt;
@@ -1462,14 +1321,14 @@ static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
        struct cvmx_usb_tx_fifo *fifo;
 
        /* We only need to fill data on outbound channels */
-       hcchar.u32 = __cvmx_usb_read_csr32(usb,
+       hcchar.u32 = cvmx_usb_read_csr32(usb,
                        CVMX_USBCX_HCCHARX(channel, usb->index));
        if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT)
                return;
 
        /* OUT Splits only have data on the start and not the complete */
-       usbc_hcsplt.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HCSPLTX(channel, usb->index));
+       usbc_hcsplt.u32 = cvmx_usb_read_csr32(usb,
+                               CVMX_USBCX_HCSPLTX(channel, usb->index));
        if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
                return;
 
@@ -1477,8 +1336,8 @@ static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
         * Find out how many bytes we need to fill and convert it into 32bit
         * words.
         */
-       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HCTSIZX(channel, usb->index));
+       usbc_hctsiz.u32 = cvmx_usb_read_csr32(usb,
+                               CVMX_USBCX_HCTSIZX(channel, usb->index));
        if (!usbc_hctsiz.s.xfersize)
                return;
 
@@ -1489,28 +1348,28 @@ static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
                fifo = &usb->nonperiodic;
 
        fifo->entry[fifo->head].channel = channel;
-       fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb,
-                       CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8);
+       fifo->entry[fifo->head].address =
+               cvmx_read64_uint64(CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) +
+                                  channel * 8);
        fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2;
        fifo->head++;
        if (fifo->head > MAX_CHANNELS)
                fifo->head = 0;
 
-       __cvmx_usb_poll_tx_fifo(usb);
+       cvmx_usb_poll_tx_fifo(usb);
 }
 
 /**
  * Perform channel specific setup for Control transactions. All
- * the generic stuff will already have been done in
- * __cvmx_usb_start_channel()
+ * the generic stuff will already have been done in cvmx_usb_start_channel().
  *
  * @usb:         USB device state populated by cvmx_usb_initialize().
  * @channel:     Channel to setup
  * @pipe:        Pipe for control transaction
  */
-static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
-                                            int channel,
-                                            struct cvmx_usb_pipe *pipe)
+static void cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
+                                          int channel,
+                                          struct cvmx_usb_pipe *pipe)
 {
        struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
        struct usb_hcd *hcd = octeon_to_hcd(priv);
@@ -1525,8 +1384,8 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
        int packets_to_transfer;
        union cvmx_usbcx_hctsizx usbc_hctsiz;
 
-       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HCTSIZX(channel, usb->index));
+       usbc_hctsiz.u32 = cvmx_usb_read_csr32(usb,
+                               CVMX_USBCX_HCTSIZX(channel, usb->index));
 
        switch (transaction->stage) {
        case CVMX_USB_STAGE_NON_CONTROL:
@@ -1538,72 +1397,72 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
                bytes_to_transfer = sizeof(*header);
                /* All Control operations start with a setup going OUT */
                USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
+                               cvmx_usbcx_hccharx, epdir,
                                CVMX_USB_DIRECTION_OUT);
                /*
                 * Setup send the control header instead of the buffer data. The
                 * buffer data will be used in the next stage
                 */
-               __cvmx_usb_write_csr64(usb,
-                       CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8,
-                       transaction->control_header);
+               cvmx_write64_uint64(CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) +
+                                       channel * 8,
+                                   transaction->control_header);
                break;
        case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
                usbc_hctsiz.s.pid = 3; /* Setup */
                bytes_to_transfer = 0;
                /* All Control operations start with a setup going OUT */
                USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
+                               cvmx_usbcx_hccharx, epdir,
                                CVMX_USB_DIRECTION_OUT);
 
                USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index),
-                               union cvmx_usbcx_hcspltx, compsplt, 1);
+                               cvmx_usbcx_hcspltx, compsplt, 1);
                break;
        case CVMX_USB_STAGE_DATA:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
-               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+               usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
+               if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                        if (header->bRequestType & USB_DIR_IN)
                                bytes_to_transfer = 0;
                        else if (bytes_to_transfer > pipe->max_packet)
                                bytes_to_transfer = pipe->max_packet;
                }
                USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
+                               cvmx_usbcx_hccharx, epdir,
                                ((header->bRequestType & USB_DIR_IN) ?
                                        CVMX_USB_DIRECTION_IN :
                                        CVMX_USB_DIRECTION_OUT));
                break;
        case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
                if (!(header->bRequestType & USB_DIR_IN))
                        bytes_to_transfer = 0;
                USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
+                               cvmx_usbcx_hccharx, epdir,
                                ((header->bRequestType & USB_DIR_IN) ?
                                        CVMX_USB_DIRECTION_IN :
                                        CVMX_USB_DIRECTION_OUT));
                USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index),
-                               union cvmx_usbcx_hcspltx, compsplt, 1);
+                               cvmx_usbcx_hcspltx, compsplt, 1);
                break;
        case CVMX_USB_STAGE_STATUS:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
                bytes_to_transfer = 0;
                USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
+                               cvmx_usbcx_hccharx, epdir,
                                ((header->bRequestType & USB_DIR_IN) ?
                                        CVMX_USB_DIRECTION_OUT :
                                        CVMX_USB_DIRECTION_IN));
                break;
        case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
                bytes_to_transfer = 0;
                USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
+                               cvmx_usbcx_hccharx, epdir,
                                ((header->bRequestType & USB_DIR_IN) ?
                                        CVMX_USB_DIRECTION_OUT :
                                        CVMX_USB_DIRECTION_IN));
                USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index),
-                               union cvmx_usbcx_hcspltx, compsplt, 1);
+                               cvmx_usbcx_hcspltx, compsplt, 1);
                break;
        }
 
@@ -1646,8 +1505,8 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
        usbc_hctsiz.s.xfersize = bytes_to_transfer;
        usbc_hctsiz.s.pktcnt = packets_to_transfer;
 
-       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index),
-                              usbc_hctsiz.u32);
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index),
+                            usbc_hctsiz.u32);
 }
 
 
@@ -1658,9 +1517,8 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
  * @channel:     Channel to setup
  * @pipe:        Pipe to start
  */
-static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
-                                    int channel,
-                                    struct cvmx_usb_pipe *pipe)
+static void cvmx_usb_start_channel(struct cvmx_usb_state *usb, int channel,
+                                  struct cvmx_usb_pipe *pipe)
 {
        struct cvmx_usb_transaction *transaction =
                list_first_entry(&pipe->transactions, typeof(*transaction),
@@ -1672,7 +1530,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
        /* Attach the channel to the pipe */
        usb->pipe_for_channel[channel] = pipe;
        pipe->channel = channel;
-       pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED;
+       pipe->flags |= CVMX_USB_PIPE_FLAGS_SCHEDULED;
 
        /* Mark this channel as in use */
        usb->idle_hardware_channels &= ~(1<<channel);
@@ -1684,12 +1542,12 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                union cvmx_usbcx_haintmsk usbc_haintmsk;
 
                /* Clear all channel status bits */
-               usbc_hcint.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_HCINTX(channel, usb->index));
+               usbc_hcint.u32 = cvmx_usb_read_csr32(usb,
+                                       CVMX_USBCX_HCINTX(channel, usb->index));
 
-               __cvmx_usb_write_csr32(usb,
-                                      CVMX_USBCX_HCINTX(channel, usb->index),
-                                      usbc_hcint.u32);
+               cvmx_usb_write_csr32(usb,
+                                    CVMX_USBCX_HCINTX(channel, usb->index),
+                                    usbc_hcint.u32);
 
                usbc_hcintmsk.u32 = 0;
                usbc_hcintmsk.s.chhltdmsk = 1;
@@ -1702,7 +1560,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                        usbc_hcintmsk.s.frmovrunmsk = 1;
                        usbc_hcintmsk.s.bblerrmsk = 1;
                        usbc_hcintmsk.s.xacterrmsk = 1;
-                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                                /*
                                 * Splits don't generate xfercompl, so we need
                                 * ACK and NYET.
@@ -1714,21 +1572,21 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                        usbc_hcintmsk.s.stallmsk = 1;
                        usbc_hcintmsk.s.xfercomplmsk = 1;
                }
-               __cvmx_usb_write_csr32(usb,
+               cvmx_usb_write_csr32(usb,
                                CVMX_USBCX_HCINTMSKX(channel, usb->index),
                                usbc_hcintmsk.u32);
 
                /* Enable the channel interrupt to propagate */
-               usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb,
+               usbc_haintmsk.u32 = cvmx_usb_read_csr32(usb,
                                        CVMX_USBCX_HAINTMSK(usb->index));
                usbc_haintmsk.s.haintmsk |= 1<<channel;
-               __cvmx_usb_write_csr32(usb,
-                                       CVMX_USBCX_HAINTMSK(usb->index),
-                                       usbc_haintmsk.u32);
+               cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index),
+                                    usbc_haintmsk.u32);
        }
 
-       /* Setup the locations the DMA engines use  */
+       /* Setup the location the DMA engine uses. */
        {
+               uint64_t reg;
                uint64_t dma_address = transaction->buffer +
                                        transaction->actual_bytes;
 
@@ -1737,13 +1595,11 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                                        transaction->iso_packets[0].offset +
                                        transaction->actual_bytes;
 
-               __cvmx_usb_write_csr64(usb,
-                       CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8,
-                       dma_address);
-
-               __cvmx_usb_write_csr64(usb,
-                       CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8,
-                       dma_address);
+               if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT)
+                       reg = CVMX_USBNX_DMA0_OUTB_CHN0(usb->index);
+               else
+                       reg = CVMX_USBNX_DMA0_INB_CHN0(usb->index);
+               cvmx_write64_uint64(reg + channel * 8, dma_address);
        }
 
        /* Setup both the size of the transfer and the SPLIT characteristics */
@@ -1767,7 +1623,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                 * We need to do split transactions when we are talking to non
                 * high speed devices that are behind a high speed hub
                 */
-               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+               if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                        /*
                         * On the start split phase (stage is even) record the
                         * frame number we will need to send the split complete.
@@ -1898,18 +1754,19 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                usbc_hctsiz.s.pktcnt = packets_to_transfer;
 
                /* Update the DATA0/DATA1 toggle */
-               usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
+               usbc_hctsiz.s.pid = cvmx_usb_get_data_pid(pipe);
                /*
                 * High speed pipes may need a hardware ping before they start
                 */
-               if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING)
+               if (pipe->flags & CVMX_USB_PIPE_FLAGS_NEED_PING)
                        usbc_hctsiz.s.dopng = 1;
 
-               __cvmx_usb_write_csr32(usb,
-                                      CVMX_USBCX_HCSPLTX(channel, usb->index),
-                                      usbc_hcsplt.u32);
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel,
-                                       usb->index), usbc_hctsiz.u32);
+               cvmx_usb_write_csr32(usb,
+                                    CVMX_USBCX_HCSPLTX(channel, usb->index),
+                                    usbc_hcsplt.u32);
+               cvmx_usb_write_csr32(usb,
+                                    CVMX_USBCX_HCTSIZX(channel, usb->index),
+                                    usbc_hctsiz.u32);
        }
 
        /* Setup the Host Channel Characteristics Register */
@@ -1928,7 +1785,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                 * immediate retries of failure. These retries happen too
                 * quickly, so we disable these entirely for splits
                 */
-               if (__cvmx_usb_pipe_needs_split(usb, pipe))
+               if (cvmx_usb_pipe_needs_split(usb, pipe))
                        usbc_hcchar.s.ec = 1;
                else if (pipe->multi_count < 1)
                        usbc_hcchar.s.ec = 1;
@@ -1945,21 +1802,21 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                usbc_hcchar.s.epdir = pipe->transfer_dir;
                usbc_hcchar.s.epnum = pipe->endpoint_num;
                usbc_hcchar.s.mps = pipe->max_packet;
-               __cvmx_usb_write_csr32(usb,
-                                      CVMX_USBCX_HCCHARX(channel, usb->index),
-                                      usbc_hcchar.u32);
+               cvmx_usb_write_csr32(usb,
+                                    CVMX_USBCX_HCCHARX(channel, usb->index),
+                                    usbc_hcchar.u32);
        }
 
        /* Do transaction type specific fixups as needed */
        switch (transaction->type) {
        case CVMX_USB_TRANSFER_CONTROL:
-               __cvmx_usb_start_channel_control(usb, channel, pipe);
+               cvmx_usb_start_channel_control(usb, channel, pipe);
                break;
        case CVMX_USB_TRANSFER_BULK:
        case CVMX_USB_TRANSFER_INTERRUPT:
                break;
        case CVMX_USB_TRANSFER_ISOCHRONOUS:
-               if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
+               if (!cvmx_usb_pipe_needs_split(usb, pipe)) {
                        /*
                         * ISO transactions require different PIDs depending on
                         * direction and how many packets are needed
@@ -1969,32 +1826,30 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
                                        USB_SET_FIELD32(
                                                CVMX_USBCX_HCTSIZX(channel,
                                                                   usb->index),
-                                               union cvmx_usbcx_hctsizx,
-                                               pid, 0);
+                                               cvmx_usbcx_hctsizx, pid, 0);
                                else /* Need MDATA */
                                        USB_SET_FIELD32(
                                                CVMX_USBCX_HCTSIZX(channel,
                                                                   usb->index),
-                                               union cvmx_usbcx_hctsizx,
-                                               pid, 3);
+                                               cvmx_usbcx_hctsizx, pid, 3);
                        }
                }
                break;
        }
        {
                union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 =
-                       __cvmx_usb_read_csr32(usb,
+                       cvmx_usb_read_csr32(usb,
                                CVMX_USBCX_HCTSIZX(channel, usb->index))};
                transaction->xfersize = usbc_hctsiz.s.xfersize;
                transaction->pktcnt = usbc_hctsiz.s.pktcnt;
        }
        /* Remeber when we start a split transaction */
-       if (__cvmx_usb_pipe_needs_split(usb, pipe))
+       if (cvmx_usb_pipe_needs_split(usb, pipe))
                usb->active_split = transaction;
        USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                       union cvmx_usbcx_hccharx, chena, 1);
+                       cvmx_usbcx_hccharx, chena, 1);
        if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-               __cvmx_usb_fill_tx_fifo(usb, channel);
+               cvmx_usb_fill_tx_fifo(usb, channel);
 }
 
 
@@ -2007,7 +1862,7 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
  *
  * Returns: Pipe or NULL if none are ready
  */
-static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(
+static struct cvmx_usb_pipe *cvmx_usb_find_ready_pipe(
                struct cvmx_usb_state *usb,
                struct list_head *list,
                uint64_t current_frame)
@@ -2018,7 +1873,7 @@ static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(
                struct cvmx_usb_transaction *t =
                        list_first_entry(&pipe->transactions, typeof(*t),
                                         node);
-               if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && t &&
+               if (!(pipe->flags & CVMX_USB_PIPE_FLAGS_SCHEDULED) && t &&
                        (pipe->next_tx_frame <= current_frame) &&
                        ((pipe->split_sc_frame == -1) ||
                         ((((int)current_frame - (int)pipe->split_sc_frame)
@@ -2039,7 +1894,7 @@ static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(
  * @usb:        USB device state populated by cvmx_usb_initialize().
  * @is_sof:     True if this schedule was called on a SOF interrupt.
  */
-static void __cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
+static void cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
 {
        int channel;
        struct cvmx_usb_pipe *pipe;
@@ -2052,12 +1907,12 @@ static void __cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
                 * at the end of a frame and cause an overrun.
                 */
                union cvmx_usbcx_hfnum hfnum = {
-                       .u32 = __cvmx_usb_read_csr32(usb,
+                       .u32 = cvmx_usb_read_csr32(usb,
                                                CVMX_USBCX_HFNUM(usb->index))
                };
 
                union cvmx_usbcx_hfir hfir = {
-                       .u32 = __cvmx_usb_read_csr32(usb,
+                       .u32 = cvmx_usb_read_csr32(usb,
                                                CVMX_USBCX_HFIR(usb->index))
                };
 
@@ -2079,23 +1934,23 @@ static void __cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
                         * way we are sure that the periodic data is sent in the
                         * beginning of the frame
                         */
-                       pipe = __cvmx_usb_find_ready_pipe(usb,
+                       pipe = cvmx_usb_find_ready_pipe(usb,
                                        usb->active_pipes +
                                        CVMX_USB_TRANSFER_ISOCHRONOUS,
                                        usb->frame_number);
                        if (likely(!pipe))
-                               pipe = __cvmx_usb_find_ready_pipe(usb,
+                               pipe = cvmx_usb_find_ready_pipe(usb,
                                                usb->active_pipes +
                                                CVMX_USB_TRANSFER_INTERRUPT,
                                                usb->frame_number);
                }
                if (likely(!pipe)) {
-                       pipe = __cvmx_usb_find_ready_pipe(usb,
+                       pipe = cvmx_usb_find_ready_pipe(usb,
                                        usb->active_pipes +
                                        CVMX_USB_TRANSFER_CONTROL,
                                        usb->frame_number);
                        if (likely(!pipe))
-                               pipe = __cvmx_usb_find_ready_pipe(usb,
+                               pipe = cvmx_usb_find_ready_pipe(usb,
                                                usb->active_pipes +
                                                CVMX_USB_TRANSFER_BULK,
                                                usb->frame_number);
@@ -2103,7 +1958,7 @@ static void __cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
                if (!pipe)
                        break;
 
-               __cvmx_usb_start_channel(usb, channel, pipe);
+               cvmx_usb_start_channel(usb, channel, pipe);
        }
 
 done:
@@ -2122,7 +1977,7 @@ done:
                }
        }
        USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index),
-                       union cvmx_usbcx_gintmsk, sofmsk, need_sof);
+                       cvmx_usbcx_gintmsk, sofmsk, need_sof);
 }
 
 static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
@@ -2226,11 +2081,10 @@ static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
  * @complete_code:
  *              Completion code
  */
-static void __cvmx_usb_perform_complete(
-                               struct cvmx_usb_state *usb,
-                               struct cvmx_usb_pipe *pipe,
-                               struct cvmx_usb_transaction *transaction,
-                               enum cvmx_usb_complete complete_code)
+static void cvmx_usb_perform_complete(struct cvmx_usb_state *usb,
+                                     struct cvmx_usb_pipe *pipe,
+                                     struct cvmx_usb_transaction *transaction,
+                                     enum cvmx_usb_complete complete_code)
 {
        /* If this was a split then clear our split in progress marker */
        if (usb->active_split == transaction)
@@ -2296,7 +2150,7 @@ static void __cvmx_usb_perform_complete(
  *
  * Returns: Transaction or NULL on failure.
  */
-static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(
+static struct cvmx_usb_transaction *cvmx_usb_submit_transaction(
                                struct cvmx_usb_state *usb,
                                struct cvmx_usb_pipe *pipe,
                                enum cvmx_usb_transfer type,
@@ -2342,7 +2196,7 @@ static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(
                 * We may need to schedule the pipe if this was the head of the
                 * pipe.
                 */
-               __cvmx_usb_schedule(usb, 0);
+               cvmx_usb_schedule(usb, 0);
        }
 
        return transaction;
@@ -2363,14 +2217,14 @@ static struct cvmx_usb_transaction *cvmx_usb_submit_bulk(
                                                struct cvmx_usb_pipe *pipe,
                                                struct urb *urb)
 {
-       return __cvmx_usb_submit_transaction(usb, pipe, CVMX_USB_TRANSFER_BULK,
-                                            urb->transfer_dma,
-                                            urb->transfer_buffer_length,
-                                            0, /* control_header */
-                                            0, /* iso_start_frame */
-                                            0, /* iso_number_packets */
-                                            NULL, /* iso_packets */
-                                            urb);
+       return cvmx_usb_submit_transaction(usb, pipe, CVMX_USB_TRANSFER_BULK,
+                                          urb->transfer_dma,
+                                          urb->transfer_buffer_length,
+                                          0, /* control_header */
+                                          0, /* iso_start_frame */
+                                          0, /* iso_number_packets */
+                                          NULL, /* iso_packets */
+                                          urb);
 }
 
 
@@ -2388,15 +2242,15 @@ static struct cvmx_usb_transaction *cvmx_usb_submit_interrupt(
                                                struct cvmx_usb_pipe *pipe,
                                                struct urb *urb)
 {
-       return __cvmx_usb_submit_transaction(usb, pipe,
-                                            CVMX_USB_TRANSFER_INTERRUPT,
-                                            urb->transfer_dma,
-                                            urb->transfer_buffer_length,
-                                            0, /* control_header */
-                                            0, /* iso_start_frame */
-                                            0, /* iso_number_packets */
-                                            NULL, /* iso_packets */
-                                            urb);
+       return cvmx_usb_submit_transaction(usb, pipe,
+                                          CVMX_USB_TRANSFER_INTERRUPT,
+                                          urb->transfer_dma,
+                                          urb->transfer_buffer_length,
+                                          0, /* control_header */
+                                          0, /* iso_start_frame */
+                                          0, /* iso_number_packets */
+                                          NULL, /* iso_packets */
+                                          urb);
 }
 
 
@@ -2421,14 +2275,14 @@ static struct cvmx_usb_transaction *cvmx_usb_submit_control(
        if ((header->bRequestType & USB_DIR_IN) == 0)
                buffer_length = le16_to_cpu(header->wLength);
 
-       return __cvmx_usb_submit_transaction(usb, pipe,
-                                            CVMX_USB_TRANSFER_CONTROL,
-                                            urb->transfer_dma, buffer_length,
-                                            control_header,
-                                            0, /* iso_start_frame */
-                                            0, /* iso_number_packets */
-                                            NULL, /* iso_packets */
-                                            urb);
+       return cvmx_usb_submit_transaction(usb, pipe,
+                                          CVMX_USB_TRANSFER_CONTROL,
+                                          urb->transfer_dma, buffer_length,
+                                          control_header,
+                                          0, /* iso_start_frame */
+                                          0, /* iso_number_packets */
+                                          NULL, /* iso_packets */
+                                          urb);
 }
 
 
@@ -2449,14 +2303,14 @@ static struct cvmx_usb_transaction *cvmx_usb_submit_isochronous(
        struct cvmx_usb_iso_packet *packets;
 
        packets = (struct cvmx_usb_iso_packet *) urb->setup_packet;
-       return __cvmx_usb_submit_transaction(usb, pipe,
-                                            CVMX_USB_TRANSFER_ISOCHRONOUS,
-                                            urb->transfer_dma,
-                                            urb->transfer_buffer_length,
-                                            0, /* control_header */
-                                            urb->start_frame,
-                                            urb->number_of_packets,
-                                            packets, urb);
+       return cvmx_usb_submit_transaction(usb, pipe,
+                                          CVMX_USB_TRANSFER_ISOCHRONOUS,
+                                          urb->transfer_dma,
+                                          urb->transfer_buffer_length,
+                                          0, /* control_header */
+                                          urb->start_frame,
+                                          urb->number_of_packets,
+                                          packets, urb);
 }
 
 
@@ -2482,15 +2336,15 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
         * treat it special
         */
        if (list_first_entry(&pipe->transactions, typeof(*transaction), node) ==
-           transaction && (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
+           transaction && (pipe->flags & CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
                union cvmx_usbcx_hccharx usbc_hcchar;
 
                usb->pipe_for_channel[pipe->channel] = NULL;
-               pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
+               pipe->flags &= ~CVMX_USB_PIPE_FLAGS_SCHEDULED;
 
                CVMX_SYNCW;
 
-               usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb,
+               usbc_hcchar.u32 = cvmx_usb_read_csr32(usb,
                                CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
                /*
                 * If the channel isn't enabled then the transaction already
@@ -2498,14 +2352,14 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
                 */
                if (usbc_hcchar.s.chena) {
                        usbc_hcchar.s.chdis = 1;
-                       __cvmx_usb_write_csr32(usb,
+                       cvmx_usb_write_csr32(usb,
                                        CVMX_USBCX_HCCHARX(pipe->channel,
                                                usb->index),
                                        usbc_hcchar.u32);
                }
        }
-       __cvmx_usb_perform_complete(usb, pipe, transaction,
-                                   CVMX_USB_COMPLETE_CANCEL);
+       cvmx_usb_perform_complete(usb, pipe, transaction,
+                                 CVMX_USB_COMPLETE_CANCEL);
        return 0;
 }
 
@@ -2570,8 +2424,7 @@ static int cvmx_usb_get_frame_number(struct cvmx_usb_state *usb)
        int frame_number;
        union cvmx_usbcx_hfnum usbc_hfnum;
 
-       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HFNUM(usb->index));
+       usbc_hfnum.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
        frame_number = usbc_hfnum.s.frnum;
 
        return frame_number;
@@ -2586,7 +2439,7 @@ static int cvmx_usb_get_frame_number(struct cvmx_usb_state *usb)
  *
  * Returns: Zero on success
  */
-static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
+static int cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
 {
        struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
        struct usb_hcd *hcd = octeon_to_hcd(priv);
@@ -2602,11 +2455,11 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
        int buffer_space_left;
 
        /* Read the interrupt status bits for the channel */
-       usbc_hcint.u32 = __cvmx_usb_read_csr32(usb,
-                       CVMX_USBCX_HCINTX(channel, usb->index));
+       usbc_hcint.u32 = cvmx_usb_read_csr32(usb,
+                               CVMX_USBCX_HCINTX(channel, usb->index));
 
        if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
-               usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb,
+               usbc_hcchar.u32 = cvmx_usb_read_csr32(usb,
                                CVMX_USBCX_HCCHARX(channel, usb->index));
 
                if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis) {
@@ -2615,7 +2468,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                         * interrupt IN transfers to get stuck until we do a
                         * write of HCCHARX without changing things
                         */
-                       __cvmx_usb_write_csr32(usb,
+                       cvmx_usb_write_csr32(usb,
                                        CVMX_USBCX_HCCHARX(channel,
                                                           usb->index),
                                        usbc_hcchar.u32);
@@ -2632,12 +2485,12 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                /* Disable all interrupts except CHHLTD */
                                hcintmsk.u32 = 0;
                                hcintmsk.s.chhltdmsk = 1;
-                               __cvmx_usb_write_csr32(usb,
+                               cvmx_usb_write_csr32(usb,
                                                CVMX_USBCX_HCINTMSKX(channel,
                                                        usb->index),
                                                hcintmsk.u32);
                                usbc_hcchar.s.chdis = 1;
-                               __cvmx_usb_write_csr32(usb,
+                               cvmx_usb_write_csr32(usb,
                                                CVMX_USBCX_HCCHARX(channel,
                                                        usb->index),
                                                usbc_hcchar.u32);
@@ -2663,9 +2516,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
        }
 
        /* Disable the channel interrupts now that it is done */
-       __cvmx_usb_write_csr32(usb,
-                               CVMX_USBCX_HCINTMSKX(channel, usb->index),
-                               0);
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
        usb->idle_hardware_channels |= (1<<channel);
 
        /* Make sure this channel is tied to a valid pipe */
@@ -2683,15 +2534,15 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
         * function will figure out which pipe needs to go
         */
        usb->pipe_for_channel[channel] = NULL;
-       pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
+       pipe->flags &= ~CVMX_USB_PIPE_FLAGS_SCHEDULED;
 
        /*
         * Read the channel config info so we can figure out how much data
         * transferred
         */
-       usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb,
+       usbc_hcchar.u32 = cvmx_usb_read_csr32(usb,
                        CVMX_USBCX_HCCHARX(channel, usb->index));
-       usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb,
+       usbc_hctsiz.u32 = cvmx_usb_read_csr32(usb,
                        CVMX_USBCX_HCTSIZX(channel, usb->index));
 
        /*
@@ -2766,7 +2617,18 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
        if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
                (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
                (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
-               pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
+               pipe->flags |= CVMX_USB_PIPE_FLAGS_NEED_PING;
+
+       if (unlikely(WARN_ON_ONCE(bytes_this_transfer < 0))) {
+               /*
+                * In some rare cases the DMA engine seems to get stuck and
+                * keeps substracting same byte count over and over again. In
+                * such case we just need to fail every transaction.
+                */
+               cvmx_usb_perform_complete(usb, pipe, transaction,
+                                         CVMX_USB_COMPLETE_ERROR);
+               return 0;
+       }
 
        if (usbc_hcint.s.stall) {
                /*
@@ -2776,52 +2638,24 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                 * the actual bytes transferred
                 */
                pipe->pid_toggle = 0;
-               __cvmx_usb_perform_complete(usb, pipe, transaction,
-                                           CVMX_USB_COMPLETE_STALL);
+               cvmx_usb_perform_complete(usb, pipe, transaction,
+                                         CVMX_USB_COMPLETE_STALL);
        } else if (usbc_hcint.s.xacterr) {
                /*
-                * We know at least one packet worked if we get a ACK or NAK.
-                * Reset the retry counter
+                * XactErr as a response means the device signaled
+                * something wrong with the transfer. For example, PID
+                * toggle errors cause these.
                 */
-               if (usbc_hcint.s.nak || usbc_hcint.s.ack)
-                       transaction->retries = 0;
-               transaction->retries++;
-               if (transaction->retries > MAX_RETRIES) {
-                       /*
-                        * XactErr as a response means the device signaled
-                        * something wrong with the transfer. For example, PID
-                        * toggle errors cause these
-                        */
-                       __cvmx_usb_perform_complete(usb, pipe, transaction,
-                                                   CVMX_USB_COMPLETE_XACTERR);
-               } else {
-                       /*
-                        * If this was a split then clear our split in progress
-                        * marker
-                        */
-                       if (usb->active_split == transaction)
-                               usb->active_split = NULL;
-                       /*
-                        * Rewind to the beginning of the transaction by anding
-                        * off the split complete bit
-                        */
-                       transaction->stage &= ~1;
-                       pipe->split_sc_frame = -1;
-                       pipe->next_tx_frame += pipe->interval;
-                       if (pipe->next_tx_frame < usb->frame_number)
-                               pipe->next_tx_frame =
-                                       usb->frame_number + pipe->interval -
-                                       (usb->frame_number -
-                                        pipe->next_tx_frame) % pipe->interval;
-               }
+               cvmx_usb_perform_complete(usb, pipe, transaction,
+                                         CVMX_USB_COMPLETE_XACTERR);
        } else if (usbc_hcint.s.bblerr) {
                /* Babble Error (BblErr) */
-               __cvmx_usb_perform_complete(usb, pipe, transaction,
-                                           CVMX_USB_COMPLETE_BABBLEERR);
+               cvmx_usb_perform_complete(usb, pipe, transaction,
+                                         CVMX_USB_COMPLETE_BABBLEERR);
        } else if (usbc_hcint.s.datatglerr) {
                /* Data toggle error */
-               __cvmx_usb_perform_complete(usb, pipe, transaction,
-                                           CVMX_USB_COMPLETE_DATATGLERR);
+               cvmx_usb_perform_complete(usb, pipe, transaction,
+                                         CVMX_USB_COMPLETE_DATATGLERR);
        } else if (usbc_hcint.s.nyet) {
                /*
                 * NYET as a response is only allowed in three cases: as a
@@ -2829,7 +2663,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                 * as a response to a bulk out. The ping case is handled by
                 * hardware, so we only have splits and bulk out
                 */
-               if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
+               if (!cvmx_usb_pipe_needs_split(usb, pipe)) {
                        transaction->retries = 0;
                        /*
                         * If there is more data to go then we need to try
@@ -2837,7 +2671,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                         */
                        if ((buffer_space_left == 0) ||
                                (bytes_in_last_packet < pipe->max_packet))
-                               __cvmx_usb_perform_complete(usb, pipe,
+                               cvmx_usb_perform_complete(usb, pipe,
                                                transaction,
                                                CVMX_USB_COMPLETE_SUCCESS);
                } else {
@@ -2869,7 +2703,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                 * Since we got an ACK, we know we don't need to do a ping on
                 * this pipe
                 */
-               pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING;
+               pipe->flags &= ~CVMX_USB_PIPE_FLAGS_NEED_PING;
 
                switch (transaction->type) {
                case CVMX_USB_TRANSFER_CONTROL:
@@ -2877,12 +2711,12 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                        case CVMX_USB_STAGE_NON_CONTROL:
                        case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
                                /* This should be impossible */
-                               __cvmx_usb_perform_complete(usb, pipe,
+                               cvmx_usb_perform_complete(usb, pipe,
                                        transaction, CVMX_USB_COMPLETE_ERROR);
                                break;
                        case CVMX_USB_STAGE_SETUP:
                                pipe->pid_toggle = 1;
-                               if (__cvmx_usb_pipe_needs_split(usb, pipe))
+                               if (cvmx_usb_pipe_needs_split(usb, pipe))
                                        transaction->stage =
                                                CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
                                else {
@@ -2909,7 +2743,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                }
                                break;
                        case CVMX_USB_STAGE_DATA:
-                               if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                               if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                                        transaction->stage =
                                                CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
                                        /*
@@ -2947,16 +2781,16 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                }
                                break;
                        case CVMX_USB_STAGE_STATUS:
-                               if (__cvmx_usb_pipe_needs_split(usb, pipe))
+                               if (cvmx_usb_pipe_needs_split(usb, pipe))
                                        transaction->stage =
                                                CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
                                else
-                                       __cvmx_usb_perform_complete(usb, pipe,
+                                       cvmx_usb_perform_complete(usb, pipe,
                                                transaction,
                                                CVMX_USB_COMPLETE_SUCCESS);
                                break;
                        case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
-                               __cvmx_usb_perform_complete(usb, pipe,
+                               cvmx_usb_perform_complete(usb, pipe,
                                                transaction,
                                                CVMX_USB_COMPLETE_SUCCESS);
                                break;
@@ -2970,7 +2804,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                         * For splits we need to continue the transfer if more
                         * data is needed
                         */
-                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                                if (transaction->stage ==
                                                CVMX_USB_STAGE_NON_CONTROL)
                                        transaction->stage =
@@ -2986,7 +2820,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                                        CVMX_USB_TRANSFER_INTERRUPT)
                                                        pipe->next_tx_frame +=
                                                                pipe->interval;
-                                                       __cvmx_usb_perform_complete(
+                                                       cvmx_usb_perform_complete(
                                                                usb,
                                                                pipe,
                                                                transaction,
@@ -3002,7 +2836,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                     CVMX_USB_DIRECTION_OUT) &&
                                    (usbc_hcint.s.nak))
                                        pipe->flags |=
-                                               __CVMX_USB_PIPE_FLAGS_NEED_PING;
+                                               CVMX_USB_PIPE_FLAGS_NEED_PING;
                                if (!buffer_space_left ||
                                        (bytes_in_last_packet <
                                         pipe->max_packet)) {
@@ -3010,15 +2844,14 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                                CVMX_USB_TRANSFER_INTERRUPT)
                                                pipe->next_tx_frame +=
                                                        pipe->interval;
-                                       __cvmx_usb_perform_complete(usb,
-                                               pipe,
+                                       cvmx_usb_perform_complete(usb, pipe,
                                                transaction,
                                                CVMX_USB_COMPLETE_SUCCESS);
                                }
                        }
                        break;
                case CVMX_USB_TRANSFER_ISOCHRONOUS:
-                       if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
+                       if (cvmx_usb_pipe_needs_split(usb, pipe)) {
                                /*
                                 * ISOCHRONOUS OUT splits don't require a
                                 * complete split stage. Instead they use a
@@ -3039,10 +2872,8 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                                (bytes_this_transfer < 188)) {
                                                pipe->next_tx_frame +=
                                                        pipe->interval;
-                                               __cvmx_usb_perform_complete(
-                                                       usb,
-                                                       pipe,
-                                                       transaction,
+                                               cvmx_usb_perform_complete(usb,
+                                                       pipe, transaction,
                                                        CVMX_USB_COMPLETE_SUCCESS);
                                        }
                                } else {
@@ -3059,7 +2890,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                                         pipe->max_packet)) {
                                                        pipe->next_tx_frame +=
                                                                pipe->interval;
-                                                       __cvmx_usb_perform_complete(
+                                                       cvmx_usb_perform_complete(
                                                                usb,
                                                                pipe,
                                                                transaction,
@@ -3071,8 +2902,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                                }
                        } else {
                                pipe->next_tx_frame += pipe->interval;
-                               __cvmx_usb_perform_complete(usb,
-                                               pipe,
+                               cvmx_usb_perform_complete(usb, pipe,
                                                transaction,
                                                CVMX_USB_COMPLETE_SUCCESS);
                        }
@@ -3110,7 +2940,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
                         * We get channel halted interrupts with no result bits
                         * sets when the cable is unplugged
                         */
-                       __cvmx_usb_perform_complete(usb, pipe, transaction,
+                       cvmx_usb_perform_complete(usb, pipe, transaction,
                                        CVMX_USB_COMPLETE_ERROR);
                }
        }
@@ -3144,21 +2974,19 @@ static int cvmx_usb_poll(struct cvmx_usb_state *usb)
        prefetch_range(usb, sizeof(*usb));
 
        /* Update the frame counter */
-       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb,
-                                               CVMX_USBCX_HFNUM(usb->index));
+       usbc_hfnum.u32 = cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
        if ((usb->frame_number&0x3fff) > usbc_hfnum.s.frnum)
                usb->frame_number += 0x4000;
        usb->frame_number &= ~0x3fffull;
        usb->frame_number |= usbc_hfnum.s.frnum;
 
        /* Read the pending interrupts */
-       usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb,
-                                               CVMX_USBCX_GINTSTS(usb->index));
+       usbc_gintsts.u32 = cvmx_usb_read_csr32(usb,
+                                              CVMX_USBCX_GINTSTS(usb->index));
 
        /* Clear the interrupts now that we know about them */
-       __cvmx_usb_write_csr32(usb,
-                               CVMX_USBCX_GINTSTS(usb->index),
-                               usbc_gintsts.u32);
+       cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index),
+                            usbc_gintsts.u32);
 
        if (usbc_gintsts.s.rxflvl) {
                /*
@@ -3169,12 +2997,12 @@ static int cvmx_usb_poll(struct cvmx_usb_state *usb)
                 * In DMA mode this is handled by hardware
                 */
                if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       __cvmx_usb_poll_rx_fifo(usb);
+                       cvmx_usb_poll_rx_fifo(usb);
        }
        if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp) {
                /* Fill the Tx FIFOs when not in DMA mode */
                if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       __cvmx_usb_poll_tx_fifo(usb);
+                       cvmx_usb_poll_tx_fifo(usb);
        }
        if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint) {
                union cvmx_usbcx_hprt usbc_hprt;
@@ -3194,11 +3022,11 @@ static int cvmx_usb_poll(struct cvmx_usb_state *usb)
                 */
                octeon_usb_port_callback(usb);
                /* Clear the port change bits */
-               usbc_hprt.u32 = __cvmx_usb_read_csr32(usb,
-                               CVMX_USBCX_HPRT(usb->index));
+               usbc_hprt.u32 = cvmx_usb_read_csr32(usb,
+                                       CVMX_USBCX_HPRT(usb->index));
                usbc_hprt.s.prtena = 0;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index),
-                                      usbc_hprt.u32);
+               cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index),
+                                    usbc_hprt.u32);
        }
        if (usbc_gintsts.s.hchint) {
                /*
@@ -3215,18 +3043,18 @@ static int cvmx_usb_poll(struct cvmx_usb_state *usb)
                 */
                union cvmx_usbcx_haint usbc_haint;
 
-               usbc_haint.u32 = __cvmx_usb_read_csr32(usb,
+               usbc_haint.u32 = cvmx_usb_read_csr32(usb,
                                        CVMX_USBCX_HAINT(usb->index));
                while (usbc_haint.u32) {
                        int channel;
 
                        channel = __fls(usbc_haint.u32);
-                       __cvmx_usb_poll_channel(usb, channel);
+                       cvmx_usb_poll_channel(usb, channel);
                        usbc_haint.u32 ^= 1<<channel;
                }
        }
 
-       __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
+       cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
 
        return 0;
 }
@@ -3510,6 +3338,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
        struct octeon_hcd *priv = hcd_to_octeon(hcd);
        struct device *dev = hcd->self.controller;
        struct cvmx_usb_port_status usb_port_status;
+       struct cvmx_usb_state *usb = &priv->usb;
        int port_status;
        struct usb_hub_descriptor *desc;
        unsigned long flags;
@@ -3687,13 +3516,18 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        return -EINVAL;
                case USB_PORT_FEAT_POWER:
                        dev_dbg(dev, " POWER\n");
-                       return -EINVAL;
+                       /*
+                        * Program the port power bit to drive VBUS on the USB.
+                        */
+                       spin_lock_irqsave(&priv->lock, flags);
+                       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index),
+                                       cvmx_usbcx_hprt, prtpwr, 1);
+                       spin_unlock_irqrestore(&priv->lock, flags);
+                       return 0;
                case USB_PORT_FEAT_RESET:
                        dev_dbg(dev, " RESET\n");
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_disable(&priv->usb);
-                       if (cvmx_usb_enable(&priv->usb))
-                               dev_dbg(dev, "Failed to enable the port\n");
+                       cvmx_usb_reset_port(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        return 0;
                case USB_PORT_FEAT_INDICATOR:
@@ -3741,7 +3575,6 @@ static int octeon_usb_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct octeon_hcd *priv;
        struct usb_hcd *hcd;
-       unsigned long flags;
        u32 clock_rate = 48000000;
        bool is_crystal_clock = false;
        const char *clock_type;
@@ -3838,20 +3671,33 @@ static int octeon_usb_probe(struct platform_device *pdev)
 
        spin_lock_init(&priv->lock);
 
-       status = cvmx_usb_initialize(&priv->usb, usb_num, initialize_flags);
+       priv->usb.init_flags = initialize_flags;
+
+       /* Initialize the USB state structure */
+       priv->usb.index = usb_num;
+       INIT_LIST_HEAD(&priv->usb.idle_pipes);
+       for (i = 0; i < ARRAY_SIZE(priv->usb.active_pipes); i++)
+               INIT_LIST_HEAD(&priv->usb.active_pipes[i]);
+
+       /* Due to an errata, CN31XX doesn't support DMA */
+       if (OCTEON_IS_MODEL(OCTEON_CN31XX)) {
+               priv->usb.init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
+               /* Only use one channel with non DMA */
+               priv->usb.idle_hardware_channels = 0x1;
+       } else if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) {
+               /* CN5XXX have an errata with channel 3 */
+               priv->usb.idle_hardware_channels = 0xf7;
+       } else {
+               priv->usb.idle_hardware_channels = 0xff;
+       }
+
+       status = cvmx_usb_initialize(dev, &priv->usb);
        if (status) {
                dev_dbg(dev, "USB initialization failed with %d\n", status);
                kfree(hcd);
                return -1;
        }
 
-       /* This delay is needed for CN3010, but I don't know why... */
-       mdelay(10);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_poll(&priv->usb);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        status = usb_add_hcd(hcd, irq, 0);
        if (status) {
                dev_dbg(dev, "USB add HCD failed with %d\n", status);
@@ -3885,7 +3731,7 @@ static int octeon_usb_remove(struct platform_device *pdev)
        return 0;
 }
 
-static struct of_device_id octeon_usb_match[] = {
+static const struct of_device_id octeon_usb_match[] = {
        {
                .compatible = "cavium,octeon-5750-usbc",
        },