iio: core: move 'mlock' to 'struct iio_dev_opaque'
authorNuno Sá <nuno.sa@analog.com>
Wed, 12 Oct 2022 15:16:20 +0000 (17:16 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Wed, 23 Nov 2022 19:44:00 +0000 (19:44 +0000)
Now that there are no more users accessing 'mlock' directly, we can move
it to the iio_dev private structure. Hence, it's now explicit that new
driver's should not directly use this lock.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20221012151620.1725215-5-nuno.sa@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/TODO
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-event.c
drivers/iio/industrialio-trigger.c
include/linux/iio/iio-opaque.h
include/linux/iio/iio.h

index 7d7326b..2ace27d 100644 (file)
@@ -7,9 +7,6 @@ tree
   - ABI Documentation
   - Audit driviers/iio/staging/Documentation
 
-- Replace iio_dev->mlock by either a local lock or use
-iio_claim_direct.(Requires analysis of the purpose of the lock.)
-
 - Converting drivers from device tree centric to more generic
 property handlers.
 
index 228598b..9cd7db5 100644 (file)
@@ -507,13 +507,14 @@ static ssize_t iio_scan_el_store(struct device *dev,
        int ret;
        bool state;
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        struct iio_buffer *buffer = this_attr->buffer;
 
        ret = kstrtobool(buf, &state);
        if (ret < 0)
                return ret;
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
        if (iio_buffer_is_active(buffer)) {
                ret = -EBUSY;
                goto error_ret;
@@ -532,7 +533,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
        }
 
 error_ret:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        return ret < 0 ? ret : len;
 
@@ -554,6 +555,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
 {
        int ret;
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
        bool state;
 
@@ -561,14 +563,14 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
        if (ret < 0)
                return ret;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
        if (iio_buffer_is_active(buffer)) {
                ret = -EBUSY;
                goto error_ret;
        }
        buffer->scan_timestamp = state;
 error_ret:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        return ret ? ret : len;
 }
@@ -642,6 +644,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr,
                            const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
        unsigned int val;
        int ret;
@@ -653,7 +656,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr,
        if (val == buffer->length)
                return len;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
        if (iio_buffer_is_active(buffer)) {
                ret = -EBUSY;
        } else {
@@ -665,7 +668,7 @@ static ssize_t length_store(struct device *dev, struct device_attribute *attr,
        if (buffer->length && buffer->length < buffer->watermark)
                buffer->watermark = buffer->length;
 out:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        return ret ? ret : len;
 }
@@ -1256,7 +1259,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                return -EINVAL;
 
        mutex_lock(&iio_dev_opaque->info_exist_lock);
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
 
        if (insert_buffer && iio_buffer_is_active(insert_buffer))
                insert_buffer = NULL;
@@ -1277,7 +1280,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
        ret = __iio_update_buffers(indio_dev, insert_buffer, remove_buffer);
 
 out_unlock:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
        mutex_unlock(&iio_dev_opaque->info_exist_lock);
 
        return ret;
@@ -1296,6 +1299,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
        int ret;
        bool requested_state;
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
        bool inlist;
 
@@ -1303,7 +1307,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
        if (ret < 0)
                return ret;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
 
        /* Find out if it is in the list */
        inlist = iio_buffer_is_active(buffer);
@@ -1317,7 +1321,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
                ret = __iio_update_buffers(indio_dev, NULL, buffer);
 
 done:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
        return (ret < 0) ? ret : len;
 }
 
@@ -1334,6 +1338,7 @@ static ssize_t watermark_store(struct device *dev,
                               const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
        unsigned int val;
        int ret;
@@ -1344,7 +1349,7 @@ static ssize_t watermark_store(struct device *dev,
        if (!val)
                return -EINVAL;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
 
        if (val > buffer->length) {
                ret = -EINVAL;
@@ -1358,7 +1363,7 @@ static ssize_t watermark_store(struct device *dev,
 
        buffer->watermark = val;
 out:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        return ret ? ret : len;
 }
index b2b7bd2..52e690f 100644 (file)
@@ -285,16 +285,16 @@ int iio_device_set_clock(struct iio_dev *indio_dev, clockid_t clock_id)
        struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
        const struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;
 
-       ret = mutex_lock_interruptible(&indio_dev->mlock);
+       ret = mutex_lock_interruptible(&iio_dev_opaque->mlock);
        if (ret)
                return ret;
        if ((ev_int && iio_event_enabled(ev_int)) ||
            iio_buffer_enabled(indio_dev)) {
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(&iio_dev_opaque->mlock);
                return -EBUSY;
        }
        iio_dev_opaque->clock_id = clock_id;
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        return 0;
 }
@@ -1674,7 +1674,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
        indio_dev->dev.type = &iio_device_type;
        indio_dev->dev.bus = &iio_bus_type;
        device_initialize(&indio_dev->dev);
-       mutex_init(&indio_dev->mlock);
+       mutex_init(&iio_dev_opaque->mlock);
        mutex_init(&iio_dev_opaque->info_exist_lock);
        INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list);
 
@@ -1696,7 +1696,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
        INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
 
        lockdep_register_key(&iio_dev_opaque->mlock_key);
-       lockdep_set_class(&indio_dev->mlock, &iio_dev_opaque->mlock_key);
+       lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key);
 
        return indio_dev;
 }
@@ -2058,10 +2058,12 @@ EXPORT_SYMBOL_GPL(__devm_iio_device_register);
  */
 int iio_device_claim_direct_mode(struct iio_dev *indio_dev)
 {
-       mutex_lock(&indio_dev->mlock);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
+
+       mutex_lock(&iio_dev_opaque->mlock);
 
        if (iio_buffer_enabled(indio_dev)) {
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(&iio_dev_opaque->mlock);
                return -EBUSY;
        }
        return 0;
@@ -2079,7 +2081,7 @@ EXPORT_SYMBOL_GPL(iio_device_claim_direct_mode);
  */
 void iio_device_release_direct_mode(struct iio_dev *indio_dev)
 {
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock);
 }
 EXPORT_SYMBOL_GPL(iio_device_release_direct_mode);
 
@@ -2096,12 +2098,14 @@ EXPORT_SYMBOL_GPL(iio_device_release_direct_mode);
  */
 int iio_device_claim_buffer_mode(struct iio_dev *indio_dev)
 {
-       mutex_lock(&indio_dev->mlock);
+       struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
+
+       mutex_lock(&iio_dev_opaque->mlock);
 
        if (iio_buffer_enabled(indio_dev))
                return 0;
 
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
        return -EBUSY;
 }
 EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode);
