can: tcan4x5x: tcan4x5x_parse_config(): reset device before register access
authorSean Nyekjaer <sean@geanix.com>
Wed, 11 Dec 2019 13:58:51 +0000 (14:58 +0100)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 2 Jan 2020 14:34:26 +0000 (15:34 +0100)
It's a good idea to reset a ip-block/spi device before using it, this
patch will reset the device.

And a generic reset function if needed elsewhere.

Signed-off-by: Sean Nyekjaer <sean@geanix.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/m_can/tcan4x5x.c

index a69476f5aec6c0ae196d35f6d1fcecb007d0cdf9..ee22e39f131b86f053dd7f83cbe3f45685df13ff 100644 (file)
@@ -166,6 +166,28 @@ static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv)
        }
 }
 
+static int tcan4x5x_reset(struct tcan4x5x_priv *priv)
+{
+       int ret = 0;
+
+       if (priv->reset_gpio) {
+               gpiod_set_value(priv->reset_gpio, 1);
+
+               /* tpulse_width minimum 30us */
+               usleep_range(30, 100);
+               gpiod_set_value(priv->reset_gpio, 0);
+       } else {
+               ret = regmap_write(priv->regmap, TCAN4X5X_CONFIG,
+                                  TCAN4X5X_SW_RESET);
+               if (ret)
+                       return ret;
+       }
+
+       usleep_range(700, 1000);
+
+       return ret;
+}
+
 static int regmap_spi_gather_write(void *context, const void *reg,
                                   size_t reg_len, const void *val,
                                   size_t val_len)
@@ -351,6 +373,7 @@ static int tcan4x5x_disable_wake(struct m_can_classdev *cdev)
 static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
 {
        struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
+       int ret;
 
        tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake",
                                                    GPIOD_OUT_HIGH);
@@ -366,7 +389,9 @@ static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
        if (IS_ERR(tcan4x5x->reset_gpio))
                tcan4x5x->reset_gpio = NULL;
 
-       usleep_range(700, 1000);
+       ret = tcan4x5x_reset(tcan4x5x);
+       if (ret)
+               return ret;
 
        tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
                                                              "device-state",