Commit ae2256f9 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-fixes-for-6.16-20250715' of...

Merge tag 'linux-can-fixes-for-6.16-20250715' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2025-07-15

Brett Werling's patch for the tcan4x5x glue code driver fixes the
detection of chips which are held in reset/sleep and must be woken up
by GPIO prior to communication.

* tag 'linux-can-fixes-for-6.16-20250715' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: tcan4x5x: fix reset gpio usage during probe
====================

Link: https://patch.msgid.link/20250715101625.3202690-1-mkl@pengutronix.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4c4ca3c4 0f97a758
Loading
Loading
Loading
Loading
+41 −20
Original line number Diff line number Diff line
@@ -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",
	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);
		}
		tcan4x5x->device_wake_gpio = NULL;
	}

	tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset",
@@ -369,14 +367,31 @@ 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)) {
	if (IS_ERR(tcan4x5x->device_state_gpio))
		tcan4x5x->device_state_gpio = NULL;
			tcan4x5x_disable_state(cdev);

	return 0;
}

static int tcan4x5x_check_gpios(struct m_can_classdev *cdev,
				const struct tcan4x5x_version_info *version_info)
{
	struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev);
	int ret;

	if (version_info->has_wake_pin && !tcan4x5x->device_wake_gpio) {
		ret = tcan4x5x_disable_wake(cdev);
		if (ret)
			return ret;
	}

	if (version_info->has_state_pin && !tcan4x5x->device_state_gpio) {
		ret = tcan4x5x_disable_state(cdev);
		if (ret)
			return ret;
	}

	return 0;
@@ -468,15 +483,21 @@ 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);
	ret = tcan4x5x_check_gpios(mcan_class, version_info);
	if (ret) {
		dev_err(&spi->dev, "Getting gpios failed %pe\n", ERR_PTR(ret));
		dev_err(&spi->dev, "Checking gpios failed %pe\n", ERR_PTR(ret));
		goto out_power;
	}