aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h58
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c307
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c56
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c16
-rw-r--r--drivers/serial/imx.c40
5 files changed, 319 insertions, 158 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 73c8a088c160..3b35cb779539 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -5,11 +5,20 @@
5 * 5 *
6 * Copyright (C) 2004 Freescale Semiconductor, Inc. 6 * Copyright (C) 2004 Freescale Semiconductor, Inc.
7 * 7 *
8 * 2006 (c) MontaVista Software, Inc.
9 * Vitaly Bordug <vbordug@ru.mvista.com>
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 *
8 */ 15 */
9#ifndef CPM_UART_H 16#ifndef CPM_UART_H
10#define CPM_UART_H 17#define CPM_UART_H
11 18
12#include <linux/config.h> 19#include <linux/config.h>
20#include <linux/platform_device.h>
21#include <linux/fs_uart_pd.h>
13 22
14#if defined(CONFIG_CPM2) 23#if defined(CONFIG_CPM2)
15#include "cpm_uart_cpm2.h" 24#include "cpm_uart_cpm2.h"
@@ -26,14 +35,14 @@
26#define FLAG_SMC 0x00000002 35#define FLAG_SMC 0x00000002
27#define FLAG_CONSOLE 0x00000001 36#define FLAG_CONSOLE 0x00000001
28 37
29#define UART_SMC1 0 38#define UART_SMC1 fsid_smc1_uart
30#define UART_SMC2 1 39#define UART_SMC2 fsid_smc2_uart
31#define UART_SCC1 2 40#define UART_SCC1 fsid_scc1_uart
32#define UART_SCC2 3 41#define UART_SCC2 fsid_scc2_uart
33#define UART_SCC3 4 42#define UART_SCC3 fsid_scc3_uart
34#define UART_SCC4 5 43#define UART_SCC4 fsid_scc4_uart
35 44
36#define UART_NR 6 45#define UART_NR fs_uart_nr
37 46
38#define RX_NUM_FIFO 4 47#define RX_NUM_FIFO 4
39#define RX_BUF_SIZE 32 48#define RX_BUF_SIZE 32
@@ -64,6 +73,7 @@ struct uart_cpm_port {
64 uint dp_addr; 73 uint dp_addr;
65 void *mem_addr; 74 void *mem_addr;
66 dma_addr_t dma_addr; 75 dma_addr_t dma_addr;
76 u32 mem_size;
67 /* helpers */ 77 /* helpers */
68 int baud; 78 int baud;
69 int bits; 79 int bits;
@@ -90,4 +100,38 @@ void scc2_lineif(struct uart_cpm_port *pinfo);
90void scc3_lineif(struct uart_cpm_port *pinfo); 100void scc3_lineif(struct uart_cpm_port *pinfo);
91void scc4_lineif(struct uart_cpm_port *pinfo); 101void scc4_lineif(struct uart_cpm_port *pinfo);
92 102
103/*
104 virtual to phys transtalion
105*/
106static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo)
107{
108 int offset;
109 u32 val = (u32)addr;
110 /* sane check */
111 if (likely((val >= (u32)pinfo->mem_addr)) &&
112 (val<((u32)pinfo->mem_addr + pinfo->mem_size))) {
113 offset = val - (u32)pinfo->mem_addr;
114 return pinfo->dma_addr+offset;
115 }
116 /* something nasty happened */
117 BUG();
118 return 0;
119}
120
121static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo)
122{
123 int offset;
124 u32 val = addr;
125 /* sane check */
126 if (likely((val >= pinfo->dma_addr) &&
127 (val<(pinfo->dma_addr + pinfo->mem_size)))) {
128 offset = val - (u32)pinfo->dma_addr;
129 return (void*)(pinfo->mem_addr+offset);
130 }
131 /* something nasty happened */
132 BUG();
133 return 0;
134}
135
136
93#endif /* CPM_UART_H */ 137#endif /* CPM_UART_H */
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index b7bf4c698a47..969f94900431 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -12,7 +12,8 @@
12 * 12 *
13 * Copyright (C) 2004 Freescale Semiconductor, Inc. 13 * Copyright (C) 2004 Freescale Semiconductor, Inc.
14 * (C) 2004 Intracom, S.A. 14 * (C) 2004 Intracom, S.A.
15 * (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> 15 * (C) 2005-2006 MontaVista Software, Inc.
16 * Vitaly Bordug <vbordug@ru.mvista.com>
16 * 17 *
17 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by 19 * it under the terms of the GNU General Public License as published by
@@ -41,6 +42,7 @@
41#include <linux/device.h> 42#include <linux/device.h>
42#include <linux/bootmem.h> 43#include <linux/bootmem.h>
43#include <linux/dma-mapping.h> 44#include <linux/dma-mapping.h>
45#include <linux/fs_uart_pd.h>
44 46
45#include <asm/io.h> 47#include <asm/io.h>
46#include <asm/irq.h> 48#include <asm/irq.h>
@@ -60,7 +62,7 @@
60/* Track which ports are configured as uarts */ 62/* Track which ports are configured as uarts */
61int cpm_uart_port_map[UART_NR]; 63int cpm_uart_port_map[UART_NR];
62/* How many ports did we config as uarts */ 64/* How many ports did we config as uarts */
63int cpm_uart_nr; 65int cpm_uart_nr = 0;
64 66
65/**************************************************************/ 67/**************************************************************/
66 68
@@ -71,18 +73,51 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo);
71 73
72/**************************************************************/ 74/**************************************************************/
73 75
74static inline unsigned long cpu2cpm_addr(void *addr) 76
77/* Place-holder for board-specific stuff */
78struct platform_device* __attribute__ ((weak)) __init
79early_uart_get_pdev(int index)
80{
81 return NULL;
82}
83
84
85static void cpm_uart_count(void)
75{ 86{
76 if ((unsigned long)addr >= CPM_ADDR) 87 cpm_uart_nr = 0;
77 return (unsigned long)addr; 88#ifdef CONFIG_SERIAL_CPM_SMC1
78 return virt_to_bus(addr); 89 cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
90#endif
91#ifdef CONFIG_SERIAL_CPM_SMC2
92 cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
93#endif
94#ifdef CONFIG_SERIAL_CPM_SCC1
95 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
96#endif
97#ifdef CONFIG_SERIAL_CPM_SCC2
98 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
99#endif
100#ifdef CONFIG_SERIAL_CPM_SCC3
101 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
102#endif
103#ifdef CONFIG_SERIAL_CPM_SCC4
104 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
105#endif
79} 106}
80 107
81static inline void *cpm2cpu_addr(unsigned long addr) 108/* Get UART number by its id */
109static int cpm_uart_id2nr(int id)
82{ 110{
83 if (addr >= CPM_ADDR) 111 int i;
84 return (void *)addr; 112 if (id < UART_NR) {
85 return bus_to_virt(addr); 113 for (i=0; i<UART_NR; i++) {
114 if (cpm_uart_port_map[i] == id)
115 return i;
116 }
117 }
118
119 /* not found or invalid argument */
120 return -1;
86} 121}
87 122
88/* 123/*
@@ -258,7 +293,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
258 } 293 }
259 294
260 /* get pointer */ 295 /* get pointer */
261 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 296 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
262 297
263 /* loop through the buffer */ 298 /* loop through the buffer */
264 while (i-- > 0) { 299 while (i-- > 0) {
@@ -438,7 +473,11 @@ static void cpm_uart_shutdown(struct uart_port *port)
438 } 473 }
439 474
440 /* Shut them really down and reinit buffer descriptors */ 475 /* Shut them really down and reinit buffer descriptors */
441 cpm_line_cr_cmd(line, CPM_CR_STOP_TX); 476 if (IS_SMC(pinfo))
477 cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
478 else
479 cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX);
480
442 cpm_uart_initbd(pinfo); 481 cpm_uart_initbd(pinfo);
443 } 482 }
444} 483}
@@ -601,7 +640,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
601 /* Pick next descriptor and fill from buffer */ 640 /* Pick next descriptor and fill from buffer */
602 bdp = pinfo->tx_cur; 641 bdp = pinfo->tx_cur;
603 642
604 p = cpm2cpu_addr(bdp->cbd_bufaddr); 643 p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
605 644
606 *p++ = port->x_char; 645 *p++ = port->x_char;
607 bdp->cbd_datlen = 1; 646 bdp->cbd_datlen = 1;
@@ -628,7 +667,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
628 667
629 while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { 668 while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
630 count = 0; 669 count = 0;
631 p = cpm2cpu_addr(bdp->cbd_bufaddr); 670 p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
632 while (count < pinfo->tx_fifosize) { 671 while (count < pinfo->tx_fifosize) {
633 *p++ = xmit->buf[xmit->tail]; 672 *p++ = xmit->buf[xmit->tail];
634 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 673 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -677,12 +716,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
677 mem_addr = pinfo->mem_addr; 716 mem_addr = pinfo->mem_addr;
678 bdp = pinfo->rx_cur = pinfo->rx_bd_base; 717 bdp = pinfo->rx_cur = pinfo->rx_bd_base;
679 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { 718 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
680 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 719 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
681 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; 720 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
682 mem_addr += pinfo->rx_fifosize; 721 mem_addr += pinfo->rx_fifosize;
683 } 722 }
684 723
685 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 724 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
686 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; 725 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
687 726
688 /* Set the physical address of the host memory 727 /* Set the physical address of the host memory
@@ -692,12 +731,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
692 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); 731 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
693 bdp = pinfo->tx_cur = pinfo->tx_bd_base; 732 bdp = pinfo->tx_cur = pinfo->tx_bd_base;
694 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { 733 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
695 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 734 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
696 bdp->cbd_sc = BD_SC_INTRPT; 735 bdp->cbd_sc = BD_SC_INTRPT;
697 mem_addr += pinfo->tx_fifosize; 736 mem_addr += pinfo->tx_fifosize;
698 } 737 }
699 738
700 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 739 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
701 bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; 740 bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
702} 741}
703 742
@@ -829,14 +868,6 @@ static int cpm_uart_request_port(struct uart_port *port)
829 if (pinfo->flags & FLAG_CONSOLE) 868 if (pinfo->flags & FLAG_CONSOLE)
830 return 0; 869 return 0;
831 870
832 /*
833 * Setup any port IO, connect any baud rate generators,
834 * etc. This is expected to be handled by board
835 * dependant code
836 */
837 if (pinfo->set_lineif)
838 pinfo->set_lineif(pinfo);
839
840 if (IS_SMC(pinfo)) { 871 if (IS_SMC(pinfo)) {
841 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 872 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
842 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 873 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -988,6 +1019,58 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
988 }, 1019 },
989}; 1020};
990 1021
1022int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
1023{
1024 struct resource *r;
1025 struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
1026 int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
1027 struct uart_cpm_port *pinfo;
1028 int line;
1029 u32 mem, pram;
1030
1031 line = cpm_uart_id2nr(idx);
1032 if(line < 0) {
1033 printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx);
1034 return -1;
1035 }
1036
1037 pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
1038
1039 pinfo->brg = pdata->brg;
1040
1041 if (!is_con) {
1042 pinfo->port.line = line;
1043 pinfo->port.flags = UPF_BOOT_AUTOCONF;
1044 }
1045
1046 if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
1047 return -EINVAL;
1048 mem = r->start;
1049
1050 if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
1051 return -EINVAL;
1052 pram = r->start;
1053
1054 if(idx > fsid_smc2_uart) {
1055 pinfo->sccp = (scc_t *)mem;
1056 pinfo->sccup = (scc_uart_t *)pram;
1057 } else {
1058 pinfo->smcp = (smc_t *)mem;
1059 pinfo->smcup = (smc_uart_t *)pram;
1060 }
1061 pinfo->tx_nrfifos = pdata->tx_num_fifo;
1062 pinfo->tx_fifosize = pdata->tx_buf_size;
1063
1064 pinfo->rx_nrfifos = pdata->rx_num_fifo;
1065 pinfo->rx_fifosize = pdata->rx_buf_size;
1066
1067 pinfo->port.uartclk = pdata->uart_clk;
1068 pinfo->port.mapbase = (unsigned long)mem;
1069 pinfo->port.irq = platform_get_irq(pdev, 0);
1070
1071 return 0;
1072}
1073
991#ifdef CONFIG_SERIAL_CPM_CONSOLE 1074#ifdef CONFIG_SERIAL_CPM_CONSOLE
992/* 1075/*
993 * Print a string to the serial port trying not to disturb 1076 * Print a string to the serial port trying not to disturb
@@ -1027,7 +1110,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
1027 * If the buffer address is in the CPM DPRAM, don't 1110 * If the buffer address is in the CPM DPRAM, don't
1028 * convert it. 1111 * convert it.
1029 */ 1112 */
1030 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 1113 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
1031 1114
1032 *cp = *s; 1115 *cp = *s;
1033 1116
@@ -1044,7 +1127,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
1044 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1127 while ((bdp->cbd_sc & BD_SC_READY) != 0)
1045 ; 1128 ;
1046 1129
1047 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 1130 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
1048 1131
1049 *cp = 13; 1132 *cp = 13;
1050 bdp->cbd_datlen = 1; 1133 bdp->cbd_datlen = 1;
@@ -1067,9 +1150,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
1067 pinfo->tx_cur = (volatile cbd_t *) bdp; 1150 pinfo->tx_cur = (volatile cbd_t *) bdp;
1068} 1151}
1069 1152
1070/* 1153
1071 * Setup console. Be careful is called early !
1072 */
1073static int __init cpm_uart_console_setup(struct console *co, char *options) 1154static int __init cpm_uart_console_setup(struct console *co, char *options)
1074{ 1155{
1075 struct uart_port *port; 1156 struct uart_port *port;
@@ -1080,9 +1161,27 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
1080 int flow = 'n'; 1161 int flow = 'n';
1081 int ret; 1162 int ret;
1082 1163
1164 struct fs_uart_platform_info *pdata;
1165 struct platform_device* pdev = early_uart_get_pdev(co->index);
1166
1083 port = 1167 port =
1084 (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; 1168 (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
1085 pinfo = (struct uart_cpm_port *)port; 1169 pinfo = (struct uart_cpm_port *)port;
1170 if (!pdev) {
1171 pr_info("cpm_uart: console: compat mode\n");
1172 /* compatibility - will be cleaned up */
1173 cpm_uart_init_portdesc();
1174
1175 if (pinfo->set_lineif)
1176 pinfo->set_lineif(pinfo);
1177 } else {
1178 pdata = pdev->dev.platform_data;
1179 if (pdata)
1180 if (pdata->init_ioports)
1181 pdata->init_ioports();
1182
1183 cpm_uart_drv_get_platform_data(pdev, 1);
1184 }
1086 1185
1087 pinfo->flags |= FLAG_CONSOLE; 1186 pinfo->flags |= FLAG_CONSOLE;
1088 1187
@@ -1097,14 +1196,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
1097 baud = 9600; 1196 baud = 9600;
1098 } 1197 }
1099 1198
1100 /*
1101 * Setup any port IO, connect any baud rate generators,
1102 * etc. This is expected to be handled by board
1103 * dependant code
1104 */
1105 if (pinfo->set_lineif)
1106 pinfo->set_lineif(pinfo);
1107
1108 if (IS_SMC(pinfo)) { 1199 if (IS_SMC(pinfo)) {
1109 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 1200 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
1110 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 1201 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -1143,11 +1234,8 @@ static struct console cpm_scc_uart_console = {
1143 1234
1144int __init cpm_uart_console_init(void) 1235int __init cpm_uart_console_init(void)
1145{ 1236{
1146 int ret = cpm_uart_init_portdesc(); 1237 register_console(&cpm_scc_uart_console);
1147 1238 return 0;
1148 if (!ret)
1149 register_console(&cpm_scc_uart_console);
1150 return ret;
1151} 1239}
1152 1240
1153console_initcall(cpm_uart_console_init); 1241console_initcall(cpm_uart_console_init);
@@ -1165,44 +1253,129 @@ static struct uart_driver cpm_reg = {
1165 .minor = SERIAL_CPM_MINOR, 1253 .minor = SERIAL_CPM_MINOR,
1166 .cons = CPM_UART_CONSOLE, 1254 .cons = CPM_UART_CONSOLE,
1167}; 1255};
1168 1256static int cpm_uart_drv_probe(struct device *dev)
1169static int __init cpm_uart_init(void)
1170{ 1257{
1171 int ret, i; 1258 struct platform_device *pdev = to_platform_device(dev);
1172 1259 struct fs_uart_platform_info *pdata;
1173 printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n"); 1260 int ret = -ENODEV;
1174 1261
1175#ifndef CONFIG_SERIAL_CPM_CONSOLE 1262 if(!pdev) {
1176 ret = cpm_uart_init_portdesc(); 1263 printk(KERN_ERR"CPM UART: platform data missing!\n");
1177 if (ret)
1178 return ret; 1264 return ret;
1179#endif 1265 }
1180 1266
1181 cpm_reg.nr = cpm_uart_nr; 1267 pdata = pdev->dev.platform_data;
1182 ret = uart_register_driver(&cpm_reg); 1268 pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no));
1183 1269
1184 if (ret) 1270 if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
1185 return ret; 1271 return ret;
1186 1272
1187 for (i = 0; i < cpm_uart_nr; i++) { 1273 if (pdata->init_ioports)
1188 int con = cpm_uart_port_map[i]; 1274 pdata->init_ioports();
1189 cpm_uart_ports[con].port.line = i;
1190 cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
1191 uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
1192 }
1193 1275
1194 return ret; 1276 ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
1277
1278 return ret;
1195} 1279}
1196 1280
1197static void __exit cpm_uart_exit(void) 1281static int cpm_uart_drv_remove(struct device *dev)
1198{ 1282{
1283 struct platform_device *pdev = to_platform_device(dev);
1284 struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
1285
1286 pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
1287 cpm_uart_id2nr(pdata->fs_no));
1288
1289 uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
1290 return 0;
1291}
1292
1293static struct device_driver cpm_smc_uart_driver = {
1294 .name = "fsl-cpm-smc:uart",
1295 .bus = &platform_bus_type,
1296 .probe = cpm_uart_drv_probe,
1297 .remove = cpm_uart_drv_remove,
1298};
1299
1300static struct device_driver cpm_scc_uart_driver = {
1301 .name = "fsl-cpm-scc:uart",
1302 .bus = &platform_bus_type,
1303 .probe = cpm_uart_drv_probe,
1304 .remove = cpm_uart_drv_remove,
1305};
1306
1307/*
1308 This is supposed to match uart devices on platform bus,
1309 */
1310static int match_is_uart (struct device* dev, void* data)
1311{
1312 struct platform_device* pdev = container_of(dev, struct platform_device, dev);
1313 int ret = 0;
1314 /* this was setfunc as uart */
1315 if(strstr(pdev->name,":uart")) {
1316 ret = 1;
1317 }
1318 return ret;
1319}
1320
1321
1322static int cpm_uart_init(void) {
1323
1324 int ret;
1199 int i; 1325 int i;
1326 struct device *dev;
1327 printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n");
1328
1329 /* lookup the bus for uart devices */
1330 dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart);
1331
1332 /* There are devices on the bus - all should be OK */
1333 if (dev) {
1334 cpm_uart_count();
1335 cpm_reg.nr = cpm_uart_nr;
1336
1337 if (!(ret = uart_register_driver(&cpm_reg))) {
1338 if ((ret = driver_register(&cpm_smc_uart_driver))) {
1339 uart_unregister_driver(&cpm_reg);
1340 return ret;
1341 }
1342 if ((ret = driver_register(&cpm_scc_uart_driver))) {
1343 driver_unregister(&cpm_scc_uart_driver);
1344 uart_unregister_driver(&cpm_reg);
1345 }
1346 }
1347 } else {
1348 /* No capable platform devices found - falling back to legacy mode */
1349 pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
1350 pr_info(
1351 "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
1352#ifndef CONFIG_SERIAL_CPM_CONSOLE
1353 ret = cpm_uart_init_portdesc();
1354 if (ret)
1355 return ret;
1356#endif
1357
1358 cpm_reg.nr = cpm_uart_nr;
1359 ret = uart_register_driver(&cpm_reg);
1360
1361 if (ret)
1362 return ret;
1363
1364 for (i = 0; i < cpm_uart_nr; i++) {
1365 int con = cpm_uart_port_map[i];
1366 cpm_uart_ports[con].port.line = i;
1367 cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
1368 uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
1369 }
1200 1370
1201 for (i = 0; i < cpm_uart_nr; i++) {
1202 int con = cpm_uart_port_map[i];
1203 uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port);
1204 } 1371 }
1372 return ret;
1373}
1205 1374
1375static void __exit cpm_uart_exit(void)
1376{
1377 driver_unregister(&cpm_scc_uart_driver);
1378 driver_unregister(&cpm_smc_uart_driver);
1206 uart_unregister_driver(&cpm_reg); 1379 uart_unregister_driver(&cpm_reg);
1207} 1380}
1208 1381
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index d789ee55cbb7..17406a05ce1f 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -8,6 +8,8 @@
8 * 8 *
9 * Copyright (C) 2004 Freescale Semiconductor, Inc. 9 * Copyright (C) 2004 Freescale Semiconductor, Inc.
10 * (C) 2004 Intracom, S.A. 10 * (C) 2004 Intracom, S.A.
11 * (C) 2006 MontaVista Software, Inc.
12 * Vitaly Bordug <vbordug@ru.mvista.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -81,58 +83,11 @@ void cpm_line_cr_cmd(int line, int cmd)
81 83
82void smc1_lineif(struct uart_cpm_port *pinfo) 84void smc1_lineif(struct uart_cpm_port *pinfo)
83{ 85{
84 volatile cpm8xx_t *cp = cpmp;
85
86 (void)cp; /* fix warning */
87#if defined (CONFIG_MPC885ADS)
88 /* Enable SMC1 transceivers */
89 {
90 cp->cp_pepar |= 0x000000c0;
91 cp->cp_pedir &= ~0x000000c0;
92 cp->cp_peso &= ~0x00000040;
93 cp->cp_peso |= 0x00000080;
94 }
95#elif defined (CONFIG_MPC86XADS)
96 unsigned int iobits = 0x000000c0;
97
98 if (!pinfo->is_portb) {
99 cp->cp_pbpar |= iobits;
100 cp->cp_pbdir &= ~iobits;
101 cp->cp_pbodr &= ~iobits;
102 } else {
103 ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
104 ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
105 ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
106 }
107#endif
108 pinfo->brg = 1; 86 pinfo->brg = 1;
109} 87}
110 88
111void smc2_lineif(struct uart_cpm_port *pinfo) 89void smc2_lineif(struct uart_cpm_port *pinfo)
112{ 90{
113 volatile cpm8xx_t *cp = cpmp;
114
115 (void)cp; /* fix warning */
116#if defined (CONFIG_MPC885ADS)
117 cp->cp_pepar |= 0x00000c00;
118 cp->cp_pedir &= ~0x00000c00;
119 cp->cp_peso &= ~0x00000400;
120 cp->cp_peso |= 0x00000800;
121#elif defined (CONFIG_MPC86XADS)
122 unsigned int iobits = 0x00000c00;
123
124 if (!pinfo->is_portb) {
125 cp->cp_pbpar |= iobits;
126 cp->cp_pbdir &= ~iobits;
127 cp->cp_pbodr &= ~iobits;
128 } else {
129 ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
130 ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
131 ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
132 }
133
134#endif
135
136 pinfo->brg = 2; 91 pinfo->brg = 2;
137} 92}
138 93
@@ -191,7 +146,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
191 /* was hostalloc but changed cause it blows away the */ 146 /* was hostalloc but changed cause it blows away the */
192 /* large tlb mapping when pinning the kernel area */ 147 /* large tlb mapping when pinning the kernel area */
193 mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); 148 mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
194 dma_addr = 0; 149 dma_addr = (u32)mem_addr;
195 } else 150 } else
196 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, 151 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
197 GFP_KERNEL); 152 GFP_KERNEL);
@@ -204,8 +159,9 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
204 } 159 }
205 160
206 pinfo->dp_addr = dp_offset; 161 pinfo->dp_addr = dp_offset;
207 pinfo->mem_addr = mem_addr; 162 pinfo->mem_addr = mem_addr; /* virtual address*/
208 pinfo->dma_addr = dma_addr; 163 pinfo->dma_addr = dma_addr; /* physical address*/
164 pinfo->mem_size = memsz;
209 165
210 pinfo->rx_buf = mem_addr; 166 pinfo->rx_buf = mem_addr;
211 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos 167 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index fd9e53ed3feb..4b2de08f46d0 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -8,6 +8,8 @@
8 * 8 *
9 * Copyright (C) 2004 Freescale Semiconductor, Inc. 9 * Copyright (C) 2004 Freescale Semiconductor, Inc.
10 * (C) 2004 Intracom, S.A. 10 * (C) 2004 Intracom, S.A.
11 * (C) 2006 MontaVista Software, Inc.
12 * Vitaly Bordug <vbordug@ru.mvista.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -142,14 +144,6 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
142 * be supported in a sane fashion. 144 * be supported in a sane fashion.
143 */ 145 */
144#ifndef CONFIG_STX_GP3 146#ifndef CONFIG_STX_GP3
145#ifdef CONFIG_MPC8560_ADS
146 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
147 io->iop_ppard |= 0x00000018;
148 io->iop_psord &= ~0x00000008; /* Rx */
149 io->iop_psord &= ~0x00000010; /* Tx */
150 io->iop_pdird &= ~0x00000008; /* Rx */
151 io->iop_pdird |= 0x00000010; /* Tx */
152#else
153 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; 147 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
154 io->iop_pparb |= 0x008b0000; 148 io->iop_pparb |= 0x008b0000;
155 io->iop_pdirb |= 0x00880000; 149 io->iop_pdirb |= 0x00880000;
@@ -157,7 +151,6 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
157 io->iop_pdirb &= ~0x00030000; 151 io->iop_pdirb &= ~0x00030000;
158 io->iop_psorb &= ~0x00030000; 152 io->iop_psorb &= ~0x00030000;
159#endif 153#endif
160#endif
161 cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff; 154 cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
162 cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; 155 cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
163 pinfo->brg = 2; 156 pinfo->brg = 2;
@@ -218,8 +211,10 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
218 211
219 memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + 212 memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
220 L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); 213 L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
221 if (is_con) 214 if (is_con) {
222 mem_addr = alloc_bootmem(memsz); 215 mem_addr = alloc_bootmem(memsz);
216 dma_addr = mem_addr;
217 }
223 else 218 else
224 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, 219 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
225 GFP_KERNEL); 220 GFP_KERNEL);
@@ -234,6 +229,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
234 pinfo->dp_addr = dp_offset; 229 pinfo->dp_addr = dp_offset;
235 pinfo->mem_addr = mem_addr; 230 pinfo->mem_addr = mem_addr;
236 pinfo->dma_addr = dma_addr; 231 pinfo->dma_addr = dma_addr;
232 pinfo->mem_size = memsz;
237 233
238 pinfo->rx_buf = mem_addr; 234 pinfo->rx_buf = mem_addr;
239 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos 235 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index c3b7a6673e9c..d202eb4f3848 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -45,6 +45,7 @@
45#include <asm/io.h> 45#include <asm/io.h>
46#include <asm/irq.h> 46#include <asm/irq.h>
47#include <asm/hardware.h> 47#include <asm/hardware.h>
48#include <asm/arch/imx-uart.h>
48 49
49/* We've been assigned a range on the "Low-density serial ports" major */ 50/* We've been assigned a range on the "Low-density serial ports" major */
50#define SERIAL_IMX_MAJOR 204 51#define SERIAL_IMX_MAJOR 204
@@ -73,7 +74,8 @@ struct imx_port {
73 struct uart_port port; 74 struct uart_port port;
74 struct timer_list timer; 75 struct timer_list timer;
75 unsigned int old_status; 76 unsigned int old_status;
76 int txirq,rxirq,rtsirq; 77 int txirq,rxirq,rtsirq;
78 int have_rtscts:1;
77}; 79};
78 80
79/* 81/*
@@ -491,8 +493,12 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
491 ucr2 = UCR2_SRST | UCR2_IRTS; 493 ucr2 = UCR2_SRST | UCR2_IRTS;
492 494
493 if (termios->c_cflag & CRTSCTS) { 495 if (termios->c_cflag & CRTSCTS) {
494 ucr2 &= ~UCR2_IRTS; 496 if( sport->have_rtscts ) {
495 ucr2 |= UCR2_CTSC; 497 ucr2 &= ~UCR2_IRTS;
498 ucr2 |= UCR2_CTSC;
499 } else {
500 termios->c_cflag &= ~CRTSCTS;
501 }
496 } 502 }
497 503
498 if (termios->c_cflag & CSTOPB) 504 if (termios->c_cflag & CSTOPB)
@@ -719,27 +725,6 @@ static void __init imx_init_ports(void)
719 imx_ports[i].timer.function = imx_timeout; 725 imx_ports[i].timer.function = imx_timeout;
720 imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; 726 imx_ports[i].timer.data = (unsigned long)&imx_ports[i];
721 } 727 }
722
723 imx_gpio_mode(PC9_PF_UART1_CTS);
724 imx_gpio_mode(PC10_PF_UART1_RTS);
725 imx_gpio_mode(PC11_PF_UART1_TXD);
726 imx_gpio_mode(PC12_PF_UART1_RXD);
727 imx_gpio_mode(PB28_PF_UART2_CTS);
728 imx_gpio_mode(PB29_PF_UART2_RTS);
729
730 imx_gpio_mode(PB30_PF_UART2_TXD);
731 imx_gpio_mode(PB31_PF_UART2_RXD);
732
733#if 0 /* We don't need these, on the mx1 the _modem_ side of the uart
734 * is implemented.
735 */
736 imx_gpio_mode(PD7_AF_UART2_DTR);
737 imx_gpio_mode(PD8_AF_UART2_DCD);
738 imx_gpio_mode(PD9_AF_UART2_RI);
739 imx_gpio_mode(PD10_AF_UART2_DSR);
740#endif
741
742
743} 728}
744 729
745#ifdef CONFIG_SERIAL_IMX_CONSOLE 730#ifdef CONFIG_SERIAL_IMX_CONSOLE
@@ -932,7 +917,14 @@ static int serial_imx_resume(struct platform_device *dev)
932 917
933static int serial_imx_probe(struct platform_device *dev) 918static int serial_imx_probe(struct platform_device *dev)
934{ 919{
920 struct imxuart_platform_data *pdata;
921
935 imx_ports[dev->id].port.dev = &dev->dev; 922 imx_ports[dev->id].port.dev = &dev->dev;
923
924 pdata = (struct imxuart_platform_data *)dev->dev.platform_data;
925 if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
926 imx_ports[dev->id].have_rtscts = 1;
927
936 uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); 928 uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
937 platform_set_drvdata(dev, &imx_ports[dev->id]); 929 platform_set_drvdata(dev, &imx_ports[dev->id]);
938 return 0; 930 return 0;