Merge 4.7-rc4 into staging-next
We want the fixes in here, and we can resolve a merge issue in drivers/iio/industrialio-trigger.c Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
@@ -56,31 +56,20 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
|
||||
struct iio_poll_func *pf = p;
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
s64 timestamp;
|
||||
|
||||
/* If we have a status register, check if this IRQ came from us */
|
||||
if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) {
|
||||
u8 status;
|
||||
|
||||
len = sdata->tf->read_byte(&sdata->tb, sdata->dev,
|
||||
sdata->sensor_settings->drdy_irq.addr_stat_drdy,
|
||||
&status);
|
||||
if (len < 0)
|
||||
dev_err(sdata->dev, "could not read channel status\n");
|
||||
|
||||
/*
|
||||
* If this was not caused by any channels on this sensor,
|
||||
* return IRQ_NONE
|
||||
*/
|
||||
if (!(status & (u8)indio_dev->active_scan_mask[0]))
|
||||
return IRQ_NONE;
|
||||
}
|
||||
/* If we do timetamping here, do it before reading the values */
|
||||
if (sdata->hw_irq_trigger)
|
||||
timestamp = sdata->hw_timestamp;
|
||||
else
|
||||
timestamp = iio_get_time_ns();
|
||||
|
||||
len = st_sensors_get_buffer_element(indio_dev, sdata->buffer_data);
|
||||
if (len < 0)
|
||||
goto st_sensors_get_buffer_element_error;
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, sdata->buffer_data,
|
||||
pf->timestamp);
|
||||
timestamp);
|
||||
|
||||
st_sensors_get_buffer_element_error:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
@@ -382,6 +382,11 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Disable DRDY, this might be still be enabled after reboot. */
|
||||
err = st_sensors_set_dataready_irq(indio_dev, false);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (sdata->current_fullscale) {
|
||||
err = st_sensors_set_fullscale(indio_dev,
|
||||
sdata->current_fullscale->num);
|
||||
@@ -443,6 +448,9 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
|
||||
else
|
||||
drdy_mask = sdata->sensor_settings->drdy_irq.mask_int2;
|
||||
|
||||
/* Flag to the poll function that the hardware trigger is in use */
|
||||
sdata->hw_irq_trigger = enable;
|
||||
|
||||
/* Enable/Disable the interrupt generator for data ready. */
|
||||
err = st_sensors_write_data_with_mask(indio_dev,
|
||||
sdata->sensor_settings->drdy_irq.addr,
|
||||
|
@@ -17,6 +17,73 @@
|
||||
#include <linux/iio/common/st_sensors.h>
|
||||
#include "st_sensors_core.h"
|
||||
|
||||
/**
|
||||
* st_sensors_irq_handler() - top half of the IRQ-based triggers
|
||||
* @irq: irq number
|
||||
* @p: private handler data
|
||||
*/
|
||||
irqreturn_t st_sensors_irq_handler(int irq, void *p)
|
||||
{
|
||||
struct iio_trigger *trig = p;
|
||||
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
|
||||
/* Get the time stamp as close in time as possible */
|
||||
sdata->hw_timestamp = iio_get_time_ns();
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* st_sensors_irq_thread() - bottom half of the IRQ-based triggers
|
||||
* @irq: irq number
|
||||
* @p: private handler data
|
||||
*/
|
||||
irqreturn_t st_sensors_irq_thread(int irq, void *p)
|
||||
{
|
||||
struct iio_trigger *trig = p;
|
||||
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If this trigger is backed by a hardware interrupt and we have a
|
||||
* status register, check if this IRQ came from us
|
||||
*/
|
||||
if (sdata->sensor_settings->drdy_irq.addr_stat_drdy) {
|
||||
u8 status;
|
||||
|
||||
ret = sdata->tf->read_byte(&sdata->tb, sdata->dev,
|
||||
sdata->sensor_settings->drdy_irq.addr_stat_drdy,
|
||||
&status);
|
||||
if (ret < 0) {
|
||||
dev_err(sdata->dev, "could not read channel status\n");
|
||||
goto out_poll;
|
||||
}
|
||||
/*
|
||||
* the lower bits of .active_scan_mask[0] is directly mapped
|
||||
* to the channels on the sensor: either bit 0 for
|
||||
* one-dimensional sensors, or e.g. x,y,z for accelerometers,
|
||||
* gyroscopes or magnetometers. No sensor use more than 3
|
||||
* channels, so cut the other status bits here.
|
||||
*/
|
||||
status &= 0x07;
|
||||
|
||||
/*
|
||||
* If this was not caused by any channels on this sensor,
|
||||
* return IRQ_NONE
|
||||
*/
|
||||
if (!indio_dev->active_scan_mask)
|
||||
return IRQ_NONE;
|
||||
if (!(status & (u8)indio_dev->active_scan_mask[0]))
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
out_poll:
|
||||
/* It's our IRQ: proceed to handle the register polling */
|
||||
iio_trigger_poll_chained(p);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
|
||||
const struct iio_trigger_ops *trigger_ops)
|
||||
{
|
||||
@@ -30,6 +97,10 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
iio_trigger_set_drvdata(sdata->trig, indio_dev);
|
||||
sdata->trig->ops = trigger_ops;
|
||||
sdata->trig->dev.parent = sdata->dev;
|
||||
|
||||
irq = sdata->get_irq_data_ready(indio_dev);
|
||||
irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
|
||||
/*
|
||||
@@ -77,9 +148,12 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
|
||||
sdata->sensor_settings->drdy_irq.addr_stat_drdy)
|
||||
irq_trig |= IRQF_SHARED;
|
||||
|
||||
err = request_threaded_irq(irq,
|
||||
iio_trigger_generic_data_rdy_poll,
|
||||
NULL,
|
||||
/* Let's create an interrupt thread masking the hard IRQ here */
|
||||
irq_trig |= IRQF_ONESHOT;
|
||||
|
||||
err = request_threaded_irq(sdata->get_irq_data_ready(indio_dev),
|
||||
st_sensors_irq_handler,
|
||||
st_sensors_irq_thread,
|
||||
irq_trig,
|
||||
sdata->trig->name,
|
||||
sdata->trig);
|
||||
@@ -88,10 +162,6 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
|
||||
goto iio_trigger_free;
|
||||
}
|
||||
|
||||
iio_trigger_set_drvdata(sdata->trig, indio_dev);
|
||||
sdata->trig->ops = trigger_ops;
|
||||
sdata->trig->dev.parent = sdata->dev;
|
||||
|
||||
err = iio_trigger_register(sdata->trig);
|
||||
if (err < 0) {
|
||||
dev_err(&indio_dev->dev, "failed to register iio trigger.\n");
|
||||
@@ -119,6 +189,18 @@ void st_sensors_deallocate_trigger(struct iio_dev *indio_dev)
|
||||
}
|
||||
EXPORT_SYMBOL(st_sensors_deallocate_trigger);
|
||||
|
||||
int st_sensors_validate_device(struct iio_trigger *trig,
|
||||
struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_dev *indio = iio_trigger_get_drvdata(trig);
|
||||
|
||||
if (indio != indio_dev)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(st_sensors_validate_device);
|
||||
|
||||
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
|
||||
MODULE_DESCRIPTION("STMicroelectronics ST-sensors trigger");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
Reference in New Issue
Block a user