Merge tag 'x86-asm-2024-03-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-2.6-block.git] / drivers / comedi / drivers / comedi_test.c
index 30ea8b53ebf8191db808b928041b0ac9a6e1512a..05ae9122823f8032bf62d8e7cd1f7570115a04f8 100644 (file)
@@ -87,6 +87,8 @@ struct waveform_private {
        struct comedi_device *dev;      /* parent comedi device */
        u64 ao_last_scan_time;          /* time of previous AO scan in usec */
        unsigned int ao_scan_period;    /* AO scan period in usec */
+       bool ai_timer_enable:1;         /* should AI timer be running? */
+       bool ao_timer_enable:1;         /* should AO timer be running? */
        unsigned short ao_loopbacks[N_CHANS];
 };
 
@@ -236,8 +238,12 @@ static void waveform_ai_timer(struct timer_list *t)
                        time_increment = devpriv->ai_convert_time - now;
                else
                        time_increment = 1;
-               mod_timer(&devpriv->ai_timer,
-                         jiffies + usecs_to_jiffies(time_increment));
+               spin_lock(&dev->spinlock);
+               if (devpriv->ai_timer_enable) {
+                       mod_timer(&devpriv->ai_timer,
+                                 jiffies + usecs_to_jiffies(time_increment));
+               }
+               spin_unlock(&dev->spinlock);
        }
 
 overrun:
@@ -393,9 +399,12 @@ static int waveform_ai_cmd(struct comedi_device *dev,
         * Seem to need an extra jiffy here, otherwise timer expires slightly
         * early!
         */
+       spin_lock_bh(&dev->spinlock);
+       devpriv->ai_timer_enable = true;
        devpriv->ai_timer.expires =
                jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1;
        add_timer(&devpriv->ai_timer);
+       spin_unlock_bh(&dev->spinlock);
        return 0;
 }
 
@@ -404,6 +413,9 @@ static int waveform_ai_cancel(struct comedi_device *dev,
 {
        struct waveform_private *devpriv = dev->private;
 
+       spin_lock_bh(&dev->spinlock);
+       devpriv->ai_timer_enable = false;
+       spin_unlock_bh(&dev->spinlock);
        if (in_softirq()) {
                /* Assume we were called from the timer routine itself. */
                del_timer(&devpriv->ai_timer);
@@ -495,8 +507,12 @@ static void waveform_ao_timer(struct timer_list *t)
                unsigned int time_inc = devpriv->ao_last_scan_time +
                                        devpriv->ao_scan_period - now;
 
-               mod_timer(&devpriv->ao_timer,
-                         jiffies + usecs_to_jiffies(time_inc));
+               spin_lock(&dev->spinlock);
+               if (devpriv->ao_timer_enable) {
+                       mod_timer(&devpriv->ao_timer,
+                                 jiffies + usecs_to_jiffies(time_inc));
+               }
+               spin_unlock(&dev->spinlock);
        }
 
 underrun:
@@ -517,9 +533,12 @@ static int waveform_ao_inttrig_start(struct comedi_device *dev,
        async->inttrig = NULL;
 
        devpriv->ao_last_scan_time = ktime_to_us(ktime_get());
+       spin_lock_bh(&dev->spinlock);
+       devpriv->ao_timer_enable = true;
        devpriv->ao_timer.expires =
                jiffies + usecs_to_jiffies(devpriv->ao_scan_period);
        add_timer(&devpriv->ao_timer);
+       spin_unlock_bh(&dev->spinlock);
 
        return 1;
 }
@@ -604,6 +623,9 @@ static int waveform_ao_cancel(struct comedi_device *dev,
        struct waveform_private *devpriv = dev->private;
 
        s->async->inttrig = NULL;
+       spin_lock_bh(&dev->spinlock);
+       devpriv->ao_timer_enable = false;
+       spin_unlock_bh(&dev->spinlock);
        if (in_softirq()) {
                /* Assume we were called from the timer routine itself. */
                del_timer(&devpriv->ao_timer);