ARM: integrator: push down SC dependencies
authorLinus Walleij <linus.walleij@linaro.org>
Sat, 17 Nov 2012 18:24:23 +0000 (19:24 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Sat, 17 Nov 2012 18:38:27 +0000 (19:38 +0100)
This pushes the dependencies on the Integrator/AP system
controller (SC) down into the PCI V3 driver and the
AP-specific board file.

First, the platform data for the PL010 UART is moved into
the integrator_ap.c board file, and the Integrator/CP is
assigned with NULL pdata. This way the callback functions
can reference the dynamically remapped AP syscon address
in both the ATAG and DT boot path, and this remapping
is localized to the board file.

Second the PCIv3 driver is making its own dynamic remapping
of the SC for the few registers it is using. When we
convert the PCIv3 driver over to using device tree having a
dynamically assigned base address will be useful, but we
will have to use the definition from <mach/platform.h> for
now, the only improvement is that it's done dynamically.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
arch/arm/mach-integrator/common.h
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/include/mach/platform.h
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-integrator/pci_v3.c

index fc9f47d289f4bbc51d2822286963d54559bcbb93..79197d8b34aa1b013e6fb6125017ec5921413410 100644 (file)
@@ -1,5 +1,10 @@
 #include <linux/amba/serial.h>
-extern struct amba_pl010_data integrator_uart_data;
+#ifdef CONFIG_ARCH_INTEGRATOR_AP
+extern struct amba_pl010_data ap_uart_data;
+#else
+/* Not used without Integrator/AP support anyway */
+struct amba_pl010_data ap_uart_data {};
+#endif
 void integrator_init_early(void);
 int integrator_init(bool is_cp);
 void integrator_reserve(void);
index 161fbf8596bd96f1a82cd6450b014f8fd2c01e24..39c060f75e470b79136cf3cdf3bc2c4f603d63b5 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/memblock.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
-#include <linux/termios.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/io.h>
@@ -47,10 +46,10 @@ static AMBA_APB_DEVICE(rtc, "rtc", 0,
        INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
 
 static AMBA_APB_DEVICE(uart0, "uart0", 0,
-       INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data);
+       INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);
 
 static AMBA_APB_DEVICE(uart1, "uart1", 0,
-       INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data);
+       INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);
 
 static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
 static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
@@ -78,6 +77,8 @@ int __init integrator_init(bool is_cp)
                uart1_device.periphid   = 0x00041010;
                kmi0_device.periphid    = 0x00041050;
                kmi1_device.periphid    = 0x00041050;
+               uart0_device.dev.platform_data = &ap_uart_data;
+               uart1_device.dev.platform_data = &ap_uart_data;
        }
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
@@ -90,49 +91,6 @@ int __init integrator_init(bool is_cp)
 
 #endif
 
-/*
- * On the Integrator platform, the port RTS and DTR are provided by
- * bits in the following SC_CTRLS register bits:
- *        RTS  DTR
- *  UART0  7    6
- *  UART1  5    4
- */
-#define SC_CTRLC       __io_address(INTEGRATOR_SC_CTRLC)
-#define SC_CTRLS       __io_address(INTEGRATOR_SC_CTRLS)
-
-static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
-{
-       unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
-       u32 phybase = dev->res.start;
-
-       if (phybase == INTEGRATOR_UART0_BASE) {
-               /* UART0 */
-               rts_mask = 1 << 4;
-               dtr_mask = 1 << 5;
-       } else {
-               /* UART1 */
-               rts_mask = 1 << 6;
-               dtr_mask = 1 << 7;
-       }
-
-       if (mctrl & TIOCM_RTS)
-               ctrlc |= rts_mask;
-       else
-               ctrls |= rts_mask;
-
-       if (mctrl & TIOCM_DTR)
-               ctrlc |= dtr_mask;
-       else
-               ctrls |= dtr_mask;
-
-       __raw_writel(ctrls, SC_CTRLS);
-       __raw_writel(ctrlc, SC_CTRLC);
-}
-
-struct amba_pl010_data integrator_uart_data = {
-       .set_mctrl = integrator_uart_set_mctrl,
-};
-
 static DEFINE_RAW_SPINLOCK(cm_lock);
 
 /**
index efeac5d0bc9ef2abfe3887e93edd653ff2973f55..be5859efe10ee9c9c178a8f6363e0613300adbfa 100644 (file)
 #define INTEGRATOR_SC_CTRLC_OFFSET      0x0C
 #define INTEGRATOR_SC_DEC_OFFSET        0x10
 #define INTEGRATOR_SC_ARB_OFFSET        0x14
-#define INTEGRATOR_SC_PCIENABLE_OFFSET  0x18
 #define INTEGRATOR_SC_LOCK_OFFSET       0x1C
 
 #define INTEGRATOR_SC_BASE              0x11000000
index 771cbe44b66243c5a000d287384c2fce59375f20..a0a7cbbb7a70a74012878ae2aebdceb0367d00af 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/of_platform.h>
 #include <linux/stat.h>
 #include <linux/sys_soc.h>
+#include <linux/termios.h>
 #include <video/vga.h>
 
 #include <mach/hardware.h>
@@ -63,7 +64,7 @@
 #include "common.h"
 
 /* Base address to the AP system controller */
