Lines Matching +full:board +full:- +full:level
1 // SPDX-License-Identifier: GPL-2.0+
6 * COMEDI - Linux Control and Measurement Device Interface
7 * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
17 #include <linux/dma-direction.h>
28 * comedi_set_hw_dev() - Set hardware device associated with COMEDI device
33 * comedi_auto_config() or one of its wrappers from the low-level COMEDI
36 * called directly by "legacy" low-level COMEDI drivers that rely on the
40 * If @dev->hw_dev is NULL, it gets a reference to @hw_dev and sets
41 * @dev->hw_dev, otherwise, it does nothing. Calling it multiple times
46 * Returns 0 if @dev->hw_dev was NULL or the same as @hw_dev, otherwise
47 * returns -EEXIST.
51 if (hw_dev == dev->hw_dev) in comedi_set_hw_dev()
53 if (dev->hw_dev) in comedi_set_hw_dev()
54 return -EEXIST; in comedi_set_hw_dev()
55 dev->hw_dev = get_device(hw_dev); in comedi_set_hw_dev()
62 put_device(dev->hw_dev); in comedi_clear_hw_dev()
63 dev->hw_dev = NULL; in comedi_clear_hw_dev()
67 * comedi_alloc_devpriv() - Allocate memory for the device private data
71 * The allocated memory is zero-filled. @dev->private points to it on
79 dev->private = kzalloc(size, GFP_KERNEL); in comedi_alloc_devpriv()
80 return dev->private; in comedi_alloc_devpriv()
85 * comedi_alloc_subdevices() - Allocate subdevices for COMEDI device
90 * COMEDI device. If successful, sets @dev->subdevices to point to the
91 * first one and @dev->n_subdevices to the number.
93 * Returns 0 on success, -EINVAL if @num_subdevices is < 1, or -ENOMEM if
102 return -EINVAL; in comedi_alloc_subdevices()
106 return -ENOMEM; in comedi_alloc_subdevices()
107 dev->subdevices = s; in comedi_alloc_subdevices()
108 dev->n_subdevices = num_subdevices; in comedi_alloc_subdevices()
111 s = &dev->subdevices[i]; in comedi_alloc_subdevices()
112 s->device = dev; in comedi_alloc_subdevices()
113 s->index = i; in comedi_alloc_subdevices()
114 s->async_dma_dir = DMA_NONE; in comedi_alloc_subdevices()
115 spin_lock_init(&s->spin_lock); in comedi_alloc_subdevices()
116 s->minor = -1; in comedi_alloc_subdevices()
123 * comedi_alloc_subdev_readback() - Allocate memory for the subdevice readback
126 * This is called by low-level COMEDI drivers to allocate an array to record
132 * On success, @s->readback points to the first element of the array, which
133 * is zero-filled. The low-level driver is responsible for updating its
134 * contents. @s->insn_read will be set to comedi_readback_insn_read()
135 * unless it is already non-NULL.
137 * Returns 0 on success, -EINVAL if the subdevice has no channels, or
138 * -ENOMEM on allocation failure.
142 if (!s->n_chan) in comedi_alloc_subdev_readback()
143 return -EINVAL; in comedi_alloc_subdev_readback()
145 s->readback = kcalloc(s->n_chan, sizeof(*s->readback), GFP_KERNEL); in comedi_alloc_subdev_readback()
146 if (!s->readback) in comedi_alloc_subdev_readback()
147 return -ENOMEM; in comedi_alloc_subdev_readback()
149 if (!s->insn_read) in comedi_alloc_subdev_readback()
150 s->insn_read = comedi_readback_insn_read; in comedi_alloc_subdev_readback()
161 lockdep_assert_held_write(&dev->attach_lock); in comedi_device_detach_cleanup()
162 lockdep_assert_held(&dev->mutex); in comedi_device_detach_cleanup()
163 if (dev->subdevices) { in comedi_device_detach_cleanup()
164 for (i = 0; i < dev->n_subdevices; i++) { in comedi_device_detach_cleanup()
165 s = &dev->subdevices[i]; in comedi_device_detach_cleanup()
167 kfree(s->private); in comedi_device_detach_cleanup()
169 if (s->async) { in comedi_device_detach_cleanup()
171 kfree(s->async); in comedi_device_detach_cleanup()
173 kfree(s->readback); in comedi_device_detach_cleanup()
175 kfree(dev->subdevices); in comedi_device_detach_cleanup()
176 dev->subdevices = NULL; in comedi_device_detach_cleanup()
177 dev->n_subdevices = 0; in comedi_device_detach_cleanup()
179 kfree(dev->private); in comedi_device_detach_cleanup()
180 if (!IS_ERR(dev->pacer)) in comedi_device_detach_cleanup()
181 kfree(dev->pacer); in comedi_device_detach_cleanup()
182 dev->private = NULL; in comedi_device_detach_cleanup()
183 dev->pacer = NULL; in comedi_device_detach_cleanup()
184 dev->driver = NULL; in comedi_device_detach_cleanup()
185 dev->board_name = NULL; in comedi_device_detach_cleanup()
186 dev->board_ptr = NULL; in comedi_device_detach_cleanup()
187 dev->mmio = NULL; in comedi_device_detach_cleanup()
188 dev->iobase = 0; in comedi_device_detach_cleanup()
189 dev->iolen = 0; in comedi_device_detach_cleanup()
190 dev->ioenabled = false; in comedi_device_detach_cleanup()
191 dev->irq = 0; in comedi_device_detach_cleanup()
192 dev->read_subdev = NULL; in comedi_device_detach_cleanup()
193 dev->write_subdev = NULL; in comedi_device_detach_cleanup()
194 dev->open = NULL; in comedi_device_detach_cleanup()
195 dev->close = NULL; in comedi_device_detach_cleanup()
201 lockdep_assert_held_write(&dev->attach_lock); in comedi_device_detach_locked()
202 lockdep_assert_held(&dev->mutex); in comedi_device_detach_locked()
204 dev->attached = false; in comedi_device_detach_locked()
205 dev->detach_count++; in comedi_device_detach_locked()
206 if (dev->driver) in comedi_device_detach_locked()
207 dev->driver->detach(dev); in comedi_device_detach_locked()
213 lockdep_assert_held(&dev->mutex); in comedi_device_detach()
214 down_write(&dev->attach_lock); in comedi_device_detach()
216 up_write(&dev->attach_lock); in comedi_device_detach()
221 return -EINVAL; in poll_invalid()
227 return -EINVAL; in insn_device_inval()
240 return -EINVAL; in insn_inval()
244 * comedi_readback_insn_read() - A generic (*insn_read) for subdevice readback.
252 * directly as the subdevice's handler (@s->insn_read) or called via a
255 * @insn->n is normally 1, which will read a single value. If higher, the
258 * Returns @insn->n on success, or -EINVAL if @s->readback is NULL.
265 unsigned int chan = CR_CHAN(insn->chanspec); in comedi_readback_insn_read()
268 if (!s->readback) in comedi_readback_insn_read()
269 return -EINVAL; in comedi_readback_insn_read()
271 for (i = 0; i < insn->n; i++) in comedi_readback_insn_read()
272 data[i] = s->readback[chan]; in comedi_readback_insn_read()
274 return insn->n; in comedi_readback_insn_read()
279 * comedi_timeout() - Busy-wait for a driver condition to occur
286 * Busy-waits for up to a second (%COMEDI_TIMEOUT_MS) for the condition or
287 * some error (other than -EBUSY) to occur. The parameters @dev, @s, @insn,
288 * and @context are passed to the callback function, which returns -EBUSY to
292 * Returns -ETIMEDOUT if timed out, otherwise the return value from the
309 if (ret != -EBUSY) in comedi_timeout()
313 return -ETIMEDOUT; in comedi_timeout()
318 * comedi_dio_insn_config() - Boilerplate (*insn_config) for DIO subdevices
325 * If @mask is 0, it is replaced with a single-bit mask corresponding to the
326 * channel number specified by @insn->chanspec. Otherwise, @mask
332 * @s->io_bits to record the directions of the masked channels. The last
334 * (%COMEDI_INPUT) or %COMEDI_OUTPUT) as recorded in @s->io_bits.
340 * instruction, @insn->n (> 0) for a %INSN_CONFIG_DIO_QUERY instruction, or
341 * -EINVAL for some other instruction.
349 unsigned int chan = CR_CHAN(insn->chanspec); in comedi_dio_insn_config()
356 s->io_bits &= ~mask; in comedi_dio_insn_config()
360 s->io_bits |= mask; in comedi_dio_insn_config()
364 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; in comedi_dio_insn_config()
365 return insn->n; in comedi_dio_insn_config()
368 return -EINVAL; in comedi_dio_insn_config()
376 * comedi_dio_update_state() - Update the internal state of DIO subdevices
380 * Updates @s->state which holds the internal state of the outputs for DIO
381 * or DO subdevices (up to 32 channels). @data[0] contains a bit-mask of
382 * the channels to be updated. @data[1] contains a bit-mask of those
384 * outputs in hardware according to @s->state. As a minimum, the channels
385 * in the returned bit-mask need to be updated.
387 * Returns @mask with non-existent channels removed.
392 unsigned int chanmask = (s->n_chan < 32) ? ((1U << s->n_chan) - 1) in comedi_dio_update_state()
398 s->state &= ~mask; in comedi_dio_update_state()
399 s->state |= (bits & mask); in comedi_dio_update_state()
407 * comedi_bytes_per_scan_cmd() - Get length of asynchronous command "scan" in
429 switch (s->type) { in comedi_bytes_per_scan_cmd()
434 num_samples = DIV_ROUND_UP(cmd->scan_end_arg, bits_per_sample); in comedi_bytes_per_scan_cmd()
437 num_samples = cmd->scan_end_arg; in comedi_bytes_per_scan_cmd()
445 * comedi_bytes_per_scan() - Get length of asynchronous command "scan" in bytes
461 struct comedi_cmd *cmd = &s->async->cmd; in comedi_bytes_per_scan()
470 struct comedi_async *async = s->async; in __comedi_nscans_left()
471 struct comedi_cmd *cmd = &async->cmd; in __comedi_nscans_left()
473 if (cmd->stop_src == TRIG_COUNT) { in __comedi_nscans_left()
476 if (async->scans_done < cmd->stop_arg) in __comedi_nscans_left()
477 scans_left = cmd->stop_arg - async->scans_done; in __comedi_nscans_left()
486 * comedi_nscans_left() - Return the number of scans left in the command
512 * comedi_nsamples_left() - Return the number of samples left in the command
522 struct comedi_async *async = s->async; in comedi_nsamples_left()
523 struct comedi_cmd *cmd = &async->cmd; in comedi_nsamples_left()
527 if (cmd->stop_src != TRIG_COUNT) in comedi_nsamples_left()
530 scans_left = __comedi_nscans_left(s, cmd->stop_arg); in comedi_nsamples_left()
534 samples_left = scans_left * cmd->scan_end_arg - in comedi_nsamples_left()
535 comedi_bytes_to_samples(s, async->scan_progress); in comedi_nsamples_left()
544 * comedi_inc_scan_progress() - Update scan progress in asynchronous command
556 struct comedi_async *async = s->async; in comedi_inc_scan_progress()
557 struct comedi_cmd *cmd = &async->cmd; in comedi_inc_scan_progress()
560 /* track the 'cur_chan' for non-SDF_PACKED subdevices */ in comedi_inc_scan_progress()
561 if (!(s->subdev_flags & SDF_PACKED)) { in comedi_inc_scan_progress()
562 async->cur_chan += comedi_bytes_to_samples(s, num_bytes); in comedi_inc_scan_progress()
563 async->cur_chan %= cmd->chanlist_len; in comedi_inc_scan_progress()
566 async->scan_progress += num_bytes; in comedi_inc_scan_progress()
567 if (async->scan_progress >= scan_length) { in comedi_inc_scan_progress()
568 unsigned int nscans = async->scan_progress / scan_length; in comedi_inc_scan_progress()
570 if (async->scans_done < (UINT_MAX - nscans)) in comedi_inc_scan_progress()
571 async->scans_done += nscans; in comedi_inc_scan_progress()
573 async->scans_done = UINT_MAX; in comedi_inc_scan_progress()
575 async->scan_progress %= scan_length; in comedi_inc_scan_progress()
576 async->events |= COMEDI_CB_EOS; in comedi_inc_scan_progress()
582 * comedi_handle_events() - Handle events and possibly stop acquisition
587 * with the subdevice. Call the subdevice's @s->cancel() handler if the
589 * to stop the acquisition at the driver level.
595 * Return a bit-mask of the handled events.
600 unsigned int events = s->async->events; in comedi_handle_events()
605 if ((events & COMEDI_CB_CANCEL_MASK) && s->cancel) in comedi_handle_events()
606 s->cancel(dev, s); in comedi_handle_events()
620 unsigned int chan = CR_CHAN(insn->chanspec); in insn_rw_emulate_bits()
631 _insn.subdev = insn->subdev; in insn_rw_emulate_bits()
633 if (insn->insn == INSN_WRITE) { in insn_rw_emulate_bits()
634 if (!(s->subdev_flags & SDF_WRITABLE)) in insn_rw_emulate_bits()
635 return -EINVAL; in insn_rw_emulate_bits()
636 _data[0] = 1U << (chan - base_chan); /* mask */ in insn_rw_emulate_bits()
638 for (i = 0; i < insn->n; i++) { in insn_rw_emulate_bits()
639 if (insn->insn == INSN_WRITE) in insn_rw_emulate_bits()
642 ret = s->insn_bits(dev, s, &_insn, _data); in insn_rw_emulate_bits()
646 if (insn->insn == INSN_READ) in insn_rw_emulate_bits()
647 data[i] = (_data[1] >> (chan - base_chan)) & 1; in insn_rw_emulate_bits()
650 return insn->n; in insn_rw_emulate_bits()
660 lockdep_assert_held(&dev->mutex); in __comedi_device_postconfig_async()
661 if ((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0) { in __comedi_device_postconfig_async()
662 dev_warn(dev->class_dev, in __comedi_device_postconfig_async()
664 return -EINVAL; in __comedi_device_postconfig_async()
666 if (!s->do_cmdtest) { in __comedi_device_postconfig_async()
667 dev_warn(dev->class_dev, in __comedi_device_postconfig_async()
669 return -EINVAL; in __comedi_device_postconfig_async()
671 if (!s->cancel) in __comedi_device_postconfig_async()
672 dev_warn(dev->class_dev, in __comedi_device_postconfig_async()
677 return -ENOMEM; in __comedi_device_postconfig_async()
679 init_waitqueue_head(&async->wait_head); in __comedi_device_postconfig_async()
680 s->async = async; in __comedi_device_postconfig_async()
682 async->max_bufsize = comedi_default_buf_maxsize_kb * 1024; in __comedi_device_postconfig_async()
684 if (buf_size > async->max_bufsize) in __comedi_device_postconfig_async()
685 buf_size = async->max_bufsize; in __comedi_device_postconfig_async()
688 dev_warn(dev->class_dev, "Buffer allocation failed\n"); in __comedi_device_postconfig_async()
689 return -ENOMEM; in __comedi_device_postconfig_async()
691 if (s->buf_change) { in __comedi_device_postconfig_async()
692 ret = s->buf_change(dev, s); in __comedi_device_postconfig_async()
708 lockdep_assert_held(&dev->mutex); in __comedi_device_postconfig()
709 if (!dev->insn_device_config) in __comedi_device_postconfig()
710 dev->insn_device_config = insn_device_inval; in __comedi_device_postconfig()
712 if (!dev->get_valid_routes) in __comedi_device_postconfig()
713 dev->get_valid_routes = get_zero_valid_routes; in __comedi_device_postconfig()
715 for (i = 0; i < dev->n_subdevices; i++) { in __comedi_device_postconfig()
716 s = &dev->subdevices[i]; in __comedi_device_postconfig()
718 if (s->type == COMEDI_SUBD_UNUSED) in __comedi_device_postconfig()
721 if (s->type == COMEDI_SUBD_DO) { in __comedi_device_postconfig()
722 if (s->n_chan < 32) in __comedi_device_postconfig()
723 s->io_bits = (1U << s->n_chan) - 1; in __comedi_device_postconfig()
725 s->io_bits = 0xffffffff; in __comedi_device_postconfig()
728 if (s->len_chanlist == 0) in __comedi_device_postconfig()
729 s->len_chanlist = 1; in __comedi_device_postconfig()
731 if (s->do_cmd) { in __comedi_device_postconfig()
737 if (!s->range_table && !s->range_table_list) in __comedi_device_postconfig()
738 s->range_table = &range_unknown; in __comedi_device_postconfig()
740 if (!s->insn_read && s->insn_bits) in __comedi_device_postconfig()
741 s->insn_read = insn_rw_emulate_bits; in __comedi_device_postconfig()
742 if (!s->insn_write && s->insn_bits) in __comedi_device_postconfig()
743 s->insn_write = insn_rw_emulate_bits; in __comedi_device_postconfig()
745 if (!s->insn_read) in __comedi_device_postconfig()
746 s->insn_read = insn_inval; in __comedi_device_postconfig()
747 if (!s->insn_write) in __comedi_device_postconfig()
748 s->insn_write = insn_inval; in __comedi_device_postconfig()
749 if (!s->insn_bits) in __comedi_device_postconfig()
750 s->insn_bits = insn_inval; in __comedi_device_postconfig()
751 if (!s->insn_config) in __comedi_device_postconfig()
752 s->insn_config = insn_inval; in __comedi_device_postconfig()
754 if (!s->poll) in __comedi_device_postconfig()
755 s->poll = poll_invalid; in __comedi_device_postconfig()
761 /* do a little post-config cleanup */
766 lockdep_assert_held(&dev->mutex); in comedi_device_postconfig()
770 down_write(&dev->attach_lock); in comedi_device_postconfig()
771 dev->attached = true; in comedi_device_postconfig()
772 up_write(&dev->attach_lock); in comedi_device_postconfig()
778 * board names.
780 * 'driv->board_name' points to a 'const char *' member within the
781 * zeroth element of an array of some private board information
783 * *board_name' that is initialized to point to a board name string that
787 * 'driv->offset' is the size of the private board information
788 * structure, say 'sizeof(struct foo_board)', and 'driv->num_names' is
789 * the length of the array of private board information structures.
791 * If one of the board names in the array of private board information
793 * returns a pointer to the pointer to the board name, otherwise it
795 * a 'struct comedi_device' that the low-level comedi driver's
797 * array of private board information structures by subtracting the
798 * offset of the member that points to the board name. (No subtraction
799 * is required if the board name pointer is the first member of the
800 * private board information structure, which is generally the case.)
804 char **name_ptr = (char **)driv->board_name; in comedi_recognize()
807 for (i = 0; i < driv->num_names; i++) { in comedi_recognize()
810 name_ptr = (void *)name_ptr + driv->offset; in comedi_recognize()
821 pr_info("comedi: valid board names for %s driver are:\n", in comedi_report_boards()
822 driv->driver_name); in comedi_report_boards()
824 name_ptr = driv->board_name; in comedi_report_boards()
825 for (i = 0; i < driv->num_names; i++) { in comedi_report_boards()
827 name_ptr = (const char **)((char *)name_ptr + driv->offset); in comedi_report_boards()
830 if (driv->num_names == 0) in comedi_report_boards()
831 pr_info(" %s\n", driv->driver_name); in comedi_report_boards()
835 * comedi_load_firmware() - Request and load firmware for a device
846 * Returns 0 on success, -EINVAL if @cb is NULL, or a negative error number
861 return -EINVAL; in comedi_load_firmware()
865 ret = cb(dev, fw->data, fw->size, context); in comedi_load_firmware()
874 * __comedi_request_region() - Request an I/O region for a legacy driver
879 * Requests the specified I/O port region which must start at a non-zero
882 * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
889 dev_warn(dev->class_dev, in __comedi_request_region()
891 dev->board_name); in __comedi_request_region()
892 return -EINVAL; in __comedi_request_region()
895 if (!request_region(start, len, dev->board_name)) { in __comedi_request_region()
896 dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n", in __comedi_request_region()
897 dev->board_name, start, len); in __comedi_request_region()
898 return -EIO; in __comedi_request_region()
906 * comedi_request_region() - Request an I/O region for a legacy driver
911 * Requests the specified I/O port region which must start at a non-zero
914 * On success, @dev->iobase is set to the base address of the region and
915 * @dev->iolen is set to its length.
917 * Returns 0 on success, -EINVAL if @start is 0, or -EIO if the request
927 dev->iobase = start; in comedi_request_region()
928 dev->iolen = len; in comedi_request_region()
936 * comedi_legacy_detach() - A generic (*detach) function for legacy drivers
941 * any special clean-up for their private device or subdevice storage. It
942 * can also be called by a driver-specific 'detach' handler.
944 * If @dev->irq is non-zero, the IRQ will be freed. If @dev->iobase and
945 * @dev->iolen are both non-zero, the I/O port region will be released.
949 if (dev->irq) { in comedi_legacy_detach()
950 free_irq(dev->irq, dev); in comedi_legacy_detach()
951 dev->irq = 0; in comedi_legacy_detach()
953 if (dev->iobase && dev->iolen) { in comedi_legacy_detach()
954 release_region(dev->iobase, dev->iolen); in comedi_legacy_detach()
955 dev->iobase = 0; in comedi_legacy_detach()
956 dev->iolen = 0; in comedi_legacy_detach()
966 lockdep_assert_held(&dev->mutex); in comedi_device_attach()
967 if (dev->attached) in comedi_device_attach()
968 return -EBUSY; in comedi_device_attach()
971 for (driv = comedi_drivers; driv; driv = driv->next) { in comedi_device_attach()
972 if (!try_module_get(driv->module)) in comedi_device_attach()
974 if (driv->num_names) { in comedi_device_attach()
975 dev->board_ptr = comedi_recognize(driv, it->board_name); in comedi_device_attach()
976 if (dev->board_ptr) in comedi_device_attach()
978 } else if (strcmp(driv->driver_name, it->board_name) == 0) { in comedi_device_attach()
981 module_put(driv->module); in comedi_device_attach()
985 /* report valid board names before returning error */ in comedi_device_attach()
986 for (driv = comedi_drivers; driv; driv = driv->next) { in comedi_device_attach()
987 if (!try_module_get(driv->module)) in comedi_device_attach()
990 module_put(driv->module); in comedi_device_attach()
992 ret = -EIO; in comedi_device_attach()
995 if (!driv->attach) { in comedi_device_attach()
997 dev_warn(dev->class_dev, in comedi_device_attach()
999 driv->driver_name); in comedi_device_attach()
1000 module_put(driv->module); in comedi_device_attach()
1001 ret = -EIO; in comedi_device_attach()
1004 dev->driver = driv; in comedi_device_attach()
1005 dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr in comedi_device_attach()
1006 : dev->driver->driver_name; in comedi_device_attach()
1007 ret = driv->attach(dev, it); in comedi_device_attach()
1012 module_put(driv->module); in comedi_device_attach()
1021 * comedi_auto_config() - Create a COMEDI device for a hardware device
1023 * @driver: COMEDI low-level driver for the hardware device.
1027 * low-level driver's 'auto_attach' handler to set-up the hardware and
1028 * allocate the COMEDI subdevices. Additional "post-configuration" setting
1030 * If the 'auto_attach' handler fails, the low-level driver's 'detach'
1031 * handler will be called as part of the clean-up.
1033 * This is usually called from a wrapper function in a bus-specific COMEDI
1035 * function in the low-level driver.
1037 * Returns 0 on success, -EINVAL if the parameters are invalid or the
1038 * post-configuration determines the driver has set the COMEDI device up
1039 * incorrectly, -ENOMEM if failed to allocate memory, -EBUSY if run out of
1051 return -EINVAL; in comedi_auto_config()
1056 return -EINVAL; in comedi_auto_config()
1059 if (!driver->auto_attach) { in comedi_auto_config()
1062 driver->driver_name); in comedi_auto_config()
1063 return -EINVAL; in comedi_auto_config()
1070 driver->driver_name); in comedi_auto_config()
1073 /* Note: comedi_alloc_board_minor() locked dev->mutex. */ in comedi_auto_config()
1074 lockdep_assert_held(&dev->mutex); in comedi_auto_config()
1076 dev->driver = driver; in comedi_auto_config()
1077 dev->board_name = dev->driver->driver_name; in comedi_auto_config()
1078 ret = driver->auto_attach(dev, context); in comedi_auto_config()
1084 "driver '%s' failed to auto-configure device.\n", in comedi_auto_config()
1085 driver->driver_name); in comedi_auto_config()
1086 mutex_unlock(&dev->mutex); in comedi_auto_config()
1093 dev_info(dev->class_dev, in comedi_auto_config()
1094 "driver '%s' has successfully auto-configured '%s'.\n", in comedi_auto_config()
1095 driver->driver_name, dev->board_name); in comedi_auto_config()
1096 mutex_unlock(&dev->mutex); in comedi_auto_config()
1103 * comedi_auto_unconfig() - Unconfigure auto-allocated COMEDI device
1109 * clean-up, the low-level COMEDI driver's 'detach' handler will be called.
1114 * This is usually called from a wrapper module in a bus-specific COMEDI
1116 * in the low-level COMEDI driver.
1127 * comedi_driver_register() - Register a low-level COMEDI driver
1128 * @driver: Low-level COMEDI driver.
1130 * The low-level COMEDI driver is added to the list of registered COMEDI
1133 * "legacy" COMEDI devices (for those low-level drivers that support it).
1140 driver->next = comedi_drivers; in comedi_driver_register()
1149 * comedi_driver_unregister() - Unregister a low-level COMEDI driver
1150 * @driver: Low-level COMEDI driver.
1152 * The low-level COMEDI driver is removed from the list of registered COMEDI
1154 * result in the low-level driver's 'detach' handler being called for those
1165 comedi_drivers = driver->next; in comedi_driver_unregister()
1167 for (prev = comedi_drivers; prev->next; prev = prev->next) { in comedi_driver_unregister()
1168 if (prev->next == driver) { in comedi_driver_unregister()
1169 prev->next = driver->next; in comedi_driver_unregister()
1183 mutex_lock(&dev->mutex); in comedi_driver_unregister()
1184 if (dev->attached && dev->driver == driver) { in comedi_driver_unregister()
1185 if (dev->use_count) in comedi_driver_unregister()
1186 dev_warn(dev->class_dev, in comedi_driver_unregister()
1188 dev->use_count); in comedi_driver_unregister()
1191 mutex_unlock(&dev->mutex); in comedi_driver_unregister()