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:
Greg Kroah-Hartman
2016-06-20 08:25:44 -07:00
561 changed files with 5221 additions and 3344 deletions

View File

@@ -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);

View File

@@ -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,

View File

@@ -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");