-static void __iomem *ap_syscon_base;
+void __iomem *ap_syscon_base;
 
 /*
  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -250,6 +251,45 @@ static struct physmap_flash_data ap_flash_data = {
        .set_vpp        = ap_flash_set_vpp,
 };
 
+/*
+ * For the PL010 found in the Integrator/AP some of the UART control is
+ * implemented in the system controller and accessed using a callback
+ * from the driver.
+ */
+static void integrator_uart_set_mctrl(struct amba_device *dev,
+                               void __iomem *base, unsigned int mctrl)
+{
+       unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
+       u32 phybase = dev->res.start;
+
+       if (phybase == INTEGRATOR_UART0_BASE) {
+               /* UART0 */
+               rts_mask = 1 << 4;
+               dtr_mask = 1 << 5;
+       } else {
+               /* UART1 */
+               rts_mask = 1 << 6;
+               dtr_mask = 1 << 7;
+       }
+
+       if (mctrl & TIOCM_RTS)
+               ctrlc |= rts_mask;
+       else
+               ctrls |= rts_mask;
+
+       if (mctrl & TIOCM_DTR)
+               ctrlc |= dtr_mask;
+       else
+               ctrls |= dtr_mask;
+
+       __raw_writel(ctrls, ap_syscon_base + INTEGRATOR_SC_CTRLS_OFFSET);
+       __raw_writel(ctrlc, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET);
+}
+
+struct amba_pl010_data ap_uart_data = {
+       .set_mctrl = integrator_uart_set_mctrl,
+};
+
 /*
  * Where is the timer (VA)?
  */
@@ -447,9 +487,9 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
                "rtc", NULL),
        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
-               "uart0", &integrator_uart_data),
+               "uart0", &ap_uart_data),
        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
-               "uart1", &integrator_uart_data),
+               "uart1", &ap_uart_data),
        OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
                "kmi0", NULL),
        OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
index c4b6af9a42391f7e6c2f3f40050be4cbacdf6d1e..29df06b35d0d1ecddce7d403b673f31218fe9241 100644 (file)
@@ -306,9 +306,9 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE,
                "rtc", NULL),
        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
-               "uart0", &integrator_uart_data),
+               "uart0", NULL),
        OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
-               "uart1", &integrator_uart_data),
+               "uart1", NULL),
        OF_DEV_AUXDATA("arm,primecell", KMI0_BASE,
                "kmi0", NULL),
        OF_DEV_AUXDATA("arm,primecell", KMI1_BASE,
index bbeca59df66bc15c3afa68418456bf78cf8f76f8..000edcda4596fb490695bd6d1766be3dd7d355a7 100644 (file)
@@ -388,9 +388,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
  * means I can't get additional information on the reason for the pm2fb
  * problems.  I suppose I'll just have to mind-meld with the machine. ;)
  */
-#define SC_PCI     __io_address(INTEGRATOR_SC_PCIENABLE)
-#define SC_LBFADDR __io_address(INTEGRATOR_SC_BASE + 0x20)
-#define SC_LBFCODE __io_address(INTEGRATOR_SC_BASE + 0x24)
+static void __iomem *ap_syscon_base;
+#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
+#define INTEGRATOR_SC_LBFADDR_OFFSET   0x20
+#define INTEGRATOR_SC_LBFCODE_OFFSET   0x24
 
 static int
 v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
@@ -401,13 +402,13 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        char buf[128];
 
        sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
-               addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
+               addr, fsr, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
                v3_readb(V3_LB_ISTAT));
        printk(KERN_DEBUG "%s", buf);
 #endif
 
        v3_writeb(V3_LB_ISTAT, 0);
-       __raw_writel(3, SC_PCI);
+       __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
 
        /*
         * If the instruction being executed was a read,
@@ -449,15 +450,15 @@ static irqreturn_t v3_irq(int dummy, void *devid)
 
        sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
                "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
-               __raw_readl(SC_LBFADDR),
-               __raw_readl(SC_LBFCODE) & 255,
+               __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
+               __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
                v3_readb(V3_LB_ISTAT));
        printascii(buf);
 #endif
 
        v3_writew(V3_PCI_STAT, 0xf000);
        v3_writeb(V3_LB_ISTAT, 0);
-       __raw_writel(3, SC_PCI);
+       __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
 
 #ifdef CONFIG_DEBUG_LL
        /*
@@ -480,6 +481,10 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
        if (nr == 0) {
                sys->mem_offset = PHYS_PCI_MEM_BASE;
                ret = pci_v3_setup_resources(sys);
+               /* Remap the Integrator system controller */
+               ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
+               if (!ap_syscon_base)
+                       return -EINVAL;
        }
 
        return ret;
@@ -568,7 +573,7 @@ void __init pci_v3_preinit(void)
        v3_writeb(V3_LB_ISTAT, 0);
        v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
        v3_writeb(V3_LB_IMASK, 0x28);
-       __raw_writel(3, SC_PCI);
+       __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
 
        /*
         * Grab the PCI error interrupt.