diff options
author | Arun Kumar Neelakantam <aneela@codeaurora.org> | 2014-04-03 14:48:41 +0530 |
---|---|---|
committer | Arun Kumar Neelakantam <aneela@codeaurora.org> | 2014-04-04 22:33:10 +0530 |
commit | 7bd79dd360de82c4d122fe4b4455a71fcb8c7b2e (patch) | |
tree | 66a47d2f2c4c4742485c4086e55eb39596293335 /drivers/tty | |
parent | 27a707958c041138defccfdb6adee2641f92b4b0 (diff) |
TTY: msm_smd_tty: Fix client notification issue in suspend state
SMD_TTY driver holds a wakeup source for 500ms to provide enough time
to notify the user client waiting for data. However, when system is in
suspend state the 500ms timer may not be sufficient to notify the
user clients because in some cases system resume of devices and tasks
is taking more time and this causes delay in client notification.
Register for PM_SUSPEND_PREPARE and PM_POST_SUSPEND events to track
system suspend and resume state and then notify the clients after system
resume completes.
CRs-Fixed: 613589
Change-Id: Iffb2ecb1c58f46e0c4a745cdcce2fb717ea2ece8
Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/msm_smd_tty.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index 67edaf557a43..179fcef767cc 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c @@ -27,6 +27,7 @@ #include <linux/slab.h> #include <linux/ipc_logging.h> #include <linux/of.h> +#include <linux/suspend.h> #include <linux/tty.h> #include <linux/tty_driver.h> @@ -40,6 +41,7 @@ #define MAX_SMD_TTYS 37 #define MAX_TTY_BUF_SIZE 2048 #define TTY_PUSH_WS_DELAY 500 +#define TTY_PUSH_WS_POST_SUSPEND_DELAY 100 #define MAX_RA_WAKE_LOCK_NAME_LEN 32 #define SMD_TTY_PROBE_WAIT_TIMEOUT 3000 #define SMD_TTY_LOG_PAGES 2 @@ -63,6 +65,10 @@ static void *smd_tty_log_ctx; static struct delayed_work smd_tty_probe_work; static int smd_tty_probe_done; +static bool smd_tty_in_suspend; +static bool smd_tty_read_in_suspend; +static struct wakeup_source read_in_suspend_ws; + /** * struct smd_tty_info - context for an individual SMD TTY device * @@ -312,6 +318,9 @@ static void smd_tty_read(unsigned long param) */ __pm_wakeup_event(&info->pending_ws, TTY_PUSH_WS_DELAY); + if (smd_tty_in_suspend) + smd_tty_read_in_suspend = true; + tty_flip_buffer_push(tty->port); } @@ -834,6 +843,31 @@ static const struct tty_operations smd_tty_ops = { .tiocmset = smd_tty_tiocmset, }; +static int smd_tty_pm_notifier(struct notifier_block *nb, + unsigned long event, void *unused) +{ + switch (event) { + case PM_SUSPEND_PREPARE: + smd_tty_read_in_suspend = false; + smd_tty_in_suspend = true; + break; + + case PM_POST_SUSPEND: + smd_tty_in_suspend = false; + if (smd_tty_read_in_suspend) { + smd_tty_read_in_suspend = false; + __pm_wakeup_event(&read_in_suspend_ws, + TTY_PUSH_WS_POST_SUSPEND_DELAY); + } + break; + } + return NOTIFY_DONE; +} + +static struct notifier_block smd_tty_pm_nb = { + .notifier_call = smd_tty_pm_notifier, + .priority = 0, +}; /** * smd_tty_log_init()- Init function for IPC logging @@ -938,6 +972,11 @@ static int smd_tty_core_init(void) smd_tty_device_init(idx); } INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker); + + ret = register_pm_notifier(&smd_tty_pm_nb); + if (ret) + pr_err("%s: power state notif error %d\n", __func__, ret); + return 0; } @@ -999,6 +1038,10 @@ static int smd_tty_devicetree_init(struct platform_device *pdev) } INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker); + ret = register_pm_notifier(&smd_tty_pm_nb); + if (ret) + pr_err("%s: power state notif error %d\n", __func__, ret); + return 0; error: @@ -1080,6 +1123,7 @@ static int __init smd_tty_init(void) schedule_delayed_work(&smd_tty_probe_work, msecs_to_jiffies(SMD_TTY_PROBE_WAIT_TIMEOUT)); + wakeup_source_init(&read_in_suspend_ws, "SMDTTY_READ_IN_SUSPEND"); return 0; } |