forked from luck/tmp_suning_uos_patched
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (GNU/Linux) iQIcBAABAgAGBQJR/oKnAAoJEFSFNJnE9BaItqYP/0V7a+3mVr2mCGq0McyUmY+P jQJ6+jg6Vv0RKajOKadv150qgQwrmCwE2Zgev8dmdrTajd/Ww0PiowUgmDSmacnE L+Tl5YDCG2arcZs6QiuccSTbssH/U8JOraFkKtlAw3dObWzMagg5eFHOXmnduHEp aY5O0v0eLySF1/1HaVkPFZ6zvWQnUh9ylnijqgZTT2JtUifuy2oR4Ib806G3ObU/ gUJFN+FbUgbSKSy5GeBVWGEAG5YS8Io6GcWtCI5gzIlwfOoL6G0cCSueuTqD1/WZ R2uHi9irjNTmdysOlONvXRiKyZqPIFY2Th8DsfbrI5y5cm/hAXM0LeZLGmEosqKM qYqdA3AIVCaVRguyqtwO4q5t/taPS+D08TfnpiKr75JfB4BO6w9fm6RLSxeBtzoQ dAQhW/T4qooefDfe/x8Ol7AElVV5vNkJ82U2zoIOhWIcAHIFdUNGFI3Y4EAirEsh aFFQRaHCInwWtIEISlEvHWc3e1LbMXQajHuSU6UKvOrcI4d9NJSGDzNb6xyRIKSb zxeC8fxKLeJAtXj9iUrBBBn41cx5DZueGJzsuCtCUvApi/jujXWrxfDK0DaAodZ3 6anolfW59YfWuEaXDBa0Y041qG4NI/fOZbrd43sY+9Bg6ZlGq2jss0u9rvI2Xtn7 xhg2F75nFKKnv7JF7cRZ =U1lS -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
cefe8a32f2
@ -60,7 +60,6 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
|
||||
{
|
||||
unsigned int stepconfig;
|
||||
int i, steps;
|
||||
u32 step_en;
|
||||
|
||||
/*
|
||||
* There are 16 configurable steps and 8 analog input
|
||||
@ -86,8 +85,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
|
||||
adc_dev->channel_step[i] = 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[] = {
|
||||
@ -142,10 +140,22 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||
int i;
|
||||
unsigned int fifo1count, read;
|
||||
int i, map_val;
|
||||
unsigned int fifo1count, read, stepid;
|
||||
u32 step = UINT_MAX;
|
||||
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,
|
||||
@ -170,12 +180,16 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
|
||||
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
|
||||
for (i = 0; i < fifo1count; i++) {
|
||||
read = tiadc_readl(adc_dev, REG_FIFO1);
|
||||
if (read >> 16 == step) {
|
||||
*val = read & 0xfff;
|
||||
stepid = read & FIFOREAD_CHNLID_MASK;
|
||||
stepid = stepid >> 0x10;
|
||||
|
||||
if (stepid == map_val) {
|
||||
read = read & FIFOREAD_DATA_MASK;
|
||||
found = true;
|
||||
*val = read;
|
||||
}
|
||||
}
|
||||
am335x_tsc_se_update(adc_dev->mfd_tscadc);
|
||||
|
||||
if (found == false)
|
||||
return -EBUSY;
|
||||
return IIO_VAL_INT;
|
||||
|
@ -127,12 +127,17 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
|
||||
void iio_trigger_poll(struct iio_trigger *trig, s64 time)
|
||||
{
|
||||
int i;
|
||||
if (!trig->use_count)
|
||||
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
|
||||
if (trig->subirqs[i].enabled) {
|
||||
trig->use_count++;
|
||||
|
||||
if (!atomic_read(&trig->use_count)) {
|
||||
atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
|
||||
|
||||
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
|
||||
if (trig->subirqs[i].enabled)
|
||||
generic_handle_irq(trig->subirq_base + i);
|
||||
}
|
||||
else
|
||||
iio_trigger_notify_done(trig);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(iio_trigger_poll);
|
||||
|
||||
@ -146,19 +151,24 @@ EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
|
||||
void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
|
||||
{
|
||||
int i;
|
||||
if (!trig->use_count)
|
||||
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
|
||||
if (trig->subirqs[i].enabled) {
|
||||
trig->use_count++;
|
||||
|
||||
if (!atomic_read(&trig->use_count)) {
|
||||
atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
|
||||
|
||||
for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
|
||||
if (trig->subirqs[i].enabled)
|
||||
handle_nested_irq(trig->subirq_base + i);
|
||||
}
|
||||
else
|
||||
iio_trigger_notify_done(trig);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(iio_trigger_poll_chained);
|
||||
|
||||
void iio_trigger_notify_done(struct iio_trigger *trig)
|
||||
{
|
||||
trig->use_count--;
|
||||
if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable)
|
||||
if (atomic_dec_and_test(&trig->use_count) && trig->ops &&
|
||||
trig->ops->try_reenable)
|
||||
if (trig->ops->try_reenable(trig))
|
||||
/* Missed an interrupt so launch new poll now */
|
||||
iio_trigger_poll(trig, 0);
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#ifndef _IIO_TRIGGER_H_
|
||||
#define _IIO_TRIGGER_H_
|
||||
@ -61,7 +62,7 @@ struct iio_trigger {
|
||||
|
||||
struct list_head list;
|
||||
struct list_head alloc_list;
|
||||
int use_count;
|
||||
atomic_t use_count;
|
||||
|
||||
struct irq_chip subirq_chip;
|
||||
int subirq_base;
|
||||
|
@ -113,11 +113,27 @@
|
||||
#define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3)
|
||||
#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 MAX_CLK_DIV 7
|
||||
#define TOTAL_STEPS 16
|
||||
#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
|
||||
|
||||
struct ti_tscadc_dev {
|
||||
|
Loading…
Reference in New Issue
Block a user