All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ssb: Make the GPIO API reentrancy safe
@ 2008-02-19 15:22 Michael Buesch
  0 siblings, 0 replies; only message in thread
From: Michael Buesch @ 2008-02-19 15:22 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

This fixes the GPIO API to be reentrancy safe.

Signed-off-by: Michael Buesch <mb@bu3sch.de>

---

For 2.6.25

Index: wireless-testing/drivers/ssb/driver_chipcommon.c
===================================================================
--- wireless-testing.orig/drivers/ssb/driver_chipcommon.c	2008-02-19 14:23:30.000000000 +0100
+++ wireless-testing/drivers/ssb/driver_chipcommon.c	2008-02-19 15:21:01.000000000 +0100
@@ -357,37 +357,31 @@ u32 ssb_chipco_gpio_in(struct ssb_chipco
 {
 	return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask;
 }
-EXPORT_SYMBOL(ssb_chipco_gpio_in);
 
 u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
 	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
 }
-EXPORT_SYMBOL(ssb_chipco_gpio_out);
 
 u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
 	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
 }
-EXPORT_SYMBOL(ssb_chipco_gpio_outen);
 
 u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
 	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
 }
-EXPORT_SYMBOL(ssb_chipco_gpio_control);
 
 u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
 	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value);
 }
-EXPORT_SYMBOL(ssb_chipco_gpio_intmask);
 
 u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value)
 {
 	return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value);
 }
-EXPORT_SYMBOL(ssb_chipco_gpio_polarity);
 
 #ifdef CONFIG_SSB_SERIAL
 int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
Index: wireless-testing/drivers/ssb/driver_extif.c
===================================================================
--- wireless-testing.orig/drivers/ssb/driver_extif.c	2008-02-19 14:35:09.000000000 +0100
+++ wireless-testing/drivers/ssb/driver_extif.c	2008-02-19 15:21:18.000000000 +0100
@@ -122,30 +122,25 @@ u32 ssb_extif_gpio_in(struct ssb_extif *
 {
 	return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
 }
-EXPORT_SYMBOL(ssb_extif_gpio_in);
 
 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
 {
 	return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
 				   mask, value);
 }
-EXPORT_SYMBOL(ssb_extif_gpio_out);
 
 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
 {
 	return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
 				   mask, value);
 }
-EXPORT_SYMBOL(ssb_extif_gpio_outen);
 
 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
 {
 	return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
 }
-EXPORT_SYMBOL(ssb_extif_gpio_polarity);
 
 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
 {
 	return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
 }
-EXPORT_SYMBOL(ssb_extif_gpio_intmask);
Index: wireless-testing/drivers/ssb/embedded.c
===================================================================
--- wireless-testing.orig/drivers/ssb/embedded.c	2008-02-19 12:38:55.000000000 +0100
+++ wireless-testing/drivers/ssb/embedded.c	2008-02-19 15:50:33.000000000 +0100
@@ -11,6 +11,8 @@
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
 
+#include "ssb_private.h"
+
 
 int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks)
 {
@@ -24,3 +26,107 @@ int ssb_watchdog_timer_set(struct ssb_bu
 	}
 	return -ENODEV;
 }
