diff options
-rw-r--r-- | drivers/misc/mei/vsc-tp.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c index 76a6aa606a26..f5ea38f22419 100644 --- a/drivers/misc/mei/vsc-tp.c +++ b/drivers/misc/mei/vsc-tp.c @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/types.h> +#include <linux/workqueue.h> #include "vsc-tp.h" @@ -76,6 +77,7 @@ struct vsc_tp { atomic_t assert_cnt; wait_queue_head_t xfer_wait; + struct work_struct event_work; vsc_tp_event_cb_t event_notify; void *event_notify_context; @@ -105,19 +107,19 @@ static irqreturn_t vsc_tp_isr(int irq, void *data) wake_up(&tp->xfer_wait); - return IRQ_WAKE_THREAD; + schedule_work(&tp->event_work); + + return IRQ_HANDLED; } -static irqreturn_t vsc_tp_thread_isr(int irq, void *data) +static void vsc_tp_event_work(struct work_struct *work) { - struct vsc_tp *tp = data; + struct vsc_tp *tp = container_of(work, struct vsc_tp, event_work); guard(mutex)(&tp->event_notify_mutex); if (tp->event_notify) tp->event_notify(tp->event_notify_context); - - return IRQ_HANDLED; } /* wakeup firmware and wait for response */ @@ -495,7 +497,7 @@ static int vsc_tp_probe(struct spi_device *spi) tp->spi = spi; irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY); - ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr, + ret = request_threaded_irq(spi->irq, vsc_tp_isr, NULL, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), tp); if (ret) @@ -503,6 +505,7 @@ static int vsc_tp_probe(struct spi_device *spi) mutex_init(&tp->mutex); mutex_init(&tp->event_notify_mutex); + INIT_WORK(&tp->event_work, vsc_tp_event_work); /* only one child acpi device */ ret = acpi_dev_for_each_child(ACPI_COMPANION(dev), @@ -527,6 +530,7 @@ static int vsc_tp_probe(struct spi_device *spi) err_destroy_lock: free_irq(spi->irq, tp); + cancel_work_sync(&tp->event_work); mutex_destroy(&tp->event_notify_mutex); mutex_destroy(&tp->mutex); @@ -542,6 +546,7 @@ static void vsc_tp_remove(struct spi_device *spi) free_irq(spi->irq, tp); + cancel_work_sync(&tp->event_work); mutex_destroy(&tp->event_notify_mutex); mutex_destroy(&tp->mutex); } |