staging: dwc2: properly mask the GRXFSIZ register
authorMatthijs Kooijman <matthijs@stdin.nl>
Fri, 30 Aug 2013 16:45:20 +0000 (18:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 30 Aug 2013 21:14:53 +0000 (14:14 -0700)
Bits 16-31 are reserved, so the old code just reads the whole register to
get bits 0-15, assuming the reserved bits would be 0 (which seems true
on current hardware, but who knows...).

This commit properly masks out the reserved bits when reading and
doesn't touch the reserved bits while writing.

Signed-off-by: Matthijs Kooijman <matthijs@stdin.nl>
Acked-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/dwc2/core.c
drivers/staging/dwc2/hw.h

index f6494df799c9c0dc739909517446cea27c746fa9..2f84c24a84ee833d36c21d0cdbc402fd30cd2a5f 100644 (file)
@@ -402,7 +402,9 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq)
 
        hsotg->total_fifo_size = hsotg->hwcfg3 >> GHWCFG3_DFIFO_DEPTH_SHIFT &
                        GHWCFG3_DFIFO_DEPTH_MASK >> GHWCFG3_DFIFO_DEPTH_SHIFT;
-       hsotg->rx_fifo_size = readl(hsotg->regs + GRXFSIZ);
+       hsotg->rx_fifo_size = (readl(hsotg->regs + GRXFSIZ) &
+                              GRXFSIZ_DEPTH_MASK) >>
+                             GRXFSIZ_DEPTH_SHIFT;
        hsotg->nperio_tx_fifo_size =
                        readl(hsotg->regs + GNPTXFSIZ) >> 16 & 0xffff;
 
@@ -507,7 +509,7 @@ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg)
 static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
 {
        struct dwc2_core_params *params = hsotg->core_params;
-       u32 nptxfsiz, hptxfsiz, dfifocfg;
+       u32 nptxfsiz, hptxfsiz, dfifocfg, grxfsiz;
 
        if (!params->enable_dynamic_fifo)
                return;
@@ -520,9 +522,12 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg)
                params->host_perio_tx_fifo_size);
 
        /* Rx FIFO */
-       dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n",
-               readl(hsotg->regs + GRXFSIZ));
-       writel(params->host_rx_fifo_size, hsotg->regs + GRXFSIZ);
+       grxfsiz = readl(hsotg->regs + GRXFSIZ);
+       dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz);
+       grxfsiz &= ~GRXFSIZ_DEPTH_MASK;
+       grxfsiz |= params->host_rx_fifo_size <<
+                  GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK;
+       writel(grxfsiz, hsotg->regs + GRXFSIZ);
        dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", readl(hsotg->regs + GRXFSIZ));
 
        /* Non-periodic Tx FIFO */
@@ -2115,7 +2120,9 @@ int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
        int valid = 1;
        int retval = 0;
 
-       if (val < 16 || val > readl(hsotg->regs + GRXFSIZ))
+       if (val < 16 || val > (readl(hsotg->regs + GRXFSIZ) &
+                              GRXFSIZ_DEPTH_MASK) >>
+                             GRXFSIZ_DEPTH_SHIFT)
                valid = 0;
 
        if (!valid) {
@@ -2123,7 +2130,9 @@ int dwc2_set_param_host_rx_fifo_size(struct dwc2_hsotg *hsotg, int val)
                        dev_err(hsotg->dev,
                                "%d invalid for host_rx_fifo_size. Check HW configuration.\n",
                                val);
-               val = readl(hsotg->regs + GRXFSIZ);
+               val = (readl(hsotg->regs + GRXFSIZ) &
+                      GRXFSIZ_DEPTH_MASK) >>
+                     GRXFSIZ_DEPTH_SHIFT;
                dev_dbg(hsotg->dev, "Setting host_rx_fifo_size to %d\n", val);
                retval = -EINVAL;
        }
index 321d071be1e264b4b8221f90e0650a08e77fc00d..fafdc199b2b5ae21efd57bee0ee3eba50e9eaee2 100644 (file)
 #define GRXSTS_EPNUM_SHIFT             0
 
 #define GRXFSIZ                                HSOTG_REG(0x024)
+#define GRXFSIZ_DEPTH_MASK             (0xffff << 0)
+#define GRXFSIZ_DEPTH_SHIFT            0
 
 #define GNPTXFSIZ                      HSOTG_REG(0x028)
 /* Use FIFOSIZE_* constants to access this register */