summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorArun Kumar Neelakantam <aneela@codeaurora.org>2014-04-03 14:48:41 +0530
committerArun Kumar Neelakantam <aneela@codeaurora.org>2014-04-04 22:33:10 +0530
commit7bd79dd360de82c4d122fe4b4455a71fcb8c7b2e (patch)
tree66a47d2f2c4c4742485c4086e55eb39596293335 /drivers/tty
parent27a707958c041138defccfdb6adee2641f92b4b0 (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.c44
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;
}