From: H Hartley Sweeten Date: Mon, 9 Dec 2013 22:31:04 +0000 (-0700) Subject: staging: comedi: pcmmio: unwind the digital i/o subdevice init X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=19e0bf12358e5914db07a9026135b5b37aa408ef;p=openwrt%2Fstaging%2Fblogic.git staging: comedi: pcmmio: unwind the digital i/o subdevice init The board supported by this driver only has one asic that provides the two digital i/o subdevices. The first dio subdevice has 24 channels that support interrupts. The second dio subdevice also has 24 channels but no interrupt support. To make the code clearer and easier to maintain, remove the for () loop that initialized these subdevices. Also, correctly initialize the interrupt subdevice. The current code does not set the SDF_CMD_READ subdev_flag and does not set the dev->read_subdev pointer in the comedi_device. Use the dev->read_subdev pointer in the interrupt handler to get the interrupt subdevice and private data pointer instead of searching for them. To keep this patch reviewable, the extra indents in interrupt_pcmmio() will be removed later. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 4da5e5864047..7026ebcc2c7c 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -398,10 +398,11 @@ static void pcmmio_stop_intr(struct comedi_device *dev, static irqreturn_t interrupt_pcmmio(int irq, void *d) { - int asic, got1 = 0; - struct comedi_device *dev = (struct comedi_device *)d; + struct comedi_device *dev = d; struct pcmmio_private *devpriv = dev->private; - int i; + struct comedi_subdevice *s = dev->read_subdev; + struct pcmmio_subdev_private *subpriv = s->private; + int asic, got1 = 0; for (asic = 0; asic < MAX_ASICS; ++asic) { if (irq == dev->irq) { @@ -447,19 +448,10 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) spin_unlock_irqrestore(&devpriv->pagelock, flags); if (triggered) { - struct comedi_subdevice *s; /* * TODO here: dispatch io lines to subdevs * with commands.. */ - dev_dbg(dev->class_dev, - "got edge detect interrupt %d asic %d which_chans: %06x\n", - irq, asic, triggered); - for (i = 2; i < dev->n_subdevices; i++) { - struct pcmmio_subdev_private *subpriv; - - s = &dev->subdevices[i]; - subpriv = s->private; /* * this is an interrupt subdev, * and it matches this asic! @@ -545,7 +537,6 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) } - } } } @@ -927,8 +918,6 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pcmmio_private *devpriv; struct pcmmio_subdev_private *subpriv; struct comedi_subdevice *s; - int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, - thisasic_chanct = 0; int ret; ret = comedi_request_region(dev, it->options[0], 32); @@ -941,16 +930,12 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) spin_lock_init(&devpriv->pagelock); - chans_left = CHANS_PER_ASIC * 1; - n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); - n_subdevs = n_dio_subdevs + 2; - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), - GFP_KERNEL); + devpriv->sprivs = kcalloc(4, sizeof(struct pcmmio_subdev_private), + GFP_KERNEL); if (!devpriv->sprivs) return -ENOMEM; - ret = comedi_alloc_subdevices(dev, n_subdevs); + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; @@ -983,73 +968,44 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, dev->iobase + PCMMIO_AO_2ND_DAC_OFFSET + PCMMIO_AO_RESOURCE_ENA_REG); - port = 0; - asic = 0; - for (sdev_no = 2; sdev_no < dev->n_subdevices; ++sdev_no) { - int byte_no; - - s = &dev->subdevices[sdev_no]; - subpriv = &devpriv->sprivs[sdev_no]; - s->private = subpriv; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmmio_dio_insn_bits; - s->insn_config = pcmmio_dio_insn_config; - s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); - subpriv->dio.intr.asic = -1; - subpriv->dio.intr.first_chan = -1; - subpriv->dio.intr.asic_chan = -1; - subpriv->dio.intr.num_asic_chans = -1; - subpriv->dio.intr.active = 0; - s->len_chanlist = 1; - - /* save the ioport address for each 'port' of 8 channels in the - subdevice */ - for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { - if (port >= PORTS_PER_ASIC) { - port = 0; - ++asic; - thisasic_chanct = 0; - } - - if (thisasic_chanct < - CHANS_PER_PORT * INTR_PORTS_PER_ASIC - && subpriv->dio.intr.asic < 0) { - /* - * this is an interrupt subdevice, - * so setup the struct - */ - subpriv->dio.intr.asic = asic; - subpriv->dio.intr.active = 0; - subpriv->dio.intr.stop_count = 0; - subpriv->dio.intr.first_chan = byte_no * 8; - subpriv->dio.intr.asic_chan = thisasic_chanct; - subpriv->dio.intr.num_asic_chans = - s->n_chan - subpriv->dio.intr.first_chan; - s->cancel = pcmmio_cancel; - s->do_cmd = pcmmio_cmd; - s->do_cmdtest = pcmmio_cmdtest; - s->len_chanlist = - subpriv->dio.intr.num_asic_chans; - } - thisasic_chanct += CHANS_PER_PORT; - } - spin_lock_init(&subpriv->dio.intr.spinlock); - - chans_left -= s->n_chan; - - if (!chans_left) { - /* - * reset the asic to our first asic, - * to do intr subdevs - */ - asic = 0; - port = 0; - } - - } + /* Digital I/O subdevice with interrupt support */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->len_chanlist = 1; + s->range_table = &range_digital; + s->insn_bits = pcmmio_dio_insn_bits; + s->insn_config = pcmmio_dio_insn_config; + + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->cancel = pcmmio_cancel; + s->do_cmd = pcmmio_cmd; + s->do_cmdtest = pcmmio_cmdtest; + + s->private = &devpriv->sprivs[2]; + subpriv = s->private; + subpriv->dio.intr.asic = 0; + subpriv->dio.intr.active = 0; + subpriv->dio.intr.stop_count = 0; + subpriv->dio.intr.first_chan = 0; + subpriv->dio.intr.asic_chan = 0; + subpriv->dio.intr.num_asic_chans = 24; + + spin_lock_init(&subpriv->dio.intr.spinlock); + + /* Digital I/O subdevice */ + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pcmmio_dio_insn_bits; + s->insn_config = pcmmio_dio_insn_config; pcmmio_reset(dev);