2020-06-30 04:57:03 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
|
|
|
|
#ifndef _INDUSTRIAL_IO_OPAQUE_H_
|
|
|
|
#define _INDUSTRIAL_IO_OPAQUE_H_
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct iio_dev_opaque - industrial I/O device opaque information
|
|
|
|
* @indio_dev: public industrial I/O device information
|
2021-04-26 17:49:03 +00:00
|
|
|
* @id: used to identify device internally
|
2022-02-07 14:38:38 +00:00
|
|
|
* @currentmode: operating mode currently in use, may be eventually
|
|
|
|
* checked by device drivers but should be considered
|
|
|
|
* read-only as this is a core internal bit
|
2021-04-26 17:49:05 +00:00
|
|
|
* @driver_module: used to make it harder to undercut users
|
2022-10-12 15:16:20 +00:00
|
|
|
* @mlock: lock used to prevent simultaneous device state changes
|
iio: Use per-device lockdep class for mlock
If an IIO driver uses callbacks from another IIO driver and calls
iio_channel_start_all_cb() from one of its buffer setup ops, then
lockdep complains due to the lock nesting, as in the below example with
lmp91000.
Since the locks are being taken on different IIO devices, there is no
actual deadlock. Fix the warning by telling lockdep to use a different
class for each iio_device.
============================================
WARNING: possible recursive locking detected
--------------------------------------------
python3/23 is trying to acquire lock:
(&indio_dev->mlock){+.+.}-{3:3}, at: iio_update_buffers
but task is already holding lock:
(&indio_dev->mlock){+.+.}-{3:3}, at: enable_store
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&indio_dev->mlock);
lock(&indio_dev->mlock);
*** DEADLOCK ***
May be due to missing lock nesting notation
5 locks held by python3/23:
#0: (sb_writers#5){.+.+}-{0:0}, at: ksys_write
#1: (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter
#2: (kn->active#14){.+.+}-{0:0}, at: kernfs_fop_write_iter
#3: (&indio_dev->mlock){+.+.}-{3:3}, at: enable_store
#4: (&iio_dev_opaque->info_exist_lock){+.+.}-{3:3}, at: iio_update_buffers
Call Trace:
__mutex_lock
iio_update_buffers
iio_channel_start_all_cb
lmp91000_buffer_postenable
__iio_update_buffers
enable_store
Fixes: 67e17300dc1d76 ("iio: potentiostat: add LMP91000 support")
Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20220829091840.2791846-1-vincent.whitchurch@axis.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2022-08-29 09:18:40 +00:00
|
|
|
* @mlock_key: lockdep class for iio_dev lock
|
2021-04-26 17:49:08 +00:00
|
|
|
* @info_exist_lock: lock to prevent use during removal
|
2021-04-26 17:49:06 +00:00
|
|
|
* @trig_readonly: mark the current trigger immutable
|
2020-06-30 04:57:08 +00:00
|
|
|
* @event_interface: event chrdevs associated with interrupt lines
|
2021-02-15 10:40:38 +00:00
|
|
|
* @attached_buffers: array of buffers statically attached by the driver
|
|
|
|
* @attached_buffers_cnt: number of buffers in the array of statically attached buffers
|
iio: buffer: add ioctl() to support opening extra buffers for IIO device
With this change, an ioctl() call is added to open a character device for a
buffer. The ioctl() number is 'i' 0x91, which follows the
IIO_GET_EVENT_FD_IOCTL ioctl.
The ioctl() will return an FD for the requested buffer index. The indexes
are the same from the /sys/iio/devices/iio:deviceX/bufferY (i.e. the Y
variable).
Since there doesn't seem to be a sane way to return the FD for buffer0 to
be the same FD for the /dev/iio:deviceX, this ioctl() will return another
FD for buffer0 (or the first buffer). This duplicate FD will be able to
access the same buffer object (for buffer0) as accessing directly the
/dev/iio:deviceX chardev.
Also, there is no IIO_BUFFER_GET_BUFFER_COUNT ioctl() implemented, as the
index for each buffer (and the count) can be deduced from the
'/sys/bus/iio/devices/iio:deviceX/bufferY' folders (i.e the number of
bufferY folders).
Used following C code to test this:
-------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h"
#include <errno.h>
#define IIO_BUFFER_GET_FD_IOCTL _IOWR('i', 0x91, int)
int main(int argc, char *argv[])
{
int fd;
int fd1;
int ret;
if ((fd = open("/dev/iio:device0", O_RDWR))<0) {
fprintf(stderr, "Error open() %d errno %d\n",fd, errno);
return -1;
}
fprintf(stderr, "Using FD %d\n", fd);
fd1 = atoi(argv[1]);
ret = ioctl(fd, IIO_BUFFER_GET_FD_IOCTL, &fd1);
if (ret < 0) {
fprintf(stderr, "Error for buffer %d ioctl() %d errno %d\n", fd1, ret, errno);
close(fd);
return -1;
}
fprintf(stderr, "Got FD %d\n", fd1);
close(fd1);
close(fd);
return 0;
}
-------------------------------------------------------------------
Results are:
-------------------------------------------------------------------
# ./test 0
Using FD 3
Got FD 4
# ./test 1
Using FD 3
Got FD 4
# ./test 2
Using FD 3
Got FD 4
# ./test 3
Using FD 3
Got FD 4
# ls /sys/bus/iio/devices/iio\:device0
buffer buffer0 buffer1 buffer2 buffer3 dev
in_voltage_sampling_frequency in_voltage_scale
in_voltage_scale_available
name of_node power scan_elements subsystem uevent
-------------------------------------------------------------------
iio:device0 has some fake kfifo buffers attached to an IIO device.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20210215104043.91251-21-alexandru.ardelean@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2021-02-15 10:40:39 +00:00
|
|
|
* @buffer_ioctl_handler: ioctl() handler for this IIO device's buffer interface
|
2020-06-30 04:57:07 +00:00
|
|
|
* @buffer_list: list of all buffers currently attached
|
2020-06-30 04:57:06 +00:00
|
|
|
* @channel_attr_list: keep track of automatically created channel
|
|
|
|
* attributes
|
|
|
|
* @chan_attr_group: group for all attrs in base directory
|
2020-09-24 08:41:55 +00:00
|
|
|
* @ioctl_handlers: ioctl handlers registered with the core handler
|
2021-02-15 10:40:29 +00:00
|
|
|
* @groups: attribute groups
|
|
|
|
* @groupcounter: index of next attribute group
|
2021-02-15 10:40:31 +00:00
|
|
|
* @legacy_scan_el_group: attribute group for legacy scan elements attribute group
|
|
|
|
* @legacy_buffer_group: attribute group for legacy buffer attributes group
|
2021-06-13 15:10:36 +00:00
|
|
|
* @bounce_buffer: for devices that call iio_push_to_buffers_with_timestamp_unaligned()
|
|
|
|
* @bounce_buffer_size: size of currently allocate bounce buffer
|
2021-04-26 17:49:07 +00:00
|
|
|
* @scan_index_timestamp: cache of the index to the timestamp
|
2021-04-26 17:49:11 +00:00
|
|
|
* @clock_id: timestamping clock posix identifier
|
2021-04-26 17:49:09 +00:00
|
|
|
* @chrdev: associated character device
|
2021-04-26 17:49:10 +00:00
|
|
|
* @flags: file ops related flags including busy flag.
|
2020-06-30 04:57:05 +00:00
|
|
|
* @debugfs_dentry: device specific debugfs dentry
|
|
|
|
* @cached_reg_addr: cached register address for debugfs reads
|
|
|
|
* @read_buf: read buffer to be used for the initial reg read
|
|
|
|
* @read_buf_len: data length in @read_buf
|
2020-06-30 04:57:03 +00:00
|
|
|
*/
|
|
|
|
struct iio_dev_opaque {
|
|
|
|
struct iio_dev indio_dev;
|
2022-02-07 14:38:38 +00:00
|
|
|
int currentmode;
|
2021-04-26 17:49:03 +00:00
|
|
|
int id;
|
2021-04-26 17:49:05 +00:00
|
|
|
struct module *driver_module;
|
2022-10-12 15:16:20 +00:00
|
|
|
struct mutex mlock;
|
iio: Use per-device lockdep class for mlock
If an IIO driver uses callbacks from another IIO driver and calls
iio_channel_start_all_cb() from one of its buffer setup ops, then
lockdep complains due to the lock nesting, as in the below example with
lmp91000.
Since the locks are being taken on different IIO devices, there is no
actual deadlock. Fix the warning by telling lockdep to use a different
class for each iio_device.
============================================
WARNING: possible recursive locking detected
--------------------------------------------
python3/23 is trying to acquire lock:
(&indio_dev->mlock){+.+.}-{3:3}, at: iio_update_buffers
but task is already holding lock:
(&indio_dev->mlock){+.+.}-{3:3}, at: enable_store
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&indio_dev->mlock);
lock(&indio_dev->mlock);
*** DEADLOCK ***
May be due to missing lock nesting notation
5 locks held by python3/23:
#0: (sb_writers#5){.+.+}-{0:0}, at: ksys_write
#1: (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter
#2: (kn->active#14){.+.+}-{0:0}, at: kernfs_fop_write_iter
#3: (&indio_dev->mlock){+.+.}-{3:3}, at: enable_store
#4: (&iio_dev_opaque->info_exist_lock){+.+.}-{3:3}, at: iio_update_buffers
Call Trace:
__mutex_lock
iio_update_buffers
iio_channel_start_all_cb
lmp91000_buffer_postenable
__iio_update_buffers
enable_store
Fixes: 67e17300dc1d76 ("iio: potentiostat: add LMP91000 support")
Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20220829091840.2791846-1-vincent.whitchurch@axis.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2022-08-29 09:18:40 +00:00
|
|
|
struct lock_class_key mlock_key;
|
2021-04-26 17:49:08 +00:00
|
|
|
struct mutex info_exist_lock;
|
2021-04-26 17:49:06 +00:00
|
|
|
bool trig_readonly;
|
2020-06-30 04:57:08 +00:00
|
|
|
struct iio_event_interface *event_interface;
|
2021-02-15 10:40:38 +00:00
|
|
|
struct iio_buffer **attached_buffers;
|
|
|
|
unsigned int attached_buffers_cnt;
|
iio: buffer: add ioctl() to support opening extra buffers for IIO device
With this change, an ioctl() call is added to open a character device for a
buffer. The ioctl() number is 'i' 0x91, which follows the
IIO_GET_EVENT_FD_IOCTL ioctl.
The ioctl() will return an FD for the requested buffer index. The indexes
are the same from the /sys/iio/devices/iio:deviceX/bufferY (i.e. the Y
variable).
Since there doesn't seem to be a sane way to return the FD for buffer0 to
be the same FD for the /dev/iio:deviceX, this ioctl() will return another
FD for buffer0 (or the first buffer). This duplicate FD will be able to
access the same buffer object (for buffer0) as accessing directly the
/dev/iio:deviceX chardev.
Also, there is no IIO_BUFFER_GET_BUFFER_COUNT ioctl() implemented, as the
index for each buffer (and the count) can be deduced from the
'/sys/bus/iio/devices/iio:deviceX/bufferY' folders (i.e the number of
bufferY folders).
Used following C code to test this:
-------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h"
#include <errno.h>
#define IIO_BUFFER_GET_FD_IOCTL _IOWR('i', 0x91, int)
int main(int argc, char *argv[])
{
int fd;
int fd1;
int ret;
if ((fd = open("/dev/iio:device0", O_RDWR))<0) {
fprintf(stderr, "Error open() %d errno %d\n",fd, errno);
return -1;
}
fprintf(stderr, "Using FD %d\n", fd);
fd1 = atoi(argv[1]);
ret = ioctl(fd, IIO_BUFFER_GET_FD_IOCTL, &fd1);
if (ret < 0) {
fprintf(stderr, "Error for buffer %d ioctl() %d errno %d\n", fd1, ret, errno);
close(fd);
return -1;
}
fprintf(stderr, "Got FD %d\n", fd1);
close(fd1);
close(fd);
return 0;
}
-------------------------------------------------------------------
Results are:
-------------------------------------------------------------------
# ./test 0
Using FD 3
Got FD 4
# ./test 1
Using FD 3
Got FD 4
# ./test 2
Using FD 3
Got FD 4
# ./test 3
Using FD 3
Got FD 4
# ls /sys/bus/iio/devices/iio\:device0
buffer buffer0 buffer1 buffer2 buffer3 dev
in_voltage_sampling_frequency in_voltage_scale
in_voltage_scale_available
name of_node power scan_elements subsystem uevent
-------------------------------------------------------------------
iio:device0 has some fake kfifo buffers attached to an IIO device.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20210215104043.91251-21-alexandru.ardelean@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
2021-02-15 10:40:39 +00:00
|
|
|
struct iio_ioctl_handler *buffer_ioctl_handler;
|
2020-06-30 04:57:07 +00:00
|
|
|
struct list_head buffer_list;
|
2020-06-30 04:57:06 +00:00
|
|
|
struct list_head channel_attr_list;
|
|
|
|
struct attribute_group chan_attr_group;
|
2020-09-24 08:41:55 +00:00
|
|
|
struct list_head ioctl_handlers;
|
2021-02-15 10:40:29 +00:00
|
|
|
const struct attribute_group **groups;
|
|
|
|
int groupcounter;
|
2021-02-15 10:40:31 +00:00
|
|
|
struct attribute_group legacy_scan_el_group;
|
|
|
|
struct attribute_group legacy_buffer_group;
|
2021-06-13 15:10:36 +00:00
|
|
|
void *bounce_buffer;
|
|
|
|
size_t bounce_buffer_size;
|
2021-04-26 17:49:07 +00:00
|
|
|
|
|
|
|
unsigned int scan_index_timestamp;
|
2021-04-26 17:49:11 +00:00
|
|
|
clockid_t clock_id;
|
2021-04-26 17:49:09 +00:00
|
|
|
struct cdev chrdev;
|
2021-04-26 17:49:10 +00:00
|
|
|
unsigned long flags;
|
2021-04-26 17:49:07 +00:00
|
|
|
|
2020-06-30 04:57:05 +00:00
|
|
|
#if defined(CONFIG_DEBUG_FS)
|
|
|
|
struct dentry *debugfs_dentry;
|
|
|
|
unsigned cached_reg_addr;
|
|
|
|
char read_buf[20];
|
|
|
|
unsigned int read_buf_len;
|
|
|
|
#endif
|
2020-06-30 04:57:03 +00:00
|
|
|
};
|
|
|
|
|
2021-04-26 17:49:04 +00:00
|
|
|
#define to_iio_dev_opaque(_indio_dev) \
|
|
|
|
container_of((_indio_dev), struct iio_dev_opaque, indio_dev)
|
2020-06-30 04:57:03 +00:00
|
|
|
|
|
|
|
#endif
|