Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio/omap: force restore if context loss is not detectable

When booting with device-tree the function pointer for detecting context
loss is not populated. Ideally, the pm_runtime framework should be
enhanced to allow a means for reporting context/state loss and we could
avoid populating such function pointers altogether. In the interim until
a generic non-device specific solution is in place, force a restore of
the gpio bank when enabling the gpio controller.

Adds a new device-tree property for the OMAP GPIO controller to indicate
if the GPIO controller is located in a power-domain that never loses
power and hence will always maintain its logic state.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Jon Hunter and committed by
Linus Walleij
a2797bea 3513cdec

+22 -10
+5 -2
Documentation/devicetree/bindings/gpio/gpio-omap.txt
··· 20 20 8 = active low level-sensitive. 21 21 22 22 OMAP specific properties: 23 - - ti,hwmods: Name of the hwmod associated to the GPIO: 24 - "gpio<X>", <X> being the 1-based instance number from the HW spec 23 + - ti,hwmods: Name of the hwmod associated to the GPIO: 24 + "gpio<X>", <X> being the 1-based instance number 25 + from the HW spec. 26 + - ti,gpio-always-on: Indicates if a GPIO bank is always powered and 27 + so will never lose its logic state. 25 28 26 29 27 30 Example:
+17 -8
drivers/gpio/gpio-omap.c
··· 1120 1120 bank->width = pdata->bank_width; 1121 1121 bank->is_mpuio = pdata->is_mpuio; 1122 1122 bank->non_wakeup_gpios = pdata->non_wakeup_gpios; 1123 - bank->loses_context = pdata->loses_context; 1124 1123 bank->regs = pdata->regs; 1125 1124 #ifdef CONFIG_OF_GPIO 1126 1125 bank->chip.of_node = of_node_get(node); 1127 1126 #endif 1127 + if (node) { 1128 + if (!of_property_read_bool(node, "ti,gpio-always-on")) 1129 + bank->loses_context = true; 1130 + } else { 1131 + bank->loses_context = pdata->loses_context; 1132 + } 1133 + 1128 1134 1129 1135 bank->domain = irq_domain_add_linear(node, bank->width, 1130 1136 &irq_domain_simple_ops, NULL); ··· 1264 1258 { 1265 1259 struct platform_device *pdev = to_platform_device(dev); 1266 1260 struct gpio_bank *bank = platform_get_drvdata(pdev); 1267 - int context_lost_cnt_after; 1268 1261 u32 l = 0, gen, gen0, gen1; 1269 1262 unsigned long flags; 1263 + int c; 1270 1264 1271 1265 spin_lock_irqsave(&bank->lock, flags); 1272 1266 _gpio_dbck_enable(bank); ··· 1282 1276 __raw_writel(bank->context.risingdetect, 1283 1277 bank->base + bank->regs->risingdetect); 1284 1278 1285 - if (bank->get_context_loss_count) { 1286 - context_lost_cnt_after = 1287 - bank->get_context_loss_count(bank->dev); 1288 - if (context_lost_cnt_after != bank->context_loss_count) { 1279 + if (bank->loses_context) { 1280 + if (!bank->get_context_loss_count) { 1289 1281 omap_gpio_restore_context(bank); 1290 1282 } else { 1291 - spin_unlock_irqrestore(&bank->lock, flags); 1292 - return 0; 1283 + c = bank->get_context_loss_count(bank->dev); 1284 + if (c != bank->context_loss_count) { 1285 + omap_gpio_restore_context(bank); 1286 + } else { 1287 + spin_unlock_irqrestore(&bank->lock, flags); 1288 + return 0; 1289 + } 1293 1290 } 1294 1291 } 1295 1292