aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h11
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c66
2 files changed, 67 insertions, 10 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 5c76e0ae0582..7274b527a3c1 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;
@@ -68,6 +77,7 @@ struct uart_cpm_port {
68 unsigned char *rx_buf; 77 unsigned char *rx_buf;
69 u32 flags; 78 u32 flags;
70 void (*set_lineif)(struct uart_cpm_port *); 79 void (*set_lineif)(struct uart_cpm_port *);
80 struct clk *clk;
71 u8 brg; 81 u8 brg;
72 uint dp_addr; 82 uint dp_addr;
73 void *mem_addr; 83 void *mem_addr;
@@ -82,6 +92,7 @@ struct uart_cpm_port {
82 int wait_closing; 92 int wait_closing;
83 /* value to combine with opcode to form cpm command */ 93 /* value to combine with opcode to form cpm command */
84 u32 command; 94 u32 command;
95 int gpios[NUM_GPIOS];
85}; 96};
86 97
87extern int cpm_uart_nr; 98extern 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..25efca5a7a1f 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -43,6 +43,9 @@
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>
48#include <linux/clk.h>
46 49
47#include <asm/io.h> 50#include <asm/io.h>
48#include <asm/irq.h> 51#include <asm/irq.h>
@@ -96,13 +99,41 @@ static unsigned int cpm_uart_tx_empty(struct uart_port *port)
96 99
97static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 100static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
98{ 101{
99 /* Whee. Do nothing. */ 102 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
103
104 if (pinfo->gpios[GPIO_RTS] >= 0)
105 gpio_set_value(pinfo->gpios[GPIO_RTS], !(mctrl & TIOCM_RTS));
106
107 if (pinfo->gpios[GPIO_DTR] >= 0)
108 gpio_set_value(pinfo->gpios[GPIO_DTR], !(mctrl & TIOCM_DTR));
100} 109}
101 110
102static unsigned int cpm_uart_get_mctrl(struct uart_port *port) 111static unsigned int cpm_uart_get_mctrl(struct uart_port *port)
103{ 112{
104 /* Whee. Do nothing. */ 113 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
105 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 114 unsigned int mctrl = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
115
116 if (pinfo->gpios[GPIO_CTS] >= 0) {
117 if (gpio_get_value(pinfo->gpios[GPIO_CTS]))
118 mctrl &= ~TIOCM_CTS;
119 }
120
121 if (pinfo->gpios[GPIO_DSR] >= 0) {
122 if (gpio_get_value(pinfo->gpios[GPIO_DSR]))
123 mctrl &= ~TIOCM_DSR;
124 }
125
126 if (pinfo->gpios[GPIO_DCD] >= 0) {
127 if (gpio_get_value(pinfo->gpios[GPIO_DCD]))
128 mctrl &= ~TIOCM_CAR;
129 }
130
131 if (pinfo->gpios[GPIO_RI] >= 0) {
132 if (!gpio_get_value(pinfo->gpios[GPIO_RI]))
133 mctrl |= TIOCM_RNG;
134 }
135
136 return mctrl;
106} 137}
107 138
108/* 139/*
@@ -566,7 +597,10 @@ static void cpm_uart_set_termios(struct uart_port *port,
566 out_be16(&sccp->scc_psmr, (sbits << 12) | scval); 597 out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
567 } 598 }
568 599
569 cpm_set_brg(pinfo->brg - 1, baud); 600 if (pinfo->clk)
601 clk_set_rate(pinfo->clk, baud);
602 else
603 cpm_set_brg(pinfo->brg - 1, baud);
570 spin_unlock_irqrestore(&port->lock, flags); 604 spin_unlock_irqrestore(&port->lock, flags);
571} 605}
572 606
@@ -991,14 +1025,23 @@ static int cpm_uart_init_port(struct device_node *np,
991 void __iomem *mem, *pram; 1025 void __iomem *mem, *pram;
992 int len; 1026 int len;
993 int ret; 1027 int ret;
1028 int i;
994 1029
995 data = of_get_property(np, "fsl,cpm-brg", &len); 1030 data = of_get_property(np, "clock", NULL);
996 if (!data || len != 4) { 1031 if (data) {
997 printk(KERN_ERR "CPM UART %s has no/invalid " 1032 struct clk *clk = clk_get(NULL, (const char*)data);
998 "fsl,cpm-brg property.\n", np->name); 1033 if (!IS_ERR(clk))
999 return -EINVAL; 1034 pinfo->clk = clk;
1035 }
1036 if (!pinfo->clk) {
1037 data = of_get_property(np, "fsl,cpm-brg", &len);
1038 if (!data || len != 4) {
1039 printk(KERN_ERR "CPM UART %s has no/invalid "
1040 "fsl,cpm-brg property.\n", np->name);
1041 return -EINVAL;
1042 }
1043 pinfo->brg = *data;
1000 } 1044 }
1001 pinfo->brg = *data;
1002 1045
1003 data = of_get_property(np, "fsl,cpm-command", &len); 1046 data = of_get_property(np, "fsl,cpm-command", &len);
1004 if (!data || len != 4) { 1047 if (!data || len != 4) {
@@ -1050,6 +1093,9 @@ static int cpm_uart_init_port(struct device_node *np,
1050 goto out_pram; 1093 goto out_pram;
1051 } 1094 }
1052 1095
1096 for (i = 0; i < NUM_GPIOS; i++)
1097 pinfo->gpios[i] = of_get_gpio(np, i);
1098
1053 return cpm_uart_request_port(&pinfo->port); 1099 return cpm_uart_request_port(&pinfo->port);
1054 1100
1055out_pram: 1101out_pram: