From cf34c4b7e9e9557db3df5b79028c90b8aeef47b5 Mon Sep 17 00:00:00 2001 From: wlq Date: Tue, 27 Dec 2016 15:36:21 +0800 Subject: [PATCH] input: touchscreen: fix tp gslx680 irq number bug Change-Id: Ic0addb0064dea5ef86741119557fd4945d1aed13 Signed-off-by: Wu Liangqing --- drivers/input/touchscreen/gslx680.c | 44 +++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/input/touchscreen/gslx680.c b/drivers/input/touchscreen/gslx680.c index 1908486d6e0b..f24b0dc69661 100644 --- a/drivers/input/touchscreen/gslx680.c +++ b/drivers/input/touchscreen/gslx680.c @@ -178,6 +178,8 @@ struct gsl_ts { struct work_struct work; struct workqueue_struct *wq; struct gsl_ts_data *dd; + int flag_irq_is_disable; + spinlock_t irq_lock; u8 *touch_data; u8 device_id; int irq; @@ -894,6 +896,30 @@ static void report_data(struct gsl_ts *ts, u16 x, u16 y, u8 pressure, u8 id) } #endif +void glsx680_ts_irq_disable(struct gsl_ts *ts) +{ + unsigned long irqflags; + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (!ts->flag_irq_is_disable) { + disable_irq_nosync(ts->client->irq); + ts->flag_irq_is_disable = 1; + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); +} + +void glsx680_ts_irq_enable(struct gsl_ts *ts) +{ + unsigned long irqflags = 0; + + spin_lock_irqsave(&ts->irq_lock, irqflags); + if (ts->flag_irq_is_disable) { + enable_irq(ts->client->irq); + ts->flag_irq_is_disable = 0; + } + spin_unlock_irqrestore(&ts->irq_lock, irqflags); +} + static void gslX680_ts_worker(struct work_struct *work) { int rc, i; @@ -1174,7 +1200,7 @@ static void gslX680_ts_worker(struct work_struct *work) i2c_lock_flag = 0; i2c_lock_schedule: #endif - enable_irq(ts->client->irq); + glsx680_ts_irq_enable(ts); } @@ -1305,7 +1331,7 @@ static irqreturn_t gsl_ts_irq(int irq, void *dev_id) struct gsl_ts *ts = (struct gsl_ts *)dev_id; //print_info("========gslX680 Interrupt=========\n"); - disable_irq_nosync(ts->client->irq); + glsx680_ts_irq_disable(ts); if (!work_pending(&ts->work)) { queue_work(ts->wq, &ts->work); @@ -1515,7 +1541,8 @@ static int gsl_ts_early_suspend(struct tp_device *tp_d) cancel_delayed_work_sync(&ts->gsl_monitor_work); #endif - disable_irq_nosync(ts->client->irq); + glsx680_ts_irq_disable(ts); + cancel_work_sync(&ts->work); #ifdef SLEEP_CLEAR_POINT msleep(10); @@ -1567,8 +1594,7 @@ static int gsl_ts_late_resume(struct tp_device *tp_d) printk("gsl_ts_resume () : queue gsl_monitor_work\n"); queue_delayed_work(gsl_monitor_workqueue, &ts->gsl_monitor_work, 300); #endif - disable_irq_nosync(ts->client->irq); - enable_irq(ts->client->irq); + glsx680_ts_irq_enable(ts); return 0; } @@ -1585,7 +1611,8 @@ static void gsl_ts_early_suspend(struct early_suspend *h) cancel_delayed_work_sync(&ts->gsl_monitor_work); #endif - disable_irq_nosync(ts->client->irq); + glsx680_ts_irq_disable(ts); + cancel_work_sync(&ts->work); #ifdef SLEEP_CLEAR_POINT msleep(10); @@ -1638,8 +1665,7 @@ static void gsl_ts_late_resume(struct early_suspend *h) printk("gsl_ts_resume () : queue gsl_monitor_work\n"); queue_delayed_work(gsl_monitor_workqueue, &ts->gsl_monitor_work, 300); #endif - disable_irq_nosync(ts->client->irq); - enable_irq(ts->client->irq); + glsx680_ts_irq_enable(ts); } #endif @@ -1684,7 +1710,7 @@ static int gsl_ts_probe(struct i2c_client *client, //printk("##################### probe [2]chip_type=%c .\n",chip_type); init_chip(ts->client, ts); check_mem_data(ts->client, ts); - + spin_lock_init(&ts->irq_lock); client->irq = gpio_to_irq(ts->irq); rc = request_irq(client->irq, gsl_ts_irq, IRQF_TRIGGER_RISING, client->name, ts); -- 2.34.1