diff options
Diffstat (limited to 'drivers/bcma/driver_chipcommon.c')
| -rw-r--r-- | drivers/bcma/driver_chipcommon.c | 99 |
1 files changed, 90 insertions, 9 deletions
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index dc96dd8ebff..b068f98920a 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c @@ -25,13 +25,14 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, return value; } -static u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc) +u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc) { if (cc->capabilities & BCMA_CC_CAP_PMU) return bcma_pmu_get_alp_clock(cc); return 20000000; } +EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock); static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc) { @@ -114,6 +115,8 @@ void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) if (cc->early_setup_done) return; + spin_lock_init(&cc->gpio_lock); + if (cc->core->id.rev >= 11) cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); @@ -137,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) bcma_core_chipcommon_early_init(cc); if (cc->core->id.rev >= 20) { - bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); - bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); + u32 pullup = 0, pulldown = 0; + + if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { + pullup = 0x402e0; + pulldown = 0x20500; + } + + bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); + bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); } if (cc->capabilities & BCMA_CC_CAP_PMU) @@ -202,28 +212,99 @@ 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) { - 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; } +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out); 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; } +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen); +/* + * If the bit is set to 0, chipcommon controlls this GPIO, + * if the bit is set to 1, it is used by some part of the chip and not our code. + */ 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); 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) { - 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; +} + +u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + unsigned long flags; + u32 res; + + if (cc->core->id.rev < 20) + return 0; + + spin_lock_irqsave(&cc->gpio_lock, flags); + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value); + spin_unlock_irqrestore(&cc->gpio_lock, flags); + + return res; +} + +u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value) +{ + unsigned long flags; + u32 res; + + if (cc->core->id.rev < 20) + return 0; + + spin_lock_irqsave(&cc->gpio_lock, flags); + res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value); + spin_unlock_irqrestore(&cc->gpio_lock, flags); + + return res; } #ifdef CONFIG_BCMA_DRIVER_MIPS @@ -258,7 +339,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc) return; } - irq = bcma_core_mips_irq(cc->core); + irq = bcma_core_irq(cc->core); /* Determine the registers of the UARTs */ cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); |
