[PATCH 17/26] staging: comedi: ni_labpc: only allocate necessary subdevices
H Hartley Sweeten
hsweeten at visionengravers.com
Wed Mar 20 01:07:39 UTC 2013
Each comedi_subdevice uses one of the minors allocated to the
comedi subsystem. The devices used with this driver need a minimum
of 2 and a maximum of 5 subdevices.
Only allocate and initialize the number of subdevices actually needed
by the device.
Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
drivers/staging/comedi/drivers/ni_labpc.c | 49 ++++++++++++++++++-------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index dea4cfc..1c00ed2 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -1564,6 +1564,7 @@ int labpc_common_attach(struct comedi_device *dev,
const struct labpc_boardinfo *thisboard = comedi_board(dev);
struct labpc_private *devpriv = dev->private;
struct comedi_subdevice *s;
+ int subdev;
int i;
short lsb, msb;
int ret;
@@ -1595,12 +1596,20 @@ int labpc_common_attach(struct comedi_device *dev,
dev->irq = irq;
}
- ret = comedi_alloc_subdevices(dev, 5);
+ /* Only allocate the subdevices needed */
+ subdev = 1 + /* all boards have ai */
+ thisboard->has_ao + /* only on some boards have ao */
+ 1 + /* all boards have 8255 dio */
+ (thisboard->register_layout == labpc_1200_layout)
+ ? 2 : 0; /* the calib and memory devices */
+ ret = comedi_alloc_subdevices(dev, subdev);
if (ret)
return ret;
+ subdev = 0;
+
/* analog input subdevice */
- s = &dev->subdevices[0];
+ s = &dev->subdevices[subdev++];
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
s->n_chan = 8;
@@ -1616,9 +1625,9 @@ int labpc_common_attach(struct comedi_device *dev,
s->cancel = labpc_cancel;
}
- /* analog output */
- s = &dev->subdevices[1];
if (thisboard->has_ao) {
+ /* analog output */
+ s = &dev->subdevices[subdev++];
/*
* Could provide command support, except it only has a
* one sample hardware buffer for analog output and no
@@ -1639,23 +1648,19 @@ int labpc_common_attach(struct comedi_device *dev,
devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
}
- } else {
- s->type = COMEDI_SUBD_UNUSED;
}
/* 8255 dio */
- s = &dev->subdevices[2];
- /* if board uses io memory we have to give a custom callback
- * function to the 8255 driver */
+ s = &dev->subdevices[subdev++];
if (thisboard->memory_mapped_io)
subdev_8255_init(dev, s, labpc_dio_mem_callback,
(unsigned long)(dev->iobase + DIO_BASE_REG));
else
subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
- /* calibration subdevices for boards that have one */
- s = &dev->subdevices[3];
if (thisboard->register_layout == labpc_1200_layout) {
+ /* calibration subdevice */
+ s = &dev->subdevices[subdev++];
s->type = COMEDI_SUBD_CALIB;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
s->n_chan = 16;
@@ -1665,12 +1670,9 @@ int labpc_common_attach(struct comedi_device *dev,
for (i = 0; i < s->n_chan; i++)
write_caldac(dev, i, s->maxdata / 2);
- } else
- s->type = COMEDI_SUBD_UNUSED;
- /* EEPROM */
- s = &dev->subdevices[4];
- if (thisboard->register_layout == labpc_1200_layout) {
+ /* EEPROM */
+ s = &dev->subdevices[subdev++];
s->type = COMEDI_SUBD_MEMORY;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
s->n_chan = EEPROM_SIZE;
@@ -1680,8 +1682,7 @@ int labpc_common_attach(struct comedi_device *dev,
for (i = 0; i < EEPROM_SIZE; i++)
devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ }
return 0;
}
@@ -1689,8 +1690,16 @@ EXPORT_SYMBOL_GPL(labpc_common_attach);
void labpc_common_detach(struct comedi_device *dev)
{
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[2]);
+ struct comedi_subdevice *s;
+ int i;
+
+ if (dev->subdevices) {
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = &dev->subdevices[i];
+ if (s->type == COMEDI_SUBD_DIO)
+ subdev_8255_cleanup(dev, s);
+ }
+ }
if (dev->irq)
free_irq(dev->irq, dev);
}
--
1.8.1.4
More information about the devel
mailing list