Commit cefe8a32 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-fixes-for-3.11b' of...

Merge tag 'iio-fixes-for-3.11b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus

Jonathan writes:

Second round of IIO fixes for the 3.11 cycle.

1) Fix a long term race in the IIO trigger handling.
   This only effects cases where a single trigger is in use
   by multiple devices.
2) ti_am335x fix an issue with incorrect data due to reading before
   the sequencer is finished.
parents 02073798 b1451e54
...@@ -60,7 +60,6 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) ...@@ -60,7 +60,6 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
{ {
unsigned int stepconfig; unsigned int stepconfig;
int i, steps; int i, steps;
u32 step_en;
/* /*
* There are 16 configurable steps and 8 analog input * There are 16 configurable steps and 8 analog input
...@@ -86,8 +85,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) ...@@ -86,8 +85,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
adc_dev->channel_step[i] = steps; adc_dev->channel_step[i] = steps;
steps++; steps++;
} }
step_en = get_adc_step_mask(adc_dev);
am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
} }
static const char * const chan_name_ain[] = { static const char * const chan_name_ain[] = {
...@@ -142,10 +140,22 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, ...@@ -142,10 +140,22 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask) int *val, int *val2, long mask)
{ {
struct tiadc_device *adc_dev = iio_priv(indio_dev); struct tiadc_device *adc_dev = iio_priv(indio_dev);
int i; int i, map_val;
unsigned int fifo1count, read; unsigned int fifo1count, read, stepid;
u32 step = UINT_MAX; u32 step = UINT_MAX;
bool found = false; bool found = false;
u32 step_en;
unsigned long timeout = jiffies + usecs_to_jiffies
(IDLE_TIMEOUT * adc_dev->channels);
step_en = get_adc_step_mask(adc_dev);
am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
/* Wait for ADC sequencer to complete sampling */
while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
if (time_after(jiffies, timeout))
return -EAGAIN;
}
map_val = chan->channel + TOTAL_CHANNELS;
/* /*
* When the sub-system is first enabled, * When the sub-system is first enabled,
...@@ -170,12 +180,16 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, ...@@ -170,12 +180,16 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
for (i = 0; i < fifo1count; i++) { for (i = 0; i < fifo1count; i++) {
read = tiadc_readl(adc_dev, REG_FIFO1); read = tiadc_readl(adc_dev, REG_FIFO1);
if (read >> 16 == step) { stepid = read & FIFOREAD_CHNLID_MASK;
*val = read & 0xfff; stepid = stepid >> 0x10;
if (stepid == map_val) {
read = read & FIFOREAD_DATA_MASK;
found = true; found = true;
*val = read;
} }
} }
am335x_tsc_se_update(adc_dev->mfd_tscadc);
if (found == false) if (found == false)
return -EBUSY; return -EBUSY;
return IIO_VAL_INT; return IIO_VAL_INT;
......
...@@ -127,11 +127,16 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, ...@@ -127,11 +127,16 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
void iio_trigger_poll(struct iio_trigger *trig, s64 time) void iio_trigger_poll(struct iio_trigger *trig, s64 time)
{ {
int i; int i;
if (!trig->use_count)
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) if (!atomic_read(&trig->use_count)) {
if (trig->subirqs[i].enabled) { atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
trig->use_count++;
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
if (trig->subirqs[i].enabled)
generic_handle_irq(trig->subirq_base + i); generic_handle_irq(trig->subirq_base + i);
else
iio_trigger_notify_done(trig);
}
} }
} }
EXPORT_SYMBOL(iio_trigger_poll); EXPORT_SYMBOL(iio_trigger_poll);
...@@ -146,19 +151,24 @@ EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll); ...@@ -146,19 +151,24 @@ EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
{ {
int i; int i;
if (!trig->use_count)
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) if (!atomic_read(&trig->use_count)) {
if (trig->subirqs[i].enabled) { atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
trig->use_count++;
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
if (trig->subirqs[i].enabled)
handle_nested_irq(trig->subirq_base + i); handle_nested_irq(trig->subirq_base + i);
else
iio_trigger_notify_done(trig);
}
} }
} }
EXPORT_SYMBOL(iio_trigger_poll_chained); EXPORT_SYMBOL(iio_trigger_poll_chained);
void iio_trigger_notify_done(struct iio_trigger *trig) void iio_trigger_notify_done(struct iio_trigger *trig)
{ {
trig->use_count--; if (atomic_dec_and_test(&trig->use_count) && trig->ops &&
if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable) trig->ops->try_reenable)
if (trig->ops->try_reenable(trig)) if (trig->ops->try_reenable(trig))
/* Missed an interrupt so launch new poll now */ /* Missed an interrupt so launch new poll now */
iio_trigger_poll(trig, 0); iio_trigger_poll(trig, 0);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/atomic.h>
#ifndef _IIO_TRIGGER_H_ #ifndef _IIO_TRIGGER_H_
#define _IIO_TRIGGER_H_ #define _IIO_TRIGGER_H_
...@@ -61,7 +62,7 @@ struct iio_trigger { ...@@ -61,7 +62,7 @@ struct iio_trigger {
struct list_head list; struct list_head list;
struct list_head alloc_list; struct list_head alloc_list;
int use_count; atomic_t use_count;
struct irq_chip subirq_chip; struct irq_chip subirq_chip;
int subirq_base; int subirq_base;
......
...@@ -113,11 +113,27 @@ ...@@ -113,11 +113,27 @@
#define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3) #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3)
#define CNTRLREG_TSCENB BIT(7) #define CNTRLREG_TSCENB BIT(7)
/* FIFO READ Register */
#define FIFOREAD_DATA_MASK (0xfff << 0)
#define FIFOREAD_CHNLID_MASK (0xf << 16)
/* Sequencer Status */
#define SEQ_STATUS BIT(5)
#define ADC_CLK 3000000 #define ADC_CLK 3000000
#define MAX_CLK_DIV 7 #define MAX_CLK_DIV 7
#define TOTAL_STEPS 16 #define TOTAL_STEPS 16
#define TOTAL_CHANNELS 8 #define TOTAL_CHANNELS 8
/*
* ADC runs at 3MHz, and it takes
* 15 cycles to latch one data output.
* Hence the idle time for ADC to
* process one sample data would be
* around 5 micro seconds.
*/
#define IDLE_TIMEOUT 5 /* microsec */
#define TSCADC_CELLS 2 #define TSCADC_CELLS 2
struct ti_tscadc_dev { struct ti_tscadc_dev {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment