Commit 770d4656 authored by Alexandru Ardelean's avatar Alexandru Ardelean Committed by Jonathan Cameron

iio: imu: adis: add unlocked read/write function versions

This will allow more flexible control to group reads & writes into a single
lock (particularly the state_lock).

The end-goal is to remove the indio_dev->mlock usage, and the simplest fix
would have been to just add another lock, which would not be a good idea on
the long-run.
Signed-off-by: default avatarAlexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 6a9afcb1
...@@ -26,7 +26,14 @@ ...@@ -26,7 +26,14 @@
#define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0) #define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
#define ADIS_GLOB_CMD_SW_RESET BIT(7) #define ADIS_GLOB_CMD_SW_RESET BIT(7)
int adis_write_reg(struct adis *adis, unsigned int reg, /**
* __adis_write_reg() - write N bytes to register (unlocked version)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @value: The value to write to device (up to 4 bytes)
* @size: The size of the @value (in bytes)
*/
int __adis_write_reg(struct adis *adis, unsigned int reg,
unsigned int value, unsigned int size) unsigned int value, unsigned int size)
{ {
unsigned int page = reg / ADIS_PAGE_SIZE; unsigned int page = reg / ADIS_PAGE_SIZE;
...@@ -70,8 +77,6 @@ int adis_write_reg(struct adis *adis, unsigned int reg, ...@@ -70,8 +77,6 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
}, },
}; };
mutex_lock(&adis->state_lock);
spi_message_init(&msg); spi_message_init(&msg);
if (adis->current_page != page) { if (adis->current_page != page) {
...@@ -96,8 +101,7 @@ int adis_write_reg(struct adis *adis, unsigned int reg, ...@@ -96,8 +101,7 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
adis->tx[3] = value & 0xff; adis->tx[3] = value & 0xff;
break; break;
default: default:
ret = -EINVAL; return -EINVAL;
goto out_unlock;
} }
xfers[size].cs_change = 0; xfers[size].cs_change = 0;
...@@ -113,20 +117,18 @@ int adis_write_reg(struct adis *adis, unsigned int reg, ...@@ -113,20 +117,18 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
adis->current_page = page; adis->current_page = page;
} }
out_unlock:
mutex_unlock(&adis->state_lock);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(adis_write_reg); EXPORT_SYMBOL_GPL(__adis_write_reg);
/** /**
* adis_read_reg() - read 2 bytes from a 16-bit register * __adis_read_reg() - read N bytes from register (unlocked version)
* @adis: The adis device * @adis: The adis device
* @reg: The address of the lower of the two registers * @reg: The address of the lower of the two registers
* @val: The value read back from the device * @val: The value read back from the device
* @size: The size of the @val buffer
*/ */
int adis_read_reg(struct adis *adis, unsigned int reg, int __adis_read_reg(struct adis *adis, unsigned int reg,
unsigned int *val, unsigned int size) unsigned int *val, unsigned int size)
{ {
unsigned int page = reg / ADIS_PAGE_SIZE; unsigned int page = reg / ADIS_PAGE_SIZE;
...@@ -166,7 +168,6 @@ int adis_read_reg(struct adis *adis, unsigned int reg, ...@@ -166,7 +168,6 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
}, },
}; };
mutex_lock(&adis->state_lock);
spi_message_init(&msg); spi_message_init(&msg);
if (adis->current_page != page) { if (adis->current_page != page) {
...@@ -188,15 +189,14 @@ int adis_read_reg(struct adis *adis, unsigned int reg, ...@@ -188,15 +189,14 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
spi_message_add_tail(&xfers[3], &msg); spi_message_add_tail(&xfers[3], &msg);
break; break;
default: default:
ret = -EINVAL; return -EINVAL;
goto out_unlock;
} }
ret = spi_sync(adis->spi, &msg); ret = spi_sync(adis->spi, &msg);
if (ret) { if (ret) {
dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n", dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
reg, ret); reg, ret);
goto out_unlock; return ret;
} else { } else {
adis->current_page = page; adis->current_page = page;
} }
...@@ -210,12 +210,9 @@ int adis_read_reg(struct adis *adis, unsigned int reg, ...@@ -210,12 +210,9 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
break; break;
} }
out_unlock:
mutex_unlock(&adis->state_lock);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(adis_read_reg); EXPORT_SYMBOL_GPL(__adis_read_reg);
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
...@@ -75,11 +75,123 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, ...@@ -75,11 +75,123 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev,
struct spi_device *spi, const struct adis_data *data); struct spi_device *spi, const struct adis_data *data);
int adis_reset(struct adis *adis); int adis_reset(struct adis *adis);
int adis_write_reg(struct adis *adis, unsigned int reg, int __adis_write_reg(struct adis *adis, unsigned int reg,
unsigned int val, unsigned int size); unsigned int val, unsigned int size);
int adis_read_reg(struct adis *adis, unsigned int reg, int __adis_read_reg(struct adis *adis, unsigned int reg,
unsigned int *val, unsigned int size); unsigned int *val, unsigned int size);
/**
* __adis_write_reg_8() - Write single byte to a register (unlocked)
* @adis: The adis device
* @reg: The address of the register to be written
* @value: The value to write
*/
static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg,
uint8_t val)
{
return __adis_write_reg(adis, reg, val, 1);
}
/**
* __adis_write_reg_16() - Write 2 bytes to a pair of registers (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @value: Value to be written
*/
static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg,
uint16_t val)
{
return __adis_write_reg(adis, reg, val, 2);
}
/**
* __adis_write_reg_32() - write 4 bytes to four registers (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the four register
* @value: Value to be written
*/
static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg,
uint32_t val)
{
return __adis_write_reg(adis, reg, val, 4);
}
/**
* __adis_read_reg_16() - read 2 bytes from a 16-bit register (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*/
static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg,
uint16_t *val)
{
unsigned int tmp;
int ret;
ret = __adis_read_reg(adis, reg, &tmp, 2);
if (ret == 0)
*val = tmp;
return ret;
}
/**
* __adis_read_reg_32() - read 4 bytes from a 32-bit register (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*/
static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg,
uint32_t *val)
{
unsigned int tmp;
int ret;
ret = __adis_read_reg(adis, reg, &tmp, 4);
if (ret == 0)
*val = tmp;
return ret;
}
/**
* adis_write_reg() - write N bytes to register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @value: The value to write to device (up to 4 bytes)
* @size: The size of the @value (in bytes)
*/
static inline int adis_write_reg(struct adis *adis, unsigned int reg,
unsigned int val, unsigned int size)
{
int ret;
mutex_lock(&adis->state_lock);
ret = __adis_write_reg(adis, reg, val, size);
mutex_unlock(&adis->state_lock);
return ret;
}
/**
* adis_read_reg() - read N bytes from register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
* @size: The size of the @val buffer
*/
static int adis_read_reg(struct adis *adis, unsigned int reg,
unsigned int *val, unsigned int size)
{
int ret;
mutex_lock(&adis->state_lock);
ret = __adis_read_reg(adis, reg, val, size);
mutex_unlock(&adis->state_lock);
return ret;
}
/** /**
* adis_write_reg_8() - Write single byte to a register * adis_write_reg_8() - Write single byte to a register
* @adis: The adis device * @adis: The adis device
......
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