Merge branch 'imx/compile-fixes' of git://git.linaro.org/people/shawnguo/linux-2...
[pandora-kernel.git] / drivers / bcma / driver_chipcommon.c
index 851e05b..e9f1b3f 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
@@ -26,6 +27,9 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
        u32 leddc_on = 10;
        u32 leddc_off = 90;
 
+       if (cc->setup_done)
+               return;
+
        if (cc->core->id.rev >= 11)
                cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
        cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -52,6 +56,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
                        ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
                         (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
        }
+
+       cc->setup_done = true;
 }
 
 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
@@ -101,3 +107,51 @@ 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);
 }
+
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
+{
+       unsigned int irq;
+       u32 baud_base;
+       u32 i;
+       unsigned int ccrev = cc->core->id.rev;
+       struct bcma_serial_port *ports = cc->serial_ports;
+
+       if (ccrev >= 11 && ccrev != 15) {
+               /* Fixed ALP clock */
+               baud_base = bcma_pmu_alp_clock(cc);
+               if (ccrev >= 21) {
+                       /* Turn off UART clock before switching clocksource. */
+                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
+                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
+                                      & ~BCMA_CC_CORECTL_UARTCLKEN);
+               }
+               /* Set the override bit so we don't divide it */
+               bcma_cc_write32(cc, BCMA_CC_CORECTL,
+                              bcma_cc_read32(cc, BCMA_CC_CORECTL)
+                              | BCMA_CC_CORECTL_UARTCLK0);
+               if (ccrev >= 21) {
+                       /* Re-enable the UART clock. */
+                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
+                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
+                                      | BCMA_CC_CORECTL_UARTCLKEN);
+               }
+       } else {
+               pr_err("serial not supported on this device ccrev: 0x%x\n",
+                      ccrev);
+               return;
+       }
+
+       irq = bcma_core_mips_irq(cc->core);
+
+       /* Determine the registers of the UARTs */
+       cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
+       for (i = 0; i < cc->nr_serial_ports; i++) {
+               ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
+                               (i * 256);
+               ports[i].irq = irq;
+               ports[i].baud_base = baud_base;
+               ports[i].reg_shift = 0;
+       }
+}
+#endif /* CONFIG_BCMA_DRIVER_MIPS */