Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b449c1ca authored by Ian Abbott's avatar Ian Abbott Committed by Greg Kroah-Hartman
Browse files

staging: comedi: add comedi_dev_get_from_minor()



Add function `struct comedi_device *comedi_dev_get_from_minor(unsigned
minor)`.  This behaves like the existing `comedi_dev_from_minor()`
except that it also increments the `struct kref refcount` member (via
new helper function `comedi_dev_get()`) to prevent it being freed.  If
it returns a valid pointer, the caller is responsible for calling
`comedi_dev_put()` to decrement the reference count.

Export `comedi_dev_get_from_minor()` and `comedi_dev_put()` as they will
be used by the "kcomedilib" module in addition to the "comedi" module
itself.

Signed-off-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5b13ed94
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -111,6 +111,14 @@ int comedi_dev_put(struct comedi_device *dev)
		return kref_put(&dev->refcount, comedi_dev_kref_release);
	return 1;
}
EXPORT_SYMBOL_GPL(comedi_dev_put);

static struct comedi_device *comedi_dev_get(struct comedi_device *dev)
{
	if (dev)
		kref_get(&dev->refcount);
	return dev;
}

static void comedi_device_cleanup(struct comedi_device *dev)
{
@@ -209,6 +217,40 @@ struct comedi_device *comedi_dev_from_minor(unsigned minor)
}
EXPORT_SYMBOL_GPL(comedi_dev_from_minor);

static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor)
{
	struct comedi_device *dev;

	BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
	mutex_lock(&comedi_board_minor_table_lock);
	dev = comedi_dev_get(comedi_board_minor_table[minor]);
	mutex_unlock(&comedi_board_minor_table_lock);
	return dev;
}

static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor)
{
	struct comedi_device *dev;
	struct comedi_subdevice *s;
	unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;

	BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
	mutex_lock(&comedi_subdevice_minor_table_lock);
	s = comedi_subdevice_minor_table[i];
	dev = comedi_dev_get(s ? s->device : NULL);
	mutex_unlock(&comedi_subdevice_minor_table_lock);
	return dev;
}

struct comedi_device *comedi_dev_get_from_minor(unsigned minor)
{
	if (minor < COMEDI_NUM_BOARD_MINORS)
		return comedi_dev_get_from_board_minor(minor);
	else
		return comedi_dev_get_from_subdevice_minor(minor);
}
EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor);

static struct comedi_subdevice *
comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
{
+2 −0
Original line number Diff line number Diff line
@@ -236,6 +236,8 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;

struct comedi_device *comedi_dev_from_minor(unsigned minor);
struct comedi_device *comedi_dev_get_from_minor(unsigned minor);
int comedi_dev_put(struct comedi_device *dev);

void init_polling(void);
void cleanup_polling(void);