@@ -2117,7 +2121,7 @@ EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode);
  */
 void iio_device_release_buffer_mode(struct iio_dev *indio_dev)
 {
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock);
 }
 EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode);
 
index 3d78da2..1a26393 100644 (file)
@@ -198,7 +198,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev)
        if (ev_int == NULL)
                return -ENODEV;
 
-       fd = mutex_lock_interruptible(&indio_dev->mlock);
+       fd = mutex_lock_interruptible(&iio_dev_opaque->mlock);
        if (fd)
                return fd;
 
@@ -219,7 +219,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev)
        }
 
 unlock:
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
        return fd;
 }
 
index 6885a18..a2f3cc2 100644 (file)
@@ -120,12 +120,12 @@ int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *tri
                return -EINVAL;
 
        iio_dev_opaque = to_iio_dev_opaque(indio_dev);
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
        WARN_ON(iio_dev_opaque->trig_readonly);
 
        indio_dev->trig = iio_trigger_get(trig);
        iio_dev_opaque->trig_readonly = true;
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        return 0;
 }
@@ -438,16 +438,16 @@ static ssize_t current_trigger_store(struct device *dev,
        struct iio_trigger *trig;
        int ret;
 
-       mutex_lock(&indio_dev->mlock);
+       mutex_lock(&iio_dev_opaque->mlock);
        if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) {
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(&iio_dev_opaque->mlock);
                return -EBUSY;
        }
        if (iio_dev_opaque->trig_readonly) {
-               mutex_unlock(&indio_dev->mlock);
+               mutex_unlock(&iio_dev_opaque->mlock);
                return -EPERM;
        }
-       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&iio_dev_opaque->mlock);
 
        trig = iio_trigger_acquire_by_name(buf);
        if (oldtrig == trig) {
index d1f8b30..5aec394 100644 (file)
@@ -11,6 +11,7 @@
  *                             checked by device drivers but should be considered
  *                             read-only as this is a core internal bit
  * @driver_module:             used to make it harder to undercut users
+ * @mlock:                     lock used to prevent simultaneous device state changes
  * @mlock_key:                 lockdep class for iio_dev lock
  * @info_exist_lock:           lock to prevent use during removal
  * @trig_readonly:             mark the current trigger immutable
@@ -43,6 +44,7 @@ struct iio_dev_opaque {
        int                             currentmode;
        int                             id;
        struct module                   *driver_module;
+       struct mutex                    mlock;
        struct lock_class_key           mlock_key;
        struct mutex                    info_exist_lock;
        bool                            trig_readonly;
index 9d3bd63..8e0afaa 100644 (file)
@@ -548,8 +548,6 @@ struct iio_buffer_setup_ops {
  *                     and owner
  * @buffer:            [DRIVER] any buffer present
  * @scan_bytes:                [INTERN] num bytes captured to be fed to buffer demux
- * @mlock:             [INTERN] lock used to prevent simultaneous device state
- *                     changes
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
  * @masklength:                [INTERN] the length of the mask established from
  *                     channels
@@ -574,7 +572,6 @@ struct iio_dev {
 
        struct iio_buffer               *buffer;
        int                             scan_bytes;
-       struct mutex                    mlock;
 
        const unsigned long             *available_scan_masks;
        unsigned                        masklength;