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)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Tue, 20 Aug 2019 11:41:26 +0000 (13:41 +0200)
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>
drivers/net/can/spi/mcp251x.c

index 1b3ac5f..74cb19a 100644 (file)
@@ -606,7 +606,7 @@ static int mcp251x_setup(struct net_device *net, struct spi_device *spi)
 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 */
@@ -620,10 +620,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;
 }