aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/driver_extif.c
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2012-11-20 17:24:32 -0500
committerJohn Crispin <blogic@openwrt.org>2012-11-21 15:55:52 -0500
commit394bc7e38be79987ed15de203920c3cddb724cc1 (patch)
tree64cb52592aab0fb2f392560fb99d8d61caa81f4a /drivers/ssb/driver_extif.c
parentda22f22e91f0d14d996c7258101575a5a06ddf85 (diff)
ssb: add locking around gpio register accesses
The GPIOs are access through some registers in the chip common core or over extif. We need locking around these GPIO accesses, all GPIOs are accessed through the same registers and parallel writes will cause problems. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Patchwork: http://patchwork.linux-mips.org/patch/4590 Acked-by: Florian Fainelli <florian@openwrt.org>
Diffstat (limited to 'drivers/ssb/driver_extif.c')
-rw-r--r--drivers/ssb/driver_extif.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
index dc47f30e9cf7..e1d0bb8ad725 100644
--- a/drivers/ssb/driver_extif.c
+++ b/drivers/ssb/driver_extif.c
@@ -118,6 +118,13 @@ void ssb_extif_watchdog_timer_set(struct ssb_extif *extif,
118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); 118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
119} 119}
120 120
121void ssb_extif_init(struct ssb_extif *extif)
122{
123 if (!extif->dev)
124 return; /* We don't have a Extif core */
125 spin_lock_init(&extif->gpio_lock);
126}
127
121u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) 128u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
122{ 129{
123 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; 130 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
@@ -125,22 +132,50 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
125 132
126u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) 133u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
127{ 134{
128 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), 135 unsigned long flags;
136 u32 res = 0;
137
138 spin_lock_irqsave(&extif->gpio_lock, flags);
139 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
129 mask, value); 140 mask, value);
141 spin_unlock_irqrestore(&extif->gpio_lock, flags);
142
143 return res;
130} 144}
131 145
132u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) 146u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
133{ 147{
134 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), 148 unsigned long flags;
149 u32 res = 0;
150
151 spin_lock_irqsave(&extif->gpio_lock, flags);
152 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
135 mask, value); 153 mask, value);
154 spin_unlock_irqrestore(&extif->gpio_lock, flags);
155
156 return res;
136} 157}
137 158
138u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) 159u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
139{ 160{
140 return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); 161 unsigned long flags;
162 u32 res = 0;
163
164 spin_lock_irqsave(&extif->gpio_lock, flags);
165 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
166 spin_unlock_irqrestore(&extif->gpio_lock, flags);
167
168 return res;
141} 169}
142 170
143u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) 171u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
144{ 172{
145 return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); 173 unsigned long flags;
174 u32 res = 0;
175
176 spin_lock_irqsave(&extif->gpio_lock, flags);
177 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
178 spin_unlock_irqrestore(&extif->gpio_lock, flags);
179
180 return res;
146} 181}