msm: smd_tty: smd_tty_open to wait until SMD channel is fully open
smd_tty_open waits with timeout for SMD channel to be fully open
before returning.
CRs-Fixed: 296382
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c
index 2a0dcfc..bfc4150 100644
--- a/arch/arm/mach-msm/smd_tty.c
+++ b/arch/arm/mach-msm/smd_tty.c
@@ -56,6 +56,8 @@
void *pil;
int in_reset;
int in_reset_updated;
+ int is_open;
+ wait_queue_head_t ch_opened_wait_queue;
spinlock_t reset_lock;
};
@@ -176,6 +178,8 @@
spin_lock_irqsave(&info->reset_lock, flags);
info->in_reset = 0;
info->in_reset_updated = 1;
+ info->is_open = 1;
+ wake_up_interruptible(&info->ch_opened_wait_queue);
spin_unlock_irqrestore(&info->reset_lock, flags);
break;
@@ -183,6 +187,8 @@
spin_lock_irqsave(&info->reset_lock, flags);
info->in_reset = 1;
info->in_reset_updated = 1;
+ info->is_open = 0;
+ wake_up_interruptible(&info->ch_opened_wait_queue);
spin_unlock_irqrestore(&info->reset_lock, flags);
/* schedule task to send TTY_BREAK */
tasklet_hi_schedule(&info->tty_tsklt);
@@ -281,6 +287,23 @@
smd_ch_edge[n],
&info->ch, info,
smd_tty_notify);
+ if (res < 0) {
+ pr_err("%s: %s open failed %d\n", __func__,
+ smd_ch_name[n], res);
+ goto release_pil;
+ }
+
+ res = wait_event_interruptible_timeout(
+ info->ch_opened_wait_queue,
+ info->is_open, (2 * HZ));
+ if (res == 0)
+ res = -ETIMEDOUT;
+ if (res < 0) {
+ pr_err("%s: wait for %s smd_open failed %d\n",
+ __func__, smd_ch_name[n], res);
+ goto release_pil;
+ }
+ res = 0;
}
}
@@ -505,6 +528,8 @@
smd_tty[0].driver.driver.name = smd_ch_name[0];
smd_tty[0].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[0].reset_lock);
+ smd_tty[0].is_open = 0;
+ init_waitqueue_head(&smd_tty[0].ch_opened_wait_queue);
/*
* DS port is opened in the kernel starting with 8660 fusion.
* Only register the platform driver for targets older than that.
@@ -524,6 +549,8 @@
smd_tty[1].driver.driver.name = smd_ch_name[1];
smd_tty[1].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[1].reset_lock);
+ smd_tty[1].is_open = 0;
+ init_waitqueue_head(&smd_tty[1].ch_opened_wait_queue);
ret = platform_driver_register(&smd_tty[1].driver);
if (ret)
goto unreg0;
@@ -531,6 +558,8 @@
smd_tty[2].driver.driver.name = smd_ch_name[2];
smd_tty[2].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[2].reset_lock);
+ smd_tty[2].is_open = 0;
+ init_waitqueue_head(&smd_tty[2].ch_opened_wait_queue);
ret = platform_driver_register(&smd_tty[2].driver);
if (ret)
goto unreg1;
@@ -538,6 +567,8 @@
smd_tty[3].driver.driver.name = smd_ch_name[3];
smd_tty[3].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[3].reset_lock);
+ smd_tty[3].is_open = 0;
+ init_waitqueue_head(&smd_tty[3].ch_opened_wait_queue);
ret = platform_driver_register(&smd_tty[3].driver);
if (ret)
goto unreg2;
@@ -545,6 +576,8 @@
smd_tty[7].driver.driver.name = smd_ch_name[7];
smd_tty[7].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[7].reset_lock);
+ smd_tty[7].is_open = 0;
+ init_waitqueue_head(&smd_tty[7].ch_opened_wait_queue);
ret = platform_driver_register(&smd_tty[7].driver);
if (ret)
goto unreg3;
@@ -552,6 +585,8 @@
smd_tty[21].driver.driver.name = smd_ch_name[21];
smd_tty[21].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[21].reset_lock);
+ smd_tty[21].is_open = 0;
+ init_waitqueue_head(&smd_tty[21].ch_opened_wait_queue);
ret = platform_driver_register(&smd_tty[21].driver);
if (ret)
goto unreg7;
@@ -559,6 +594,8 @@
smd_tty[27].driver.driver.name = smd_ch_name[27];
smd_tty[27].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[27].reset_lock);
+ smd_tty[27].is_open = 0;
+ init_waitqueue_head(&smd_tty[27].ch_opened_wait_queue);
ret = platform_driver_register(&smd_tty[27].driver);
if (ret)
goto unreg21;
@@ -566,6 +603,8 @@
smd_tty[36].driver.driver.name = "LOOPBACK_TTY";
smd_tty[36].driver.driver.owner = THIS_MODULE;
spin_lock_init(&smd_tty[36].reset_lock);
+ smd_tty[36].is_open = 0;
+ init_waitqueue_head(&smd_tty[36].ch_opened_wait_queue);
INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
ret = platform_driver_register(&smd_tty[36].driver);
if (ret)