diff options
| -rw-r--r-- | Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt | 11 | ||||
| -rw-r--r-- | drivers/serial/cpm_uart/cpm_uart.h | 10 | ||||
| -rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 40 |
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 | ||
| 10 | Modem control lines connected to GPIO controllers are listed in the gpios | ||
| 11 | property as described in booting-without-of.txt, section IX.1 in the following | ||
| 12 | order: | ||
| 13 | |||
| 14 | CTS, RTS, DCD, DSR, DTR, and RI. | ||
| 15 | |||
| 16 | The gpios property is optional and can be left out when control lines are | ||
| 17 | not used. | ||
| 18 | |||
| 10 | Example: | 19 | Example: |
| 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 | |||
| 53 | struct uart_cpm_port { | 62 | struct 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 | ||
| 87 | extern int cpm_uart_nr; | 97 | extern 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 | ||
| 97 | static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 99 | static 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 | ||
| 102 | static unsigned int cpm_uart_get_mctrl(struct uart_port *port) | 110 | static 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 | ||
| 1055 | out_pram: | 1089 | out_pram: |
