From 7485d26b7e13ee8ff82adb271ac90a996c1fe830 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 24 Jul 2008 18:36:37 +0200 Subject: cpm_uart: Modem control lines support This patch replaces the get_mctrl/set_mctrl stubs with modem control line read/write access through the GPIO lib. Available modem control lines are described in the device tree using GPIO bindings. The driver expect a GPIO pin for each of the CTS, RTS, DCD, DSR, DTR and RI signals. Unused control lines can be left out. Signed-off-by: Laurent Pinchart Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart_core.c | 40 ++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'drivers/serial/cpm_uart/cpm_uart_core.c') diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index a4f86927a74b..5e0c17f71653 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -96,13 +98,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port) static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) { - /* Whee. Do nothing. */ + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + + if (pinfo->gpios[GPIO_RTS] >= 0) + gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS)); + + if (pinfo->gpios[GPIO_DTR] >= 0) + gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR)); } static unsigned int cpm_uart_get_mctrl(struct uart_port *port) { - /* Whee. Do nothing. */ - return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; + unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + + if (pinfo->gpios[GPIO_CTS] >= 0) { + if (gpio_get_value(pinfo->gpios[GPIO_CTS])) + mctrl &= ~TIOCM_CTS; + } + + if (pinfo->gpios[GPIO_DSR] >= 0) { + if (gpio_get_value(pinfo->gpios[GPIO_DSR])) + mctrl &= ~TIOCM_DSR; + } + + if (pinfo->gpios[GPIO_DCD] >= 0) { + if (gpio_get_value(pinfo->gpios[GPIO_DCD])) + mctrl &= ~TIOCM_CAR; + } + + if (pinfo->gpios[GPIO_RI] >= 0) { + if (!gpio_get_value(pinfo->gpios[GPIO_RI])) + mctrl |= TIOCM_RNG; + } + + return mctrl; } /* @@ -991,6 +1021,7 @@ static int cpm_uart_init_port(struct device_node *np, void __iomem *mem, *pram; int len; int ret; + int i; data = of_get_property(np, "fsl,cpm-brg", &len); if (!data || len != 4) { @@ -1050,6 +1081,9 @@ static int cpm_uart_init_port(struct device_node *np, goto out_pram; } + for (i = 0; i < NUM_GPIOS; i++) + pinfo->gpios[i] = of_get_gpio(np, i); + return cpm_uart_request_port(&pinfo->port); out_pram: -- cgit v1.2.3-59-g8ed1b From 80776554b6c93cf828ddc702010c6a189aa0d0e9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 28 Jul 2008 10:42:16 +0200 Subject: cpm_uart: Add generic clock API support to set baudrates This patch introduces baudrate setting support via the generic clock API. When present the optional device tree clock property is used instead of fsl-cpm-brg. Platforms can then define complex clock schemes, to output the serial clock on an external pin for instance. Signed-off-by: Laurent Pinchart Signed-off-by: Kumar Gala --- arch/powerpc/platforms/Kconfig | 1 + drivers/serial/cpm_uart/cpm_uart.h | 1 + drivers/serial/cpm_uart/cpm_uart_core.c | 26 +++++++++++++++++++------- 3 files changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers/serial/cpm_uart/cpm_uart_core.c') diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 18a71839dc9e..4c900efa164e 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -283,6 +283,7 @@ config FSL_ULI1575 config CPM bool + select PPC_CLOCK config OF_RTC bool diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 5999ef5ac78e..7274b527a3c1 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -77,6 +77,7 @@ struct uart_cpm_port { unsigned char *rx_buf; u32 flags; void (*set_lineif)(struct uart_cpm_port *); + struct clk *clk; u8 brg; uint dp_addr; void *mem_addr; diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 5e0c17f71653..25efca5a7a1f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -596,7 +597,10 @@ static void cpm_uart_set_termios(struct uart_port *port, out_be16(&sccp->scc_psmr, (sbits << 12) | scval); } - cpm_set_brg(pinfo->brg - 1, baud); + if (pinfo->clk) + clk_set_rate(pinfo->clk, baud); + else + cpm_set_brg(pinfo->brg - 1, baud); spin_unlock_irqrestore(&port->lock, flags); } @@ -1023,13 +1027,21 @@ static int cpm_uart_init_port(struct device_node *np, int ret; int i; - data = of_get_property(np, "fsl,cpm-brg", &len); - if (!data || len != 4) { - printk(KERN_ERR "CPM UART %s has no/invalid " - "fsl,cpm-brg property.\n", np->name); - return -EINVAL; + data = of_get_property(np, "clock", NULL); + if (data) { + struct clk *clk = clk_get(NULL, (const char*)data); + if (!IS_ERR(clk)) + pinfo->clk = clk; + } + if (!pinfo->clk) { + data = of_get_property(np, "fsl,cpm-brg", &len); + if (!data || len != 4) { + printk(KERN_ERR "CPM UART %s has no/invalid " + "fsl,cpm-brg property.\n", np->name); + return -EINVAL; + } + pinfo->brg = *data; } - pinfo->brg = *data; data = of_get_property(np, "fsl,cpm-command", &len); if (!data || len != 4) { -- cgit v1.2.3-59-g8ed1b