]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/ssb/driver_extif.c
ssb: add locking around gpio register accesses
[karo-tx-linux.git] / drivers / ssb / driver_extif.c
index dc47f30e9cf7c1be458291ba0d9691bc7768e569..e1d0bb8ad7256c55a463617dd1b5745c307725e0 100644 (file)
@@ -118,6 +118,13 @@ void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
        extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
 }
 
+void ssb_extif_init(struct ssb_extif *extif)
+{
+       if (!extif->dev)
+               return; /* We don't have a Extif core */
+       spin_lock_init(&extif->gpio_lock);
+}
+
 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
 {
        return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
@@ -125,22 +132,50 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
 
 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
 {
-       return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
+       unsigned long flags;
+       u32 res = 0;
+
+       spin_lock_irqsave(&extif->gpio_lock, flags);
+       res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
                                   mask, value);
+       spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+       return res;
 }
 
 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
 {
-       return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
+       unsigned long flags;
+       u32 res = 0;
+
+       spin_lock_irqsave(&extif->gpio_lock, flags);
+       res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
                                   mask, value);
+       spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+       return res;
 }
 
 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
 {
-       return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
+       unsigned long flags;
+       u32 res = 0;
+
+       spin_lock_irqsave(&extif->gpio_lock, flags);
+       res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
+       spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+       return res;
 }
 
 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
 {
-       return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
+       unsigned long flags;
+       u32 res = 0;
+
+       spin_lock_irqsave(&extif->gpio_lock, flags);
+       res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
+       spin_unlock_irqrestore(&extif->gpio_lock, flags);
+
+       return res;
 }