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

Commit 2f69915c authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: introduce, and use, comedi_spriv_free()



The comedi_subdevice 'private' variable is a void * that is available
for the subdevice to use in manner. It's common in comedi drivers for
the driver to allocate memory for a subdevice and store the pointer
to that memory in the 'private' variable. It's then the responsibility
of the driver to free that memory when the device is detached.

Due to how the attach/detach works in comedi, the drivers need to do
some sanity checking before they can free the allocated memory during
the detach.

Introduce a helper function, comedi_spriv_free(), to handle freeing
the private data allocated for a subdevice. This allows moving all the
sanity checks into the helper function and makes it safe to call
with any context. It also allows removing some of the boilerplate
code in the (*detach) functions.

Remove the subdev_8255_cleanup() export in the 8255 subdevice driver
as well as the addi_watchdog_cleanup() export in the addi_watchdog
driver and use the new helper instead.

The amplc_dio200_common driver uses a number of local helper functions
to free the private data for it's subdevices. Remove those as well and
use the new helper.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f4362867
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -348,6 +348,8 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,

int comedi_alloc_subdevices(struct comedi_device *, int);

void comedi_spriv_free(struct comedi_device *, int subdev_num);

int __comedi_request_region(struct comedi_device *,
			    unsigned long start, unsigned long len);
int comedi_request_region(struct comedi_device *,
+12 −0
Original line number Diff line number Diff line
@@ -86,6 +86,18 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
}
EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);

void comedi_spriv_free(struct comedi_device *dev, int subdev_num)
{
	struct comedi_subdevice *s;

	if (dev->subdevices && subdev_num < dev->n_subdevices) {
		s = &dev->subdevices[subdev_num];
		kfree(s->private);
		s->private = NULL;
	}
}
EXPORT_SYMBOL_GPL(comedi_spriv_free);

static void cleanup_device(struct comedi_device *dev)
{
	int i;
+1 −7
Original line number Diff line number Diff line
@@ -334,12 +334,6 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
}
EXPORT_SYMBOL_GPL(subdev_8255_init_irq);

void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
{
	kfree(s->private);
}
EXPORT_SYMBOL_GPL(subdev_8255_cleanup);

/*

   Start of the 8255 standalone device
@@ -397,7 +391,7 @@ static void dev_8255_detach(struct comedi_device *dev)
			spriv = s->private;
			release_region(spriv->iobase, _8255_SIZE);
		}
		subdev_8255_cleanup(dev, s);
		comedi_spriv_free(dev, i);
	}
}

+0 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
			 int (*io) (int, int, int, unsigned long),
			 unsigned long iobase);
void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s);
void subdev_8255_interrupt(struct comedi_device *dev,
			   struct comedi_subdevice *s);

+3 −11
Original line number Diff line number Diff line
@@ -241,20 +241,12 @@ static int pci_8255_auto_attach(struct comedi_device *dev,

static void pci_8255_detach(struct comedi_device *dev)
{
	const struct pci_8255_boardinfo *board = comedi_board(dev);
	struct pci_8255_private *devpriv = dev->private;
	struct comedi_subdevice *s;
	int i;

	if (!board || !devpriv)
		return;
	if (dev->subdevices) {
		for (i = 0; i < board->n_8255; i++) {
			s = &dev->subdevices[i];
			subdev_8255_cleanup(dev, s);
		}
	}
	if (devpriv->mmio_base)
	for (i = 0; i < dev->n_subdevices; i++)
		comedi_spriv_free(dev, i);
	if (devpriv && devpriv->mmio_base)
		iounmap(devpriv->mmio_base);
	comedi_pci_disable(dev);
}
Loading