]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
iio: imu: adis: add unlocked read/write function versions
authorAlexandru Ardelean <alexandru.ardelean@analog.com>
Fri, 22 Nov 2019 13:24:12 +0000 (15:24 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 23 Nov 2019 11:57:42 +0000 (11:57 +0000)
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: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/imu/adis.c
include/linux/iio/imu/adis.h

index db562fec79b29c3f921996955e3723b08915c8fe..2f518e6c727dbbe44db4e12f472c19bf6d3bdc04 100644 (file)
 #define ADIS_MSC_CTRL_DATA_RDY_DIO2    BIT(0)
 #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 page = reg / ADIS_PAGE_SIZE;
@@ -70,8 +77,6 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                },
        };
 
-       mutex_lock(&adis->state_lock);
-
        spi_message_init(&msg);
 
        if (adis->current_page != page) {
@@ -96,8 +101,7 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                adis->tx[3] = value & 0xff;
                break;
        default:
-               ret = -EINVAL;
-               goto out_unlock;
+               return -EINVAL;
        }
 
        xfers[size].cs_change = 0;
@@ -113,20 +117,18 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                adis->current_page = page;
        }
 
-out_unlock:
-       mutex_unlock(&adis->state_lock);
-
        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
  * @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
  */
-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 page = reg / ADIS_PAGE_SIZE;
@@ -166,7 +168,6 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                },
        };
 
-       mutex_lock(&adis->state_lock);
        spi_message_init(&msg);
 
        if (adis->current_page != page) {
@@ -188,15 +189,14 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                spi_message_add_tail(&xfers[3], &msg);
                break;
        default:
-               ret = -EINVAL;
-               goto out_unlock;
+               return -EINVAL;
        }
 
        ret = spi_sync(adis->spi, &msg);
        if (ret) {
                dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
                                reg, ret);
-               goto out_unlock;
+               return ret;
        } else {
                adis->current_page = page;
        }
@@ -210,12 +210,9 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                break;
        }
 
-out_unlock:
-       mutex_unlock(&adis->state_lock);
-
        return ret;
 }
-EXPORT_SYMBOL_GPL(adis_read_reg);
+EXPORT_SYMBOL_GPL(__adis_read_reg);
 
 #ifdef CONFIG_DEBUG_FS
 
index 100b5d1cebf13bd97bda77ff8e7a0c80b2f32f99..38ebe41092e167ebbae2a4411dceae0bd3ee0d82 100644 (file)
@@ -75,11 +75,123 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev,
        struct spi_device *spi, const struct adis_data *data);
 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);
-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);
 
+/**
+ * __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: The adis device