summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2025-04-15 13:39:01 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-05-02 07:44:39 +0200
commit4e386645bc01db2d6f7593e0b539366064e72c25 (patch)
tree62970a2ced59369097bee2be39800e3c8202f763
parenta1166e98d80ccb2af4b4fb3bb30041ffc4e8fffc (diff)
downloadlinux-4e386645bc01db2d6f7593e0b539366064e72c25.tar.gz
linux-4e386645bc01db2d6f7593e0b539366064e72c25.tar.bz2
linux-4e386645bc01db2d6f7593e0b539366064e72c25.zip
comedi: jr3_pci: Fix synchronous deletion of timer
commit 44d9b3f584c59a606b521e7274e658d5b866c699 upstream. When `jr3_pci_detach()` is called during device removal, it calls `timer_delete_sync()` to stop the timer, but the timer expiry function always reschedules the timer, so the synchronization is ineffective. Call `timer_shutdown_sync()` instead. It does not matter that the timer expiry function pointer is cleared, because the device is being removed. Fixes: 07b509e6584a5 ("Staging: comedi: add jr3_pci driver") Cc: stable <stable@kernel.org> Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Link: https://lore.kernel.org/r/20250415123901.13483-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/comedi/drivers/jr3_pci.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/comedi/drivers/jr3_pci.c b/drivers/comedi/drivers/jr3_pci.c
index f963080dd61f..8ef13f5baf07 100644
--- a/drivers/comedi/drivers/jr3_pci.c
+++ b/drivers/comedi/drivers/jr3_pci.c
@@ -88,6 +88,7 @@ struct jr3_pci_poll_delay {
struct jr3_pci_dev_private {
struct timer_list timer;
struct comedi_device *dev;
+ bool timer_enable;
};
union jr3_pci_single_range {
@@ -597,10 +598,11 @@ static void jr3_pci_poll_dev(struct timer_list *t)
delay = sub_delay.max;
}
}
+ if (devpriv->timer_enable) {
+ devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
+ add_timer(&devpriv->timer);
+ }
spin_unlock_irqrestore(&dev->spinlock, flags);
-
- devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
- add_timer(&devpriv->timer);
}
static struct jr3_pci_subdev_private *
@@ -749,6 +751,7 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
devpriv->dev = dev;
timer_setup(&devpriv->timer, jr3_pci_poll_dev, 0);
devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
+ devpriv->timer_enable = true;
add_timer(&devpriv->timer);
return 0;
@@ -758,8 +761,12 @@ static void jr3_pci_detach(struct comedi_device *dev)
{
struct jr3_pci_dev_private *devpriv = dev->private;
- if (devpriv)
- del_timer_sync(&devpriv->timer);
+ if (devpriv) {
+ spin_lock_bh(&dev->spinlock);
+ devpriv->timer_enable = false;
+ spin_unlock_bh(&dev->spinlock);
+ timer_delete_sync(&devpriv->timer);
+ }
comedi_pci_detach(dev);
}