aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma/driver_chipcommon.c
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2012-11-20 17:24:27 -0500
committerJohn Crispin <blogic@openwrt.org>2012-11-21 15:55:51 -0500
commitef85fb28305fad7617f307383ebba554a3a891a2 (patch)
treeb644911eafc8f3d0d59fcdbceac556c9f9567f94 /drivers/bcma/driver_chipcommon.c
parent0ef0165b206f4dc86d719c92b0b6a244f690ceb4 (diff)
bcma: add locking around GPIO register accesses
The GPIOs are access through some registers in the chip common core. 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/4585 Acked-by: Florian Fainelli <florian@openwrt.org>
Diffstat (limited to 'drivers/bcma/driver_chipcommon.c')
-rw-r--r--drivers/bcma/driver_chipcommon.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index a4c3ebcc4c86..c9b63d9ff61d 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -30,6 +30,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
30 if (cc->setup_done) 30 if (cc->setup_done)
31 return; 31 return;
32 32
33 spin_lock_init(&cc->gpio_lock);
34
33 if (cc->core->id.rev >= 11) 35 if (cc->core->id.rev >= 11)
34 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 36 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
35 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 37 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -84,28 +86,63 @@ u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
84 86
85u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) 87u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
86{ 88{
87 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); 89 unsigned long flags;
90 u32 res;
91
92 spin_lock_irqsave(&cc->gpio_lock, flags);
93 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
94 spin_unlock_irqrestore(&cc->gpio_lock, flags);
95
96 return res;
88} 97}
89 98
90u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) 99u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
91{ 100{
92 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); 101 unsigned long flags;
102 u32 res;
103
104 spin_lock_irqsave(&cc->gpio_lock, flags);
105 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
106 spin_unlock_irqrestore(&cc->gpio_lock, flags);
107
108 return res;
93} 109}
94 110
95u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) 111u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
96{ 112{
97 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); 113 unsigned long flags;
114 u32 res;
115
116 spin_lock_irqsave(&cc->gpio_lock, flags);
117 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
118 spin_unlock_irqrestore(&cc->gpio_lock, flags);
119
120 return res;
98} 121}
99EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); 122EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
100 123
101u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) 124u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
102{ 125{
103 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); 126 unsigned long flags;
127 u32 res;
128
129 spin_lock_irqsave(&cc->gpio_lock, flags);
130 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
131 spin_unlock_irqrestore(&cc->gpio_lock, flags);
132
133 return res;
104} 134}
105 135
106u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) 136u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
107{ 137{
108 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 138 unsigned long flags;
139 u32 res;
140
141 spin_lock_irqsave(&cc->gpio_lock, flags);
142 res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
143 spin_unlock_irqrestore(&cc->gpio_lock, flags);
144
145 return res;
109} 146}
110 147
111#ifdef CONFIG_BCMA_DRIVER_MIPS 148#ifdef CONFIG_BCMA_DRIVER_MIPS