diff options
Diffstat (limited to 'include/linux/comedi')
| -rw-r--r-- | include/linux/comedi/comedi_8254.h | 6 | ||||
| -rw-r--r-- | include/linux/comedi/comedi_isadma.h | 2 | ||||
| -rw-r--r-- | include/linux/comedi/comedidev.h | 70 | ||||
| -rw-r--r-- | include/linux/comedi/comedilib.h | 34 |
4 files changed, 94 insertions, 18 deletions
diff --git a/include/linux/comedi/comedi_8254.h b/include/linux/comedi/comedi_8254.h index d527f04400df..91f5861061ec 100644 --- a/include/linux/comedi/comedi_8254.h +++ b/include/linux/comedi/comedi_8254.h @@ -83,11 +83,11 @@ typedef unsigned int comedi_8254_iocb_fn(struct comedi_8254 *i8254, int dir, * @divisor: divisor for single counter * @divisor1: divisor loaded into first cascaded counter * @divisor2: divisor loaded into second cascaded counter - * #next_div: next divisor for single counter + * @next_div: next divisor for single counter * @next_div1: next divisor to use for first cascaded counter * @next_div2: next divisor to use for second cascaded counter - * @clock_src; current clock source for each counter (driver specific) - * @gate_src; current gate source for each counter (driver specific) + * @clock_src: current clock source for each counter (driver specific) + * @gate_src: current gate source for each counter (driver specific) * @busy: flags used to indicate that a counter is "busy" * @insn_config: driver specific (*insn_config) callback */ diff --git a/include/linux/comedi/comedi_isadma.h b/include/linux/comedi/comedi_isadma.h index 9d2b12db7e6e..7514ce222fa6 100644 --- a/include/linux/comedi/comedi_isadma.h +++ b/include/linux/comedi/comedi_isadma.h @@ -48,11 +48,11 @@ struct comedi_isadma_desc { */ struct comedi_isadma { struct device *dev; - struct comedi_isadma_desc *desc; int n_desc; int cur_dma; unsigned int chan; unsigned int chan2; + struct comedi_isadma_desc desc[] __counted_by(n_desc); }; #if IS_ENABLED(CONFIG_ISA_DMA_API) diff --git a/include/linux/comedi/comedidev.h b/include/linux/comedi/comedidev.h index c08416a7364b..577a08f37aee 100644 --- a/include/linux/comedi/comedidev.h +++ b/include/linux/comedi/comedidev.h @@ -15,6 +15,7 @@ #include <linux/spinlock_types.h> #include <linux/rwsem.h> #include <linux/kref.h> +#include <linux/completion.h> #include <linux/comedi.h> #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) @@ -234,16 +235,12 @@ struct comedi_buf_page { * * A COMEDI data buffer is allocated as individual pages, either in * conventional memory or DMA coherent memory, depending on the attached, - * low-level hardware device. (The buffer pages also get mapped into the - * kernel's contiguous virtual address space pointed to by the 'prealloc_buf' - * member of &struct comedi_async.) + * low-level hardware device. * * The buffer is normally freed when the COMEDI device is detached from the * low-level driver (which may happen due to device removal), but if it happens * to be mmapped at the time, the pages cannot be freed until the buffer has - * been munmapped. That is what the reference counter is for. (The virtual - * address space pointed by 'prealloc_buf' is freed when the COMEDI device is - * detached.) + * been munmapped. That is what the reference counter is for. */ struct comedi_buf_map { struct device *dma_hw_dev; @@ -255,7 +252,6 @@ struct comedi_buf_map { /** * struct comedi_async - Control data for asynchronous COMEDI commands - * @prealloc_buf: Kernel virtual address of allocated acquisition buffer. * @prealloc_bufsz: Buffer size (in bytes). * @buf_map: Map of buffer pages. * @max_bufsize: Maximum allowed buffer size (in bytes). @@ -277,6 +273,8 @@ struct comedi_buf_map { * @events: Bit-vector of events that have occurred. * @cmd: Details of comedi command in progress. * @wait_head: Task wait queue for file reader or writer. + * @run_complete: "run complete" completion event. + * @run_active: "run active" reference counter. * @cb_mask: Bit-vector of events that should wake waiting tasks. * @inttrig: Software trigger function for command, or NULL. * @@ -344,7 +342,6 @@ struct comedi_buf_map { * less than or equal to UINT_MAX). */ struct comedi_async { - void *prealloc_buf; unsigned int prealloc_bufsz; struct comedi_buf_map *buf_map; unsigned int max_bufsize; @@ -363,6 +360,8 @@ struct comedi_async { unsigned int events; struct comedi_cmd cmd; wait_queue_head_t wait_head; + struct completion run_complete; + refcount_t run_active; unsigned int cb_mask; int (*inttrig)(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int x); @@ -590,6 +589,8 @@ struct comedi_device *comedi_dev_get_from_minor(unsigned int minor); int comedi_dev_put(struct comedi_device *dev); bool comedi_is_subdevice_running(struct comedi_subdevice *s); +bool comedi_get_is_subdevice_running(struct comedi_subdevice *s); +void comedi_put_is_subdevice_running(struct comedi_subdevice *s); void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size); void comedi_set_spriv_auto_free(struct comedi_subdevice *s); @@ -1025,10 +1026,55 @@ int comedi_load_firmware(struct comedi_device *dev, struct device *hw_dev, unsigned long context), unsigned long context); -int __comedi_request_region(struct comedi_device *dev, - unsigned long start, unsigned long len); -int comedi_request_region(struct comedi_device *dev, - unsigned long start, unsigned long len); +int __comedi_check_request_region(struct comedi_device *dev, + unsigned long start, unsigned long len, + unsigned long minstart, unsigned long maxend, + unsigned long minalign); +int comedi_check_request_region(struct comedi_device *dev, + unsigned long start, unsigned long len, + unsigned long minstart, unsigned long maxend, + unsigned long minalign); + +/** + * __comedi_request_region() - Request an I/O region for a legacy driver + * @dev: COMEDI device. + * @start: Base address of the I/O region. + * @len: Length of the I/O region. + * + * Requests the specified I/O port region which must start at a non-zero + * address. + * + * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request + * fails. + */ +static inline int __comedi_request_region(struct comedi_device *dev, + unsigned long start, + unsigned long len) +{ + return __comedi_check_request_region(dev, start, len, 0, ~0ul, 1); +} + +/** + * comedi_request_region() - Request an I/O region for a legacy driver + * @dev: COMEDI device. + * @start: Base address of the I/O region. + * @len: Length of the I/O region. + * + * Requests the specified I/O port region which must start at a non-zero + * address. + * + * On success, @dev->iobase is set to the base address of the region and + * @dev->iolen is set to its length. + * + * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request + * fails. + */ +static inline int comedi_request_region(struct comedi_device *dev, + unsigned long start, unsigned long len) +{ + return comedi_check_request_region(dev, start, len, 0, ~0ul, 1); +} + void comedi_legacy_detach(struct comedi_device *dev); int comedi_auto_config(struct device *hardware_device, diff --git a/include/linux/comedi/comedilib.h b/include/linux/comedi/comedilib.h index 0223c9cd9215..1f2b22b383cc 100644 --- a/include/linux/comedi/comedilib.h +++ b/include/linux/comedi/comedilib.h @@ -10,8 +10,38 @@ #ifndef _LINUX_COMEDILIB_H #define _LINUX_COMEDILIB_H -struct comedi_device *comedi_open(const char *path); -int comedi_close(struct comedi_device *dev); +struct comedi_device *comedi_open_from(const char *path, int from); + +/** + * comedi_open() - Open a COMEDI device from the kernel + * @filename: Fake pathname of the form "/dev/comediN". + * + * Converts @filename to a COMEDI device number and "opens" it if it exists + * and is attached to a low-level COMEDI driver. + * + * Return: A pointer to the COMEDI device on success. + * Return %NULL on failure. + */ +static inline struct comedi_device *comedi_open(const char *path) +{ + return comedi_open_from(path, -1); +} + +int comedi_close_from(struct comedi_device *dev, int from); + +/** + * comedi_close() - Close a COMEDI device from the kernel + * @dev: COMEDI device. + * + * Closes a COMEDI device previously opened by comedi_open(). + * + * Returns: 0 + */ +static inline int comedi_close(struct comedi_device *dev) +{ + return comedi_close_from(dev, -1); +} + int comedi_dio_get_config(struct comedi_device *dev, unsigned int subdev, unsigned int chan, unsigned int *io); int comedi_dio_config(struct comedi_device *dev, unsigned int subdev, |
