[PATCH 02/10] staging: comedi: pcmuio: refactor interrupt_pcmuio()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Refactor this function into two new functions in order to reduce the indent
levels and clean up the ugly line breaks that, unsuccessfully, try to keep
the lines < 80 chars.

The first function handles the irq for a specific asic.

The second function handles the irq for a specific subdevice that is
associated with the asic.

Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/staging/comedi/drivers/pcmuio.c | 255 +++++++++++++++-----------------
 1 file changed, 116 insertions(+), 139 deletions(-)

diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index f7f2762..15c8a9a 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -447,154 +447,131 @@ static void pcmuio_stop_intr(struct comedi_device *dev,
 	}
 }
 
-static irqreturn_t interrupt_pcmuio(int irq, void *d)
+static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      unsigned triggered)
+{
+	struct pcmuio_subdev_private *subpriv = s->private;
+	unsigned int len = s->async->cmd.chanlist_len;
+	unsigned oldevents = s->async->events;
+	unsigned int val = 0;
+	unsigned long flags;
+	unsigned mytrig;
+	unsigned int i;
+
+	spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+
+	if (!subpriv->intr.active)
+		goto done;
+
+	mytrig = triggered >> subpriv->intr.asic_chan;
+	mytrig &= ((0x1 << subpriv->intr.num_asic_chans) - 1);
+	mytrig <<= subpriv->intr.first_chan;
+
+	if (!(mytrig & subpriv->intr.enabled_mask))
+		goto done;
+
+	for (i = 0; i < len; i++) {
+		unsigned int chan = CR_CHAN(s->async->cmd.chanlist[i]);
+		if (mytrig & (1U << chan))
+			val |= (1U << i);
+	}
+
+	/* Write the scan to the buffer. */
+	if (comedi_buf_put(s->async, ((short *)&val)[0]) &&
+	    comedi_buf_put(s->async, ((short *)&val)[1])) {
+		s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+	} else {
+		/* Overflow! Stop acquisition!! */
+		/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+		pcmuio_stop_intr(dev, s);
+	}
+
+	/* Check for end of acquisition. */
+	if (!subpriv->intr.continuous) {
+		/* stop_src == TRIG_COUNT */
+		if (subpriv->intr.stop_count > 0) {
+			subpriv->intr.stop_count--;
+			if (subpriv->intr.stop_count == 0) {
+				s->async->events |= COMEDI_CB_EOA;
+				/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+				pcmuio_stop_intr(dev, s);
+			}
+		}
+	}
+
+done:
+	spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+	if (oldevents != s->async->events)
+		comedi_event(dev, s);
+}
+
+static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic)
 {
-	struct comedi_device *dev = (struct comedi_device *)d;
 	struct pcmuio_private *devpriv = dev->private;
 	struct pcmuio_subdev_private *subpriv;
-	int asic, got1 = 0;
+	unsigned long iobase = devpriv->asics[asic].iobase;
+	unsigned triggered = 0;
+	int got1 = 0;
+	unsigned long flags;
+	unsigned char int_pend;
 	int i;
 
-	for (asic = 0; asic < MAX_ASICS; ++asic) {
-		if (irq == devpriv->asics[asic].irq) {
-			unsigned long flags;
-			unsigned triggered = 0;
-			unsigned long iobase = devpriv->asics[asic].iobase;
-			/* it is an interrupt for ASIC #asic */
-			unsigned char int_pend;
-
-			spin_lock_irqsave(&devpriv->asics[asic].spinlock,
-					  flags);
-
-			int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
-
-			if (int_pend) {
-				int port;
-				for (port = 0; port < INTR_PORTS_PER_ASIC;
-				     ++port) {
-					if (int_pend & (0x1 << port)) {
-						unsigned char
-						    io_lines_with_edges = 0;
-						switch_page(dev, asic,
-							    PAGE_INT_ID);
-						io_lines_with_edges =
-						    inb(iobase +
-							REG_INT_ID0 + port);
-
-						if (io_lines_with_edges)
-							/* clear pending interrupt */
-							outb(0, iobase +
-							     REG_INT_ID0 +
-							     port);
-
-						triggered |=
-						    io_lines_with_edges <<
-						    port * 8;
-					}
-				}
-
-				++got1;
+	spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
+
+	int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+	if (int_pend) {
+		for (i = 0; i < INTR_PORTS_PER_ASIC; ++i) {
+			if (int_pend & (0x1 << i)) {
+				unsigned char val;
+
+				switch_page(dev, asic, PAGE_INT_ID);
+				val = inb(iobase + REG_INT_ID0 + i);
+				if (val)
+					/* clear pending interrupt */
+					outb(0, iobase + REG_INT_ID0 + i);
+
+					triggered |= (val << (i * 8));
 			}
+		}
+
+		++got1;
+	}
 
-			spin_unlock_irqrestore(&devpriv->asics[asic].spinlock,
-					       flags);
-
-			if (triggered) {
-				struct comedi_subdevice *s;
-				/* TODO here: dispatch io lines to subdevs with commands.. */
-				printk
-				    ("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n",
-				     irq, asic, triggered);
-				for (i = 0; i < dev->n_subdevices; i++) {
-					s = &dev->subdevices[i];
-					subpriv = s->private;
-					if (subpriv->intr.asic == asic) {	/* this is an interrupt subdev, and it matches this asic! */
-						unsigned long flags;
-						unsigned oldevents;
-
-						spin_lock_irqsave(&subpriv->
-								  intr.spinlock,
-								  flags);
-
-						oldevents = s->async->events;
-
-						if (subpriv->intr.active) {
-							unsigned mytrig =
-							    ((triggered >>
-							      subpriv->intr.asic_chan)
-							     &
-							     ((0x1 << subpriv->
-							       intr.
-							       num_asic_chans) -
-							      1)) << subpriv->
-							    intr.first_chan;
-							if (mytrig &
-							    subpriv->intr.enabled_mask)
-							{
-								unsigned int val
-								    = 0;
-								unsigned int n,
-								    ch, len;
-
-								len =
-								    s->
-								    async->cmd.chanlist_len;
-								for (n = 0;
-								     n < len;
-								     n++) {
-									ch = CR_CHAN(s->async->cmd.chanlist[n]);
-									if (mytrig & (1U << ch)) {
-										val |= (1U << n);
-									}
-								}
-								/* Write the scan to the buffer. */
-								if (comedi_buf_put(s->async, ((short *)&val)[0])
-								    &&
-								    comedi_buf_put
-								    (s->async,
-								     ((short *)
-								      &val)[1]))
-								{
-									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
-								} else {
-									/* Overflow! Stop acquisition!! */
-									/* TODO: STOP_ACQUISITION_CALL_HERE!! */
-									pcmuio_stop_intr
-									    (dev,
-									     s);
-								}
-
-								/* Check for end of acquisition. */
-								if (!subpriv->intr.continuous) {
-									/* stop_src == TRIG_COUNT */
-									if (subpriv->intr.stop_count > 0) {
-										subpriv->intr.stop_count--;
-										if (subpriv->intr.stop_count == 0) {
-											s->async->events |= COMEDI_CB_EOA;
-											/* TODO: STOP_ACQUISITION_CALL_HERE!! */
-											pcmuio_stop_intr
-											    (dev,
-											     s);
-										}
-									}
-								}
-							}
-						}
-
-						spin_unlock_irqrestore
-						    (&subpriv->intr.spinlock,
-						     flags);
-
-						if (oldevents !=
-						    s->async->events) {
-							comedi_event(dev, s);
-						}
-
-					}
-
-				}
+	spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
+
+	if (triggered) {
+		struct comedi_subdevice *s;
+		/* TODO here: dispatch io lines to subdevs with commands.. */
+		for (i = 0; i < dev->n_subdevices; i++) {
+			s = &dev->subdevices[i];
+			subpriv = s->private;
+			if (subpriv->intr.asic == asic) {
+				/*
+				 * This is an interrupt subdev, and it
+				 * matches this asic!
+				 */
+				pcmuio_handle_intr_subdev(dev, s,
+							  triggered);
 			}
+		}
+	}
+	return got1;
+}
 
+static irqreturn_t interrupt_pcmuio(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct pcmuio_private *devpriv = dev->private;
+	int got1 = 0;
+	int asic;
+
+	for (asic = 0; asic < MAX_ASICS; ++asic) {
+		if (irq == devpriv->asics[asic].irq) {
+			/* it is an interrupt for ASIC #asic */
+			if (pcmuio_handle_asic_interrupt(dev, asic))
+				got1++;
 		}
 	}
 	if (!got1)
-- 
1.8.1.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux