Hi Gwendal,

Thank you for your patch.

On 28/4/20 0:59, Gwendal Grignou wrote:
> Allocate callbacks array before enumerating the sensors:
> The probe routine for these sensors (for instance cros_ec_sensors_probe)
> can be called within the sensorhub probe routine
> (cros_ec_sensors_probe())
> 
> Fixes: 145d59baff594 ("platform/chrome: cros_ec_sensorhub: Add FIFO support")
> 
> Signed-off-by: Gwendal Grignou <gwen...@chromium.org>

Applied as a fix for 5.7

> ---
>  drivers/platform/chrome/cros_ec_sensorhub.c   | 80 +++++++++++--------
>  .../platform/chrome/cros_ec_sensorhub_ring.c  | 73 ++++++++++-------
>  .../linux/platform_data/cros_ec_sensorhub.h   |  1 +
>  3 files changed, 93 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/platform/chrome/cros_ec_sensorhub.c 
> b/drivers/platform/chrome/cros_ec_sensorhub.c
> index b7f2c00db5e1e..9c4af76a9956e 100644
> --- a/drivers/platform/chrome/cros_ec_sensorhub.c
> +++ b/drivers/platform/chrome/cros_ec_sensorhub.c
> @@ -52,28 +52,15 @@ static int cros_ec_sensorhub_register(struct device *dev,
>       int sensor_type[MOTIONSENSE_TYPE_MAX] = { 0 };
>       struct cros_ec_command *msg = sensorhub->msg;
>       struct cros_ec_dev *ec = sensorhub->ec;
> -     int ret, i, sensor_num;
> +     int ret, i;
>       char *name;
>  
> -     sensor_num = cros_ec_get_sensor_count(ec);
> -     if (sensor_num < 0) {
> -             dev_err(dev,
> -                     "Unable to retrieve sensor information (err:%d)\n",
> -                     sensor_num);
> -             return sensor_num;
> -     }
> -
> -     sensorhub->sensor_num = sensor_num;
> -     if (sensor_num == 0) {
> -             dev_err(dev, "Zero sensors reported.\n");
> -             return -EINVAL;
> -     }
>  
>       msg->version = 1;
>       msg->insize = sizeof(struct ec_response_motion_sense);
>       msg->outsize = sizeof(struct ec_params_motion_sense);
>  
> -     for (i = 0; i < sensor_num; i++) {
> +     for (i = 0; i < sensorhub->sensor_num; i++) {
>               sensorhub->params->cmd = MOTIONSENSE_CMD_INFO;
>               sensorhub->params->info.sensor_num = i;
>  
> @@ -140,8 +127,7 @@ static int cros_ec_sensorhub_probe(struct platform_device 
> *pdev)
>       struct cros_ec_dev *ec = dev_get_drvdata(dev->parent);
>       struct cros_ec_sensorhub *data;
>       struct cros_ec_command *msg;
> -     int ret;
> -     int i;
> +     int ret, i, sensor_num;
>  
>       msg = devm_kzalloc(dev, sizeof(struct cros_ec_command) +
>                          max((u16)sizeof(struct ec_params_motion_sense),
> @@ -166,10 +152,52 @@ static int cros_ec_sensorhub_probe(struct 
> platform_device *pdev)
>       dev_set_drvdata(dev, data);
>  
>       /* Check whether this EC is a sensor hub. */
> -     if (cros_ec_check_features(data->ec, EC_FEATURE_MOTION_SENSE)) {
> +     if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) {
> +             sensor_num = cros_ec_get_sensor_count(ec);
> +             if (sensor_num < 0) {
> +                     dev_err(dev,
> +                             "Unable to retrieve sensor information 
> (err:%d)\n",
> +                             sensor_num);
> +                     return sensor_num;
> +             }
> +             if (sensor_num == 0) {
> +                     dev_err(dev, "Zero sensors reported.\n");
> +                     return -EINVAL;
> +             }
> +             data->sensor_num = sensor_num;
> +
> +             /*
> +              * Prepare the ring handler before enumering the
> +              * sensors.
> +              */
> +             if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
> +                     ret = cros_ec_sensorhub_ring_allocate(data);
> +                     if (ret)
> +                             return ret;
> +             }
> +
> +             /* Enumerate the sensors.*/
>               ret = cros_ec_sensorhub_register(dev, data);
>               if (ret)
>                       return ret;
> +
> +             /*
> +              * When the EC does not have a FIFO, the sensors will query
> +              * their data themselves via sysfs or a software trigger.
> +              */
> +             if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
> +                     ret = cros_ec_sensorhub_ring_add(data);
> +                     if (ret)
> +                             return ret;
> +                     /*
> +                      * The msg and its data is not under the control of the
> +                      * ring handler.
> +                      */
> +                     return devm_add_action_or_reset(dev,
> +                                     cros_ec_sensorhub_ring_remove,
> +                                     data);
> +             }
> +
>       } else {
>               /*
>                * If the device has sensors but does not claim to
> @@ -184,22 +212,6 @@ static int cros_ec_sensorhub_probe(struct 
> platform_device *pdev)
>               }
>       }
>  
> -     /*
> -      * If the EC does not have a FIFO, the sensors will query their data
> -      * themselves via sysfs or a software trigger.
> -      */
> -     if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
> -             ret = cros_ec_sensorhub_ring_add(data);
> -             if (ret)
> -                     return ret;
> -             /*
> -              * The msg and its data is not under the control of the ring
> -              * handler.
> -              */
> -             return devm_add_action_or_reset(dev,
> -                                             cros_ec_sensorhub_ring_remove,
> -                                             data);
> -     }
>  
>       return 0;
>  }
> diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c 
> b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
> index c48e5b38a4417..24e48d96ed766 100644
> --- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c
> +++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c
> @@ -957,17 +957,15 @@ static int cros_ec_sensorhub_event(struct 
> notifier_block *nb,
>  }
>  
>  /**
> - * cros_ec_sensorhub_ring_add() - Add the FIFO functionality if the EC
> - *                             supports it.
> + * cros_ec_sensorhub_ring_allocate() - Prepare the FIFO functionality if the 
> EC
> + *                                  supports it.
>   *
>   * @sensorhub : Sensor Hub object.
>   *
>   * Return: 0 on success.
>   */
> -int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub)
> +int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub)
>  {
> -     struct cros_ec_dev *ec = sensorhub->ec;
> -     int ret;
>       int fifo_info_length =
>               sizeof(struct ec_response_motion_sense_fifo_info) +
>               sizeof(u16) * sensorhub->sensor_num;
> @@ -978,6 +976,49 @@ int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub 
> *sensorhub)
>       if (!sensorhub->fifo_info)
>               return -ENOMEM;
>  
> +     /*
> +      * Allocate the callback area based on the number of sensors.
> +      * Add one for the sensor ring.
> +      */
> +     sensorhub->push_data = devm_kcalloc(sensorhub->dev,
> +                     sensorhub->sensor_num,
> +                     sizeof(*sensorhub->push_data),
> +                     GFP_KERNEL);
> +     if (!sensorhub->push_data)
> +             return -ENOMEM;
> +
> +     sensorhub->tight_timestamps = cros_ec_check_features(
> +                     sensorhub->ec,
> +                     EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS);
> +
> +     if (sensorhub->tight_timestamps) {
> +             sensorhub->batch_state = devm_kcalloc(sensorhub->dev,
> +                             sensorhub->sensor_num,
> +                             sizeof(*sensorhub->batch_state),
> +                             GFP_KERNEL);
> +             if (!sensorhub->batch_state)
> +                     return -ENOMEM;
> +     }
> +
> +     return 0;
> +}
> +
> +/**
> + * cros_ec_sensorhub_ring_add() - Add the FIFO functionality if the EC
> + *                             supports it.
> + *
> + * @sensorhub : Sensor Hub object.
> + *
> + * Return: 0 on success.
> + */
> +int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub)
> +{
> +     struct cros_ec_dev *ec = sensorhub->ec;
> +     int ret;
> +     int fifo_info_length =
> +             sizeof(struct ec_response_motion_sense_fifo_info) +
> +             sizeof(u16) * sensorhub->sensor_num;
> +
>       /* Retrieve FIFO information */
>       sensorhub->msg->version = 2;
>       sensorhub->params->cmd = MOTIONSENSE_CMD_FIFO_INFO;
> @@ -998,31 +1039,9 @@ int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub 
> *sensorhub)
>       if (!sensorhub->ring)
>               return -ENOMEM;
>  
> -     /*
> -      * Allocate the callback area based on the number of sensors.
> -      */
> -     sensorhub->push_data = devm_kcalloc(
> -                     sensorhub->dev, sensorhub->sensor_num,
> -                     sizeof(*sensorhub->push_data),
> -                     GFP_KERNEL);
> -     if (!sensorhub->push_data)
> -             return -ENOMEM;
> -
>       sensorhub->fifo_timestamp[CROS_EC_SENSOR_LAST_TS] =
>               cros_ec_get_time_ns();
>  
> -     sensorhub->tight_timestamps = cros_ec_check_features(
> -                     ec, EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS);
> -
> -     if (sensorhub->tight_timestamps) {
> -             sensorhub->batch_state = devm_kcalloc(sensorhub->dev,
> -                             sensorhub->sensor_num,
> -                             sizeof(*sensorhub->batch_state),
> -                             GFP_KERNEL);
> -             if (!sensorhub->batch_state)
> -                     return -ENOMEM;
> -     }
> -
>       /* Register the notifier that will act as a top half interrupt. */
>       sensorhub->notifier.notifier_call = cros_ec_sensorhub_event;
>       ret = blocking_notifier_chain_register(&ec->ec_dev->event_notifier,
> diff --git a/include/linux/platform_data/cros_ec_sensorhub.h 
> b/include/linux/platform_data/cros_ec_sensorhub.h
> index c588be843f61b..0ecce6aa69d5e 100644
> --- a/include/linux/platform_data/cros_ec_sensorhub.h
> +++ b/include/linux/platform_data/cros_ec_sensorhub.h
> @@ -185,6 +185,7 @@ int cros_ec_sensorhub_register_push_data(struct 
> cros_ec_sensorhub *sensorhub,
>  void cros_ec_sensorhub_unregister_push_data(struct cros_ec_sensorhub 
> *sensorhub,
>                                           u8 sensor_num);
>  
> +int cros_ec_sensorhub_ring_allocate(struct cros_ec_sensorhub *sensorhub);
>  int cros_ec_sensorhub_ring_add(struct cros_ec_sensorhub *sensorhub);
>  void cros_ec_sensorhub_ring_remove(void *arg);
>  int cros_ec_sensorhub_ring_fifo_enable(struct cros_ec_sensorhub *sensorhub,
> 

Reply via email to