From d563de575579a8f4e71c8c90f82bd9a3df52f65a Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Tue, 22 Nov 2011 08:38:17 -0700 Subject: [PATCH 1/2] msm: smd_tty: Reset the open flag in close operation The open flag in each SMD tty device is not reset during the close operation. When the SMD tty device is closed and reopened quickly, this leads to the completion of open operation even though the underlying SMD channel is not open completely. Hence the few initial operations on the SMD tty device fails. The open flag is reset during the close operation, so that the successive open operation waits until the underlying SMD channel is open completely. Change-Id: I6c154a3c0fc9d084d4374c696fe05b8593999cf9 CRs-Fixed: 318810 Signed-off-by: Karthikeyan Ramasubramanian --- arch/arm/mach-msm/smd_tty.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c index 6f151cbd911..76a02b0dc99 100644 --- a/arch/arm/mach-msm/smd_tty.c +++ b/arch/arm/mach-msm/smd_tty.c @@ -323,12 +323,16 @@ out: static void smd_tty_close(struct tty_struct *tty, struct file *f) { struct smd_tty_info *info = tty->driver_data; + unsigned long flags; if (info == 0) return; mutex_lock(&smd_tty_lock); if (--info->open_count == 0) { + spin_lock_irqsave(&info->reset_lock, flags); + info->is_open = 0; + spin_unlock_irqrestore(&info->reset_lock, flags); if (info->tty) { tasklet_kill(&info->tty_tsklt); wake_lock_destroy(&info->wake_lock); From f8ad4130a7d8edf1d4b7c9c282cb4b263933c39d Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Tue, 22 Nov 2011 09:11:18 -0700 Subject: [PATCH 2/2] msm: smd_tty: Check the device is open before scheduling tasklets When the SMD tty device is closed, tasklets to perform read operation is killed first and then the underlying SMD channel is closed. There is a race condition where the tasklet gets rescuduled between these two operations. So ensure that the device is open before scheduling tasklets to avoid this race condition. Change-Id: I80c4e1538a69b5b05c1aadb0f4b0905f96a90001 CRs-Fixed: 318764 Signed-off-by: Karthikeyan Ramasubramanian --- arch/arm/mach-msm/smd_tty.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c index 76a02b0dc99..b9086e35688 100644 --- a/arch/arm/mach-msm/smd_tty.c +++ b/arch/arm/mach-msm/smd_tty.c @@ -98,7 +98,15 @@ static int is_in_reset(struct smd_tty_info *info) static void buf_req_retry(unsigned long param) { struct smd_tty_info *info = (struct smd_tty_info *)param; - tasklet_hi_schedule(&info->tty_tsklt); + unsigned long flags; + + spin_lock_irqsave(&info->reset_lock, flags); + if (info->is_open) { + spin_unlock_irqrestore(&info->reset_lock, flags); + tasklet_hi_schedule(&info->tty_tsklt); + return; + } + spin_unlock_irqrestore(&info->reset_lock, flags); } static void smd_tty_read(unsigned long param) @@ -163,6 +171,12 @@ static void smd_tty_notify(void *priv, unsigned event) switch (event) { case SMD_EVENT_DATA: + spin_lock_irqsave(&info->reset_lock, flags); + if (!info->is_open) { + spin_unlock_irqrestore(&info->reset_lock, flags); + break; + } + spin_unlock_irqrestore(&info->reset_lock, flags); /* There may be clients (tty framework) that are blocked * waiting for space to write data, so if a possible read * interrupt came in wake anyone waiting and disable the @@ -390,8 +404,15 @@ static int smd_tty_chars_in_buffer(struct tty_struct *tty) static void smd_tty_unthrottle(struct tty_struct *tty) { struct smd_tty_info *info = tty->driver_data; - tasklet_hi_schedule(&info->tty_tsklt); - return; + unsigned long flags; + + spin_lock_irqsave(&info->reset_lock, flags); + if (info->is_open) { + spin_unlock_irqrestore(&info->reset_lock, flags); + tasklet_hi_schedule(&info->tty_tsklt); + return; + } + spin_unlock_irqrestore(&info->reset_lock, flags); } /*