From 3181ceb5a74e75bf60e6d0cbef91dc0c43a3c446 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 2 Jul 2019 18:18:21 +0800 Subject: [PATCH] input: touchscreen: gsl3673: fixes the correct way during s2r The early used the fb for display, the new drm display can't callback the suspend to resume function in gsl3673 driver. 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: I36c7d89edaf4052e614c5a354f7a0a12c9c4275a Signed-off-by: Caesar Wang --- drivers/input/touchscreen/gsl3673.c | 59 ++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/gsl3673.c b/drivers/input/touchscreen/gsl3673.c index a608eb40d551..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; @@ -1030,6 +1037,9 @@ 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,6 +1063,8 @@ static int gsl_ts_suspend(struct device *dev) report_data(ts, 1, 1, 10, 1); input_sync(ts->input); #endif + ts->flag_activated = false; + return 0; } @@ -1062,6 +1074,9 @@ static int gsl_ts_resume(struct device *dev) int i; int rc; + if (ts->flag_activated) + return 0; + gsl3673_shutdown_high(); mdelay(5); reset_chip(ts->client); @@ -1086,24 +1101,51 @@ static int 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); - gsl_ts_suspend(&ts->client->dev); - return 0; + 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); - int rc; - rc = gsl_ts_resume(&ts->client->dev); - return rc; + return gsl_ts_resume(&ts->client->dev); } static void gsl_download_fw_work(struct work_struct *work) @@ -1174,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); @@ -1197,6 +1241,10 @@ static int gsl_ts_remove(struct i2c_client *client) return 0; } +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"}, { } @@ -1214,6 +1262,7 @@ static struct i2c_driver gsl_ts_driver = { .name = GSL3673_I2C_NAME, .owner = THIS_MODULE, .of_match_table = of_match_ptr(gsl_ts_ids), + .pm = &gsl_ts_pm, }, .probe = gsl_ts_probe, .remove = gsl_ts_remove,