Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2797bea authored by Jon Hunter's avatar Jon Hunter Committed by Linus Walleij
Browse files

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: default avatarJon Hunter <jon-hunter@ti.com>
Acked-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: default avatarKevin Hilman <khilman@linaro.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 3513cdec
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -21,7 +21,10 @@ Required properties:

OMAP specific properties:
- ti,hwmods:		Name of the hwmod associated to the GPIO:
  "gpio<X>", <X> being the 1-based instance number from the HW spec
			"gpio<X>", <X> being the 1-based instance number
			from the HW spec.
- ti,gpio-always-on: 	Indicates if a GPIO bank is always powered and
			so will never lose its logic state.


Example:
+17 −8
Original line number Diff line number Diff line
@@ -1120,11 +1120,17 @@ static int omap_gpio_probe(struct platform_device *pdev)
	bank->width = pdata->bank_width;
	bank->is_mpuio = pdata->is_mpuio;
	bank->non_wakeup_gpios = pdata->non_wakeup_gpios;
	bank->loses_context = pdata->loses_context;
	bank->regs = pdata->regs;
#ifdef CONFIG_OF_GPIO
	bank->chip.of_node = of_node_get(node);
#endif
	if (node) {
		if (!of_property_read_bool(node, "ti,gpio-always-on"))
			bank->loses_context = true;
	} else {
		bank->loses_context = pdata->loses_context;
	}


	bank->domain = irq_domain_add_linear(node, bank->width,
					     &irq_domain_simple_ops, NULL);
@@ -1258,9 +1264,9 @@ static int omap_gpio_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct gpio_bank *bank = platform_get_drvdata(pdev);
	int context_lost_cnt_after;
	u32 l = 0, gen, gen0, gen1;
	unsigned long flags;
	int c;

	spin_lock_irqsave(&bank->lock, flags);
	_gpio_dbck_enable(bank);
@@ -1276,16 +1282,19 @@ static int omap_gpio_runtime_resume(struct device *dev)
	__raw_writel(bank->context.risingdetect,
		     bank->base + bank->regs->risingdetect);

	if (bank->get_context_loss_count) {
		context_lost_cnt_after =
			bank->get_context_loss_count(bank->dev);
		if (context_lost_cnt_after != bank->context_loss_count) {
	if (bank->loses_context) {
		if (!bank->get_context_loss_count) {
			omap_gpio_restore_context(bank);
		} else {
			c = bank->get_context_loss_count(bank->dev);
			if (c != bank->context_loss_count) {
				omap_gpio_restore_context(bank);
			} else {
				spin_unlock_irqrestore(&bank->lock, flags);
				return 0;
			}
		}
	}

	if (!bank->workaround_enabled) {
		spin_unlock_irqrestore(&bank->lock, flags);