From: Kevin Hilman <khilman@xxxxxx> When a GPIO is freed or shutdown, ensure that the proper bit in dbck_enable_mask is cleared also. Otherwise, context restore on subsequent off-mode transition will restore previous debounce values from the shadow copies (bank->context.debounce*) leading to mismatch state between driver state and hardware state. This was discovered when board code was doing gpio_request_one() gpio_set_debounce() gpio_free() which was leaving the GPIO debounce settings in a confused state. If that GPIO bank is subsequently used with off-mode enabled, bogus state would be restored, leaving GPIO debounce enabled which then prevented the CORE powerdomain from transitioning. To fix, ensure that right bit in bank->dbck_enable_mask is cleared when a GPIO is freed/shutdown so debounce state doesn't persist after free/reset. If this GPIO is the last debounce-enabled GPIO in the bank, the debounce will also be cut. Special thanks to Grazvydas Ignotas for pointing out a bug in the first version that would've disabled debounce on any runtime PM transition. And, special thanks to Jon Hunter for pointing out a bug in the second version which was mistakenly clearing all debounce bits on reset instead of individual GPIOs, as well as suggesting cutting the debounce clock after all debounce bits are cleared. Tesed on 37xx/EVM board which configures GPIO debounce for the ads7846 touchscreen in its board file using the above sequence, and so was failing off-mode tests in dynamic idle. Verified that off-mode tests are passing with this patch. Reported-by: Paul Walmsley <paul@xxxxxxxxx> Cc: Igor Grinberg <grinberg@xxxxxxxxxxxxxx> Cc: Grazvydas Ignotas <notasas@xxxxxxxxx> Cc: Jon Hunter <jon-hunter@xxxxxx> Signed-off-by: Kevin Hilman <khilman@xxxxxx> --- drivers/gpio/gpio-omap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 94cbc84..ce1da19 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -539,6 +539,8 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) _set_gpio_irqenable(bank, gpio, 0); _clear_gpio_irqstatus(bank, gpio); _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); + bank->dbck_enable_mask &= ~(GPIO_BIT(bank, gpio)); + _gpio_dbck_disable(bank); } /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html