“ae4c42e4e4d76d003f8ca551fe1aef93ff9a4b21”上不存在“...include/git@gitcode.net:openharmony/kernel_linux.git”
提交 ef85fb28 编写于 作者: H Hauke Mehrtens 提交者: John Crispin

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: NHauke Mehrtens <hauke@hauke-m.de>
Patchwork: http://patchwork.linux-mips.org/patch/4585Acked-by: NFlorian Fainelli <florian@openwrt.org>
上级 0ef0165b
...@@ -30,6 +30,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) ...@@ -30,6 +30,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
if (cc->setup_done) if (cc->setup_done)
return; return;
spin_lock_init(&cc->gpio_lock);
if (cc->core->id.rev >= 11) if (cc->core->id.rev >= 11)
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 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,28 +86,63 @@ u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
{ {
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); unsigned long flags;
u32 res;
spin_lock_irqsave(&cc->gpio_lock, flags);
res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
spin_unlock_irqrestore(&cc->gpio_lock, flags);
return res;
} }
u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
{ {
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); unsigned long flags;
u32 res;
spin_lock_irqsave(&cc->gpio_lock, flags);
res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
spin_unlock_irqrestore(&cc->gpio_lock, flags);
return res;
} }
u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
{ {
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); unsigned long flags;
u32 res;
spin_lock_irqsave(&cc->gpio_lock, flags);
res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
spin_unlock_irqrestore(&cc->gpio_lock, flags);
return res;
} }
EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
{ {
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); unsigned long flags;
u32 res;
spin_lock_irqsave(&cc->gpio_lock, flags);
res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
spin_unlock_irqrestore(&cc->gpio_lock, flags);
return res;
} }
u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
{ {
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); unsigned long flags;
u32 res;
spin_lock_irqsave(&cc->gpio_lock, flags);
res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
spin_unlock_irqrestore(&cc->gpio_lock, flags);
return res;
} }
#ifdef CONFIG_BCMA_DRIVER_MIPS #ifdef CONFIG_BCMA_DRIVER_MIPS
......
...@@ -567,6 +567,9 @@ struct bcma_drv_cc { ...@@ -567,6 +567,9 @@ struct bcma_drv_cc {
int nr_serial_ports; int nr_serial_ports;
struct bcma_serial_port serial_ports[4]; struct bcma_serial_port serial_ports[4];
#endif /* CONFIG_BCMA_DRIVER_MIPS */ #endif /* CONFIG_BCMA_DRIVER_MIPS */
/* Lock for GPIO register access. */
spinlock_t gpio_lock;
}; };
/* Register access */ /* Register access */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册