input: cyttsp-i2c: Move irq handler to threaded context
Change-Id: I60d038fc06c8f040cf2b69d6b65d9b8e210ff08b
Signed-off-by: Mohan Pallaka <mpallaka@codeaurora.org>
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index aefce3e..4aa4796 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -36,7 +36,6 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/workqueue.h>
#include <linux/byteorder/generic.h>
#include <linux/bitops.h>
#include <linux/pm_runtime.h>
@@ -61,7 +60,6 @@
struct cyttsp {
struct i2c_client *client;
struct input_dev *input;
- struct work_struct work;
struct timer_list timer;
struct mutex mutex;
char phys[32];
@@ -93,13 +91,10 @@
static void cyttsp_late_resume(struct early_suspend *handler);
#endif /* CONFIG_HAS_EARLYSUSPEND */
-static struct workqueue_struct *cyttsp_ts_wq;
-
/* ****************************************************************************
* Prototypes for static functions
* ************************************************************************** */
-static void cyttsp_xy_worker(struct work_struct *work);
static irqreturn_t cyttsp_irq(int irq, void *handle);
static int cyttsp_inlist(u16 prev_track[],
u8 cur_trk_id, u8 *prev_loc, u8 num_touches);
@@ -690,11 +685,6 @@
else
disable_irq(ts->client->irq);
- rc = cancel_work_sync(&ts->work);
-
- if (rc && ts->client->irq)
- enable_irq(ts->client->irq);
-
/* enter bootloader idle mode */
rc = cyttsp_soft_reset(ts);
@@ -922,12 +912,8 @@
static DEVICE_ATTR(cyttsp_fw_name, 0664, cyttsp_fw_name_show,
cyttsp_fw_name_store);
-/* The cyttsp_xy_worker function reads the XY coordinates and sends them to
- * the input layer. It is scheduled from the interrupt (or timer).
- */
-void cyttsp_xy_worker(struct work_struct *work)
+static void cyttsp_xy_handler(struct cyttsp *ts)
{
- struct cyttsp *ts = container_of(work, struct cyttsp, work);
u8 id, tilt, rev_x, rev_y;
u8 i, loc;
u8 prv_tch; /* number of previous touches */
@@ -950,7 +936,7 @@
u8 st_z2;
s32 retval;
- cyttsp_xdebug("TTSP worker start 1:\n");
+ cyttsp_xdebug("TTSP handler start 1:\n");
/* get event data from CYTTSP device */
i = CY_NUM_RETRY;
@@ -963,10 +949,10 @@
if (retval < CY_OK) {
/* return immediately on
* failure to read device on the i2c bus */
- goto exit_xy_worker;
+ goto exit_xy_handler;
}
- cyttsp_xdebug("TTSP worker start 2:\n");
+ cyttsp_xdebug("TTSP handler start 2:\n");
/* compare own irq counter with the device irq counter */
if (ts->client->irq) {
@@ -1043,7 +1029,7 @@
tries++ < 100);
cyttsp_putbl(ts, 2, true, false, false);
}
- goto exit_xy_worker;
+ goto exit_xy_handler;
} else {
cur_tch = GET_NUM_TOUCHES(g_xy_data.tt_stat);
if (IS_LARGE_AREA(g_xy_data.tt_stat)) {
@@ -1126,7 +1112,7 @@
if ((prv_tch == CY_NTCH) &&
((cur_tch == CY_NTCH) ||
(cur_tch > CY_NUM_MT_TCH_ID))) {
- goto exit_xy_worker;
+ goto exit_xy_handler;
}
cyttsp_debug("prev=%d curr=%d\n", prv_tch, cur_tch);
@@ -1816,19 +1802,10 @@
ts->act_trk[id] = cur_trk[id];
}
-exit_xy_worker:
- if (cyttsp_disable_touch) {
- /* Turn off the touch interrupts */
- cyttsp_debug("Not enabling touch\n");
- } else {
- if (ts->client->irq == 0) {
- /* restart event timer */
- mod_timer(&ts->timer, jiffies + TOUCHSCREEN_TIMEOUT);
- } else {
- /* re-enable the interrupt after processing */
- enable_irq(ts->client->irq);
- }
- }
+exit_xy_handler:
+ /* restart event timer */
+ if (ts->client->irq == 0)
+ mod_timer(&ts->timer, jiffies + TOUCHSCREEN_TIMEOUT);
return;
}
@@ -1882,7 +1859,7 @@
cyttsp_xdebug("TTSP Device timer event\n");
/* schedule motion signal handling */
- queue_work(cyttsp_ts_wq, &ts->work);
+ cyttsp_xy_handler(ts);
return;
}
@@ -1899,11 +1876,8 @@
cyttsp_xdebug("%s: Got IRQ\n", CY_I2C_NAME);
- /* disable further interrupts until this interrupt is processed */
- disable_irq_nosync(ts->client->irq);
+ cyttsp_xy_handler(ts);
- /* schedule motion signal handling */
- queue_work(cyttsp_ts_wq, &ts->work);
return IRQ_HANDLED;
}
@@ -2565,9 +2539,6 @@
goto error_free_device;
}
- /* Prepare our worker structure prior to setting up the timer/ISR */
- INIT_WORK(&ts->work, cyttsp_xy_worker);
-
if (gpio_is_valid(ts->platform_data->resout_gpio)) {
/* configure touchscreen reset out gpio */
retval = gpio_request(ts->platform_data->resout_gpio,
@@ -2664,9 +2635,8 @@
mod_timer(&ts->timer, jiffies + TOUCHSCREEN_TIMEOUT);
} else {
cyttsp_info("Setting up interrupt\n");
- /* request_irq() will also call enable_irq() */
- error = request_irq(client->irq, cyttsp_irq,
- IRQF_TRIGGER_FALLING,
+ error = request_threaded_irq(client->irq, NULL, cyttsp_irq,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
client->dev.driver->name, ts);
if (error) {
cyttsp_alert("error: could not request irq\n");
@@ -2988,15 +2958,10 @@
return 0;
}
- /* disable worker */
if (ts->client->irq == 0)
del_timer(&ts->timer);
else
- disable_irq_nosync(ts->client->irq);
- retval = cancel_work_sync(&ts->work);
-
- if (retval)
- enable_irq(ts->client->irq);
+ disable_irq(ts->client->irq);
if (!(retval < CY_OK)) {
if (ts->platform_data->use_sleep &&
@@ -3058,10 +3023,6 @@
device_remove_file(&client->dev, &dev_attr_cyttsp_force_update_fw);
device_remove_file(&client->dev, &dev_attr_cyttsp_fw_name);
- /* Start cleaning up by removing any delayed work and the timer */
- if (cancel_delayed_work((struct delayed_work *)&ts->work) < CY_OK)
- cyttsp_alert("error: could not remove work from workqueue\n");
-
/* free up timer or irq */
if (ts->client->irq == 0) {
err = del_timer(&ts->timer);
@@ -3127,12 +3088,6 @@
cyttsp_info("I2C Touchscreen Driver (Built %s @ %s)\n", \
__DATE__, __TIME__);
- cyttsp_ts_wq = create_singlethread_workqueue("cyttsp_ts_wq");
- if (cyttsp_ts_wq == NULL) {
- cyttsp_debug("No memory for cyttsp_ts_wq\n");
- return -ENOMEM;
- }
-
ret = i2c_add_driver(&cyttsp_driver);
return ret;
@@ -3140,8 +3095,6 @@
static void cyttsp_exit(void)
{
- if (cyttsp_ts_wq)
- destroy_workqueue(cyttsp_ts_wq);
return i2c_del_driver(&cyttsp_driver);
}