[SERIAL] amba-pl010: allow platforms to specify modem control method
[deliverable/linux.git] / arch / arm / mach-integrator / core.c
index 20071a2767cc8ab8f542afe15ea1cd7c58356d6f..576a5e979c0003b6ed8112ce15d1b2d2dacea8c2 100644 (file)
@@ -15,7 +15,9 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+#include <linux/termios.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -28,6 +30,8 @@
 
 #include "common.h"
 
+static struct amba_pl010_data integrator_uart_data;
+
 static struct amba_device rtc_device = {
        .dev            = {
                .bus_id = "mb:15",
@@ -44,6 +48,7 @@ static struct amba_device rtc_device = {
 static struct amba_device uart0_device = {
        .dev            = {
                .bus_id = "mb:16",
+               .platform_data = &integrator_uart_data,
        },
        .res            = {
                .start  = INTEGRATOR_UART0_BASE,
@@ -57,6 +62,7 @@ static struct amba_device uart0_device = {
 static struct amba_device uart1_device = {
        .dev            = {
                .bus_id = "mb:17",
+               .platform_data = &integrator_uart_data,
        },
        .res            = {
                .start  = INTEGRATOR_UART1_BASE,
@@ -115,6 +121,46 @@ static int __init integrator_init(void)
 
 arch_initcall(integrator_init);
 
+/*
+ * 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_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS       (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+
+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;
+
+       if (dev == &uart0_device) {
+               rts_mask = 1 << 4;
+               dtr_mask = 1 << 5;
+       } else {
+               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);
+}
+
+static struct amba_pl010_data integrator_uart_data = {
+       .set_mctrl = integrator_uart_set_mctrl,
+};
+
 #define CM_CTRL        IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET
 
 static DEFINE_SPINLOCK(cm_lock);
This page took 0.06541 seconds and 5 git commands to generate.