Skip to content

Commit

Permalink
Merge tag 'iio-fixes-for-4.0a' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/jic23/iio into staging-linus

Jonathan writes:

First round of fixes for IIO in the 4.0 cycle. Note a followup
set dependent on patches in the recent merge windows will follow shortly.

* dht11 - fix a read off the end of an array, add some locking to prevent
          the read function being interrupted and make sure gpio/irq lines
	  are not enabled for irqs during output.
* iadc - timeout should be in jiffies not msecs
* mpu6050 - avoid a null id from ACPI emumeration being dereferenced.
* mxs-lradc - fix up some interaction issues between the touchscreen driver
              and iio driver.  Mostly about making sure that the adc driver
              only affects channels that are not being used for the
              touchscreen.
* ad2s1200 - sign extension fix for a result of c type promotion.
* adis16400 - sign extension fix for a result of c type promotion.
* mcp3422 - scale table was transposed.
* ad5686 - use _optional regulator get to avoid a dummy reg being allocate
           which would cause the driver to fail to initialize.
* gp2ap020a00f - select REGMAP_I2C
* si7020 - revert an incorrect cleanup up and then fix the issue that made
           that cleanup seem like a good idea.
  • Loading branch information
Greg Kroah-Hartman committed Feb 28, 2015
2 parents c517d83 + e01becb commit d582cb7
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 151 deletions.
17 changes: 4 additions & 13 deletions drivers/iio/adc/mcp3422.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,11 @@
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
}

/* LSB is in nV to eliminate floating point */
static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625};

/*
* scales calculated as:
* rates_to_lsb[sample_rate] / (1 << pga);
* pga is 1 for 0, 2
*/

static const int mcp3422_scales[4][4] = {
{ 1000000, 250000, 62500, 15625 },
{ 500000 , 125000, 31250, 7812 },
{ 250000 , 62500 , 15625, 3906 },
{ 125000 , 31250 , 7812 , 1953 } };
{ 1000000, 500000, 250000, 125000 },
{ 250000 , 125000, 62500 , 31250 },
{ 62500 , 31250 , 15625 , 7812 },
{ 15625 , 7812 , 3906 , 1953 } };

/* Constant msleep times for data acquisitions */
static const int mcp3422_read_times[4] = {
Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/adc/qcom-spmi-iadc.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data)
if (iadc->poll_eoc) {
ret = iadc_poll_wait_eoc(iadc, wait);
} else {
ret = wait_for_completion_timeout(&iadc->complete, wait);
ret = wait_for_completion_timeout(&iadc->complete,
usecs_to_jiffies(wait));
if (!ret)
ret = -ETIMEDOUT;
else
Expand Down
2 changes: 1 addition & 1 deletion drivers/iio/dac/ad5686.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static int ad5686_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);

