Re: [PATCH] iio: accel: st_sensors: Support generic mounting matrix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 5/17/21 9:46 AM, Andy Shevchenko wrote:
> On Sat, May 15, 2021 at 6:17 AM Linus Walleij <linus.walleij@xxxxxxxxxx> wrote:
>>
>> The ST accelerators support a special type of quirky
>> mounting matrix found in ACPI systems, but not a generic
>> mounting matrix such as from the device tree.
>>
>> Augment the ACPI hack to be a bit more generic and
>> accept a mounting matrix from device properties.
>>
>> This makes it possible to fix orientation on the Ux500
>> HREF device.
> 
> I think this entire thread may be interesting to Hans, hence Cc him.

Thanks I'm fine with the suggested change, but I've some
review marks below (inline).

> 
> 
>> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
>> Cc: Denis Ciocca <denis.ciocca@xxxxxx>
>> Cc: Daniel Drake <drake@xxxxxxxxxxxx>
>> Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
>> ---
>>  drivers/iio/accel/st_accel_core.c | 51 ++++++++++++++++++++-----------
>>  1 file changed, 34 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
>> index 43c50167d220..cfbcf740e3cb 100644
>> --- a/drivers/iio/accel/st_accel_core.c
>> +++ b/drivers/iio/accel/st_accel_core.c
>> @@ -1069,26 +1069,25 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
>>  #define ST_ACCEL_TRIGGER_OPS NULL
>>  #endif
>>
>> -#ifdef CONFIG_ACPI
>>  static const struct iio_mount_matrix *
>> -get_mount_matrix(const struct iio_dev *indio_dev,
>> -                const struct iio_chan_spec *chan)
>> +st_accel_get_mount_matrix(const struct iio_dev *indio_dev,
>> +                         const struct iio_chan_spec *chan)
>>  {
>>         struct st_sensor_data *adata = iio_priv(indio_dev);
>>
>>         return adata->mount_matrix;
>>  }
>>
>> -static const struct iio_chan_spec_ext_info mount_matrix_ext_info[] = {
>> -       IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, get_mount_matrix),
>> +static const struct iio_chan_spec_ext_info st_accel_mount_matrix_ext_info[] = {
>> +       IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_accel_get_mount_matrix),
>>         { },
>>  };
>>
>> +#ifdef CONFIG_ACPI
>>  /* Read ST-specific _ONT orientation data from ACPI and generate an
>>   * appropriate mount matrix.
>>   */
>> -static int apply_acpi_orientation(struct iio_dev *indio_dev,
>> -                                 struct iio_chan_spec *channels)
>> +static int apply_acpi_orientation(struct iio_dev *indio_dev)
>>  {
>>         struct st_sensor_data *adata = iio_priv(indio_dev);
>>         struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
>> @@ -1207,22 +1206,20 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev,
>>                 }
>>         }
>>
>> -       /* Expose the mount matrix via ext_info */
>> -       for (i = 0; i < indio_dev->num_channels; i++)
>> -               channels[i].ext_info = mount_matrix_ext_info;
>> -
>>         ret = 0;
>>         dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n");
>>
>>  out:
>>         kfree(buffer.pointer);
>> +       dev_warn(&indio_dev->dev,
>> +                "failed to apply ACPI orientation data: %d\n", ret);
>> +

This path is also taken on a successful return, so the dev_warn needs
to be guarded by a "if (ret)" condition.

>>         return ret;
>>  }
>>  #else /* !CONFIG_ACPI */
>> -static int apply_acpi_orientation(struct iio_dev *indio_dev,
>> -                                 struct iio_chan_spec *channels)
>> +static int apply_acpi_orientation(struct iio_dev *indio_dev)
>>  {
>> -       return 0;
>> +       return -EINVAL;
>>  }
>>  #endif
>>
>> @@ -1251,6 +1248,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>>         struct iio_chan_spec *channels;
>>         size_t channels_size;
>>         int err;
>> +       int i;
>>
>>         indio_dev->modes = INDIO_DIRECT_MODE;
>>         indio_dev->info = &accel_info;
>> @@ -1275,9 +1273,28 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>>                 goto st_accel_power_off;
>>         }
>>
>> -       if (apply_acpi_orientation(indio_dev, channels))
>> -               dev_warn(&indio_dev->dev,
>> -                        "failed to apply ACPI orientation data: %d\n", err);
>> +       /* First try ACPI orientation then try the generic function */
>> +       err = apply_acpi_orientation(indio_dev);
>> +       if (err) {
>> +               adata->mount_matrix = devm_kmalloc(&indio_dev->dev,
>> +                                                  sizeof(*adata->mount_matrix),
>> +                                                  GFP_KERNEL);
>> +               if (!adata->mount_matrix) {
>> +                       err = -ENOMEM;
>> +                       goto st_accel_power_off;
>> +               }

So now we to this devm_kmalloc both in apply_acpi_orientation() if it succeeds
as well as here if apply_acpi_orientation() fails. It would be better to just
stop kmallocing it all together in both places and just embed the struct in adata,
iow make adata->mount_matrix be the actual iio_mount_matrix struct, rather then
a pointer to it.

This will allow removing the 2 devm_kmalloc calls + their error handling.

Regards,

Hans



>> +
>> +               err = iio_read_mount_matrix(adata->dev, "mount-matrix",
>> +                                           adata->mount_matrix);
>> +               if (err)
>> +                       goto st_accel_power_off;
>> +       }
>> +       /*
>> +        * We have at least an identity matrix, so expose the mount
>> +        * matrix via ext_info
>> +        */
>> +       for (i = 0; i < indio_dev->num_channels; i++)
>> +               channels[i].ext_info = st_accel_mount_matrix_ext_info;
>>
>>         indio_dev->channels = channels;
>>         adata->current_fullscale = &adata->sensor_settings->fs.fs_avl[0];
>> --
>> 2.31.1
>>
> 
> 




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux