[PATCH 64/87] staging: comedi: pcl816: don't calc the timer divisors twice

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

 



The timer divisors are calculated in the (*do_cmdtest) before the (*do_cmd)
is called by the comedi core. The extra sanity checks in the (*do_cmd) are
not necessary, the values returned from i8253_cascade_ns_to_timer() will be
greater than 1. Save the values in the private data so they don't need to be
recalced.

Refactor pcl816_start_pacer() to use the values from the private data.

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

diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 9a0b8b6..6cd7154 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -122,6 +122,8 @@ struct pcl816_private {
 	unsigned int ai_act_chanlist_len;	/*  how long is actual MUX list */
 	unsigned int ai_act_chanlist_pos;	/*  actual position in MUX list */
 	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
+	unsigned int divisor1;
+	unsigned int divisor2;
 };
 
 /*
@@ -136,9 +138,9 @@ static void setup_channel_list(struct comedi_device *dev,
 static int pcl816_ai_cancel(struct comedi_device *dev,
 			    struct comedi_subdevice *s);
 
-static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters,
-			       unsigned int divisor1, unsigned int divisor2)
+static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters)
 {
+	struct pcl816_private *devpriv = dev->private;
 	unsigned long timer_base = dev->iobase + PCL816_TIMER_BASE;
 
 	i8254_set_mode(timer_base, 0, 0, I8254_MODE1 | I8254_BINARY);
@@ -150,8 +152,8 @@ static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters,
 	udelay(1);
 
 	if (load_counters) {
-		i8254_write(timer_base, 0, 2, divisor2);
-		i8254_write(timer_base, 0, 1, divisor1);
+		i8254_write(timer_base, 0, 2, devpriv->divisor2);
+		i8254_write(timer_base, 0, 1, devpriv->divisor1);
 	}
 }
 
@@ -396,8 +398,9 @@ static irqreturn_t interrupt_pcl816(int irq, void *d)
 static int pcl816_ai_cmdtest(struct comedi_device *dev,
 			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
+	struct pcl816_private *devpriv = dev->private;
 	int err = 0;
-	int tmp, divisor1 = 0, divisor2 = 0;
+	int tmp;
 
 	/* Step 1 : check if triggers are trivially valid */
 
@@ -446,7 +449,8 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
 	if (cmd->convert_src == TRIG_TIMER) {
 		tmp = cmd->convert_arg;
 		i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
-					  &divisor1, &divisor2,
+					  &devpriv->divisor1,
+					  &devpriv->divisor2,
 					  &cmd->convert_arg, cmd->flags);
 		if (cmd->convert_arg < 10000)
 			cmd->convert_arg = 10000;
@@ -472,33 +476,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
 static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pcl816_private *devpriv = dev->private;
-	unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
 	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int dma_flags, bytes, dmairq;
 	unsigned int seglen;
 
 	if (devpriv->irq_blocked)
 		return -EBUSY;
 
-	if (cmd->convert_src == TRIG_TIMER) {
-		if (cmd->convert_arg < 10000)
-			cmd->convert_arg = 10000;
-
-		i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
-					  &divisor1, &divisor2,
-					  &cmd->convert_arg, cmd->flags);
-
-		/*  PCL816 crash if any divisor is set to 1 */
-		if (divisor1 == 1) {
-			divisor1 = 2;
-			divisor2 /= 2;
-		}
-		if (divisor2 == 1) {
-			divisor2 = 2;
-			divisor1 /= 2;
-		}
-	}
-
-	pcl816_start_pacer(dev, false, 0, 0);
+	pcl816_start_pacer(dev, false);
 
 	seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
 	if (seglen < 1)
@@ -546,7 +531,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		enable_dma(devpriv->dma);
 	}
 
-	pcl816_start_pacer(dev, true, divisor1, divisor2);
+	pcl816_start_pacer(dev, true);
 	dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
 
 	switch (cmd->convert_src) {
-- 
1.8.5.2

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-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