diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-3.6/501-bcma-add-gpio-driver.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.6/501-bcma-add-gpio-driver.patch | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.6/501-bcma-add-gpio-driver.patch b/target/linux/brcm47xx/patches-3.6/501-bcma-add-gpio-driver.patch new file mode 100644 index 0000000000..b8f72a12c6 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.6/501-bcma-add-gpio-driver.patch @@ -0,0 +1,140 @@ +--- a/drivers/bcma/driver_chipcommon.c ++++ b/drivers/bcma/driver_chipcommon.c +@@ -70,6 +70,8 @@ void bcma_core_chipcommon_init(struct bc + (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); + } + ++ spin_lock_init(&cc->gpio_lock); ++ + cc->setup_done = true; + } + +@@ -92,34 +94,81 @@ u32 bcma_chipco_irq_status(struct bcma_d + + u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask) + { +- return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; ++ unsigned long flags; ++ u32 res; ++ ++ spin_lock_irqsave(&cc->gpio_lock, flags); ++ res = bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; ++ spin_unlock_irqrestore(&cc->gpio_lock, flags); ++ ++ return res; + } ++EXPORT_SYMBOL_GPL(bcma_chipco_gpio_in); + + 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); + + 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; + } ++EXPORT_SYMBOL_GPL(bcma_chipco_gpio_intmask); + + 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; + } ++EXPORT_SYMBOL_GPL(bcma_chipco_gpio_polarity); + + #ifdef CONFIG_BCMA_DRIVER_MIPS + void bcma_chipco_serial_init(struct bcma_drv_cc *cc) +--- a/include/linux/bcma/bcma_driver_chipcommon.h ++++ b/include/linux/bcma/bcma_driver_chipcommon.h +@@ -551,6 +551,9 @@ struct bcma_drv_cc { + int nr_serial_ports; + struct bcma_serial_port serial_ports[4]; + #endif /* CONFIG_BCMA_DRIVER_MIPS */ ++ ++ /* Lock for GPIO register access. */ ++ spinlock_t gpio_lock; + }; + + /* Register access */ +@@ -581,13 +584,22 @@ void bcma_chipco_irq_mask(struct bcma_dr + + u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask); + ++#define BCMA_CC_GPIO_LINES 16 ++ + /* Chipcommon GPIO pin access. */ +-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_outen(struct bcma_drv_cc *cc, u32 mask, u32 value); +-u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value); +-u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value); +-u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); ++extern u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask); ++extern u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value); ++extern u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value); ++extern u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, ++ u32 value); ++extern u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, ++ u32 value); ++extern u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, ++ u32 value); ++static inline int bcma_chipco_gpio_count(void) ++{ ++ return BCMA_CC_GPIO_LINES; ++} + + /* PMU support */ + extern void bcma_pmu_init(struct bcma_drv_cc *cc); |