summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorTarun Kanti DebBarma <tarun.kanti@ti.com>2011-11-24 03:03:28 +0530
committerTarun Kanti DebBarma <tarun.kanti@ti.com>2012-02-06 16:41:35 +0530
commit72f83af99838bb663f85b65386db5b875748f379 (patch)
tree612ddc67b783a82a40650acbf8a5a2e40f712307 /drivers/gpio
parent2dc983c565e03f6f6f96c5fe7449b65d86af4dee (diff)
gpio/omap: fix debounce clock handling
The dbck_enable_mask indicates which all GPIOs within a bank have debounce enabled and dbck is enabled/disabled based upon this. But there is no mechanism to track the dbck state. In order to manage the dbck state we need additional flag and logic so that turning off/on dbck is synchronized with pm_runtime_put/get_sync calls. Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-omap.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index d483cc9f0c63..69e61aecab71 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -67,6 +67,7 @@ struct gpio_bank {
struct clk *dbck;
u32 mod_usage;
u32 dbck_enable_mask;
+ bool dbck_enabled;
struct device *dev;
bool is_mpuio;
bool dbck_flag;
@@ -158,6 +159,22 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set)
__raw_writel(l, base + reg);
}
+static inline void _gpio_dbck_enable(struct gpio_bank *bank)
+{
+ if (bank->dbck_enable_mask && !bank->dbck_enabled) {
+ clk_enable(bank->dbck);
+ bank->dbck_enabled = true;
+ }
+}
+
+static inline void _gpio_dbck_disable(struct gpio_bank *bank)
+{
+ if (bank->dbck_enable_mask && bank->dbck_enabled) {
+ clk_disable(bank->dbck);
+ bank->dbck_enabled = false;
+ }
+}
+
/**
* _set_gpio_debounce - low level gpio debounce time
* @bank: the gpio bank we're acting upon
@@ -1178,6 +1195,7 @@ save_gpio_context:
bank->get_context_loss_count(bank->dev);
omap_gpio_save_context(bank);
+ _gpio_dbck_disable(bank);
spin_unlock_irqrestore(&bank->lock, flags);
return 0;
@@ -1192,6 +1210,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
unsigned long flags;
spin_lock_irqsave(&bank->lock, flags);
+ _gpio_dbck_enable(bank);
if (!bank->enabled_non_wakeup_gpios || !bank->workaround_enabled) {
spin_unlock_irqrestore(&bank->lock, flags);
return 0;
@@ -1274,16 +1293,11 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
- int j;
-
if (!bank->mod_usage || !bank->loses_context)
continue;
bank->power_mode = pwr_mode;
- for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
- clk_disable(bank->dbck);
-
pm_runtime_put_sync_suspend(bank->dev);
}
}
@@ -1293,14 +1307,9 @@ void omap2_gpio_resume_after_idle(void)
struct gpio_bank *bank;
list_for_each_entry(bank, &omap_gpio_list, node) {
- int j;
-
if (!bank->mod_usage || !bank->loses_context)
continue;
- for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
- clk_enable(bank->dbck);
-
pm_runtime_get_sync(bank->dev);
}
}