aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorsonic zhang <sonic.adi@gmail.com>2009-12-09 15:31:28 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:43:06 -0500
commitccf68e59e93181df9353c0cc721459d18ff200b6 (patch)
tree2b532778787f5c3e37663760be6643b653662819 /drivers/serial
parent13dda80e48439b446d0bc9bab34b91484bc8f533 (diff)
serial: fit blackfin uart over sport driver into common uart infrastructure
Fit blackfin uart over sport driver into common uart inftrastructure. It is based on the early platform interfaces to get the platform data early when the console is initilized. 1. Enable sport uart driver to change uart baud, data bit, stop bit at runtime. Bind the index of uart device nodes to physical index of sports. 2. Move all platform data into arch specific board files. Register and probe platform device data in both early and normal stages. 3. Console is registered in sport uart driver as well. 4. Remove 500 us block waiting in sport tx stop code by putting a dummy data into tx fifo to make sure the sport tx stops when all bytes are shifted out except for the dummy data. 5. clean up a bit and fix up coding style. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Mike Frysinger <vapier@gentoo.org> Cc: Bryan Wu <cooloney@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig52
-rw-r--r--drivers/serial/bfin_sport_uart.c701
-rw-r--r--drivers/serial/bfin_sport_uart.h38
3 files changed, 511 insertions, 280 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 888a0ce91c4b..cb935b1f4f6c 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1418,38 +1418,34 @@ config SERIAL_BFIN_SPORT
1418 To compile this driver as a module, choose M here: the 1418 To compile this driver as a module, choose M here: the
1419 module will be called bfin_sport_uart. 1419 module will be called bfin_sport_uart.
1420 1420
1421choice 1421config SERIAL_BFIN_SPORT_CONSOLE
1422 prompt "Baud rate for Blackfin SPORT UART" 1422 bool "Console on Blackfin sport emulated uart"
1423 depends on SERIAL_BFIN_SPORT 1423 depends on SERIAL_BFIN_SPORT=y
1424 default SERIAL_SPORT_BAUD_RATE_57600 1424 select SERIAL_CORE_CONSOLE
1425 help
1426 Choose a baud rate for the SPORT UART, other uart settings are
1427 8 bit, 1 stop bit, no parity, no flow control.
1428
1429config SERIAL_SPORT_BAUD_RATE_115200
1430 bool "115200"
1431
1432config SERIAL_SPORT_BAUD_RATE_57600
1433 bool "57600"
1434 1425
1435config SERIAL_SPORT_BAUD_RATE_38400 1426config SERIAL_BFIN_SPORT0_UART
1436 bool "38400" 1427 bool "Enable UART over SPORT0"
1428 depends on SERIAL_BFIN_SPORT && !(BF542 || BF542M || BF544 || BF544M)
1429 help
1430 Enable UART over SPORT0
1437 1431
1438config SERIAL_SPORT_BAUD_RATE_19200 1432config SERIAL_BFIN_SPORT1_UART
1439 bool "19200" 1433 bool "Enable UART over SPORT1"
1434 depends on SERIAL_BFIN_SPORT
1435 help
1436 Enable UART over SPORT1
1440 1437
1441config SERIAL_SPORT_BAUD_RATE_9600 1438config SERIAL_BFIN_SPORT2_UART
1442 bool "9600" 1439 bool "Enable UART over SPORT2"
1443endchoice 1440 depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539)
1441 help
1442 Enable UART over SPORT2
1444 1443
1445config SPORT_BAUD_RATE 1444config SERIAL_BFIN_SPORT3_UART
1446 int 1445 bool "Enable UART over SPORT3"
1447 depends on SERIAL_BFIN_SPORT 1446 depends on SERIAL_BFIN_SPORT && (BF54x || BF538 || BF539)
1448 default 115200 if (SERIAL_SPORT_BAUD_RATE_115200) 1447 help
1449 default 57600 if (SERIAL_SPORT_BAUD_RATE_57600) 1448 Enable UART over SPORT3
1450 default 38400 if (SERIAL_SPORT_BAUD_RATE_38400)
1451 default 19200 if (SERIAL_SPORT_BAUD_RATE_19200)
1452 default 9600 if (SERIAL_SPORT_BAUD_RATE_9600)
1453 1449
1454config SERIAL_TIMBERDALE 1450config SERIAL_TIMBERDALE
1455 tristate "Support for timberdale UART" 1451 tristate "Support for timberdale UART"
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index 088bb35475f1..7c72888fbf94 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -1,27 +1,11 @@
1/* 1/*
2 * File: linux/drivers/serial/bfin_sport_uart.c 2 * Blackfin On-Chip Sport Emulated UART Driver
3 * 3 *
4 * Based on: drivers/serial/bfin_5xx.c by Aubrey Li. 4 * Copyright 2006-2009 Analog Devices Inc.
5 * Author: Roy Huang <roy.huang@analog.com>
6 * 5 *
7 * Created: Nov 22, 2006 6 * Enter bugs at http://blackfin.uclinux.org/
8 * Copyright: (c) 2006-2007 Analog Devices Inc.
9 * Description: this driver enable SPORTs on Blackfin emulate UART.
10 * 7 *
11 * This program is free software; you can redistribute it and/or modify 8 * Licensed under the GPL-2 or later.
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see the file COPYING, or write
23 * to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */ 9 */
26 10
27/* 11/*
@@ -29,39 +13,18 @@
29 * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf 13 * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
30 * This application note describe how to implement a UART on a Sharc DSP, 14 * This application note describe how to implement a UART on a Sharc DSP,
31 * but this driver is implemented on Blackfin Processor. 15 * but this driver is implemented on Blackfin Processor.
16 * Transmit Frame Sync is not used by this driver to transfer data out.
32 */ 17 */
33 18
34/* After reset, there is a prelude of low level pulse when transmit data first 19/* #define DEBUG */
35 * time. No addtional pulse in following transmit.
36 * According to document:
37 * The SPORTs are ready to start transmitting or receiving data no later than
38 * three serial clock cycles after they are enabled in the SPORTx_TCR1 or
39 * SPORTx_RCR1 register. No serial clock cycles are lost from this point on.
40 * The first internal frame sync will occur one frame sync delay after the
41 * SPORTs are ready. External frame syncs can occur as soon as the SPORT is
42 * ready.
43 */
44 20
45/* Thanks to Axel Alatalo <axel@rubico.se> for fixing sport rx bug. Sometimes 21#define DRV_NAME "bfin-sport-uart"
46 * sport receives data incorrectly. The following is Axel's words. 22#define DEVICE_NAME "ttySS"
47 * As EE-191, sport rx samples 3 times of the UART baudrate and takes the 23#define pr_fmt(fmt) DRV_NAME ": " fmt
48 * middle smaple of every 3 samples as the data bit. For a 8-N-1 UART setting,
49 * 30 samples will be required for a byte. If transmitter sends a 1/3 bit short
50 * byte due to buadrate drift, then the 30th sample of a byte, this sample is
51 * also the third sample of the stop bit, will happens on the immediately
52 * following start bit which will be thrown away and missed. Thus since parts
53 * of the startbit will be missed and the receiver will begin to drift, the
54 * effect accumulates over time until synchronization is lost.
55 * If only require 2 samples of the stopbit (by sampling in total 29 samples),
56 * then a to short byte as in the case above will be tolerated. Then the 1/3
57 * early startbit will trigger a framesync since the last read is complete
58 * after only 2/3 stopbit and framesync is active during the last 1/3 looking
59 * for a possible early startbit. */
60
61//#define DEBUG
62 24
63#include <linux/module.h> 25#include <linux/module.h>
64#include <linux/ioport.h> 26#include <linux/ioport.h>
27#include <linux/io.h>
65#include <linux/init.h> 28#include <linux/init.h>
66#include <linux/console.h> 29#include <linux/console.h>
67#include <linux/sysrq.h> 30#include <linux/sysrq.h>
@@ -75,23 +38,36 @@
75 38
76#include "bfin_sport_uart.h" 39#include "bfin_sport_uart.h"
77 40
41#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
78unsigned short bfin_uart_pin_req_sport0[] = 42unsigned short bfin_uart_pin_req_sport0[] =
79 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \ 43 {P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, \
80 P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0}; 44 P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0};
81 45#endif
46#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART
82unsigned short bfin_uart_pin_req_sport1[] = 47unsigned short bfin_uart_pin_req_sport1[] =
83 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \ 48 {P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, \
84 P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0}; 49 P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0};
85 50#endif
86#define DRV_NAME "bfin-sport-uart" 51#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART
52unsigned short bfin_uart_pin_req_sport2[] =
53 {P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, \
54 P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0};
55#endif
56#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART
57unsigned short bfin_uart_pin_req_sport3[] =
58 {P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, \
59 P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0};
60#endif
87 61
88struct sport_uart_port { 62struct sport_uart_port {
89 struct uart_port port; 63 struct uart_port port;
90 char *name;
91
92 int tx_irq;
93 int rx_irq;
94 int err_irq; 64 int err_irq;
65 unsigned short csize;
66 unsigned short rxmask;
67 unsigned short txmask1;
68 unsigned short txmask2;
69 unsigned char stopb;
70/* unsigned char parib; */
95}; 71};
96 72
97static void sport_uart_tx_chars(struct sport_uart_port *up); 73static void sport_uart_tx_chars(struct sport_uart_port *up);
@@ -99,36 +75,42 @@ static void sport_stop_tx(struct uart_port *port);
99 75
100static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value) 76static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
101{ 77{
102 pr_debug("%s value:%x\n", __func__, value); 78 pr_debug("%s value:%x, mask1=0x%x, mask2=0x%x\n", __func__, value,
103 /* Place a Start and Stop bit */ 79 up->txmask1, up->txmask2);
80
81 /* Place Start and Stop bits */
104 __asm__ __volatile__ ( 82 __asm__ __volatile__ (
105 "R2 = b#01111111100;" 83 "%[val] <<= 1;"
106 "R3 = b#10000000001;" 84 "%[val] = %[val] & %[mask1];"
107 "%0 <<= 2;" 85 "%[val] = %[val] | %[mask2];"
108 "%0 = %0 & R2;" 86 : [val]"+d"(value)
109 "%0 = %0 | R3;" 87 : [mask1]"d"(up->txmask1), [mask2]"d"(up->txmask2)
110 : "=d"(value) 88 : "ASTAT"
111 : "d"(value)
112 : "ASTAT", "R2", "R3"
113 ); 89 );
114 pr_debug("%s value:%x\n", __func__, value); 90 pr_debug("%s value:%x\n", __func__, value);
115 91
116 SPORT_PUT_TX(up, value); 92 SPORT_PUT_TX(up, value);
117} 93}
118 94
119static inline unsigned int rx_one_byte(struct sport_uart_port *up) 95static inline unsigned char rx_one_byte(struct sport_uart_port *up)
120{ 96{
121 unsigned int value, extract; 97 unsigned int value;
98 unsigned char extract;
122 u32 tmp_mask1, tmp_mask2, tmp_shift, tmp; 99 u32 tmp_mask1, tmp_mask2, tmp_shift, tmp;
123 100
124 value = SPORT_GET_RX32(up); 101 if ((up->csize + up->stopb) > 7)
125 pr_debug("%s value:%x\n", __func__, value); 102 value = SPORT_GET_RX32(up);
103 else
104 value = SPORT_GET_RX(up);
105
106 pr_debug("%s value:%x, cs=%d, mask=0x%x\n", __func__, value,
107 up->csize, up->rxmask);
126 108
127 /* Extract 8 bits data */ 109 /* Extract data */
128 __asm__ __volatile__ ( 110 __asm__ __volatile__ (
129 "%[extr] = 0;" 111 "%[extr] = 0;"
130 "%[mask1] = 0x1801(Z);" 112 "%[mask1] = %[rxmask];"
131 "%[mask2] = 0x0300(Z);" 113 "%[mask2] = 0x0200(Z);"
132 "%[shift] = 0;" 114 "%[shift] = 0;"
133 "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];" 115 "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];"
134 ".Lloop_s:" 116 ".Lloop_s:"
@@ -138,9 +120,9 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up)
138 "%[mask1] = %[mask1] - %[mask2];" 120 "%[mask1] = %[mask1] - %[mask2];"
139 ".Lloop_e:" 121 ".Lloop_e:"
140 "%[shift] += 1;" 122 "%[shift] += 1;"
141 : [val]"=d"(value), [extr]"=d"(extract), [shift]"=d"(tmp_shift), [tmp]"=d"(tmp), 123 : [extr]"=&d"(extract), [shift]"=&d"(tmp_shift), [tmp]"=&d"(tmp),
142 [mask1]"=d"(tmp_mask1), [mask2]"=d"(tmp_mask2) 124 [mask1]"=&d"(tmp_mask1), [mask2]"=&d"(tmp_mask2)
143 : "d"(value), [lc]"a"(8) 125 : [val]"d"(value), [rxmask]"d"(up->rxmask), [lc]"a"(up->csize)
144 : "ASTAT", "LB0", "LC0", "LT0" 126 : "ASTAT", "LB0", "LC0", "LT0"
145 ); 127 );
146 128
@@ -148,29 +130,28 @@ static inline unsigned int rx_one_byte(struct sport_uart_port *up)
148 return extract; 130 return extract;
149} 131}
150 132
151static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate) 133static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate)
152{ 134{
153 int tclkdiv, tfsdiv, rclkdiv; 135 int tclkdiv, rclkdiv;
136 unsigned int sclk = get_sclk();
154 137
155 /* Set TCR1 and TCR2 */ 138 /* Set TCR1 and TCR2, TFSR is not enabled for uart */
156 SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); 139 SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK));
157 SPORT_PUT_TCR2(up, 10); 140 SPORT_PUT_TCR2(up, size + 1);
158 pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); 141 pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up));
159 142
160 /* Set RCR1 and RCR2 */ 143 /* Set RCR1 and RCR2 */
161 SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK)); 144 SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK));
162 SPORT_PUT_RCR2(up, 28); 145 SPORT_PUT_RCR2(up, (size + 1) * 2 - 1);
163 pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up)); 146 pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up));
164 147
165 tclkdiv = sclk/(2 * baud_rate) - 1; 148 tclkdiv = sclk / (2 * baud_rate) - 1;
166 tfsdiv = 12; 149 rclkdiv = sclk / (2 * baud_rate * 2) - 1;
167 rclkdiv = sclk/(2 * baud_rate * 3) - 1;
168 SPORT_PUT_TCLKDIV(up, tclkdiv); 150 SPORT_PUT_TCLKDIV(up, tclkdiv);
169 SPORT_PUT_TFSDIV(up, tfsdiv);
170 SPORT_PUT_RCLKDIV(up, rclkdiv); 151 SPORT_PUT_RCLKDIV(up, rclkdiv);
171 SSYNC(); 152 SSYNC();
172 pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, tfsdiv:%d, rclkdiv:%d\n", 153 pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, rclkdiv:%d\n",
173 __func__, sclk, baud_rate, tclkdiv, tfsdiv, rclkdiv); 154 __func__, sclk, baud_rate, tclkdiv, rclkdiv);
174 155
175 return 0; 156 return 0;
176} 157}
@@ -181,23 +162,29 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
181 struct tty_struct *tty = up->port.state->port.tty; 162 struct tty_struct *tty = up->port.state->port.tty;
182 unsigned int ch; 163 unsigned int ch;
183 164
184 do { 165 spin_lock(&up->port.lock);
166
167 while (SPORT_GET_STAT(up) & RXNE) {
185 ch = rx_one_byte(up); 168 ch = rx_one_byte(up);
186 up->port.icount.rx++; 169 up->port.icount.rx++;
187 170
188 if (uart_handle_sysrq_char(&up->port, ch)) 171 if (!uart_handle_sysrq_char(&up->port, ch))
189 ;
190 else
191 tty_insert_flip_char(tty, ch, TTY_NORMAL); 172 tty_insert_flip_char(tty, ch, TTY_NORMAL);
192 } while (SPORT_GET_STAT(up) & RXNE); 173 }
193 tty_flip_buffer_push(tty); 174 tty_flip_buffer_push(tty);
194 175
176 spin_unlock(&up->port.lock);
177
195 return IRQ_HANDLED; 178 return IRQ_HANDLED;
196} 179}
197 180
198static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) 181static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
199{ 182{
200 sport_uart_tx_chars(dev_id); 183 struct sport_uart_port *up = dev_id;
184
185 spin_lock(&up->port.lock);
186 sport_uart_tx_chars(up);
187 spin_unlock(&up->port.lock);
201 188
202 return IRQ_HANDLED; 189 return IRQ_HANDLED;
203} 190}
@@ -208,6 +195,8 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
208 struct tty_struct *tty = up->port.state->port.tty; 195 struct tty_struct *tty = up->port.state->port.tty;
209 unsigned int stat = SPORT_GET_STAT(up); 196 unsigned int stat = SPORT_GET_STAT(up);
210 197
198 spin_lock(&up->port.lock);
199
211 /* Overflow in RX FIFO */ 200 /* Overflow in RX FIFO */
212 if (stat & ROVF) { 201 if (stat & ROVF) {
213 up->port.icount.overrun++; 202 up->port.icount.overrun++;
@@ -216,15 +205,16 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
216 } 205 }
217 /* These should not happen */ 206 /* These should not happen */
218 if (stat & (TOVF | TUVF | RUVF)) { 207 if (stat & (TOVF | TUVF | RUVF)) {
219 printk(KERN_ERR "SPORT Error:%s %s %s\n", 208 pr_err("SPORT Error:%s %s %s\n",
220 (stat & TOVF)?"TX overflow":"", 209 (stat & TOVF) ? "TX overflow" : "",
221 (stat & TUVF)?"TX underflow":"", 210 (stat & TUVF) ? "TX underflow" : "",
222 (stat & RUVF)?"RX underflow":""); 211 (stat & RUVF) ? "RX underflow" : "");
223 SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN); 212 SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
224 SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN); 213 SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
225 } 214 }
226 SSYNC(); 215 SSYNC();
227 216
217 spin_unlock(&up->port.lock);
228 return IRQ_HANDLED; 218 return IRQ_HANDLED;
229} 219}
230 220
@@ -232,60 +222,37 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
232static int sport_startup(struct uart_port *port) 222static int sport_startup(struct uart_port *port)
233{ 223{
234 struct sport_uart_port *up = (struct sport_uart_port *)port; 224 struct sport_uart_port *up = (struct sport_uart_port *)port;
235 char buffer[20]; 225 int ret;
236 int retval;
237 226
238 pr_debug("%s enter\n", __func__); 227 pr_debug("%s enter\n", __func__);
239 snprintf(buffer, 20, "%s rx", up->name); 228 ret = request_irq(up->port.irq, sport_uart_rx_irq, 0,
240 retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); 229 "SPORT_UART_RX", up);
241 if (retval) { 230 if (ret) {
242 printk(KERN_ERR "Unable to request interrupt %s\n", buffer); 231 dev_err(port->dev, "unable to request SPORT RX interrupt\n");
243 return retval; 232 return ret;
244 } 233 }
245 234
246 snprintf(buffer, 20, "%s tx", up->name); 235 ret = request_irq(up->port.irq+1, sport_uart_tx_irq, 0,
247 retval = request_irq(up->tx_irq, sport_uart_tx_irq, IRQF_SAMPLE_RANDOM, buffer, up); 236 "SPORT_UART_TX", up);
248 if (retval) { 237 if (ret) {
249 printk(KERN_ERR "Unable to request interrupt %s\n", buffer); 238 dev_err(port->dev, "unable to request SPORT TX interrupt\n");
250 goto fail1; 239 goto fail1;
251 } 240 }
252 241
253 snprintf(buffer, 20, "%s err", up->name); 242 ret = request_irq(up->err_irq, sport_uart_err_irq, 0,
254 retval = request_irq(up->err_irq, sport_uart_err_irq, IRQF_SAMPLE_RANDOM, buffer, up); 243 "SPORT_UART_STATUS", up);
255 if (retval) { 244 if (ret) {
256 printk(KERN_ERR "Unable to request interrupt %s\n", buffer); 245 dev_err(port->dev, "unable to request SPORT status interrupt\n");
257 goto fail2; 246 goto fail2;
258 } 247 }
259 248
260 if (port->line) {
261 if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME))
262 goto fail3;
263 } else {
264 if (peripheral_request_list(bfin_uart_pin_req_sport0, DRV_NAME))
265 goto fail3;
266 }
267
268 sport_uart_setup(up, get_sclk(), port->uartclk);
269
270 /* Enable receive interrupt */
271 SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) | RSPEN));
272 SSYNC();
273
274 return 0; 249 return 0;
250 fail2:
251 free_irq(up->port.irq+1, up);
252 fail1:
253 free_irq(up->port.irq, up);
275 254
276 255 return ret;
277fail3:
278 printk(KERN_ERR DRV_NAME
279 ": Requesting Peripherals failed\n");
280
281 free_irq(up->err_irq, up);
282fail2:
283 free_irq(up->tx_irq, up);
284fail1:
285 free_irq(up->rx_irq, up);
286
287 return retval;
288
289} 256}
290 257
291static void sport_uart_tx_chars(struct sport_uart_port *up) 258static void sport_uart_tx_chars(struct sport_uart_port *up)
@@ -344,20 +311,17 @@ static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
344static void sport_stop_tx(struct uart_port *port) 311static void sport_stop_tx(struct uart_port *port)
345{ 312{
346 struct sport_uart_port *up = (struct sport_uart_port *)port; 313 struct sport_uart_port *up = (struct sport_uart_port *)port;
347 unsigned int stat;
348 314
349 pr_debug("%s enter\n", __func__); 315 pr_debug("%s enter\n", __func__);
350 316
351 stat = SPORT_GET_STAT(up);
352 while(!(stat & TXHRE)) {
353 udelay(1);
354 stat = SPORT_GET_STAT(up);
355 }
356 /* Although the hold register is empty, last byte is still in shift 317 /* Although the hold register is empty, last byte is still in shift
357 * register and not sent out yet. If baud rate is lower than default, 318 * register and not sent out yet. So, put a dummy data into TX FIFO.
358 * delay should be longer. For example, if the baud rate is 9600, 319 * Then, sport tx stops when last byte is shift out and the dummy
359 * the delay must be at least 2ms by experience */ 320 * data is moved into the shift register.
360 udelay(500); 321 */
322 SPORT_PUT_TX(up, 0xffff);
323 while (!(SPORT_GET_STAT(up) & TXHRE))
324 cpu_relax();
361 325
362 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); 326 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
363 SSYNC(); 327 SSYNC();
@@ -370,6 +334,7 @@ static void sport_start_tx(struct uart_port *port)
370 struct sport_uart_port *up = (struct sport_uart_port *)port; 334 struct sport_uart_port *up = (struct sport_uart_port *)port;
371 335
372 pr_debug("%s enter\n", __func__); 336 pr_debug("%s enter\n", __func__);
337
373 /* Write data into SPORT FIFO before enable SPROT to transmit */ 338 /* Write data into SPORT FIFO before enable SPROT to transmit */
374 sport_uart_tx_chars(up); 339 sport_uart_tx_chars(up);
375 340
@@ -403,37 +368,24 @@ static void sport_shutdown(struct uart_port *port)
403{ 368{
404 struct sport_uart_port *up = (struct sport_uart_port *)port; 369 struct sport_uart_port *up = (struct sport_uart_port *)port;
405 370
406 pr_debug("%s enter\n", __func__); 371 dev_dbg(port->dev, "%s enter\n", __func__);
407 372
408 /* Disable sport */ 373 /* Disable sport */
409 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN)); 374 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
410 SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN)); 375 SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
411 SSYNC(); 376 SSYNC();
412 377
413 if (port->line) { 378 free_irq(up->port.irq, up);
414 peripheral_free_list(bfin_uart_pin_req_sport1); 379 free_irq(up->port.irq+1, up);
415 } else {
416 peripheral_free_list(bfin_uart_pin_req_sport0);
417 }
418
419 free_irq(up->rx_irq, up);
420 free_irq(up->tx_irq, up);
421 free_irq(up->err_irq, up); 380 free_irq(up->err_irq, up);
422} 381}
423 382
424static void sport_set_termios(struct uart_port *port,
425 struct ktermios *termios, struct ktermios *old)
426{
427 pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag);
428 uart_update_timeout(port, CS8 ,port->uartclk);
429}
430
431static const char *sport_type(struct uart_port *port) 383static const char *sport_type(struct uart_port *port)
432{ 384{
433 struct sport_uart_port *up = (struct sport_uart_port *)port; 385 struct sport_uart_port *up = (struct sport_uart_port *)port;
434 386
435 pr_debug("%s enter\n", __func__); 387 pr_debug("%s enter\n", __func__);
436 return up->name; 388 return up->port.type == PORT_BFIN_SPORT ? "BFIN-SPORT-UART" : NULL;
437} 389}
438 390
439static void sport_release_port(struct uart_port *port) 391static void sport_release_port(struct uart_port *port)
@@ -461,6 +413,110 @@ static int sport_verify_port(struct uart_port *port, struct serial_struct *ser)
461 return 0; 413 return 0;
462} 414}
463 415
416static void sport_set_termios(struct uart_port *port,
417 struct ktermios *termios, struct ktermios *old)
418{
419 struct sport_uart_port *up = (struct sport_uart_port *)port;
420 unsigned long flags;
421 int i;
422
423 pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag);
424
425 switch (termios->c_cflag & CSIZE) {
426 case CS8:
427 up->csize = 8;
428 break;
429 case CS7:
430 up->csize = 7;
431 break;
432 case CS6:
433 up->csize = 6;
434 break;
435 case CS5:
436 up->csize = 5;
437 break;
438 default:
439 pr_warning("requested word length not supported\n");
440 }
441
442 if (termios->c_cflag & CSTOPB) {
443 up->stopb = 1;
444 }
445 if (termios->c_cflag & PARENB) {
446 pr_warning("PAREN bits is not supported yet\n");
447 /* up->parib = 1; */
448 }
449
450 port->read_status_mask = OE;
451 if (termios->c_iflag & INPCK)
452 port->read_status_mask |= (FE | PE);
453 if (termios->c_iflag & (BRKINT | PARMRK))
454 port->read_status_mask |= BI;
455
456 /*
457 * Characters to ignore
458 */
459 port->ignore_status_mask = 0;
460 if (termios->c_iflag & IGNPAR)
461 port->ignore_status_mask |= FE | PE;
462 if (termios->c_iflag & IGNBRK) {
463 port->ignore_status_mask |= BI;
464 /*
465 * If we're ignoring parity and break indicators,
466 * ignore overruns too (for real raw support).
467 */
468 if (termios->c_iflag & IGNPAR)
469 port->ignore_status_mask |= OE;
470 }
471
472 /* RX extract mask */
473 up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8);
474 /* TX masks, 8 bit data and 1 bit stop for example:
475 * mask1 = b#0111111110
476 * mask2 = b#1000000000
477 */
478 for (i = 0, up->txmask1 = 0; i < up->csize; i++)
479 up->txmask1 |= (1<<i);
480 up->txmask2 = (1<<i);
481 if (up->stopb) {
482 ++i;
483 up->txmask2 |= (1<<i);
484 }
485 up->txmask1 <<= 1;
486 up->txmask2 <<= 1;
487 /* uart baud rate */
488 port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16);
489
490 spin_lock_irqsave(&up->port.lock, flags);
491
492 /* Disable UART */
493 SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
494 SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
495
496 sport_uart_setup(up, up->csize + up->stopb, port->uartclk);
497
498 /* driver TX line high after config, one dummy data is
499 * necessary to stop sport after shift one byte
500 */
501 SPORT_PUT_TX(up, 0xffff);
502 SPORT_PUT_TX(up, 0xffff);
503 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
504 SSYNC();
505 while (!(SPORT_GET_STAT(up) & TXHRE))
506 cpu_relax();
507 SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
508 SSYNC();
509
510 /* Port speed changed, update the per-port timeout. */
511 uart_update_timeout(port, termios->c_cflag, port->uartclk);
512
513 /* Enable sport rx */
514 SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) | RSPEN);
515 SSYNC();
516
517 spin_unlock_irqrestore(&up->port.lock, flags);
518}
519
464struct uart_ops sport_uart_ops = { 520struct uart_ops sport_uart_ops = {
465 .tx_empty = sport_tx_empty, 521 .tx_empty = sport_tx_empty,
466 .set_mctrl = sport_set_mctrl, 522 .set_mctrl = sport_set_mctrl,
@@ -480,138 +536,319 @@ struct uart_ops sport_uart_ops = {
480 .verify_port = sport_verify_port, 536 .verify_port = sport_verify_port,
481}; 537};
482 538
483static struct sport_uart_port sport_uart_ports[] = { 539#define BFIN_SPORT_UART_MAX_PORTS 4
484 { /* SPORT 0 */ 540
485 .name = "SPORT0", 541static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS];
486 .tx_irq = IRQ_SPORT0_TX, 542
487 .rx_irq = IRQ_SPORT0_RX, 543#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
488 .err_irq= IRQ_SPORT0_ERROR, 544static int __init
489 .port = { 545sport_uart_console_setup(struct console *co, char *options)
490 .type = PORT_BFIN_SPORT, 546{
491 .iotype = UPIO_MEM, 547 struct sport_uart_port *up;
492 .membase = (void __iomem *)SPORT0_TCR1, 548 int baud = 57600;
493 .mapbase = SPORT0_TCR1, 549 int bits = 8;
494 .irq = IRQ_SPORT0_RX, 550 int parity = 'n';
495 .uartclk = CONFIG_SPORT_BAUD_RATE, 551 int flow = 'n';
496 .fifosize = 8, 552
497 .ops = &sport_uart_ops, 553 /* Check whether an invalid uart number has been specified */
498 .line = 0, 554 if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS)
499 }, 555 return -ENODEV;
500 }, { /* SPORT 1 */ 556
501 .name = "SPORT1", 557 up = bfin_sport_uart_ports[co->index];
502 .tx_irq = IRQ_SPORT1_TX, 558 if (!up)
503 .rx_irq = IRQ_SPORT1_RX, 559 return -ENODEV;
504 .err_irq= IRQ_SPORT1_ERROR, 560
505 .port = { 561 if (options)
506 .type = PORT_BFIN_SPORT, 562 uart_parse_options(options, &baud, &parity, &bits, &flow);
507 .iotype = UPIO_MEM, 563
508 .membase = (void __iomem *)SPORT1_TCR1, 564 return uart_set_options(&up->port, co, baud, parity, bits, flow);
509 .mapbase = SPORT1_TCR1, 565}
510 .irq = IRQ_SPORT1_RX, 566
511 .uartclk = CONFIG_SPORT_BAUD_RATE, 567static void sport_uart_console_putchar(struct uart_port *port, int ch)
512 .fifosize = 8, 568{
513 .ops = &sport_uart_ops, 569 struct sport_uart_port *up = (struct sport_uart_port *)port;
514 .line = 1, 570
515 }, 571 while (SPORT_GET_STAT(up) & TXF)
572 barrier();
573
574 tx_one_byte(up, ch);
575}
576
577/*
578 * Interrupts are disabled on entering
579 */
580static void
581sport_uart_console_write(struct console *co, const char *s, unsigned int count)
582{
583 struct sport_uart_port *up = bfin_sport_uart_ports[co->index];
584 unsigned long flags;
585
586 spin_lock_irqsave(&up->port.lock, flags);
587
588 if (SPORT_GET_TCR1(up) & TSPEN)
589 uart_console_write(&up->port, s, count, sport_uart_console_putchar);
590 else {
591 /* dummy data to start sport */
592 while (SPORT_GET_STAT(up) & TXF)
593 barrier();
594 SPORT_PUT_TX(up, 0xffff);
595 /* Enable transmit, then an interrupt will generated */
596 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
597 SSYNC();
598
599 uart_console_write(&up->port, s, count, sport_uart_console_putchar);
600
601 /* Although the hold register is empty, last byte is still in shift
602 * register and not sent out yet. So, put a dummy data into TX FIFO.
603 * Then, sport tx stops when last byte is shift out and the dummy
604 * data is moved into the shift register.
605 */
606 while (SPORT_GET_STAT(up) & TXF)
607 barrier();
608 SPORT_PUT_TX(up, 0xffff);
609 while (!(SPORT_GET_STAT(up) & TXHRE))
610 barrier();
611
612 /* Stop sport tx transfer */
613 SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
614 SSYNC();
516 } 615 }
616
617 spin_unlock_irqrestore(&up->port.lock, flags);
618}
619
620static struct uart_driver sport_uart_reg;
621
622static struct console sport_uart_console = {
623 .name = DEVICE_NAME,
624 .write = sport_uart_console_write,
625 .device = uart_console_device,
626 .setup = sport_uart_console_setup,
627 .flags = CON_PRINTBUFFER,
628 .index = -1,
629 .data = &sport_uart_reg,
517}; 630};
518 631
632#define SPORT_UART_CONSOLE (&sport_uart_console)
633#else
634#define SPORT_UART_CONSOLE NULL
635#endif /* CONFIG_SERIAL_BFIN_SPORT_CONSOLE */
636
637
519static struct uart_driver sport_uart_reg = { 638static struct uart_driver sport_uart_reg = {
520 .owner = THIS_MODULE, 639 .owner = THIS_MODULE,
521 .driver_name = "SPORT-UART", 640 .driver_name = DRV_NAME,
522 .dev_name = "ttySS", 641 .dev_name = DEVICE_NAME,
523 .major = 204, 642 .major = 204,
524 .minor = 84, 643 .minor = 84,
525 .nr = ARRAY_SIZE(sport_uart_ports), 644 .nr = BFIN_SPORT_UART_MAX_PORTS,
526 .cons = NULL, 645 .cons = SPORT_UART_CONSOLE,
527}; 646};
528 647
529static int sport_uart_suspend(struct platform_device *dev, pm_message_t state) 648#ifdef CONFIG_PM
649static int sport_uart_suspend(struct device *dev)
530{ 650{
531 struct sport_uart_port *sport = platform_get_drvdata(dev); 651 struct sport_uart_port *sport = dev_get_drvdata(dev);
532 652
533 pr_debug("%s enter\n", __func__); 653 dev_dbg(dev, "%s enter\n", __func__);
534 if (sport) 654 if (sport)
535 uart_suspend_port(&sport_uart_reg, &sport->port); 655 uart_suspend_port(&sport_uart_reg, &sport->port);
536 656
537 return 0; 657 return 0;
538} 658}
539 659
540static int sport_uart_resume(struct platform_device *dev) 660static int sport_uart_resume(struct device *dev)
541{ 661{
542 struct sport_uart_port *sport = platform_get_drvdata(dev); 662 struct sport_uart_port *sport = dev_get_drvdata(dev);
543 663
544 pr_debug("%s enter\n", __func__); 664 dev_dbg(dev, "%s enter\n", __func__);
545 if (sport) 665 if (sport)
546 uart_resume_port(&sport_uart_reg, &sport->port); 666 uart_resume_port(&sport_uart_reg, &sport->port);
547 667
548 return 0; 668 return 0;
549} 669}
550 670
551static int sport_uart_probe(struct platform_device *dev) 671static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
672 .suspend = sport_uart_suspend,
673 .resume = sport_uart_resume,
674};
675#endif
676
677static int __devinit sport_uart_probe(struct platform_device *pdev)
552{ 678{
553 pr_debug("%s enter\n", __func__); 679 struct resource *res;
554 sport_uart_ports[dev->id].port.dev = &dev->dev; 680 struct sport_uart_port *sport;
555 uart_add_one_port(&sport_uart_reg, &sport_uart_ports[dev->id].port); 681 int ret = 0;
556 platform_set_drvdata(dev, &sport_uart_ports[dev->id]);
557 682
558 return 0; 683 dev_dbg(&pdev->dev, "%s enter\n", __func__);
684
685 if (pdev->id < 0 || pdev->id >= BFIN_SPORT_UART_MAX_PORTS) {
686 dev_err(&pdev->dev, "Wrong sport uart platform device id.\n");
687 return -ENOENT;
688 }
689
690 if (bfin_sport_uart_ports[pdev->id] == NULL) {
691 bfin_sport_uart_ports[pdev->id] =
692 kmalloc(sizeof(struct sport_uart_port), GFP_KERNEL);
693 sport = bfin_sport_uart_ports[pdev->id];
694 if (!sport) {
695 dev_err(&pdev->dev,
696 "Fail to kmalloc sport_uart_port\n");
697 return -ENOMEM;
698 }
699
700 ret = peripheral_request_list(
701 (unsigned short *)pdev->dev.platform_data, DRV_NAME);
702 if (ret) {
703 dev_err(&pdev->dev,
704 "Fail to request SPORT peripherals\n");
705 goto out_error_free_mem;
706 }
707
708 spin_lock_init(&sport->port.lock);
709 sport->port.fifosize = SPORT_TX_FIFO_SIZE,
710 sport->port.ops = &sport_uart_ops;
711 sport->port.line = pdev->id;
712 sport->port.iotype = UPIO_MEM;
713 sport->port.flags = UPF_BOOT_AUTOCONF;
714
715 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
716 if (res == NULL) {
717 dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
718 ret = -ENOENT;
719 goto out_error_free_peripherals;
720 }
721
722 sport->port.membase = ioremap(res->start,
723 res->end - res->start);
724 if (!sport->port.membase) {
725 dev_err(&pdev->dev, "Cannot map sport IO\n");
726 ret = -ENXIO;
727 goto out_error_free_peripherals;
728 }
729
730 sport->port.irq = platform_get_irq(pdev, 0);
731 if (sport->port.irq < 0) {
732 dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n");
733 ret = -ENOENT;
734 goto out_error_unmap;
735 }
736
737 sport->err_irq = platform_get_irq(pdev, 1);
738 if (sport->err_irq < 0) {
739 dev_err(&pdev->dev, "No sport status IRQ specified\n");
740 ret = -ENOENT;
741 goto out_error_unmap;
742 }
743 }
744
745#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
746 if (!is_early_platform_device(pdev)) {
747#endif
748 sport = bfin_sport_uart_ports[pdev->id];
749 sport->port.dev = &pdev->dev;
750 dev_set_drvdata(&pdev->dev, sport);
751 ret = uart_add_one_port(&sport_uart_reg, &sport->port);
752#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
753 }
754#endif
755 if (!ret)
756 return 0;
757
758 if (sport) {
759out_error_unmap:
760 iounmap(sport->port.membase);
761out_error_free_peripherals:
762 peripheral_free_list(
763 (unsigned short *)pdev->dev.platform_data);
764out_error_free_mem:
765 kfree(sport);
766 bfin_sport_uart_ports[pdev->id] = NULL;
767 }
768
769 return ret;
559} 770}
560 771
561static int sport_uart_remove(struct platform_device *dev) 772static int __devexit sport_uart_remove(struct platform_device *pdev)
562{ 773{
563 struct sport_uart_port *sport = platform_get_drvdata(dev); 774 struct sport_uart_port *sport = platform_get_drvdata(pdev);
564 775
565 pr_debug("%s enter\n", __func__); 776 dev_dbg(&pdev->dev, "%s enter\n", __func__);
566 platform_set_drvdata(dev, NULL); 777 dev_set_drvdata(&pdev->dev, NULL);
567 778
568 if (sport) 779 if (sport) {
569 uart_remove_one_port(&sport_uart_reg, &sport->port); 780 uart_remove_one_port(&sport_uart_reg, &sport->port);
781 iounmap(sport->port.membase);
782 peripheral_free_list(
783 (unsigned short *)pdev->dev.platform_data);
784 kfree(sport);
785 bfin_sport_uart_ports[pdev->id] = NULL;
786 }
570 787
571 return 0; 788 return 0;
572} 789}
573 790
574static struct platform_driver sport_uart_driver = { 791static struct platform_driver sport_uart_driver = {
575 .probe = sport_uart_probe, 792 .probe = sport_uart_probe,
576 .remove = sport_uart_remove, 793 .remove = __devexit_p(sport_uart_remove),
577 .suspend = sport_uart_suspend,
578 .resume = sport_uart_resume,
579 .driver = { 794 .driver = {
580 .name = DRV_NAME, 795 .name = DRV_NAME,
796#ifdef CONFIG_PM
797 .pm = &bfin_sport_uart_dev_pm_ops,
798#endif
581 }, 799 },
582}; 800};
583 801
802#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
803static __initdata struct early_platform_driver early_sport_uart_driver = {
804 .class_str = DRV_NAME,
805 .pdrv = &sport_uart_driver,
806 .requested_id = EARLY_PLATFORM_ID_UNSET,
807};
808
809static int __init sport_uart_rs_console_init(void)
810{
811 early_platform_driver_register(&early_sport_uart_driver, DRV_NAME);
812
813 early_platform_driver_probe(DRV_NAME, BFIN_SPORT_UART_MAX_PORTS, 0);
814
815 register_console(&sport_uart_console);
816
817 return 0;
818}
819console_initcall(sport_uart_rs_console_init);
820#endif
821
584static int __init sport_uart_init(void) 822static int __init sport_uart_init(void)
585{ 823{
586 int ret; 824 int ret;
587 825
588 pr_debug("%s enter\n", __func__); 826 pr_info("Serial: Blackfin uart over sport driver\n");
827
589 ret = uart_register_driver(&sport_uart_reg); 828 ret = uart_register_driver(&sport_uart_reg);
590 if (ret != 0) { 829 if (ret) {
591 printk(KERN_ERR "Failed to register %s:%d\n", 830 pr_err("failed to register %s:%d\n",
592 sport_uart_reg.driver_name, ret); 831 sport_uart_reg.driver_name, ret);
593 return ret; 832 return ret;
594 } 833 }
595 834
596 ret = platform_driver_register(&sport_uart_driver); 835 ret = platform_driver_register(&sport_uart_driver);
597 if (ret != 0) { 836 if (ret) {
598 printk(KERN_ERR "Failed to register sport uart driver:%d\n", ret); 837 pr_err("failed to register sport uart driver:%d\n", ret);
599 uart_unregister_driver(&sport_uart_reg); 838 uart_unregister_driver(&sport_uart_reg);
600 } 839 }
601 840
602
603 pr_debug("%s exit\n", __func__);
604 return ret; 841 return ret;
605} 842}
843module_init(sport_uart_init);
606 844
607static void __exit sport_uart_exit(void) 845static void __exit sport_uart_exit(void)
608{ 846{
609 pr_debug("%s enter\n", __func__);
610 platform_driver_unregister(&sport_uart_driver); 847 platform_driver_unregister(&sport_uart_driver);
611 uart_unregister_driver(&sport_uart_reg); 848 uart_unregister_driver(&sport_uart_reg);
612} 849}
613
614module_init(sport_uart_init);
615module_exit(sport_uart_exit); 850module_exit(sport_uart_exit);
616 851
852MODULE_AUTHOR("Sonic Zhang, Roy Huang");
853MODULE_DESCRIPTION("Blackfin serial over SPORT driver");
617MODULE_LICENSE("GPL"); 854MODULE_LICENSE("GPL");
diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/serial/bfin_sport_uart.h
index 671d41cc1a3f..abe03614e4df 100644
--- a/drivers/serial/bfin_sport_uart.h
+++ b/drivers/serial/bfin_sport_uart.h
@@ -1,29 +1,23 @@
1/* 1/*
2 * File: linux/drivers/serial/bfin_sport_uart.h 2 * Blackfin On-Chip Sport Emulated UART Driver
3 * 3 *
4 * Based on: include/asm-blackfin/mach-533/bfin_serial_5xx.h 4 * Copyright 2006-2008 Analog Devices Inc.
5 * Author: Roy Huang <roy.huang>analog.com>
6 * 5 *
7 * Created: Nov 22, 2006 6 * Enter bugs at http://blackfin.uclinux.org/
8 * Copyright: (C) Analog Device Inc.
9 * Description: this driver enable SPORTs on Blackfin emulate UART.
10 * 7 *
11 * This program is free software; you can redistribute it and/or modify 8 * Licensed under the GPL-2 or later.
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see the file COPYING, or write
23 * to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */ 9 */
26 10
11/*
12 * This driver and the hardware supported are in term of EE-191 of ADI.
13 * http://www.analog.com/UploadedFiles/Application_Notes/399447663EE191.pdf
14 * This application note describe how to implement a UART on a Sharc DSP,
15 * but this driver is implemented on Blackfin Processor.
16 * Transmit Frame Sync is not used by this driver to transfer data out.
17 */
18
19#ifndef _BFIN_SPORT_UART_H
20#define _BFIN_SPORT_UART_H
27 21
28#define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */ 22#define OFFSET_TCR1 0x00 /* Transmit Configuration 1 Register */
29#define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */ 23#define OFFSET_TCR2 0x04 /* Transmit Configuration 2 Register */
@@ -61,3 +55,7 @@
61#define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v) 55#define SPORT_PUT_RCLKDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RCLKDIV), v)
62#define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v) 56#define SPORT_PUT_RFSDIV(sport, v) bfin_write16(((sport)->port.membase + OFFSET_RFSDIV), v)
63#define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v) 57#define SPORT_PUT_STAT(sport, v) bfin_write16(((sport)->port.membase + OFFSET_STAT), v)
58
59#define SPORT_TX_FIFO_SIZE 8
60
61#endif /* _BFIN_SPORT_UART_H */