summaryrefslogtreecommitdiff
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorRay Poudrier <rapoudrier@nvidia.com>2011-11-14 16:26:27 -0800
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-21 15:31:17 +0530
commit964834f1203e375c13be8d3fb58b3fada083c579 (patch)
tree264984266456ec0ec7b5db47030c1c71fd6d5b85 /drivers/input/keyboard
parent7bf8839d96911891af925b031bb54f80fcdba1f0 (diff)
input: tegra-kbc: add is_open, don't suspend if no clock
Added is_open to know whether the clock has been disabled. Occasionally _close is called before _suspend during LP0 cycles resulting in a hang as the clock is disabled. Bug 855753 Change-Id: Ida938ada7d14085e11096b25cf41431fc2d46215 Reviewed-on: http://git-master/r/50218 Reviewed-on: http://git-master/r/64257 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/tegra-kbc.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index 134960a219ea..152cbf2af5f5 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -83,6 +83,7 @@ struct tegra_kbc {
unsigned int num_pressed_keys;
struct timer_list timer;
struct clk *clk;
+ int is_open;
unsigned long scan_timeout_count;
unsigned long one_scan_time;
};
@@ -480,6 +481,7 @@ static int tegra_kbc_start(struct tegra_kbc *kbc)
u32 val = 0;
clk_enable(kbc->clk);
+ kbc->is_open = 1;
/* Reset the KBC controller to clear all previous status.*/
tegra_periph_reset_assert(kbc->clk);
@@ -549,6 +551,7 @@ static void tegra_kbc_stop(struct tegra_kbc *kbc)
del_timer_sync(&kbc->timer);
clk_disable(kbc->clk);
+ kbc->is_open = 0;
}
static int tegra_kbc_open(struct input_dev *dev)
@@ -666,6 +669,7 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev)
goto err_iounmap;
}
+ kbc->is_open = 0;
kbc->wake_enable_rows = 0;
kbc->wake_enable_cols = 0;
for (i = 0; i < pdata->wake_cnt; i++) {
@@ -782,6 +786,10 @@ static int tegra_kbc_suspend(struct device *dev)
unsigned long int_st;
dev_dbg(&pdev->dev, "KBC: tegra_kbc_suspend\n");
+
+ if (!kbc->is_open)
+ return 0;
+
if (device_may_wakeup(&pdev->dev)) {
timeout = DIV_ROUND_UP((kbc->scan_timeout_count +
kbc->one_scan_time), 32);
@@ -820,6 +828,9 @@ static int tegra_kbc_resume(struct device *dev)
struct tegra_kbc *kbc = platform_get_drvdata(pdev);
int err = 0;
+ if (!kbc->is_open)
+ return tegra_kbc_start(kbc);
+
if (device_may_wakeup(&pdev->dev)) {
disable_irq_wake(kbc->irq);
tegra_kbc_setup_wakekeys(kbc, false);