input: touchscreen: fix tp gslxxxx irq number bug
authorBin Yang <yangbin@rock-chips.com>
Wed, 7 Dec 2016 02:53:08 +0000 (10:53 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 8 Dec 2016 06:30:40 +0000 (14:30 +0800)
gslxxxx wrong irq number with the same vopb, may cause vopb abnormal.

ts->irq is gpio number, gslxxxx irq number is ts->client->irq
ts->client->irq = gpio_to_irq(ts->irq)

Change-Id: Ic1f6a46437a2a185f3218d3f0406deeddd9d670a
Signed-off-by: Bin Yang <yangbin@rock-chips.com>
drivers/input/touchscreen/gsl3673.c
drivers/input/touchscreen/gslx680.c

index b5153298334a195dc8aff43d82a22a4912971783..87d5256f27bf9d005cf335a43ae02be30b0022f2 100644 (file)
@@ -200,6 +200,8 @@ struct gsl_ts {
        u8 device_id;
        int irq;
        int rst;
+       int flag_irq_is_disable;
+       spinlock_t irq_lock;
        struct tp_device  tp;
 };
 
@@ -739,6 +741,30 @@ static void report_data(struct gsl_ts *ts, u16 x, u16 y, u8 pressure, u8 id)
 #endif
 }
 
+void 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 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 gsl3673_ts_worker(struct work_struct *work)
 {
        int rc, i;
@@ -853,7 +879,8 @@ schedule:
        i2c_lock_flag = 0;
 i2c_lock_schedule:
 #endif
-       enable_irq(ts->irq);
+       ts_irq_enable(ts);
+
 }
 
 #ifdef GSL_MONITOR
@@ -921,7 +948,7 @@ static irqreturn_t gsl_ts_irq(int irq, void *dev_id)
 {
        struct gsl_ts *ts = (struct gsl_ts *)dev_id;
 
-       disable_irq_nosync(ts->irq);
+       ts_irq_disable(ts);
        if (!work_pending(&ts->work))
                queue_work(ts->wq, &ts->work);
        return IRQ_HANDLED;
@@ -1009,7 +1036,9 @@ static int gsl_ts_suspend(struct device *dev)
 #ifdef GSL_MONITOR
        cancel_delayed_work_sync(&gsl_monitor_work);
 #endif
-       disable_irq_nosync(ts->irq);
+       ts_irq_disable(ts);
+       cancel_work_sync(&ts->work);
+
        gsl3673_shutdown_low();
 #ifdef SLEEP_CLEAR_POINT
        msleep(10);
@@ -1058,8 +1087,8 @@ static int gsl_ts_resume(struct device *dev)
 #ifdef GSL_MONITOR
        queue_delayed_work(gsl_monitor_workqueue, &gsl_monitor_work, 300);
 #endif
-       disable_irq_nosync(ts->irq);
-       enable_irq(ts->irq);
+       ts_irq_enable(ts);
+
        return 0;
 }
 
@@ -1118,6 +1147,7 @@ static int  gsl_ts_probe(struct i2c_client *client,
                goto error_init_chip_fail;
        }
        check_mem_data(ts->client);
+       spin_lock_init(&ts->irq_lock);
        client->irq = gpio_to_irq(ts->irq);
        rc = devm_request_irq(&client->dev, client->irq, gsl_ts_irq,
                                IRQF_TRIGGER_RISING, client->name, ts);
index 2742c35697eb327a72839e8da3c3fbf2b229b6e4..1908486d6e0b5530dfc6f2af1781c920d4b025bf 100644 (file)
@@ -1174,7 +1174,7 @@ static void gslX680_ts_worker(struct work_struct *work)
        i2c_lock_flag = 0;
       i2c_lock_schedule:
 #endif
-       enable_irq(ts->irq);
+       enable_irq(ts->client->irq);
 
 }
 
@@ -1305,7 +1305,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->irq);
+       disable_irq_nosync(ts->client->irq);
 
        if (!work_pending(&ts->work)) {
                queue_work(ts->wq, &ts->work);
@@ -1515,7 +1515,7 @@ static int gsl_ts_early_suspend(struct tp_device *tp_d)
        cancel_delayed_work_sync(&ts->gsl_monitor_work);
 #endif
 
-       disable_irq_nosync(ts->irq);
+       disable_irq_nosync(ts->client->irq);
 
 #ifdef SLEEP_CLEAR_POINT
        msleep(10);
@@ -1567,8 +1567,8 @@ 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->irq);
-       enable_irq(ts->irq);
+       disable_irq_nosync(ts->client->irq);
+       enable_irq(ts->client->irq);
 
        return 0;
 }
@@ -1585,7 +1585,7 @@ static void gsl_ts_early_suspend(struct early_suspend *h)
        cancel_delayed_work_sync(&ts->gsl_monitor_work);
 #endif
 
-       disable_irq_nosync(ts->irq);
+       disable_irq_nosync(ts->client->irq);
 
 #ifdef SLEEP_CLEAR_POINT
        msleep(10);
@@ -1638,8 +1638,9 @@ 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->irq);
-       enable_irq(ts->irq);
+       disable_irq_nosync(ts->client->irq);
+       enable_irq(ts->client->irq);
+
 }
 #endif
 
@@ -1766,7 +1767,7 @@ static int gsl_ts_remove(struct i2c_client *client)
 
        device_init_wakeup(&client->dev, 0);
        cancel_work_sync(&ts->work);
-       free_irq(ts->irq, ts);
+       free_irq(ts->client->irq, ts);
        destroy_workqueue(ts->wq);
        //device_remove_file(&ts->input->dev, &dev_attr_debug_enable);