lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250711-translucent-gharial-from-tartarus-e3cdf0-mkl@pengutronix.de>
Date: Fri, 11 Jul 2025 11:45:10 +0200
From: Marc Kleine-Budde <mkl@...gutronix.de>
To: Brett Werling <brett.werling@...min.com>
Cc: linux-can@...r.kernel.org, linux-kernel@...r.kernel.org, 
	Vincent Mailhol <mailhol.vincent@...adoo.fr>, bwerl.dev@...il.com
Subject: Re: [PATCH] can: tcan4x5x: fix reset gpio usage during probe

On 08.07.2025 13:11:53, Brett Werling wrote:
> 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 <brett.werling@...min.com>
> ---
>  drivers/net/can/m_can/tcan4x5x-core.c | 56 +++++++++++++++------------
>  1 file changed, 32 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
> index 8edaa339d590..c37733bf124e 100644
> --- a/drivers/net/can/m_can/tcan4x5x-core.c
> +++ b/drivers/net/can/m_can/tcan4x5x-core.c
> @@ -343,21 +343,19 @@ static void tcan4x5x_get_dt_data(struct m_can_classdev *cdev)
>  		of_property_read_bool(cdev->dev->of_node, "ti,nwkrq-voltage-vio");
>  }
>  
> -static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
> -			      const struct tcan4x5x_version_info *version_info)
> +static int tcan4x5x_get_gpios(struct m_can_classdev *cdev)
>  {
>  	struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
>  	int ret;
>  
> -	if (version_info->has_wake_pin) {
> -		tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake",
> -							    GPIOD_OUT_HIGH);
> -		if (IS_ERR(tcan4x5x->device_wake_gpio)) {
> -			if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER)
> -				return -EPROBE_DEFER;
> +	tcan4x5x->device_wake_gpio = devm_gpiod_get_optional(cdev->dev,
> +							     "device-wake",
> +							     GPIOD_OUT_HIGH);
> +	if (IS_ERR(tcan4x5x->device_wake_gpio)) {
> +		if (PTR_ERR(tcan4x5x->device_wake_gpio) == -EPROBE_DEFER)
> +			return -EPROBE_DEFER;
>  
> -			tcan4x5x_disable_wake(cdev);

Although the original code doesn't propagate any errors....

> -		}
> +		tcan4x5x->device_wake_gpio = NULL;
>  	}
>  
>  	tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset",
> @@ -369,19 +367,27 @@ static int tcan4x5x_get_gpios(struct m_can_classdev *cdev,
>  	if (ret)
>  		return ret;
>  
> -	if (version_info->has_state_pin) {
> -		tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
> -								      "device-state",
> -								      GPIOD_IN);
> -		if (IS_ERR(tcan4x5x->device_state_gpio)) {
> -			tcan4x5x->device_state_gpio = NULL;
> -			tcan4x5x_disable_state(cdev);
> -		}
> -	}
> +	tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
> +							      "device-state",
> +							      GPIOD_IN);
> +	if (IS_ERR(tcan4x5x->device_state_gpio))
> +		tcan4x5x->device_state_gpio = NULL;
>  
>  	return 0;
>  }
>  
> +static void tcan4x5x_check_gpios(struct m_can_classdev *cdev,
> +				 const struct tcan4x5x_version_info *version_info)
> +{
> +	struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
> +
> +	if (version_info->has_wake_pin && !tcan4x5x->device_wake_gpio)
> +		tcan4x5x_disable_wake(cdev);

... please add error checking and propagate errors.

> +
> +	if (version_info->has_state_pin && !tcan4x5x->device_state_gpio)
> +		tcan4x5x_disable_state(cdev);
> +}
> +
>  static const struct m_can_ops tcan4x5x_ops = {
>  	.init = tcan4x5x_init,
>  	.deinit = tcan4x5x_deinit,
> @@ -468,17 +474,19 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
>  		goto out_m_can_class_free_dev;
>  	}
>  
> +	ret = tcan4x5x_get_gpios(mcan_class);
> +	if (ret) {
> +		dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
> +		goto out_power;
> +	}
> +
>  	version_info = tcan4x5x_find_version(priv);
>  	if (IS_ERR(version_info)) {
>  		ret = PTR_ERR(version_info);
>  		goto out_power;
>  	}
>  
> -	ret = tcan4x5x_get_gpios(mcan_class, version_info);
> -	if (ret) {
> -		dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
> -		goto out_power;
> -	}
> +	tcan4x5x_check_gpios(mcan_class, version_info);

same here

>  
>  	tcan4x5x_get_dt_data(mcan_class);

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

Download attachment "signature.asc" of type "application/pgp-signature" (489 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