OSDN Git Service

can: mcp251x: mcp251x_hw_reset(): allow more time after a reset
authorMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 13 Aug 2019 14:01:02 +0000 (16:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Oct 2019 20:40:53 +0000 (13:40 -0700)
commit d84ea2123f8d27144e3f4d58cd88c9c6ddc799de upstream.

Some boards take longer than 5ms to power up after a reset, so allow
some retries attempts before giving up.

Fixes: ff06d611a31c ("can: mcp251x: Improve mcp251x_hw_reset()")
Cc: linux-stable <stable@vger.kernel.org>
Tested-by: Sean Nyekjaer <sean@geanix.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/can/spi/mcp251x.c

index 3bcbfcf..83ddb7d 100644 (file)
@@ -627,7 +627,7 @@ static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
 static int mcp251x_hw_reset(struct spi_device *spi)
 {
        struct mcp251x_priv *priv = spi_get_drvdata(spi);
-       u8 reg;
+       unsigned long timeout;
        int ret;
 
        /* Wait for oscillator startup timer after power up */
@@ -641,10 +641,19 @@ static int mcp251x_hw_reset(struct spi_device *spi)
        /* Wait for oscillator startup timer after reset */
        mdelay(MCP251X_OST_DELAY_MS);
 
-       reg = mcp251x_read_reg(spi, CANSTAT);
-       if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
-               return -ENODEV;
-
+       /* Wait for reset to finish */
+       timeout = jiffies + HZ;
+       while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) !=
+              CANCTRL_REQOP_CONF) {
+               usleep_range(MCP251X_OST_DELAY_MS * 1000,
+                            MCP251X_OST_DELAY_MS * 1000 * 2);
+
+               if (time_after(jiffies, timeout)) {
+                       dev_err(&spi->dev,
+                               "MCP251x didn't enter in conf mode after reset\n");
+                       return -EBUSY;
+               }
+       }
        return 0;
 }