Re: [PATCH] mfd: cros_ec: Read EC features during probe to catch transfer error

Lee Jones <[email protected]>
Newsgroups dev.linux.lists.chrome-platform,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Fri, 22 May 2026, Andrei Kuchynski wrote:

> cros_ec_check_features() does not return an error if the underlying
> EC_CMD_GET_FEATURES command fails. Consequently, when the Fingerprint
> device fails to respond, the probe function ignores the failure and falls
> back to installing it as 'cros_ec' device instead of 'cros_fp'.
> This leads to a sysfs duplicate filename collision later when the real
> 'cros_ec' device attempts to register:
> 
>   cros-ec-spi spi5.0: EC failed to respond in time
>   cros-ec-dev.19.auto: cannot get EC features: -110
>   sysfs : cannot create duplicate filename '/class/chromeos/cros_ec'
>         : sysfs_do_create_link_sd+0x94/0xdc
>         : ec_device_probe+0x150/0x4f0
> 
> Fix this by extracting the feature reading logic into a new helper function
> cros_ec_read_features() and calling it during ec_device_probe().
> If the transfer fails, abort the broken device initialization.

You're doing 2 things here.  Move the function first, then add the new
call into MFD in a subsequent patch.

> Signed-off-by: Andrei Kuchynski <[email protected]>
> ---
>  drivers/mfd/cros_ec_dev.c                   |  4 +++
>  drivers/platform/chrome/cros_ec_proto.c     | 30 +++++++++++++++------
>  include/linux/platform_data/cros_ec_proto.h |  2 ++
>  3 files changed, 28 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c
> index 39430dd44e30c..7810b1c871849 100644
> --- a/drivers/mfd/cros_ec_dev.c
> +++ b/drivers/mfd/cros_ec_dev.c
> @@ -203,6 +203,10 @@ static int ec_device_probe(struct platform_device *pdev)
>  	ec->features.flags[1] = -1U; /* Not cached yet */
>  	device_initialize(&ec->class_dev);
>  
> +	retval = cros_ec_read_features(ec);
> +	if (retval < 0)
> +		return retval;

You just leaked ec->class_dev.

	goto failed;  ?

> +
>  	for (i = 0; i < ARRAY_SIZE(cros_mcu_devices); i++) {
>  		/*
>  		 * Check whether this is actually a dedicated MCU rather
> diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
> index 1d8d9168ec1aa..724d1313f6b21 100644
> --- a/drivers/platform/chrome/cros_ec_proto.c
> +++ b/drivers/platform/chrome/cros_ec_proto.c
> @@ -946,6 +946,27 @@ u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev)
>  }
>  EXPORT_SYMBOL(cros_ec_get_host_event);
>  
> +/**
> + * cros_ec_read_features() - Read EC features
> + *
> + * @ec: EC device.
> + *
> + * Return: >= 0 on success, negative error number on failure.
> + */
> +int cros_ec_read_features(struct cros_ec_dev *ec)
> +{
> +	int ret = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
> +			      NULL, 0, &ec->features, sizeof(ec->features));
> +
> +	if (ret < 0) {
> +		dev_warn(ec->dev, "cannot get EC features: %d\n", ret);
> +		memset(&ec->features, 0, sizeof(ec->features));
> +	}
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(cros_ec_read_features);
> +
>  /**
>   * cros_ec_check_features() - Test for the presence of EC features
>   *
> @@ -960,17 +981,10 @@ EXPORT_SYMBOL(cros_ec_get_host_event);
>  bool cros_ec_check_features(struct cros_ec_dev *ec, int feature)
>  {
>  	struct ec_response_get_features *features = &ec->features;
> -	int ret;
>  
>  	if (features->flags[0] == -1U && features->flags[1] == -1U) {
>  		/* features bitmap not read yet */
> -		ret = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
> -				  NULL, 0, features, sizeof(*features));
> -		if (ret < 0) {
> -			dev_warn(ec->dev, "cannot get EC features: %d\n", ret);
> -			memset(features, 0, sizeof(*features));
> -		}
> -
> +		cros_ec_read_features(ec);
>  		dev_dbg(ec->dev, "EC features %08x %08x\n",
>  			features->flags[0], features->flags[1]);
>  	}
> diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h
> index 6ed1c4c5ce2ef..a1ccecf5e1f83 100644
> --- a/include/linux/platform_data/cros_ec_proto.h
> +++ b/include/linux/platform_data/cros_ec_proto.h
> @@ -271,6 +271,8 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
>  
>  u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev);
>  
> +int cros_ec_read_features(struct cros_ec_dev *ec);
> +
>  bool cros_ec_check_features(struct cros_ec_dev *ec, int feature);
>  
>  int cros_ec_get_sensor_count(struct cros_ec_dev *ec);
> -- 
> 2.54.0.746.g67dd491aae-goog
> 

-- 
Lee Jones
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.