]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 10 Dec 2019 18:01:13 +0000 (18:01 +0000)
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()")
Tested-by: Sean Nyekjaer <sean@geanix.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/net/can/spi/mcp251x.c

index cc7ee1b6602bf31b0fa5e192f0cc70e2aaa8278b..0cd7e3bd4ccc71e4b6260cf055925ec600a7f698 100644 (file)
@@ -626,7 +626,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 */
@@ -640,10 +640,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;
 }