ARM64: configs: rockchip_linux: enable rk3328 internal codec
[firefly-linux-kernel-4.4.55.git] / drivers / input / touchscreen / gslx680.c
index 1908486d6e0b5530dfc6f2af1781c920d4b025bf..f24b0dc696617be8fc9c11e03fa424eb90246663 100644 (file)
@@ -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);