From 3f40fb9196382afa98d64947a48460f6e720bc38 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Thu, 11 Jul 2019 12:29:05 +0800 Subject: [PATCH] input/touchscreen: fixes s2r for gsl3673 The Android will callback the fb_bank to notice for the early suspend and late resume. In order to keep using the pm sleep and fb callback way with this patch. Change-Id: Ia32ccbede1c6f2b579ad4d21371f2c1774fe4440 Signed-off-by: Caesar Wang --- drivers/input/touchscreen/gsl3673.c | 71 +++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/gsl3673.c b/drivers/input/touchscreen/gsl3673.c index 47ea9bace1ff..8c6ef5f7ce3e 100644 --- a/drivers/input/touchscreen/gsl3673.c +++ b/drivers/input/touchscreen/gsl3673.c @@ -201,6 +201,13 @@ struct gsl_ts { int irq; int rst; int flag_irq_is_disable; + + /* whether the device is registered, true: registered */ + bool flag_activated; + + /* whether the device need resume, true: need resume */ + bool flag_need_resume; + spinlock_t irq_lock; struct tp_device tp; struct work_struct download_fw_work; @@ -1025,11 +1032,14 @@ error_unreg_device: return rc; } -static int __maybe_unused gsl_ts_suspend(struct device *dev) +static int gsl_ts_suspend(struct device *dev) { struct gsl_ts *ts = dev_get_drvdata(dev); int i; + if (!ts->flag_activated) + return 0; + #ifdef GSL_MONITOR cancel_delayed_work_sync(&gsl_monitor_work); #endif @@ -1053,15 +1063,20 @@ static int __maybe_unused gsl_ts_suspend(struct device *dev) report_data(ts, 1, 1, 10, 1); input_sync(ts->input); #endif + ts->flag_activated = false; + return 0; } -static int __maybe_unused gsl_ts_resume(struct device *dev) +static int gsl_ts_resume(struct device *dev) { struct gsl_ts *ts = dev_get_drvdata(dev); int i; int rc; + if (ts->flag_activated) + return 0; + gsl3673_shutdown_high(); mdelay(5); reset_chip(ts->client); @@ -1086,9 +1101,53 @@ static int __maybe_unused gsl_ts_resume(struct device *dev) #endif ts_irq_enable(ts); + ts->flag_activated = true; + return 0; } +static int __maybe_unused gsl_ts_pm_suspend(struct device *dev) +{ + struct gsl_ts *ts = dev_get_drvdata(dev); + int ret; + + if (!ts->flag_activated) + return 0; + + ret = gsl_ts_suspend(dev); + if (ret < 0) + return ret; + + ts->flag_need_resume = true; + return 0; +} + +static int __maybe_unused gsl_ts_pm_resume(struct device *dev) +{ + struct gsl_ts *ts = dev_get_drvdata(dev); + + if (!ts->flag_need_resume) + return 0; + + ts->flag_need_resume = false; + return gsl_ts_resume(dev); +} + +static int gsl_ts_early_suspend(struct tp_device *tp_d) + +{ + struct gsl_ts *ts = container_of(tp_d, struct gsl_ts, tp); + + return gsl_ts_suspend(&ts->client->dev); +} + +static int gsl_ts_late_resume(struct tp_device *tp_d) +{ + struct gsl_ts *ts = container_of(tp_d, struct gsl_ts, tp); + + return gsl_ts_resume(&ts->client->dev); +} + static void gsl_download_fw_work(struct work_struct *work) { struct gsl_ts *ts = container_of(work, struct gsl_ts, download_fw_work); @@ -1117,6 +1176,8 @@ static int gsl_ts_probe(struct i2c_client *client, ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; + ts->tp.tp_resume = gsl_ts_late_resume; + ts->tp.tp_suspend = gsl_ts_early_suspend; tp_register_fb(&ts->tp); ts->client = client; i2c_set_clientdata(client, ts); @@ -1155,6 +1216,8 @@ static int gsl_ts_probe(struct i2c_client *client, proc_create(GSL_CONFIG_PROC_FILE, 0644, NULL, &gsl_seq_fops); gsl_proc_flag = 0; #endif + ts->flag_activated = true; + return 0; error_init_chip_fail: cancel_work_sync(&ts->download_fw_work); @@ -1178,7 +1241,9 @@ static int gsl_ts_remove(struct i2c_client *client) return 0; } -static SIMPLE_DEV_PM_OPS(gsl_ts_pm, gsl_ts_suspend, gsl_ts_resume); +static const struct dev_pm_ops gsl_ts_pm = { + SET_SYSTEM_SLEEP_PM_OPS(gsl_ts_pm_suspend, gsl_ts_pm_resume) +}; static const struct of_device_id gsl_ts_ids[] = { {.compatible = "GSL,GSL3673"},