diff options
Diffstat (limited to 'drivers/iio/adc/ti_am335x_adc.c')
| -rw-r--r-- | drivers/iio/adc/ti_am335x_adc.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c index 8a368756881b..c3cfacca2541 100644 --- a/drivers/iio/adc/ti_am335x_adc.c +++ b/drivers/iio/adc/ti_am335x_adc.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | 32 | ||
| 33 | struct tiadc_device { | 33 | struct tiadc_device { |
| 34 | struct ti_tscadc_dev *mfd_tscadc; | 34 | struct ti_tscadc_dev *mfd_tscadc; |
| 35 | struct mutex fifo1_lock; /* to protect fifo access */ | ||
| 35 | int channels; | 36 | int channels; |
| 36 | u8 channel_line[8]; | 37 | u8 channel_line[8]; |
| 37 | u8 channel_step[8]; | 38 | u8 channel_step[8]; |
| @@ -359,6 +360,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
| 359 | int *val, int *val2, long mask) | 360 | int *val, int *val2, long mask) |
| 360 | { | 361 | { |
| 361 | struct tiadc_device *adc_dev = iio_priv(indio_dev); | 362 | struct tiadc_device *adc_dev = iio_priv(indio_dev); |
| 363 | int ret = IIO_VAL_INT; | ||
| 362 | int i, map_val; | 364 | int i, map_val; |
| 363 | unsigned int fifo1count, read, stepid; | 365 | unsigned int fifo1count, read, stepid; |
| 364 | bool found = false; | 366 | bool found = false; |
| @@ -372,13 +374,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
| 372 | if (!step_en) | 374 | if (!step_en) |
| 373 | return -EINVAL; | 375 | return -EINVAL; |
| 374 | 376 | ||
| 377 | mutex_lock(&adc_dev->fifo1_lock); | ||
| 375 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); | 378 | fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); |
| 376 | while (fifo1count--) | 379 | while (fifo1count--) |
| 377 | tiadc_readl(adc_dev, REG_FIFO1); | 380 | tiadc_readl(adc_dev, REG_FIFO1); |
| 378 | 381 | ||
| 379 | am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en); | 382 | am335x_tsc_se_set_once(adc_dev->mfd_tscadc, step_en); |
| 380 | 383 | ||
| 381 | timeout = jiffies + usecs_to_jiffies | 384 | timeout = jiffies + msecs_to_jiffies |
| 382 | (IDLE_TIMEOUT * adc_dev->channels); | 385 | (IDLE_TIMEOUT * adc_dev->channels); |
| 383 | /* Wait for Fifo threshold interrupt */ | 386 | /* Wait for Fifo threshold interrupt */ |
| 384 | while (1) { | 387 | while (1) { |
| @@ -388,7 +391,8 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
| 388 | 391 | ||
| 389 | if (time_after(jiffies, timeout)) { | 392 | if (time_after(jiffies, timeout)) { |
| 390 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); | 393 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); |
| 391 | return -EAGAIN; | 394 | ret = -EAGAIN; |
| 395 | goto err_unlock; | ||
| 392 | } | 396 | } |
| 393 | } | 397 | } |
| 394 | map_val = adc_dev->channel_step[chan->scan_index]; | 398 | map_val = adc_dev->channel_step[chan->scan_index]; |
| @@ -414,8 +418,11 @@ static int tiadc_read_raw(struct iio_dev *indio_dev, | |||
| 414 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); | 418 | am335x_tsc_se_adc_done(adc_dev->mfd_tscadc); |
| 415 | 419 | ||
| 416 | if (found == false) | 420 | if (found == false) |
| 417 | return -EBUSY; | 421 | ret = -EBUSY; |
| 418 | return IIO_VAL_INT; | 422 | |
| 423 | err_unlock: | ||
| 424 | mutex_unlock(&adc_dev->fifo1_lock); | ||
| 425 | return ret; | ||
| 419 | } | 426 | } |
| 420 | 427 | ||
| 421 | static const struct iio_info tiadc_info = { | 428 | static const struct iio_info tiadc_info = { |
| @@ -483,6 +490,7 @@ static int tiadc_probe(struct platform_device *pdev) | |||
| 483 | 490 | ||
| 484 | tiadc_step_config(indio_dev); | 491 | tiadc_step_config(indio_dev); |
| 485 | tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD); | 492 | tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD); |
| 493 | mutex_init(&adc_dev->fifo1_lock); | ||
| 486 | 494 | ||
| 487 | err = tiadc_channel_init(indio_dev, adc_dev->channels); | 495 | err = tiadc_channel_init(indio_dev, adc_dev->channels); |
| 488 | if (err < 0) | 496 | if (err < 0) |
