Skip to content

Commit 0f97a75

Browse files
Brett Werlingmarckleinebudde
authored andcommitted
can: tcan4x5x: fix reset gpio usage during probe
Fixes reset GPIO usage during probe by ensuring we retrieve the GPIO and take the device out of reset (if it defaults to being in reset) before we attempt to communicate with the device. This is achieved by moving the call to tcan4x5x_get_gpios() before tcan4x5x_find_version() and avoiding any device communication while getting the GPIOs. Once we determine the version, we can then take the knowledge of which GPIOs we obtained and use it to decide whether we need to disable the wake or state pin functions within the device. This change is necessary in a situation where the reset GPIO is pulled high externally before the CPU takes control of it, meaning we need to explicitly bring the device out of reset before we can start communicating with it at all. This also has the effect of fixing an issue where a reset of the device would occur after having called tcan4x5x_disable_wake(), making the original behavior not actually disable the wake. This patch should now disable wake or state pin functions well after the reset occurs. Signed-off-by: Brett Werling <[email protected]> Link: https://patch.msgid.link/[email protected] Cc: Markus Schneider-Pargmann <[email protected]> Fixes: 142c6dc ("can: tcan4x5x: Add support for tcan4552/4553") Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent f0f2b99 commit 0f97a75

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

drivers/net/can/m_can/tcan4x5x-core.c

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -343,21 +343,19 @@ static void tcan4x5x_get_dt_data(struct m_can_classdev *cdev)
343343
of_property_read_bool(cdev->dev->of_node, "ti,nwkrq-voltage-vio");
344344
}
345345

346-
static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
347-
const struct tcan4x5x_version_info *version_info)
346+
static int tcan4x5x_get_gpios(struct m_can_classdev *cdev)
348347
{
349348
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
350349
int ret;
351350

352-
if (version_info->has_wake_pin) {
353-
tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake",
354-
GPIOD_OUT_HIGH);
355-
if (IS_ERR(tcan4x5x->device_wake_gpio)) {
356-
if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER)
357-
return -EPROBE_DEFER;
351+
tcan4x5x->device_wake_gpio = devm_gpiod_get_optional(cdev->dev,
352+
"device-wake",
353+
GPIOD_OUT_HIGH);
354+
if (IS_ERR(tcan4x5x->device_wake_gpio)) {
355+
if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER)
356+
return -EPROBE_DEFER;
358357

359-
tcan4x5x_disable_wake(cdev);
360-
}
358+
tcan4x5x->device_wake_gpio = NULL;
361359
}
362360

363361
tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset",
@@ -369,14 +367,31 @@ static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
369367
if (ret)
370368
return ret;
371369

372-
if (version_info->has_state_pin) {
373-
tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
374-
"device-state",
375-
GPIOD_IN);
376-
if (IS_ERR(tcan4x5x->device_state_gpio)) {
377-
tcan4x5x->device_state_gpio = NULL;
378-
tcan4x5x_disable_state(cdev);
379-
}
370+
tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
371+
"device-state",
372+
GPIOD_IN);
373+
if (IS_ERR(tcan4x5x->device_state_gpio))
374+
tcan4x5x->device_state_gpio = NULL;
375+
376+
return 0;
377+
}
378+
379+
static int tcan4x5x_check_gpios(struct m_can_classdev *cdev,
380+
const struct tcan4x5x_version_info *version_info)
381+
{
382+
struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
383+
int ret;
384+
385+
if (version_info->has_wake_pin && !tcan4x5x->device_wake_gpio) {
386+
ret = tcan4x5x_disable_wake(cdev);
387+
if (ret)
388+
return ret;
389+
}
390+
391+
if (version_info->has_state_pin && !tcan4x5x->device_state_gpio) {
392+
ret = tcan4x5x_disable_state(cdev);
393+
if (ret)
394+
return ret;
380395
}
381396

382397
return 0;
@@ -468,15 +483,21 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
468483
goto out_m_can_class_free_dev;
469484
}
470485

486+
ret = tcan4x5x_get_gpios(mcan_class);
487+
if (ret) {
488+
dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
489+
goto out_power;
490+
}
491+
471492
version_info = tcan4x5x_find_version(priv);
472493
if (IS_ERR(version_info)) {
473494
ret = PTR_ERR(version_info);
474495
goto out_power;
475496
}
476497

477-
ret = tcan4x5x_get_gpios(mcan_class, version_info);
498+
ret = tcan4x5x_check_gpios(mcan_class, version_info);
478499
if (ret) {
479-
dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
500+
dev_err(&spi->dev, "Checking gpios failed %pe\n", ERR_PTR(ret));
480501
goto out_power;
481502
}
482503

0 commit comments

Comments
 (0)