+
+u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&bus->gpio_lock, flags);
+	if (ssb_chipco_available(&bus->chipco))
+		res = ssb_chipco_gpio_in(&bus->chipco, mask);
+	else if (ssb_extif_available(&bus->extif))
+		res = ssb_extif_gpio_in(&bus->extif, mask);
+	else
+		SSB_WARN_ON(1);
+	spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL(ssb_gpio_in);
+
+u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&bus->gpio_lock, flags);
+	if (ssb_chipco_available(&bus->chipco))
+		res = ssb_chipco_gpio_out(&bus->chipco, mask, value);
+	else if (ssb_extif_available(&bus->extif))
+		res = ssb_extif_gpio_out(&bus->extif, mask, value);
+	else
+		SSB_WARN_ON(1);
+	spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL(ssb_gpio_out);
+
+u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&bus->gpio_lock, flags);
+	if (ssb_chipco_available(&bus->chipco))
+		res = ssb_chipco_gpio_outen(&bus->chipco, mask, value);
+	else if (ssb_extif_available(&bus->extif))
+		res = ssb_extif_gpio_outen(&bus->extif, mask, value);
+	else
+		SSB_WARN_ON(1);
+	spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL(ssb_gpio_outen);
+
+u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&bus->gpio_lock, flags);
+	if (ssb_chipco_available(&bus->chipco))
+		res = ssb_chipco_gpio_control(&bus->chipco, mask, value);
+	spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL(ssb_gpio_control);
+
+u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&bus->gpio_lock, flags);
+	if (ssb_chipco_available(&bus->chipco))
+		res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value);
+	else if (ssb_extif_available(&bus->extif))
+		res = ssb_extif_gpio_intmask(&bus->extif, mask, value);
+	else
+		SSB_WARN_ON(1);
+	spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL(ssb_gpio_intmask);
+
+u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value)
+{
+	unsigned long flags;
+	u32 res = 0;
+
+	spin_lock_irqsave(&bus->gpio_lock, flags);
+	if (ssb_chipco_available(&bus->chipco))
+		res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value);
+	else if (ssb_extif_available(&bus->extif))
+		res = ssb_extif_gpio_polarity(&bus->extif, mask, value);
+	else
+		SSB_WARN_ON(1);
+	spin_unlock_irqrestore(&bus->gpio_lock, flags);
+
+	return res;
+}
+EXPORT_SYMBOL(ssb_gpio_polarity);
Index: wireless-testing/include/linux/ssb/ssb.h
===================================================================
--- wireless-testing.orig/include/linux/ssb/ssb.h	2008-02-16 19:08:15.000000000 +0100
+++ wireless-testing/include/linux/ssb/ssb.h	2008-02-19 15:01:00.000000000 +0100
@@ -283,6 +283,11 @@ struct ssb_bus {
 	/* Contents of the SPROM. */
 	struct ssb_sprom sprom;
 
+#ifdef CONFIG_SSB_EMBEDDED
+	/* Lock for GPIO register access. */
+	spinlock_t gpio_lock;
+#endif /* EMBEDDED */
+
 	/* Internal-only stuff follows. Do not touch. */
 	struct list_head list;
 #ifdef CONFIG_SSB_DEBUG
Index: wireless-testing/include/linux/ssb/ssb_embedded.h
===================================================================
--- wireless-testing.orig/include/linux/ssb/ssb_embedded.h	2008-02-19 12:38:55.000000000 +0100
+++ wireless-testing/include/linux/ssb/ssb_embedded.h	2008-02-19 14:57:36.000000000 +0100
@@ -7,4 +7,12 @@
 
 extern int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks);
 
+/* Generic GPIO API */
+u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask);
+u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value);
+u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value);
+
 #endif /* LINUX_SSB_EMBEDDED_H_ */
Index: wireless-testing/drivers/ssb/main.c
===================================================================
--- wireless-testing.orig/drivers/ssb/main.c	2008-02-19 13:20:45.000000000 +0100
+++ wireless-testing/drivers/ssb/main.c	2008-02-19 15:38:01.000000000 +0100
@@ -569,6 +569,9 @@ static int ssb_bus_register(struct ssb_b
 
 	spin_lock_init(&bus->bar_lock);
 	INIT_LIST_HEAD(&bus->list);
+#ifdef CONFIG_SSB_EMBEDDED
+	spin_lock_init(&bus->gpio_lock);
+#endif
 
 	/* Powerup the bus */
 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);

-- 
Greetings Michael.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-02-19 15:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-19 15:22 [PATCH] ssb: Make the GPIO API reentrancy safe Michael Buesch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.