public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: OMAP: Add support for dynamic GPIO switch update
@ 2008-12-15 12:08 Jani Nikula
  2008-12-15 12:14 ` Trilok Soni
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Jani Nikula @ 2008-12-15 12:08 UTC (permalink / raw)
  To: linux-omap; +Cc: juha.yrjola, ext-jani.1.nikula

Add new function omap_update_gpio_switch() to support dynamically
changing the GPIO switch notify callback functions and debounce
timeouts.

Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com>
---
 arch/arm/plat-omap/gpio-switch.c              |   39 +++++++++++++++++++++++-
 arch/arm/plat-omap/include/mach/gpio-switch.h |    7 ++++-
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-omap/gpio-switch.c b/arch/arm/plat-omap/gpio-switch.c
index 2b5665d..955cd29 100644
--- a/arch/arm/plat-omap/gpio-switch.c
+++ b/arch/arm/plat-omap/gpio-switch.c
@@ -40,6 +40,7 @@ struct gpio_switch {
 	void (* notify)(void *data, int state);
 	void *notify_data;
 
+	spinlock_t		lock;
 	struct work_struct	work;
 	struct timer_list	timer;
 	struct platform_device	pdev;
@@ -188,6 +189,7 @@ static irqreturn_t gpio_sw_irq_handler(int irq, void *arg)
 	struct gpio_switch *sw = arg;
 	unsigned long timeout;
 	int state;
+	unsigned long flags;
 
 	if (!sw->both_edges) {
 		if (gpio_get_value(sw->gpio))
@@ -200,10 +202,13 @@ static irqreturn_t gpio_sw_irq_handler(int irq, void *arg)
 	if (sw->state == state)
 		return IRQ_HANDLED;
 
+	spin_lock_irqsave(&sw->lock, flags);
 	if (state)
 		timeout = sw->debounce_rising;
 	else
 		timeout = sw->debounce_falling;
+	spin_unlock_irqrestore(&sw->lock, flags);
+
 	if (!timeout)
 		schedule_work(&sw->work);
 	else
@@ -223,14 +228,24 @@ static void gpio_sw_handler(struct work_struct *work)
 {
 	struct gpio_switch *sw = container_of(work, struct gpio_switch, work);
 	int state;
+	unsigned long flags;
+	void (*notify)(void *data, int state);
+	void *notify_data;
 
 	state = gpio_sw_get_state(sw);
 	if (sw->state == state)
 		return;
 
 	sw->state = state;
-	if (sw->notify != NULL)
-		sw->notify(sw->notify_data, state);
+
+	spin_lock_irqsave(&sw->lock, flags);
+	notify = sw->notify;
+	notify_data = sw->notify_data;
+	spin_unlock_irqrestore(&sw->lock, flags);
+
+	if (notify != NULL)
+		notify(notify_data, state);
+
 	sysfs_notify(&sw->pdev.dev.kobj, NULL, "state");
 	print_sw_state(sw, state);
 }
@@ -323,6 +338,7 @@ static int __init new_switch(struct gpio_switch *sw)
 		return r;
 	}
 
+	spin_lock_init(&sw->lock);
 	INIT_WORK(&sw->work, gpio_sw_handler);
 	init_timer(&sw->timer);
 
@@ -388,6 +404,25 @@ no_check:
 	return NULL;
 }
 
+int omap_update_gpio_switch(const struct omap_gpio_switch *cfg)
+{
+	unsigned long flags;
+	struct gpio_switch *sw = find_switch(cfg->gpio, cfg->name);
+
+	if (!sw)
+		return -EINVAL;
+
+	spin_lock_irqsave(&sw->lock, flags);
+	sw->debounce_rising = cfg->debounce_rising;
+	sw->debounce_falling = cfg->debounce_falling;
+	sw->notify = cfg->notify;
+	sw->notify_data = cfg->notify_data;
+	spin_unlock_irqrestore(&sw->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(omap_update_gpio_switch);
+
 static int __init add_board_switches(void)
 {
 	int i;
diff --git a/arch/arm/plat-omap/include/mach/gpio-switch.h b/arch/arm/plat-omap/include/mach/gpio-switch.h
index a143253..53c1fd5 100644
--- a/arch/arm/plat-omap/include/mach/gpio-switch.h
+++ b/arch/arm/plat-omap/include/mach/gpio-switch.h
@@ -47,12 +47,17 @@ struct omap_gpio_switch {
 	void *notify_data;
 };
 
-/* Call at init time only */
 #ifdef CONFIG_OMAP_GPIO_SWITCH
+/* Call at init time only */
 extern void omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
 					int count);
+extern int omap_update_gpio_switch(const struct omap_gpio_switch *cfg);
 #else
 #define omap_register_gpio_switches(tbl, count)	do { } while (0)
+static inline int omap_update_gpio_switch(const struct omap_gpio_switch *cfg)
+{
+	return 0;
+}
 #endif
 
 #endif
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2008-12-21 20:26 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-15 12:08 [PATCH] ARM: OMAP: Add support for dynamic GPIO switch update Jani Nikula
2008-12-15 12:14 ` Trilok Soni
2008-12-15 13:31   ` Felipe Balbi
2008-12-15 13:22 ` Felipe Balbi
2008-12-15 13:44   ` Jani Nikula
2008-12-15 13:56     ` Felipe Balbi
2008-12-15 13:40 ` Juha Yrjölä
2008-12-15 14:52   ` Jani Nikula
2008-12-15 15:29     ` Juha Yrjölä
2008-12-15 15:58       ` Jani Nikula
2008-12-16  6:05         ` Trilok Soni
2008-12-18 11:42           ` GPIO switch framework (was: Re: [PATCH] ARM: OMAP: Add support for dynamic GPIO switch update) Jani Nikula
2008-12-18 13:00             ` Trilok Soni
2008-12-18 13:40               ` Jani Nikula
2008-12-19  8:47                 ` Trilok Soni
2008-12-19  8:51                   ` Brian Swetland
2008-12-21 20:26             ` David Brownell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox