Thread (31 messages) 31 messages, 2 authors, 2011-07-29
STALE5430d

[PATCH v4 REPOST 18/20] gpio/omap: use pm-runtime framework

From: DebBarma, Tarun Kanti <hidden>
Date: 2011-07-27 11:44:58
Also in: linux-omap

Todd,
[...]
quoted
+		/* Initialize the gpio bank registers to init time value */
+		omap_gpio_mod_init(bank);
omap_gpio_mod_init calls mpuio_init calls platform_driver_register
which can't be called in an IRQs off and spinlocked atomic context,
for example, device_private_init calls kzalloc with GFP_KERNEL.

Concurrency protection for this will need to happen prior to the
spinlock (assuming it really does need to be an IRQ saving spinlock
and not a mutex).   Possibly a new mutex is needed to protect the
check for first usage and init'ing the bank (and blocking a racing
second caller until the init is done).
I have isolated mpuio_init() from omap_gpio_mod_init().
mpuio_init() is now called once in omap_gpio_probe().
The omap_gpio_mod_init may be unbalanced with the code performed below
on last free of a GPIO for the bank?  If all GPIOs are freed and then
a new GPIO used, does omap_gpio_mod_init do the right thing?  Need a
separate flag to indicate whether one-time init has ever been
performed, vs. needing runtime PM enable/disable?
With the above changes I am seeing omap_gpio_mod_init() is balanced.
Let me know if I am still missing something.
--
Tarun
quoted
+	}
+
 	/* Set trigger to none. You need to enable the desired trigger with
 	 * request_irq() or set_irq_type().
 	 */
@@ -517,7 +535,6 @@ static void omap_gpio_free(struct gpio_chip *chip,
unsigned offset)
quoted
 	unsigned long flags;

 	spin_lock_irqsave(&bank->lock, flags);
-
 	if (bank->regs->wkup_status)
 		/* Disable wake-up during idle for dynamic tick */
 		_gpio_rmw(base, bank->regs->wkup_status, 1 << offset, 0);
@@ -535,6 +552,18 @@ static void omap_gpio_free(struct gpio_chip *chip,
unsigned offset)
quoted
 	}

 	_reset_gpio(bank, bank->chip.base + offset);
+
+	/*
+	 * If this is the last gpio to be freed in the bank,
+	 * disable the bank module.
+	 */
+	if (!bank->mod_usage) {
+		if (IS_ERR_VALUE(pm_runtime_put_sync(bank->dev) < 0)) {
+			dev_err(bank->dev, "%s: GPIO bank %d "
+					"pm_runtime_put_sync failed\n",
+					__func__, bank->id);
+		}
+	}
 	spin_unlock_irqrestore(&bank->lock, flags);

Todd
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help