Commit 0bd39455 authored by Shreeya Patel's avatar Shreeya Patel Committed by Jonathan Cameron

Staging: iio: ade7758: Expand buf_lock to cover both buffer and state protection

iio_dev->mlock is to be used only by the IIO core for protecting
device mode changes between INDIO_DIRECT and INDIO_BUFFER.

This patch replaces the use of mlock with the already established
buf_lock mutex.

Introducing 'unlocked' forms of read and write registers. The
read/write frequency functions now require buf_lock to be held.
That's not obvious so avoid this but moving the locking inside
the functions where it is then clear that they are taking the
unlocked forms of the register read/write.

It isn't readily apparent that write frequency function requires
the locks to be taken, so move it inside the function to where it
is required to protect.

Also, the read raw does not require iio_dev->mlock for
reads. It can run concurrently as resource protection is handled
by buf_lock in read register.
Signed-off-by: default avatarShreeya Patel <shreeya.patel23498@gmail.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent c87742ab
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
* @trig: data ready trigger registered with iio * @trig: data ready trigger registered with iio
* @tx: transmit buffer * @tx: transmit buffer
* @rx: receive buffer * @rx: receive buffer
* @buf_lock: mutex to protect tx and rx * @buf_lock: mutex to protect tx, rx, read and write frequency
**/ **/
struct ade7758_state { struct ade7758_state {
struct spi_device *us; struct spi_device *us;
......
...@@ -24,17 +24,25 @@ ...@@ -24,17 +24,25 @@
#include "meter.h" #include "meter.h"
#include "ade7758.h" #include "ade7758.h"
int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) static int __ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
{ {
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev); struct ade7758_state *st = iio_priv(indio_dev);
mutex_lock(&st->buf_lock);
st->tx[0] = ADE7758_WRITE_REG(reg_address); st->tx[0] = ADE7758_WRITE_REG(reg_address);
st->tx[1] = val; st->tx[1] = val;
ret = spi_write(st->us, st->tx, 2); return spi_write(st->us, st->tx, 2);
}
int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
{
int ret;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
mutex_lock(&st->buf_lock);
ret = __ade7758_spi_write_reg_8(dev, reg_address, val);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
return ret; return ret;
...@@ -91,7 +99,7 @@ static int ade7758_spi_write_reg_24(struct device *dev, u8 reg_address, ...@@ -91,7 +99,7 @@ static int ade7758_spi_write_reg_24(struct device *dev, u8 reg_address,
return ret; return ret;
} }
int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) static int __ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
{ {
struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev); struct ade7758_state *st = iio_priv(indio_dev);
...@@ -111,7 +119,6 @@ int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) ...@@ -111,7 +119,6 @@ int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
}, },
}; };
mutex_lock(&st->buf_lock);
st->tx[0] = ADE7758_READ_REG(reg_address); st->tx[0] = ADE7758_READ_REG(reg_address);
st->tx[1] = 0; st->tx[1] = 0;
...@@ -124,7 +131,19 @@ int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) ...@@ -124,7 +131,19 @@ int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
*val = st->rx[0]; *val = st->rx[0];
error_ret: error_ret:
return ret;
}
int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
int ret;
mutex_lock(&st->buf_lock);
ret = __ade7758_spi_read_reg_8(dev, reg_address, val);
mutex_unlock(&st->buf_lock); mutex_unlock(&st->buf_lock);
return ret; return ret;
} }
...@@ -484,6 +503,8 @@ static int ade7758_write_samp_freq(struct device *dev, int val) ...@@ -484,6 +503,8 @@ static int ade7758_write_samp_freq(struct device *dev, int val)
{ {
int ret; int ret;
u8 reg, t; u8 reg, t;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ade7758_state *st = iio_priv(indio_dev);
switch (val) { switch (val) {
case 26040: case 26040:
...@@ -499,20 +520,23 @@ static int ade7758_write_samp_freq(struct device *dev, int val) ...@@ -499,20 +520,23 @@ static int ade7758_write_samp_freq(struct device *dev, int val)
t = 3; t = 3;
break; break;
default: default:
ret = -EINVAL; return -EINVAL;
goto out;
} }
ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg); mutex_lock(&st->buf_lock);
ret = __ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg);
if (ret) if (ret)
goto out; goto out;
reg &= ~(5 << 3); reg &= ~(5 << 3);
reg |= t << 5; reg |= t << 5;
ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg); ret = __ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg);
out: out:
mutex_unlock(&st->buf_lock);
return ret; return ret;
} }
...@@ -526,9 +550,9 @@ static int ade7758_read_raw(struct iio_dev *indio_dev, ...@@ -526,9 +550,9 @@ static int ade7758_read_raw(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
mutex_lock(&indio_dev->mlock);
ret = ade7758_read_samp_freq(&indio_dev->dev, val); ret = ade7758_read_samp_freq(&indio_dev->dev, val);
mutex_unlock(&indio_dev->mlock);
return ret; return ret;
default: default:
return -EINVAL; return -EINVAL;
...@@ -547,9 +571,9 @@ static int ade7758_write_raw(struct iio_dev *indio_dev, ...@@ -547,9 +571,9 @@ static int ade7758_write_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SAMP_FREQ: case IIO_CHAN_INFO_SAMP_FREQ:
if (val2) if (val2)
return -EINVAL; return -EINVAL;
mutex_lock(&indio_dev->mlock);
ret = ade7758_write_samp_freq(&indio_dev->dev, val); ret = ade7758_write_samp_freq(&indio_dev->dev, val);
mutex_unlock(&indio_dev->mlock);
return ret; return ret;
default: default:
return -EINVAL; return -EINVAL;
......
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