aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2021-03-01 16:57:57 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-03-10 09:25:31 +0100
commit036695a65e4f4a731bce35cfc4ee6c05a86bd015 (patch)
tree96f14c1fbe6e6b28113a6339c3607e3b30ba87a5
parentstaging: comedi: dt2814: Remove struct dt2814_private (diff)
downloadlinux-dev-036695a65e4f4a731bce35cfc4ee6c05a86bd015.tar.xz
linux-dev-036695a65e4f4a731bce35cfc4ee6c05a86bd015.zip
staging: comedi: dt2814: Clear stale AI data on detach
When the Comedi "detach" handler is called, it is possible that an extra A/D conversion (triggered during termination of a Comedi asynchronous command) is still in progress. In that case, the FINISH bit in the Status register will eventually get set and there will be stale data waiting to be read from the A/D Data register. The interrupt handler will also be called if still connected at the time. That should all be mostly harmless, but it would be better to wait for any such conversion to complete and clear any stale data during the "detach". Add a custom "detach" handler `dt2814_detach()` to do that if an interrupt handler has been set up. (There is no need to do it if no interrupt handler was set up because Comedi asynchronous command support is disabled in that case.) Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Link: https://lore.kernel.org/r/20210301165757.243065-7-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index d18f9a5a9fb1..ed44ce0d151b 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -346,11 +346,24 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
+static void dt2814_detach(struct comedi_device *dev)
+{
+ if (dev->irq) {
+ /*
+ * An extra conversion triggered on termination of an
+ * asynchronous command may still be in progress. Wait for
+ * it to finish and clear the data or error status.
+ */
+ dt2814_ai_clear(dev);
+ }
+ comedi_legacy_detach(dev);
+}
+
static struct comedi_driver dt2814_driver = {
.driver_name = "dt2814",
.module = THIS_MODULE,
.attach = dt2814_attach,
- .detach = comedi_legacy_detach,
+ .detach = dt2814_detach,
};
module_comedi_driver(dt2814_driver);