st->reg = devm_regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get_optional(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
Expand Down
69 changes: 41 additions & 28 deletions drivers/iio/humidity/dht11.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
Expand All @@ -39,8 +40,12 @@

#define DHT11_DATA_VALID_TIME 2000000000 /* 2s in ns */

#define DHT11_EDGES_PREAMBLE 4
#define DHT11_EDGES_PREAMBLE 2
#define DHT11_BITS_PER_READ 40
/*
* Note that when reading the sensor actually 84 edges are detected, but
* since the last edge is not significant, we only store 83:
*/
#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1)

/* Data transmission timing (nano seconds) */
Expand All @@ -57,6 +62,7 @@ struct dht11 {
int irq;

struct completion completion;
struct mutex lock;

s64 timestamp;
int temperature;
Expand Down Expand Up @@ -88,7 +94,7 @@ static int dht11_decode(struct dht11 *dht11, int offset)
unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum;

/* Calculate timestamp resolution */
for (i = 0; i < dht11->num_edges; ++i) {
for (i = 1; i < dht11->num_edges; ++i) {
t = dht11->edges[i].ts - dht11->edges[i-1].ts;
if (t > 0 && t < timeres)
timeres = t;
Expand Down Expand Up @@ -138,13 +144,35 @@ static int dht11_decode(struct dht11 *dht11, int offset)
return 0;
}

/*
* IRQ handler called on GPIO edges
*/
static irqreturn_t dht11_handle_irq(int irq, void *data)
{
struct iio_dev *iio = data;
struct dht11 *dht11 = iio_priv(iio);

/* TODO: Consider making the handler safe for IRQ sharing */
if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
dht11->edges[dht11->num_edges].ts = iio_get_time_ns();
dht11->edges[dht11->num_edges++].value =
gpio_get_value(dht11->gpio);

if (dht11->num_edges >= DHT11_EDGES_PER_READ)
complete(&dht11->completion);
}

return IRQ_HANDLED;
}

static int dht11_read_raw(struct iio_dev *iio_dev,
const struct iio_chan_spec *chan,
int *val, int *val2, long m)
{
struct dht11 *dht11 = iio_priv(iio_dev);
int ret;

mutex_lock(&dht11->lock);
if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) {
reinit_completion(&dht11->completion);

Expand All @@ -157,8 +185,17 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
if (ret)
goto err;

ret = request_irq(dht11->irq, dht11_handle_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
iio_dev->name, iio_dev);
if (ret)
goto err;

ret = wait_for_completion_killable_timeout(&dht11->completion,
HZ);

free_irq(dht11->irq, iio_dev);

if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) {
dev_err(&iio_dev->dev,
"Only %d signal edges detected\n",
Expand All @@ -185,6 +222,7 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
ret = -EINVAL;
err:
dht11->num_edges = -1;
mutex_unlock(&dht11->lock);
return ret;
}

Expand All @@ -193,27 +231,6 @@ static const struct iio_info dht11_iio_info = {
.read_raw = dht11_read_raw,
};

/*
* IRQ handler called on GPIO edges
*/
static irqreturn_t dht11_handle_irq(int irq, void *data)
{
struct iio_dev *iio = data;
struct dht11 *dht11 = iio_priv(iio);

/* TODO: Consider making the handler safe for IRQ sharing */
if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
dht11->edges[dht11->num_edges].ts = iio_get_time_ns();
dht11->edges[dht11->num_edges++].value =
gpio_get_value(dht11->gpio);

if (dht11->num_edges >= DHT11_EDGES_PER_READ)
complete(&dht11->completion);
}

return IRQ_HANDLED;
}

static const struct iio_chan_spec dht11_chan_spec[] = {
{ .type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), },
Expand Down Expand Up @@ -256,18 +273,14 @@ static int dht11_probe(struct platform_device *pdev)
dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio);
return -EINVAL;
}
ret = devm_request_irq(dev, dht11->irq, dht11_handle_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
pdev->name, iio);
if (ret)
return ret;

dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1;
dht11->num_edges = -1;

platform_set_drvdata(pdev, iio);

init_completion(&dht11->completion);
mutex_init(&dht11->lock);
iio->name = pdev->name;
iio->dev.parent = &pdev->dev;
iio->info = &dht11_iio_info;
Expand Down
6 changes: 3 additions & 3 deletions drivers/iio/humidity/si7020.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ static int si7020_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
struct i2c_client *client = iio_priv(indio_dev);
struct i2c_client **client = iio_priv(indio_dev);
int ret;

switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = i2c_smbus_read_word_data(client,
ret = i2c_smbus_read_word_data(*client,
chan->type == IIO_TEMP ?
SI7020CMD_TEMP_HOLD :
SI7020CMD_RH_HOLD);
Expand Down Expand Up @@ -126,7 +126,7 @@ static int si7020_probe(struct i2c_client *client,
/* Wait the maximum power-up time after software reset. */
msleep(15);

indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*client));
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;

Expand Down
3 changes: 2 additions & 1 deletion drivers/iio/imu/adis16400_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/bitops.h>

#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
Expand Down Expand Up @@ -414,7 +415,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
mutex_unlock(&indio_dev->mlock);
if (ret)
return ret;
val16 = ((val16 & 0xFFF) << 4) >> 4;
val16 = sign_extend32(val16, 11);
*val = val16;
return IIO_VAL_INT;
case IIO_CHAN_INFO_OFFSET:
Expand Down
6 changes: 5 additions & 1 deletion drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,11 @@ static int inv_mpu_probe(struct i2c_client *client,

i2c_set_clientdata(client, indio_dev);
indio_dev->dev.parent = &client->dev;
indio_dev->name = id->name;
/* id will be NULL when enumerated via ACPI */
if (id)
indio_dev->name = (char *)id->name;
else
indio_dev->name = (char *)dev_name(&client->dev);
indio_dev->channels = inv_mpu_channels;
indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);

Expand Down
1 change: 1 addition & 0 deletions drivers/iio/light/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ config CM36651
config GP2AP020A00F
tristate "Sharp GP2AP020A00F Proximity/ALS sensor"
depends on I2C
select REGMAP_I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IRQ_WORK
Expand Down
Loading

0 comments on commit d582cb7

Please sign in to comment.