From 6288b64ec1333159782a335cc2b7f46df4092ca2 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Mon, 14 Oct 2019 18:00:32 +0200 Subject: [PATCH 082/351] input: cyttsp4: Make the driver not hog the system's workqueue The driver's work items can take 100's of ms, use a separate thread for this. Signed-off-by: Ondrej Jirman --- drivers/input/touchscreen/cyttsp4_core.c | 20 ++++++++++++++------ drivers/input/touchscreen/cyttsp4_core.h | 3 ++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index 9d69bde42622..ed7ae5abe648 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c @@ -705,7 +705,7 @@ static void cyttsp4_queue_startup_(struct cyttsp4 *cd) { if (cd->startup_state == STARTUP_NONE) { cd->startup_state = STARTUP_QUEUED; - schedule_work(&cd->startup_work); + queue_work(cd->wq, &cd->startup_work); dev_dbg(cd->dev, "%s: cyttsp4_startup queued\n", __func__); } else { dev_dbg(cd->dev, "%s: startup_state = %d\n", __func__, @@ -1222,9 +1222,7 @@ static void cyttsp4_watchdog_timer(struct timer_list *t) dev_vdbg(cd->dev, "%s: Watchdog timer triggered\n", __func__); - schedule_work(&cd->watchdog_work); - - return; + queue_work(cd->wq, &cd->watchdog_work); } static int cyttsp4_request_exclusive(struct cyttsp4 *cd, void *ownptr, @@ -2038,6 +2036,13 @@ struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, goto error_disable_vdd; } + cd->wq = alloc_workqueue("cyttsp4", WQ_SYSFS, 0); + if (!cd->wq) { + rc = -ENOMEM; + dev_err(dev, "failed to allocate workqueue\n"); + goto error_disable_vdd; + } + /* Initialize device info */ cd->dev = dev; cd->bus_ops = ops; @@ -2061,7 +2066,7 @@ struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, if (rc) { dev_err(cd->dev, "failed to request IRQ %d, err: %d\n", cd->irq, rc); - goto error_disable_vdd; + goto error_free_wq; } /* Setup watchdog timer */ @@ -2095,6 +2100,8 @@ struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, cyttsp4_stop_wd_timer(cd); pm_runtime_disable(dev); cyttsp4_free_si_ptrs(cd); +error_free_wq: + destroy_workqueue(cd->wq); error_disable_vdd: gpiod_set_value_cansleep(cd->reset_gpio, 1); gpiod_set_value_cansleep(cd->power_gpio, 0); @@ -2122,8 +2129,9 @@ int cyttsp4_remove(struct cyttsp4 *cd) pm_runtime_suspend(dev); pm_runtime_disable(dev); - cancel_work_sync(&cd->startup_work); cyttsp4_stop_wd_timer(cd); + cancel_work_sync(&cd->startup_work); + destroy_workqueue(cd->wq); cyttsp4_free_si_ptrs(cd); return 0; } diff --git a/drivers/input/touchscreen/cyttsp4_core.h b/drivers/input/touchscreen/cyttsp4_core.h index 678e14414d20..4f8a407e60e4 100644 --- a/drivers/input/touchscreen/cyttsp4_core.h +++ b/drivers/input/touchscreen/cyttsp4_core.h @@ -62,7 +62,7 @@ enum cyttsp_cmd_bits { }; /* Timeout in ms. */ -#define CY_WATCHDOG_TIMEOUT 1000 +#define CY_WATCHDOG_TIMEOUT 10000 #define CY_MAX_PRINT_SIZE 512 #ifdef VERBOSE_DEBUG @@ -330,6 +330,7 @@ struct cyttsp4 { enum cyttsp4_startup_state startup_state; int int_status; wait_queue_head_t wait_q; + struct workqueue_struct *wq; int irq; struct work_struct startup_work; struct work_struct watchdog_work; -- 2.34.0