aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurentp@cse-semaphore.com>2008-07-24 12:36:37 -0400
committerKumar Gala <galak@kernel.crashing.org>2008-07-28 08:48:04 -0400
commit7485d26b7e13ee8ff82adb271ac90a996c1fe830 (patch)
tree13bc7e6f30aa6cfb039e780b597f264eccf9d3df
parentdc2380ec8572fcd7f7e9579afc9fb223300d922f (diff)
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 <laurentp@cse-semaphore.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt11
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h10
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c40
3 files changed, 58 insertions, 3 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt
index b35f3482e3e4..2ea76d9d137c 100644
--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt
@@ -7,6 +7,15 @@ Currently defined compatibles:
7- fsl,cpm2-scc-uart 7- fsl,cpm2-scc-uart
8- fsl,qe-uart 8- fsl,qe-uart
9 9
10Modem control lines connected to GPIO controllers are listed in the gpios
11property as described in booting-without-of.txt, section IX.1 in the following
12order:
13
14CTS, RTS, DCD, DSR, DTR, and RI.
15
16The gpios property is optional and can be left out when control lines are
17not used.
18
10Example: 19Example:
11 20
12 serial@11a00 { 21 serial@11a00 {
@@ -18,4 +27,6 @@ Example:
18 interrupt-parent = <&PIC>; 27 interrupt-parent = <&PIC>;
19 fsl,cpm-brg = <1>; 28 fsl,cpm-brg = <1>;
20 fsl,cpm-command = <00800000>; 29 fsl,cpm-command = <00800000>;
30 gpios = <&gpio_c 15 0
31 &gpio_d 29 0>;
21 }; 32 };
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 5c76e0ae0582..5999ef5ac78e 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -50,6 +50,15 @@
50 50
51#define SCC_WAIT_CLOSING 100 51#define SCC_WAIT_CLOSING 100
52 52
53#define GPIO_CTS 0
54#define GPIO_RTS 1
55#define GPIO_DCD 2
56#define GPIO_DSR 3
57#define GPIO_DTR 4
58#define GPIO_RI 5
59
60#define NUM_GPIOS (GPIO_RI+1)
61
53struct uart_cpm_port { 62struct uart_cpm_port {
54 struct uart_port port; 63 struct uart_port port;
55 u16 rx_nrfifos; 64 u16 rx_nrfifos;
@@ -82,6 +91,7 @@ struct uart_cpm_port {
82 int wait_closing; 91 int wait_closing;
83 /* value to combine with opcode to form cpm command */ 92 /* value to combine with opcode to form cpm command */
84 u32 command; 93 u32 command;
94 int gpios[NUM_GPIOS];
85}; 95};
86 96
87extern int cpm_uart_nr; 97extern int cpm_uart_nr;
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 @@
43#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
44#include <linux/fs_uart_pd.h> 44#include <linux/fs_uart_pd.h>
45#include <linux/of_platform.h> 45#include <linux/of_platform.h>
46#include <linux/gpio.h>
47#include <linux/of_gpio.h>
46 48
47#include <asm/io.h> 49#include <asm/io.h>
48#include <asm/irq.h> 50#include <asm/irq.h>
@@ -96,13 +98,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port)
96 98
97static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 99static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
98{ 100{
99 /* Whee. Do nothing. */ 101 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
102
103 if (pinfo->gpios[GPIO_RTS] >= 0)
104 gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
105
106 if (pinfo->gpios[GPIO_DTR] >= 0)
107 gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
100} 108}
101 109
102static unsigned int cpm_uart_get_mctrl(struct uart_port *port) 110static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
103{ 111{
104 /* Whee. Do nothing. */ 112 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
105 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 113 unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
114
115 if (pinfo->gpios[GPIO_CTS] >= 0) {
116 if (gpio_get_value(pinfo->gpios[GPIO_CTS]))
117 mctrl &= ~TIOCM_CTS;
118 }
119
120 if (pinfo->gpios[GPIO_DSR] >= 0) {
121 if (gpio_get_value(pinfo->gpios[GPIO_DSR]))
122 mctrl &= ~TIOCM_DSR;
123 }
124
125 if (pinfo->gpios[GPIO_DCD] >= 0) {
126 if (gpio_get_value(pinfo->gpios[GPIO_DCD]))
127 mctrl &= ~TIOCM_CAR;
128 }
129
130 if (pinfo->gpios[GPIO_RI] >= 0) {
131 if (!gpio_get_value(pinfo->gpios[GPIO_RI]))
132 mctrl |= TIOCM_RNG;
133 }
134
135 return mctrl;
106} 136}
107 137
108/* 138/*
@@ -991,6 +1021,7 @@ static int cpm_uart_init_port(struct device_node *np,
991 void __iomem *mem, *pram; 1021 void __iomem *mem, *pram;
992 int len; 1022 int len;
993 int ret; 1023 int ret;
1024 int i;
994 1025
995 data = of_get_property(np, "fsl,cpm-brg", &len); 1026 data = of_get_property(np, "fsl,cpm-brg", &len);
996 if (!data || len != 4) { 1027 if (!data || len != 4) {
@@ -1050,6 +1081,9 @@ static int cpm_uart_init_port(struct device_node *np,
1050 goto out_pram; 1081 goto out_pram;
1051 } 1082 }
1052 1083
1084 for (i = 0; i < NUM_GPIOS; i++)
1085 pinfo->gpios[i] = of_get_gpio(np, i);
1086
1053 return cpm_uart_request_port(&pinfo->port); 1087 return cpm_uart_request_port(&pinfo->port);
1054 1088
1055out_pram: 1089out_pram: