Re: [PATCH 1/2] iio: bmi160: Support hardware fifo

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

 



On 09/11/16 17:16, Marcin Niestroj wrote:
> On 09.11.2016 15:16, Marcin Niestroj wrote:
>> Hi,
>> Thanks for review, below are my comments.
>>
>> On 03.11.2016 13:09, Peter Meerwald-Stadler wrote:
>>>
>>>> This patch was developed primarily based on bmc150_accel hardware fifo
>>>> implementation.
>>>
>>> parts of the patch are cleanup and bugfixing; should be separate?
>>>
>>> more comments below
>>>
>>>> IRQ handler was added, which for now is responsible only for handling
>>>> watermark interrupts. The BMI160 chip has two interrupt outputs. By
>>>> default INT is considered to be connected. If INT2 is used instead, the
>>>> interrupt-names device-tree property can be used to specify that.
>>>>
>>>> Signed-off-by: Marcin Niestroj <m.niestroj@xxxxxxxxxxxxxxxx>
> 
> <snip>
> 
>>>> @@ -574,8 +1114,11 @@ int bmi160_core_probe(struct device *dev,
>>>> struct regmap *regmap,
>>>>
>>>>      data = iio_priv(indio_dev);
>>>>      dev_set_drvdata(dev, indio_dev);
>>>> +    data->irq = irq;
>>>>      data->regmap = regmap;
>>>>
>>>> +    mutex_init(&data->mutex);
>>>> +
>>>>      ret = bmi160_chip_init(data, use_spi);
>>>>      if (ret < 0)
>>>>          return ret;
>>>> @@ -591,10 +1134,50 @@ int bmi160_core_probe(struct device *dev,
>>>> struct regmap *regmap,
>>>>      indio_dev->info = &bmi160_info;
>>>>
>>>>      ret = iio_triggered_buffer_setup(indio_dev, NULL,
>>>> -                     bmi160_trigger_handler, NULL);
>>>> +                     bmi160_trigger_handler,
>>>> +                     &bmi160_buffer_ops);
>>>>      if (ret < 0)
>>>>          goto uninit;
>>>>
>>>> +    if (data->irq > 0) {
>>>> +        /* Check which interrupt pin is connected to our board */
>>>> +        irq2 = of_irq_get_byname(dev->of_node, "INT2");
>>>> +        if (irq2 == data->irq) {
>>>> +            dev_dbg(dev, "Using interrupt line INT2\n");
>>>> +            data->irq_data = &bmi160_irq2_data;
>>>> +        } else {
>>>> +            dev_dbg(dev, "Using interrupt line INT1\n");
>>>> +            data->irq_data = &bmi160_irq1_data;
>>>> +        }
>>>> +
>>>> +        ret = devm_request_threaded_irq(dev,
>>>> +                        data->irq,
>>>> +                        bmi160_irq_handler,
>>>> +                        bmi160_irq_thread_handler,
>>>> +                        IRQF_ONESHOT,
>>>> +                        BMI160_IRQ_NAME,
>>>> +                        indio_dev);
>>>> +        if (ret)
>>>> +            return ret;
> 
> I just noticed, that there should be a "goto buffer_cleanup" instead.
> 
>>>> +
>>>> +        ret = bmi160_enable_irq(data);
>>>> +        if (ret < 0)
>>>> +            goto buffer_cleanup;
>>>> +
>>>> +        if (block_supported) {
>>>> +            indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
>>>> +            indio_dev->info = &bmi160_info_fifo;
>>>> +            indio_dev->buffer->attrs = bmi160_fifo_attributes;
>>>> +            data->fifo_buffer = devm_kmalloc(dev,
>>>> +                            BMI160_FIFO_LENGTH,
>>>> +                            GFP_KERNEL);
>>>> +            if (!data->fifo_buffer) {
>>>> +                ret = -ENOMEM;
>>>
>>> need to disable irq on failure?
>>
>> Yes, I missed that.
> 
> I am just wondering now if it is really neccessary. bmi160_enable_irq()
> is just enabling IRQ output on INT1 or INT2 depending on device-tree.
> This alone will not trigger interrupts, as all should be masked at this
> stage.
You should always unwind everything in error paths as it makes them
'obviously' correct rather than subject to subtle bugs.
> 
>>
>>>
>>>> +                goto buffer_cleanup;
>>>> +            }
>>>> +        }
>>>> +    }
>>>> +
>>>>      ret = iio_device_register(indio_dev);
>>>>      if (ret < 0)
>>>>          goto buffer_cleanup;
>>>> diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c
>>>> b/drivers/iio/imu/bmi160/bmi160_i2c.c
>>>> index 07a179d..aa63f89 100644
>>>> --- a/drivers/iio/imu/bmi160/bmi160_i2c.c
>>>> +++ b/drivers/iio/imu/bmi160/bmi160_i2c.c
>>>> @@ -23,6 +23,10 @@ static int bmi160_i2c_probe(struct i2c_client
>>>> *client,
>>>>  {
>>>>      struct regmap *regmap;
>>>>      const char *name = NULL;
>>>> +    bool block_supported =
>>>> +        i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
>>>> +        i2c_check_functionality(client->adapter,
>>>> +                    I2C_FUNC_SMBUS_READ_I2C_BLOCK);
>>>>
>>>>      regmap = devm_regmap_init_i2c(client, &bmi160_regmap_config);
>>>>      if (IS_ERR(regmap)) {
>>>> @@ -34,7 +38,8 @@ static int bmi160_i2c_probe(struct i2c_client *client,
>>>>      if (id)
>>>>          name = id->name;
>>>>
>>>> -    return bmi160_core_probe(&client->dev, regmap, name, false);
>>>> +    return bmi160_core_probe(&client->dev, regmap, name, client->irq,
>>>> +                false, block_supported);
>>>>  }
>>>>
>>>>  static int bmi160_i2c_remove(struct i2c_client *client)
>>>> diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c
>>>> b/drivers/iio/imu/bmi160/bmi160_spi.c
>>>> index 1ec8b12..9b57fbe 100644
>>>> --- a/drivers/iio/imu/bmi160/bmi160_spi.c
>>>> +++ b/drivers/iio/imu/bmi160/bmi160_spi.c
>>>> @@ -25,7 +25,8 @@ static int bmi160_spi_probe(struct spi_device *spi)
>>>>              (int)PTR_ERR(regmap));
>>>>          return PTR_ERR(regmap);
>>>>      }
>>>> -    return bmi160_core_probe(&spi->dev, regmap, id->name, true);
>>>> +    return bmi160_core_probe(&spi->dev, regmap, id->name, spi->irq,
>>>> +                true, true);
>>>>  }
>>>>
>>>>  static int bmi160_spi_remove(struct spi_device *spi)
>>>>
>>>
>>
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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