-From b7c100827012ba588089807475affe0c69a3f817 Mon Sep 17 00:00:00 2001
+From 4d58b9a14669e5ea0026f0d27257041aecfcbed3 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Mon, 6 Jun 2011 00:07:33 +0200
-Subject: [PATCH 06/14] bcma: add serial console support
+Subject: [PATCH 06/26] bcma: add serial console support
-This adds support for serial console to bcma, when operating on an
-embedded device.
+This adds support for serial console to bcma, when operating on an SoC.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
- drivers/bcma/bcma_private.h | 6 +++
- drivers/bcma/driver_chipcommon.c | 64 +++++++++++++++++++++++++++++++++
- drivers/bcma/driver_mips.c | 9 +++++
- include/linux/bcma/bcma_driver_mips.h | 11 ++++++
- 4 files changed, 90 insertions(+), 0 deletions(-)
+ drivers/bcma/bcma_private.h | 8 ++++
+ drivers/bcma/driver_chipcommon.c | 48 +++++++++++++++++++++++++++
+ drivers/bcma/driver_chipcommon_pmu.c | 26 ++++++++++++++
+ drivers/bcma/driver_mips.c | 1 +
+ include/linux/bcma/bcma_driver_chipcommon.h | 14 ++++++++
+ 5 files changed, 97 insertions(+), 0 deletions(-)
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
-@@ -29,6 +29,12 @@ void bcma_init_bus(struct bcma_bus *bus)
+@@ -29,6 +29,14 @@ void bcma_init_bus(struct bcma_bus *bus)
/* sprom.c */
int bcma_sprom_get(struct bcma_bus *bus);
+/* driver_chipcommon.c */
+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+extern int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
-+ struct bcma_drv_mips_serial_port *ports);
++void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
++
++/* driver_chipcommon_pmu.c */
++u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
+
#ifdef CONFIG_BCMA_HOST_PCI
/* host_pci.c */
extern int __init bcma_host_pci_init(void);
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
-@@ -92,3 +92,67 @@ u32 bcma_chipco_gpio_polarity(struct bcm
+@@ -106,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
}
+
+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+int bcma_chipco_serial_init(struct bcma_drv_cc *cc,
-+ struct bcma_drv_mips_serial_port *ports)
++void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
+{
-+ int nr_ports = 0;
-+ u32 plltype;
+ unsigned int irq;
-+ u32 baud_base, div;
-+ u32 i, n;
++ u32 baud_base;
++ u32 i;
+ unsigned int ccrev = cc->core->id.rev;
++ struct bcma_serial_port *ports = cc->serial_ports;
+
-+ plltype = (cc->capabilities & BCMA_CC_CAP_PLLT);
-+ irq = bcma_core_mips_irq(cc->core);
-+
-+ if ((ccrev >= 11) && (ccrev != 15) && (ccrev != 20)) {
++ if (ccrev >= 11 && ccrev != 15) {
+ /* Fixed ALP clock */
-+ baud_base = 20000000;
-+ if (cc->capabilities & BCMA_CC_CAP_PMU) {
-+ /* FIXME: baud_base is different for devices with a PMU */
-+ WARN_ON(1);
-+ }
-+ div = 1;
++ 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);
+ }
-+ } else
++ } else {
+ pr_err("serial not supported on this device ccrev: 0x%x\n",
+ ccrev);
++ return;
++ }
+
-+ /* Determine the registers of the UARTs */
-+ n = (cc->capabilities & BCMA_CC_CAP_NRUART);
-+ for (i = 0; i < n; i++) {
-+ void __iomem *cc_mmio;
-+ void __iomem *uart_regs;
-+
-+ cc_mmio = cc->core->bus->mmio +
-+ (cc->core->core_index * BCMA_CORE_SIZE);
-+ uart_regs = cc_mmio + BCMA_CC_UART0_DATA;
-+ uart_regs += (i * 256);
++ irq = bcma_core_mips_irq(cc->core);
+
-+ nr_ports++;
-+ ports[i].regs = uart_regs;
++ /* 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;
+ }
-+
-+ return nr_ports;
+}
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
---- a/drivers/bcma/driver_mips.c
-+++ b/drivers/bcma/driver_mips.c
-@@ -157,6 +157,14 @@ static void bcma_core_mips_dump_irq(stru
- }
+--- a/drivers/bcma/driver_chipcommon_pmu.c
++++ b/drivers/bcma/driver_chipcommon_pmu.c
+@@ -136,3 +136,29 @@ void bcma_pmu_init(struct bcma_drv_cc *c
+ bcma_pmu_swreg_init(cc);
+ bcma_pmu_workarounds(cc);
}
-
-+static void bcma_core_mips_serial_init(struct bcma_drv_mips *mcore)
++
++u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
+{
-+ struct bcma_bus *bus = mcore->core->bus;
++ struct bcma_bus *bus = cc->core->bus;
+
-+ mcore->nr_serial_ports = bcma_chipco_serial_init(&bus->drv_cc,
-+ mcore->serial_ports);
++ switch (bus->chipinfo.id) {
++ case 0x4716:
++ case 0x4748:
++ case 47162:
++ case 0x4313:
++ case 0x5357:
++ case 0x4749:
++ case 53572:
++ /* always 20Mhz */
++ return 20000 * 1000;
++ case 0x5356:
++ case 0x5300:
++ /* always 25Mhz */
++ return 25000 * 1000;
++ default:
++ pr_warn("No ALP clock specified for %04X device, "
++ "pmu rev. %d, using default %d Hz\n",
++ bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
++ }
++ return BCMA_CC_PMU_ALP_CLOCK;
+}
-+
- static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
- {
- struct bcma_bus *bus = mcore->core->bus;
-@@ -229,6 +237,7 @@ void bcma_core_mips_init(struct bcma_drv
+--- a/drivers/bcma/driver_mips.c
++++ b/drivers/bcma/driver_mips.c
+@@ -238,6 +238,7 @@ void bcma_core_mips_init(struct bcma_drv
if (mcore->setup_done)
return;
-+ bcma_core_mips_serial_init(mcore);
++ bcma_chipco_serial_init(&bus->drv_cc);
bcma_core_mips_flash_detect(mcore);
mcore->setup_done = true;
}
---- a/include/linux/bcma/bcma_driver_mips.h
-+++ b/include/linux/bcma/bcma_driver_mips.h
-@@ -32,11 +32,22 @@
-
- struct bcma_device;
+--- a/include/linux/bcma/bcma_driver_chipcommon.h
++++ b/include/linux/bcma/bcma_driver_chipcommon.h
+@@ -241,6 +241,9 @@
+ #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
+ #define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
-+struct bcma_drv_mips_serial_port {
++/* ALP clock on pre-PMU chips */
++#define BCMA_CC_PMU_ALP_CLOCK 20000000
++
+ /* Data for the PMU, if available.
+ * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
+ */
+@@ -255,6 +258,14 @@ struct bcma_pflash {
+ u32 window;
+ u32 window_size;
+ };
++
++struct bcma_serial_port {
+ void *regs;
+ unsigned long clockspeed;
+ unsigned int irq;
+ unsigned int baud_base;
+ unsigned int reg_shift;
+};
-+
- struct bcma_drv_mips {
- struct bcma_device *core;
- u8 setup_done:1;
- unsigned int assigned_irqs;
+ #endif /* CONFIG_BCMA_DRIVER_MIPS */
-+ int nr_serial_ports;
-+ struct bcma_drv_mips_serial_port serial_ports[4];
+ struct bcma_drv_cc {
+@@ -268,6 +279,9 @@ struct bcma_drv_cc {
+ struct bcma_chipcommon_pmu pmu;
+ #ifdef CONFIG_BCMA_DRIVER_MIPS
+ struct bcma_pflash pflash;
+
- u8 flash_buswidth;
- u32 flash_window;
- u32 flash_window_size;
++ int nr_serial_ports;
++ struct bcma_serial_port serial_ports[4];
+ #endif /* CONFIG_BCMA_DRIVER_MIPS */
+ };
+