mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
staging: comedi: drivers: let core handle freeing s->private
Introduce a new subdevice runflags, SRF_FREE_SPRIV, and a new helper function, comedi_set_spriv(), that the drivers can use to set the comedi_subdevice private data pointer. The helper function will also set SRF_FREE_SPRIV to allow the comedi core to automatically free the subdevice private data during the cleanup_device() stage of the detach. Currently s->private is only allocated by the 8255, addi_watchdog, amplc_dio200_common, and ni_65xx drivers. All users of those drivers can then have the comedi_spriv_free() calls removed and in many cases the (*detach) can then simply be the appropriate comedi core provided function. The ni_65xx driver uses a helper function, ni_65xx_alloc_subdevice_private(), to allocate the private data. Refactor the function to return an errno or call comedi_set_spriv() instead of returning a pointer to the private data and requiring the caller to handle it. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cadf87a090
commit
588ba6dc5f
@@ -531,6 +531,21 @@ static bool comedi_is_subdevice_idle(struct comedi_subdevice *s)
|
||||
return (runflags & (SRF_ERROR | SRF_RUNNING)) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* comedi_set_spriv() - Set the subdevice private data pointer.
|
||||
* @s: comedi_subdevice struct
|
||||
* @data: pointer to the private data
|
||||
*
|
||||
* This also sets the subdevice runflags to allow the core to automatically
|
||||
* free the private data during the detach.
|
||||
*/
|
||||
void comedi_set_spriv(struct comedi_subdevice *s, void *data)
|
||||
{
|
||||
s->private = data;
|
||||
comedi_set_subdevice_runflags(s, ~0, SRF_FREE_SPRIV);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(comedi_set_spriv);
|
||||
|
||||
/*
|
||||
This function restores a subdevice to an idle state.
|
||||
*/
|
||||
|
||||
@@ -265,10 +265,12 @@ enum subdevice_runflags {
|
||||
/* indicates an COMEDI_CB_ERROR event has occurred since the last
|
||||
* command was started */
|
||||
SRF_ERROR = 0x00000004,
|
||||
SRF_RUNNING = 0x08000000
|
||||
SRF_RUNNING = 0x08000000,
|
||||
SRF_FREE_SPRIV = 0x80000000, /* free s->private on detach */
|
||||
};
|
||||
|
||||
bool comedi_is_subdevice_running(struct comedi_subdevice *s);
|
||||
void comedi_set_spriv(struct comedi_subdevice *s, void *data);
|
||||
|
||||
int comedi_check_chanlist(struct comedi_subdevice *s,
|
||||
int n,
|
||||
@@ -356,8 +358,6 @@ 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_load_firmware(struct comedi_device *, struct device *,
|
||||
const char *name,
|
||||
int (*cb)(struct comedi_device *,
|
||||
|
||||
@@ -83,18 +83,6 @@ 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;
|
||||
@@ -103,6 +91,8 @@ static void cleanup_device(struct comedi_device *dev)
|
||||
if (dev->subdevices) {
|
||||
for (i = 0; i < dev->n_subdevices; i++) {
|
||||
s = &dev->subdevices[i];
|
||||
if (s->runflags & SRF_FREE_SPRIV)
|
||||
kfree(s->private);
|
||||
comedi_free_subdevice_minor(s);
|
||||
if (s->async) {
|
||||
comedi_buf_alloc(dev, s, 0);
|
||||
|
||||
@@ -288,12 +288,11 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
|
||||
if (!spriv)
|
||||
return -ENOMEM;
|
||||
comedi_set_spriv(s, spriv);
|
||||
|
||||
spriv->iobase = iobase;
|
||||
spriv->io = io ? io : subdev_8255_io;
|
||||
|
||||
s->private = spriv;
|
||||
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
|
||||
s->n_chan = 24;
|
||||
@@ -386,7 +385,6 @@ static void dev_8255_detach(struct comedi_device *dev)
|
||||
spriv = s->private;
|
||||
release_region(spriv->iobase, _8255_SIZE);
|
||||
}
|
||||
comedi_spriv_free(dev, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,10 +238,7 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
|
||||
static void pci_8255_detach(struct comedi_device *dev)
|
||||
{
|
||||
struct pci_8255_private *devpriv = dev->private;
|
||||
int i;
|
||||
|
||||
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);
|
||||
|
||||
@@ -196,7 +196,6 @@ static void apci1516_detach(struct comedi_device *dev)
|
||||
{
|
||||
if (dev->iobase)
|
||||
apci1516_reset(dev);
|
||||
comedi_spriv_free(dev, 2);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -347,7 +347,6 @@ static void apci2032_detach(struct comedi_device *dev)
|
||||
free_irq(dev->irq, dev);
|
||||
if (dev->read_subdev)
|
||||
kfree(dev->read_subdev->private);
|
||||
comedi_spriv_free(dev, 1);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,6 @@ static void apci2200_detach(struct comedi_device *dev)
|
||||
{
|
||||
if (dev->iobase)
|
||||
apci2200_reset(dev);
|
||||
comedi_spriv_free(dev, 2);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,11 +129,10 @@ int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase)
|
||||
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
|
||||
if (!spriv)
|
||||
return -ENOMEM;
|
||||
comedi_set_spriv(s, spriv);
|
||||
|
||||
spriv->iobase = iobase;
|
||||
|
||||
s->private = spriv;
|
||||
|
||||
s->type = COMEDI_SUBD_TIMER;
|
||||
s->subdev_flags = SDF_WRITEABLE;
|
||||
s->n_chan = 1;
|
||||
|
||||
@@ -1173,19 +1173,11 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
|
||||
static void pci_dio_detach(struct comedi_device *dev)
|
||||
{
|
||||
struct pci_dio_private *devpriv = dev->private;
|
||||
struct comedi_subdevice *s;
|
||||
int i;
|
||||
|
||||
if (devpriv) {
|
||||
if (devpriv->valid)
|
||||
pci_dio_reset(dev);
|
||||
}
|
||||
for (i = 0; i < dev->n_subdevices; i++) {
|
||||
s = &dev->subdevices[i];
|
||||
if (s->type == COMEDI_SUBD_DIO)
|
||||
comedi_spriv_free(dev, i);
|
||||
s->private = NULL; /* some private data is static */
|
||||
}
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -255,17 +255,11 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aio_aio12_8_detach(struct comedi_device *dev)
|
||||
{
|
||||
comedi_spriv_free(dev, 2);
|
||||
comedi_legacy_detach(dev);
|
||||
}
|
||||
|
||||
static struct comedi_driver aio_aio12_8_driver = {
|
||||
.driver_name = "aio_aio12_8",
|
||||
.module = THIS_MODULE,
|
||||
.attach = aio_aio12_8_attach,
|
||||
.detach = aio_aio12_8_detach,
|
||||
.detach = comedi_legacy_detach,
|
||||
.board_name = &board_types[0].name,
|
||||
.num_names = ARRAY_SIZE(board_types),
|
||||
.offset = sizeof(struct aio12_8_boardtype),
|
||||
|
||||
@@ -559,6 +559,7 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
|
||||
if (!subpriv)
|
||||
return -ENOMEM;
|
||||
comedi_set_spriv(s, subpriv);
|
||||
|
||||
subpriv->ofs = offset;
|
||||
subpriv->valid_isns = valid_isns;
|
||||
@@ -568,7 +569,6 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
/* Disable interrupt sources. */
|
||||
dio200_write8(dev, subpriv->ofs, 0);
|
||||
|
||||
s->private = subpriv;
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
|
||||
if (layout->has_int_sce) {
|
||||
@@ -886,8 +886,8 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
|
||||
if (!subpriv)
|
||||
return -ENOMEM;
|
||||
comedi_set_spriv(s, subpriv);
|
||||
|
||||
s->private = subpriv;
|
||||
s->type = COMEDI_SUBD_COUNTER;
|
||||
s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
|
||||
s->n_chan = 3;
|
||||
@@ -1022,8 +1022,10 @@ static int dio200_subdev_8255_init(struct comedi_device *dev,
|
||||
subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
|
||||
if (!subpriv)
|
||||
return -ENOMEM;
|
||||
comedi_set_spriv(s, subpriv);
|
||||
|
||||
subpriv->ofs = offset;
|
||||
s->private = subpriv;
|
||||
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
|
||||
s->n_chan = 24;
|
||||
@@ -1225,28 +1227,11 @@ void amplc_dio200_common_detach(struct comedi_device *dev)
|
||||
{
|
||||
const struct dio200_board *thisboard = comedi_board(dev);
|
||||
struct dio200_private *devpriv = dev->private;
|
||||
const struct dio200_layout *layout;
|
||||
unsigned n;
|
||||
|
||||
if (!thisboard || !devpriv)
|
||||
return;
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
if (dev->subdevices) {
|
||||
layout = dio200_board_layout(thisboard);
|
||||
for (n = 0; n < dev->n_subdevices; n++) {
|
||||
switch (layout->sdtype[n]) {
|
||||
case sd_8254:
|
||||
case sd_8255:
|
||||
case sd_intr:
|
||||
comedi_spriv_free(dev, n);
|
||||
break;
|
||||
case sd_timer:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amplc_dio200_common_detach);
|
||||
|
||||
|
||||
@@ -538,7 +538,6 @@ static void pc236_detach(struct comedi_device *dev)
|
||||
return;
|
||||
if (dev->iobase)
|
||||
pc236_intr_disable(dev);
|
||||
comedi_spriv_free(dev, 0);
|
||||
if (is_isa_board(thisboard)) {
|
||||
comedi_legacy_detach(dev);
|
||||
} else if (is_pci_board(thisboard)) {
|
||||
|
||||
@@ -2830,7 +2830,6 @@ static void pci230_detach(struct comedi_device *dev)
|
||||
{
|
||||
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
|
||||
|
||||
comedi_spriv_free(dev, 2);
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
comedi_pci_disable(dev);
|
||||
|
||||
@@ -1602,7 +1602,6 @@ static void cb_pcidas_detach(struct comedi_device *dev)
|
||||
}
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
comedi_spriv_free(dev, 2);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -4158,7 +4158,6 @@ static void detach(struct comedi_device *dev)
|
||||
devpriv->ao_dma_desc_bus_addr);
|
||||
}
|
||||
}
|
||||
comedi_spriv_free(dev, 4);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -393,18 +393,11 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cb_pcidda_detach(struct comedi_device *dev)
|
||||
{
|
||||
comedi_spriv_free(dev, 1);
|
||||
comedi_spriv_free(dev, 2);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
static struct comedi_driver cb_pcidda_driver = {
|
||||
.driver_name = "cb_pcidda",
|
||||
.module = THIS_MODULE,
|
||||
.auto_attach = cb_pcidda_auto_attach,
|
||||
.detach = cb_pcidda_detach,
|
||||
.detach = comedi_pci_disable,
|
||||
};
|
||||
|
||||
static int cb_pcidda_pci_probe(struct pci_dev *dev,
|
||||
|
||||
@@ -192,17 +192,11 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cb_pcimdda_detach(struct comedi_device *dev)
|
||||
{
|
||||
comedi_spriv_free(dev, 1);
|
||||
comedi_pci_disable(dev);
|
||||
}
|
||||
|
||||
static struct comedi_driver cb_pcimdda_driver = {
|
||||
.driver_name = "cb_pcimdda",
|
||||
.module = THIS_MODULE,
|
||||
.auto_attach = cb_pcimdda_auto_attach,
|
||||
.detach = cb_pcimdda_detach,
|
||||
.detach = comedi_pci_disable,
|
||||
};
|
||||
|
||||
static int cb_pcimdda_pci_probe(struct pci_dev *dev,
|
||||
|
||||
@@ -747,7 +747,6 @@ static void daqboard2000_detach(struct comedi_device *dev)
|
||||
{
|
||||
struct daqboard2000_private *devpriv = dev->private;
|
||||
|
||||
comedi_spriv_free(dev, 2);
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
if (devpriv) {
|
||||
|
||||
@@ -560,12 +560,6 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(das08_common_attach);
|
||||
|
||||
void das08_common_detach(struct comedi_device *dev)
|
||||
{
|
||||
comedi_spriv_free(dev, 4);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(das08_common_detach);
|
||||
|
||||
static int __init das08_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user