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