1 From ed7c10e75256f03fba7fe0119a2048f230848710 Mon Sep 17 00:00:00 2001
2 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
3 Date: Wed, 13 Jan 2016 17:43:57 +0100
4 Subject: [PATCH 257/366] Revert "ARM: OMAP2: Drop the concept of certain power
5 domains not being able to lose context."
7 Requested by Grygorii Strashko <grygorii.strashko@ti.com>, not required
10 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
12 arch/arm/mach-omap2/gpio.c | 1 +
13 arch/arm/mach-omap2/powerdomain.c | 40 +++++++++++++++++++++++++++++++++
14 arch/arm/mach-omap2/powerdomain.h | 1 +
15 drivers/gpio/gpio-omap.c | 36 +++++++++++++++++------------
16 include/linux/platform_data/gpio-omap.h | 1 +
17 5 files changed, 65 insertions(+), 14 deletions(-)
19 diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
20 index 689a1af..7a57714 100644
21 --- a/arch/arm/mach-omap2/gpio.c
22 +++ b/arch/arm/mach-omap2/gpio.c
23 @@ -130,6 +130,7 @@ static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
26 pwrdm = omap_hwmod_get_pwrdm(oh);
27 + pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
29 pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata));
31 diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
32 index ef4227f..78af6d8 100644
33 --- a/arch/arm/mach-omap2/powerdomain.c
34 +++ b/arch/arm/mach-omap2/powerdomain.c
35 @@ -1166,3 +1166,43 @@ int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
40 + * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
41 + * @pwrdm: struct powerdomain *
43 + * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
44 + * can lose either memory or logic context or if @pwrdm is invalid, or
45 + * returns 0 otherwise. This function is not concerned with how the
46 + * powerdomain registers are programmed (i.e., to go off or not); it's
47 + * concerned with whether it's ever possible for this powerdomain to
48 + * go off while some other part of the chip is active. This function
49 + * assumes that every powerdomain can go to either ON or INACTIVE.
51 +bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
56 + pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
61 + if (pwrdm->pwrsts & PWRSTS_OFF)
64 + if (pwrdm->pwrsts & PWRSTS_RET) {
65 + if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
68 + for (i = 0; i < pwrdm->banks; i++)
69 + if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
73 + for (i = 0; i < pwrdm->banks; i++)
74 + if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
79 diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
80 index 5e0c033..28a796c 100644
81 --- a/arch/arm/mach-omap2/powerdomain.h
82 +++ b/arch/arm/mach-omap2/powerdomain.h
83 @@ -244,6 +244,7 @@ int pwrdm_state_switch(struct powerdomain *pwrdm);
84 int pwrdm_pre_transition(struct powerdomain *pwrdm);
85 int pwrdm_post_transition(struct powerdomain *pwrdm);
86 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
87 +bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
89 extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state);
91 diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
92 index 4423b6d..e183351 100644
93 --- a/drivers/gpio/gpio-omap.c
94 +++ b/drivers/gpio/gpio-omap.c
95 @@ -69,7 +69,7 @@ struct gpio_bank {
100 + bool loses_context;
104 @@ -1208,9 +1208,15 @@ static int omap_gpio_probe(struct platform_device *pdev)
105 #ifdef CONFIG_OF_GPIO
106 bank->chip.of_node = of_node_get(node);
109 - bank->get_context_loss_count =
110 - pdata->get_context_loss_count;
112 + if (!of_property_read_bool(node, "ti,gpio-always-on"))
113 + bank->loses_context = true;
115 + bank->loses_context = pdata->loses_context;
117 + if (bank->loses_context)
118 + bank->get_context_loss_count =
119 + pdata->get_context_loss_count;
122 if (bank->regs->set_dataout && bank->regs->clr_dataout)
123 @@ -1367,7 +1373,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
124 * been initialised and so initialise it now. Also initialise
125 * the context loss count.
127 - if (!bank->context_valid) {
128 + if (bank->loses_context && !bank->context_valid) {
129 omap_gpio_init_context(bank);
131 if (bank->get_context_loss_count)
132 @@ -1388,15 +1394,17 @@ static int omap_gpio_runtime_resume(struct device *dev)
133 writel_relaxed(bank->context.risingdetect,
134 bank->base + bank->regs->risingdetect);
136 - if (!bank->get_context_loss_count) {
137 - omap_gpio_restore_context(bank);
139 - c = bank->get_context_loss_count(bank->dev);
140 - if (c != bank->context_loss_count) {
141 + if (bank->loses_context) {
142 + if (!bank->get_context_loss_count) {
143 omap_gpio_restore_context(bank);
145 - spin_unlock_irqrestore(&bank->lock, flags);
147 + c = bank->get_context_loss_count(bank->dev);
148 + if (c != bank->context_loss_count) {
149 + omap_gpio_restore_context(bank);
151 + raw_spin_unlock_irqrestore(&bank->lock, flags);
157 @@ -1468,7 +1476,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
158 struct gpio_bank *bank;
160 list_for_each_entry(bank, &omap_gpio_list, node) {
161 - if (!BANK_USED(bank))
162 + if (!BANK_USED(bank) || !bank->loses_context)
165 bank->power_mode = pwr_mode;
166 @@ -1482,7 +1490,7 @@ void omap2_gpio_resume_after_idle(void)
167 struct gpio_bank *bank;
169 list_for_each_entry(bank, &omap_gpio_list, node) {
170 - if (!BANK_USED(bank))
171 + if (!BANK_USED(bank) || !bank->loses_context)
174 pm_runtime_get_sync(bank->dev);
175 diff --git a/include/linux/platform_data/gpio-omap.h b/include/linux/platform_data/gpio-omap.h
176 index ff43e01..cb26181 100644
177 --- a/include/linux/platform_data/gpio-omap.h
178 +++ b/include/linux/platform_data/gpio-omap.h
179 @@ -198,6 +198,7 @@ struct omap_gpio_platform_data {
180 int bank_width; /* GPIO bank width */
181 int bank_stride; /* Only needed for omap1 MPUIO */
182 bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
183 + bool loses_context; /* whether the bank would ever lose context */
184 bool is_mpuio; /* whether the bank is of type MPUIO */
185 u32 non_wakeup_gpios;