diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-10 12:00:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-10 12:00:51 -0400 |
commit | 8ae3f1d09566038606a18576604ecc957a935c48 (patch) | |
tree | 428a087efd8596ec38c2cf9af557eac97d887353 | |
parent | e6e8ac441cd2c1fed16f1864b170d9d471aeb7fe (diff) | |
parent | cefe8a32f2a5887246ed250115e34bee6ecc8d61 (diff) |
Merge tag 'staging-3.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver fixes from Greg KH:
"Here are 3 small fixes for staging/IIO drivers for 3.11-rc5. Nothing
huge, two IIO driver fixes, and a zcache fix. All of these have been
in linux-next for a while"
* tag 'staging-3.11-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
staging: zcache: fix "zcache=" kernel parameter
iio: ti_am335x_adc: Fix wrong samples received on 1st read
iio:trigger: Fix use_count race condition
-rw-r--r-- | drivers/iio/adc/ti_am335x_adc.c | 30 | ||||
-rw-r--r-- | drivers/iio/industrialio-trigger.c | 34 | ||||
-rw-r--r-- | drivers/staging/zcache/zcache-main.c | 6 | ||||
-rw-r--r-- | include/linux/iio/trigger.h | 3 | ||||
-rw-r--r-- | include/linux/mfd/ti_am335x_tscadc.h | 16 |
5 files changed, 66 insertions, 23 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 0ad208a69c29..3ceac3e91dde 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c | |||
@@ -60,7 +60,6 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) | |||
60 | { | 60 | { |
61 | unsigned int stepconfig; | 61 | unsigned int stepconfig; |
62 | int i, steps; | 62 | int i, steps; |
63 | u32 step_en; | ||
64 | 63 | ||
65 | /* | 64 | /* |
66 | * There are 16 configurable steps and 8 analog input | 65 | * There are 16 configurable steps and 8 analog input |
@@ -86,8 +85,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev) | |||
86 | adc_dev->channel_step[i] = steps; | 85 | adc_dev->channel_step[i] = steps; |
87 | steps++; | 86 | steps++; |
88 | } | 87 | } |
89 | step_en = get_adc_step_mask(adc_dev); | 88 | |
90 | am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); | ||
91 | } | 89 | } |
92 | 90 | ||
93 | static const char * const chan_name_ain[] = { | 91 | static const char * const chan_name_ain[] = { |
@@ -142,10 +140,22 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
142 | int *val, int *val2, long mask) | 140 | int *val, int *val2, long mask) |
143 | { | 141 | { |
144 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | 142 | struct tiadc_device *adc_dev = iio_priv(indio_dev); |
145 | int i; | 143 | int i, map_val; |
146 | unsigned int fifo1count, read; | 144 | unsigned int fifo1count, read, stepid; |
147 | u32 step = UINT_MAX; | 145 | u32 step = UINT_MAX; |
148 | bool found = false; | 146 | bool found = false; |
147 | u32 step_en; | ||
148 | unsigned long timeout = jiffies + usecs_to_jiffies | ||
149 | (IDLE_TIMEOUT * adc_dev->channels); | ||
150 | step_en = get_adc_step_mask(adc_dev); | ||
151 | am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); | ||
152 | |||
153 | /* Wait for ADC sequencer to complete sampling */ | ||
154 | while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) { | ||
155 | if (time_after(jiffies, timeout)) | ||
156 | return -EAGAIN; | ||
157 | } | ||
158 | map_val = chan->channel + TOTAL_CHANNELS; | ||
149 | 159 | ||
150 | /* | 160 | /* |
151 | * When the sub-system is first enabled, | 161 | * When the sub-system is first enabled, |
@@ -170,12 +180,16 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
170 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); | 180 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); |
171 | for (i = 0; i < fifo1count; i++) { | 181 | for (i = 0; i < fifo1count; i++) { |
172 | read = tiadc_readl(adc_dev, REG_FIFO1); | 182 | read = tiadc_readl(adc_dev, REG_FIFO1); |
173 | if (read >> 16 == step) { | 183 | stepid = read & FIFOREAD_CHNLID_MASK; |
174 | *val = read & 0xfff; | 184 | stepid = stepid >> 0x10; |
185 | |||
186 | if (stepid == map_val) { | ||
187 | read = read & FIFOREAD_DATA_MASK; | ||
175 | found = true; | 188 | found = true; |
189 | *val = read; | ||
176 | } | 190 | } |
177 | } | 191 | } |
178 | am335x_tsc_se_update(adc_dev->mfd_tscadc); | 192 | |
179 | if (found == false) | 193 | if (found == false) |
180 | return -EBUSY; | 194 | return -EBUSY; |
181 | return IIO_VAL_INT; | 195 | return IIO_VAL_INT; |
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index ea8a4146620d..0dd9bb873130 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c | |||
@@ -127,12 +127,17 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, | |||
127 | void iio_trigger_poll(struct iio_trigger *trig, s64 time) | 127 | void iio_trigger_poll(struct iio_trigger *trig, s64 time) |
128 | { | 128 | { |
129 | int i; | 129 | int i; |
130 | if (!trig->use_count) | 130 | |
131 | for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) | 131 | if (!atomic_read(&trig->use_count)) { |
132 | if (trig->subirqs[i].enabled) { | 132 | atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER); |
133 | trig->use_count++; | 133 | |
134 | for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { | ||
135 | if (trig->subirqs[i].enabled) | ||
134 | generic_handle_irq(trig->subirq_base + i); | 136 | generic_handle_irq(trig->subirq_base + i); |
135 | } | 137 | else |
138 | iio_trigger_notify_done(trig); | ||
139 | } | ||
140 | } | ||
136 | } | 141 | } |
137 | EXPORT_SYMBOL(iio_trigger_poll); | 142 | EXPORT_SYMBOL(iio_trigger_poll); |
138 | 143 | ||
@@ -146,19 +151,24 @@ EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll); | |||
146 | void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) | 151 | void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) |
147 | { | 152 | { |
148 | int i; | 153 | int i; |
149 | if (!trig->use_count) | 154 | |
150 | for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) | 155 | if (!atomic_read(&trig->use_count)) { |
151 | if (trig->subirqs[i].enabled) { | 156 | atomic_set(&trig->use_count, CONFIG_IIO_CONSUMERS_PER_TRIGGER); |
152 | trig->use_count++; | 157 | |
158 | for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { | ||
159 | if (trig->subirqs[i].enabled) | ||
153 | handle_nested_irq(trig->subirq_base + i); | 160 | handle_nested_irq(trig->subirq_base + i); |
154 | } | 161 | else |
162 | iio_trigger_notify_done(trig); | ||
163 | } | ||
164 | } | ||
155 | } | 165 | } |
156 | EXPORT_SYMBOL(iio_trigger_poll_chained); | 166 | EXPORT_SYMBOL(iio_trigger_poll_chained); |
157 | 167 | ||
158 | void iio_trigger_notify_done(struct iio_trigger *trig) | 168 | void iio_trigger_notify_done(struct iio_trigger *trig) |
159 | { | 169 | { |
160 | trig->use_count--; | 170 | if (atomic_dec_and_test(&trig->use_count) && trig->ops && |
161 | if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable) | 171 | trig->ops->try_reenable) |
162 | if (trig->ops->try_reenable(trig)) | 172 | if (trig->ops->try_reenable(trig)) |
163 | /* Missed an interrupt so launch new poll now */ | 173 | /* Missed an interrupt so launch new poll now */ |
164 | iio_trigger_poll(trig, 0); | 174 | iio_trigger_poll(trig, 0); |
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index dcceed29d31a..81972fa47beb 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c | |||
@@ -1811,10 +1811,12 @@ static int zcache_comp_init(void) | |||
1811 | #else | 1811 | #else |
1812 | if (*zcache_comp_name != '\0') { | 1812 | if (*zcache_comp_name != '\0') { |
1813 | ret = crypto_has_comp(zcache_comp_name, 0, 0); | 1813 | ret = crypto_has_comp(zcache_comp_name, 0, 0); |
1814 | if (!ret) | 1814 | if (!ret) { |
1815 | pr_info("zcache: %s not supported\n", | 1815 | pr_info("zcache: %s not supported\n", |
1816 | zcache_comp_name); | 1816 | zcache_comp_name); |
1817 | goto out; | 1817 | ret = 1; |
1818 | goto out; | ||
1819 | } | ||
1818 | } | 1820 | } |
1819 | if (!ret) | 1821 | if (!ret) |
1820 | strcpy(zcache_comp_name, "lzo"); | 1822 | strcpy(zcache_comp_name, "lzo"); |
diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index 3869c525b052..369cf2cd5144 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/atomic.h> | ||
11 | 12 | ||
12 | #ifndef _IIO_TRIGGER_H_ | 13 | #ifndef _IIO_TRIGGER_H_ |
13 | #define _IIO_TRIGGER_H_ | 14 | #define _IIO_TRIGGER_H_ |
@@ -61,7 +62,7 @@ struct iio_trigger { | |||
61 | 62 | ||
62 | struct list_head list; | 63 | struct list_head list; |
63 | struct list_head alloc_list; | 64 | struct list_head alloc_list; |
64 | int use_count; | 65 | atomic_t use_count; |
65 | 66 | ||
66 | struct irq_chip subirq_chip; | 67 | struct irq_chip subirq_chip; |
67 | int subirq_base; | 68 | int subirq_base; |
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h index 8d73fe29796a..db1791bb997a 100644 --- a/include/linux/mfd/ti_am335x_tscadc.h +++ b/include/linux/mfd/ti_am335x_tscadc.h | |||
@@ -113,11 +113,27 @@ | |||
113 | #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3) | 113 | #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3) |
114 | #define CNTRLREG_TSCENB BIT(7) | 114 | #define CNTRLREG_TSCENB BIT(7) |
115 | 115 | ||
116 | /* FIFO READ Register */ | ||
117 | #define FIFOREAD_DATA_MASK (0xfff << 0) | ||
118 | #define FIFOREAD_CHNLID_MASK (0xf << 16) | ||
119 | |||
120 | /* Sequencer Status */ | ||
121 | #define SEQ_STATUS BIT(5) | ||
122 | |||
116 | #define ADC_CLK 3000000 | 123 | #define ADC_CLK 3000000 |
117 | #define MAX_CLK_DIV 7 | 124 | #define MAX_CLK_DIV 7 |
118 | #define TOTAL_STEPS 16 | 125 | #define TOTAL_STEPS 16 |
119 | #define TOTAL_CHANNELS 8 | 126 | #define TOTAL_CHANNELS 8 |
120 | 127 | ||
128 | /* | ||
129 | * ADC runs at 3MHz, and it takes | ||
130 | * 15 cycles to latch one data output. | ||
131 | * Hence the idle time for ADC to | ||
132 | * process one sample data would be | ||
133 | * around 5 micro seconds. | ||
134 | */ | ||
135 | #define IDLE_TIMEOUT 5 /* microsec */ | ||
136 | |||
121 | #define TSCADC_CELLS 2 | 137 | #define TSCADC_CELLS 2 |
122 | 138 | ||
123 | struct ti_tscadc_dev { | 139 | struct ti_tscadc_dev { |