diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-01 07:51:02 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-01 07:51:02 -0400 |
commit | dce5bdfe8fc1e3b49fa6fcf21e07bb12360e1b98 (patch) | |
tree | 0694ddd5dc9185aa5300c7c1ad32d8a6a128725e | |
parent | 3d8bbe243dc7418b4b2eadcbf5693887d076a521 (diff) | |
parent | 4ce7ca89d6e8eae9e201cd0e972ba323f33e2fb4 (diff) |
Merge tag 'iio-fixes-for-4.0d' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus
Jonathan writes:
IIO fixes for 4.0 set 4
A couple more IIO fixes.
* Fix check for HAS_IOMEM in the cc100001_adc driver to avoid build errors.
Rather curiously it was ORed with Regulator and clock support.
* vf610 driver was trying to use an ADC clock outside the possible
spec on some boards. The driver assumed a fixed clock speed previously
across all boards, but that is not true. This fix ensures that the
reported frequency is correct on all boards.
* The adis imu common code directly set the current trigger to the
driver supplied one. Unfortunately this didn't increase the use count
leading to a double free via a particular path of changing the trigger
then removing the driver.
-rw-r--r-- | drivers/iio/adc/Kconfig | 3 | ||||
-rw-r--r-- | drivers/iio/adc/vf610_adc.c | 91 | ||||
-rw-r--r-- | drivers/iio/imu/adis_trigger.c | 2 |
3 files changed, 64 insertions, 32 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 202daf889be2..46379b1fb25b 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -137,7 +137,8 @@ config AXP288_ADC | |||
137 | 137 | ||
138 | config CC10001_ADC | 138 | config CC10001_ADC |
139 | tristate "Cosmic Circuits 10001 ADC driver" | 139 | tristate "Cosmic Circuits 10001 ADC driver" |
140 | depends on HAS_IOMEM || HAVE_CLK || REGULATOR | 140 | depends on HAVE_CLK || REGULATOR |
141 | depends on HAS_IOMEM | ||
141 | select IIO_BUFFER | 142 | select IIO_BUFFER |
142 | select IIO_TRIGGERED_BUFFER | 143 | select IIO_TRIGGERED_BUFFER |
143 | help | 144 | help |
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 8ec353c01d98..e63b8e76d4c3 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c | |||
@@ -141,9 +141,13 @@ struct vf610_adc { | |||
141 | struct regulator *vref; | 141 | struct regulator *vref; |
142 | struct vf610_adc_feature adc_feature; | 142 | struct vf610_adc_feature adc_feature; |
143 | 143 | ||
144 | u32 sample_freq_avail[5]; | ||
145 | |||
144 | struct completion completion; | 146 | struct completion completion; |
145 | }; | 147 | }; |
146 | 148 | ||
149 | static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; | ||
150 | |||
147 | #define VF610_ADC_CHAN(_idx, _chan_type) { \ | 151 | #define VF610_ADC_CHAN(_idx, _chan_type) { \ |
148 | .type = (_chan_type), \ | 152 | .type = (_chan_type), \ |
149 | .indexed = 1, \ | 153 | .indexed = 1, \ |
@@ -180,35 +184,47 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = { | |||
180 | /* sentinel */ | 184 | /* sentinel */ |
181 | }; | 185 | }; |
182 | 186 | ||
183 | /* | 187 | static inline void vf610_adc_calculate_rates(struct vf610_adc *info) |
184 | * ADC sample frequency, unit is ADCK cycles. | 188 | { |
185 | * ADC clk source is ipg clock, which is the same as bus clock. | 189 | unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk); |
186 | * | 190 | int i; |
187 | * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder) | 191 | |
188 | * SFCAdder: fixed to 6 ADCK cycles | 192 | /* |
189 | * AverageNum: 1, 4, 8, 16, 32 samples for hardware average. | 193 | * Calculate ADC sample frequencies |
190 | * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode | 194 | * Sample time unit is ADCK cycles. ADCK clk source is ipg clock, |
191 | * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles | 195 | * which is the same as bus clock. |
192 | * | 196 | * |
193 | * By default, enable 12 bit resolution mode, clock source | 197 | * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder) |
194 | * set to ipg clock, So get below frequency group: | 198 | * SFCAdder: fixed to 6 ADCK cycles |
195 | */ | 199 | * AverageNum: 1, 4, 8, 16, 32 samples for hardware average. |
196 | static const u32 vf610_sample_freq_avail[5] = | 200 | * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode |
197 | {1941176, 559332, 286957, 145374, 73171}; | 201 | * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles |
202 | */ | ||
203 | adck_rate = ipg_rate / info->adc_feature.clk_div; | ||
204 | for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++) | ||
205 | info->sample_freq_avail[i] = | ||
206 | adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3)); | ||
207 | } | ||
198 | 208 | ||
199 | static inline void vf610_adc_cfg_init(struct vf610_adc *info) | 209 | static inline void vf610_adc_cfg_init(struct vf610_adc *info) |
200 | { | 210 | { |
211 | struct vf610_adc_feature *adc_feature = &info->adc_feature; | ||
212 | |||
201 | /* set default Configuration for ADC controller */ | 213 | /* set default Configuration for ADC controller */ |
202 | info->adc_feature.clk_sel = VF610_ADCIOC_BUSCLK_SET; | 214 | adc_feature->clk_sel = VF610_ADCIOC_BUSCLK_SET; |
203 | info->adc_feature.vol_ref = VF610_ADCIOC_VR_VREF_SET; | 215 | adc_feature->vol_ref = VF610_ADCIOC_VR_VREF_SET; |
216 | |||
217 | adc_feature->calibration = true; | ||
218 | adc_feature->ovwren = true; | ||
219 | |||
220 | adc_feature->res_mode = 12; | ||
221 | adc_feature->sample_rate = 1; | ||
222 | adc_feature->lpm = true; | ||
204 | 223 | ||
205 | info->adc_feature.calibration = true; | 224 | /* Use a save ADCK which is below 20MHz on all devices */ |
206 | info->adc_feature.ovwren = true; | 225 | adc_feature->clk_div = 8; |
207 | 226 | ||
208 | info->adc_feature.clk_div = 1; | 227 | vf610_adc_calculate_rates(info); |
209 | info->adc_feature.res_mode = 12; | ||
210 | info->adc_feature.sample_rate = 1; | ||
211 | info->adc_feature.lpm = true; | ||
212 | } | 228 | } |
213 | 229 | ||
214 | static void vf610_adc_cfg_post_set(struct vf610_adc *info) | 230 | static void vf610_adc_cfg_post_set(struct vf610_adc *info) |
@@ -290,12 +306,10 @@ static void vf610_adc_cfg_set(struct vf610_adc *info) | |||
290 | 306 | ||
291 | cfg_data = readl(info->regs + VF610_REG_ADC_CFG); | 307 | cfg_data = readl(info->regs + VF610_REG_ADC_CFG); |
292 | 308 | ||
293 | /* low power configuration */ | ||
294 | cfg_data &= ~VF610_ADC_ADLPC_EN; | 309 | cfg_data &= ~VF610_ADC_ADLPC_EN; |
295 | if (adc_feature->lpm) | 310 | if (adc_feature->lpm) |
296 | cfg_data |= VF610_ADC_ADLPC_EN; | 311 | cfg_data |= VF610_ADC_ADLPC_EN; |
297 | 312 | ||
298 | /* disable high speed */ | ||
299 | cfg_data &= ~VF610_ADC_ADHSC_EN; | 313 | cfg_data &= ~VF610_ADC_ADHSC_EN; |
300 | 314 | ||
301 | writel(cfg_data, info->regs + VF610_REG_ADC_CFG); | 315 | writel(cfg_data, info->regs + VF610_REG_ADC_CFG); |
@@ -435,10 +449,27 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id) | |||
435 | return IRQ_HANDLED; | 449 | return IRQ_HANDLED; |
436 | } | 450 | } |
437 | 451 | ||
438 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1941176, 559332, 286957, 145374, 73171"); | 452 | static ssize_t vf610_show_samp_freq_avail(struct device *dev, |
453 | struct device_attribute *attr, char *buf) | ||
454 | { | ||
455 | struct vf610_adc *info = iio_priv(dev_to_iio_dev(dev)); | ||
456 | size_t len = 0; | ||
457 | int i; | ||
458 | |||
459 | for (i = 0; i < ARRAY_SIZE(info->sample_freq_avail); i++) | ||
460 | len += scnprintf(buf + len, PAGE_SIZE - len, | ||
461 | "%u ", info->sample_freq_avail[i]); | ||
462 | |||
463 | /* replace trailing space by newline */ | ||
464 | buf[len - 1] = '\n'; | ||
465 | |||
466 | return len; | ||
467 | } | ||
468 | |||
469 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(vf610_show_samp_freq_avail); | ||
439 | 470 | ||
440 | static struct attribute *vf610_attributes[] = { | 471 | static struct attribute *vf610_attributes[] = { |
441 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | 472 | &iio_dev_attr_sampling_frequency_available.dev_attr.attr, |
442 | NULL | 473 | NULL |
443 | }; | 474 | }; |
444 | 475 | ||
@@ -502,7 +533,7 @@ static int vf610_read_raw(struct iio_dev *indio_dev, | |||
502 | return IIO_VAL_FRACTIONAL_LOG2; | 533 | return IIO_VAL_FRACTIONAL_LOG2; |
503 | 534 | ||
504 | case IIO_CHAN_INFO_SAMP_FREQ: | 535 | case IIO_CHAN_INFO_SAMP_FREQ: |
505 | *val = vf610_sample_freq_avail[info->adc_feature.sample_rate]; | 536 | *val = info->sample_freq_avail[info->adc_feature.sample_rate]; |
506 | *val2 = 0; | 537 | *val2 = 0; |
507 | return IIO_VAL_INT; | 538 | return IIO_VAL_INT; |
508 | 539 | ||
@@ -525,9 +556,9 @@ static int vf610_write_raw(struct iio_dev *indio_dev, | |||
525 | switch (mask) { | 556 | switch (mask) { |
526 | case IIO_CHAN_INFO_SAMP_FREQ: | 557 | case IIO_CHAN_INFO_SAMP_FREQ: |
527 | for (i = 0; | 558 | for (i = 0; |
528 | i < ARRAY_SIZE(vf610_sample_freq_avail); | 559 | i < ARRAY_SIZE(info->sample_freq_avail); |
529 | i++) | 560 | i++) |
530 | if (val == vf610_sample_freq_avail[i]) { | 561 | if (val == info->sample_freq_avail[i]) { |
531 | info->adc_feature.sample_rate = i; | 562 | info->adc_feature.sample_rate = i; |
532 | vf610_adc_sample_set(info); | 563 | vf610_adc_sample_set(info); |
533 | return 0; | 564 | return 0; |
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index e0017c22bb9c..f53e9a803a0e 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c | |||
@@ -60,7 +60,7 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) | |||
60 | iio_trigger_set_drvdata(adis->trig, adis); | 60 | iio_trigger_set_drvdata(adis->trig, adis); |
61 | ret = iio_trigger_register(adis->trig); | 61 | ret = iio_trigger_register(adis->trig); |
62 | 62 | ||
63 | indio_dev->trig = adis->trig; | 63 | indio_dev->trig = iio_trigger_get(adis->trig); |
64 | if (ret) | 64 | if (ret) |
65 | goto error_free_irq; | 65 | goto error_free_irq; |
66 | 66 | ||