blob: 2ae378cc65b6c627d84cc82c4538a2e64154b906 [file] [log] [blame]
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * Serial port driver for the ETRAX 100LX chip
3 *
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004 * Copyright (C) 1998-2007 Axis Communications AB
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 *
6 * Many, many authors. Based once upon a time on serial.c for 16x50.
7 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 */
9
10static char *serial_version = "$Revision: 1.25 $";
11
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/types.h>
13#include <linux/errno.h>
14#include <linux/signal.h>
15#include <linux/sched.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/tty.h>
19#include <linux/tty_flip.h>
20#include <linux/major.h>
21#include <linux/string.h>
22#include <linux/fcntl.h>
23#include <linux/mm.h>
24#include <linux/slab.h>
25#include <linux/init.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/kernel.h>
Arjan van de Venf392ecf2006-01-12 18:44:32 +000027#include <linux/mutex.h>
Jiri Slaby1977f032007-10-18 23:40:25 -070028#include <linux/bitops.h>
Jesper Nilsson9e040a32009-04-30 15:08:13 -070029#include <linux/seq_file.h>
30#include <linux/delay.h>
31#include <linux/module.h>
32#include <linux/uaccess.h>
33#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <asm/irq.h>
Jesper Nilsson77accbf2007-11-14 17:01:15 -080036#include <asm/dma.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Jesper Nilsson556dcee2008-10-21 17:45:58 +020038#include <arch/svinto.h>
David Howellsb1a154d2012-03-28 18:30:02 +010039#include <arch/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
41/* non-arch dependent serial structures are in linux/serial.h */
42#include <linux/serial.h>
43/* while we keep our own stuff (struct e100_serial) in a local .h file */
Jesper Nilsson77accbf2007-11-14 17:01:15 -080044#include "crisv10.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <asm/fasttimer.h>
Jesper Nilsson556dcee2008-10-21 17:45:58 +020046#include <arch/io_interface_mux.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
48#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
49#ifndef CONFIG_ETRAX_FAST_TIMER
50#error "Enable FAST_TIMER to use SERIAL_FAST_TIMER"
51#endif
52#endif
53
54#if defined(CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS) && \
55 (CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS == 0)
56#error "RX_TIMEOUT_TICKS == 0 not allowed, use 1"
57#endif
58
59#if defined(CONFIG_ETRAX_RS485_ON_PA) && defined(CONFIG_ETRAX_RS485_ON_PORT_G)
60#error "Disable either CONFIG_ETRAX_RS485_ON_PA or CONFIG_ETRAX_RS485_ON_PORT_G"
61#endif
62
63/*
64 * All of the compatibilty code so we can compile serial.c against
65 * older kernels is hidden in serial_compat.h
66 */
67#if defined(LOCAL_HEADERS)
68#include "serial_compat.h"
69#endif
70
Linus Torvalds1da177e2005-04-16 15:20:36 -070071struct tty_driver *serial_driver;
72
Linus Torvalds1da177e2005-04-16 15:20:36 -070073/* number of characters left in xmit buffer before we ask for more */
74#define WAKEUP_CHARS 256
75
76//#define SERIAL_DEBUG_INTR
77//#define SERIAL_DEBUG_OPEN
78//#define SERIAL_DEBUG_FLOW
79//#define SERIAL_DEBUG_DATA
80//#define SERIAL_DEBUG_THROTTLE
81//#define SERIAL_DEBUG_IO /* Debug for Extra control and status pins */
82//#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */
83
84/* Enable this to use serial interrupts to handle when you
85 expect the first received event on the serial port to
86 be an error, break or similar. Used to be able to flash IRMA
87 from eLinux */
88#define SERIAL_HANDLE_EARLY_ERRORS
89
Linus Torvalds1da177e2005-04-16 15:20:36 -070090/* Currently 16 descriptors x 128 bytes = 2048 bytes */
91#define SERIAL_DESCR_BUF_SIZE 256
92
93#define SERIAL_PRESCALE_BASE 3125000 /* 3.125MHz */
94#define DEF_BAUD_BASE SERIAL_PRESCALE_BASE
95
96/* We don't want to load the system with massive fast timer interrupt
97 * on high baudrates so limit it to 250 us (4kHz) */
98#define MIN_FLUSH_TIME_USEC 250
99
100/* Add an x here to log a lot of timer stuff */
101#define TIMERD(x)
102/* Debug details of interrupt handling */
103#define DINTR1(x) /* irq on/off, errors */
104#define DINTR2(x) /* tx and rx */
105/* Debug flip buffer stuff */
106#define DFLIP(x)
107/* Debug flow control and overview of data flow */
108#define DFLOW(x)
109#define DBAUD(x)
110#define DLOG_INT_TRIG(x)
111
112//#define DEBUG_LOG_INCLUDED
113#ifndef DEBUG_LOG_INCLUDED
114#define DEBUG_LOG(line, string, value)
115#else
116struct debug_log_info
117{
118 unsigned long time;
119 unsigned long timer_data;
120// int line;
121 const char *string;
122 int value;
123};
124#define DEBUG_LOG_SIZE 4096
125
126struct debug_log_info debug_log[DEBUG_LOG_SIZE];
127int debug_log_pos = 0;
128
129#define DEBUG_LOG(_line, _string, _value) do { \
130 if ((_line) == SERIAL_DEBUG_LINE) {\
131 debug_log_func(_line, _string, _value); \
132 }\
133}while(0)
134
135void debug_log_func(int line, const char *string, int value)
136{
137 if (debug_log_pos < DEBUG_LOG_SIZE) {
138 debug_log[debug_log_pos].time = jiffies;
139 debug_log[debug_log_pos].timer_data = *R_TIMER_DATA;
140// debug_log[debug_log_pos].line = line;
141 debug_log[debug_log_pos].string = string;
142 debug_log[debug_log_pos].value = value;
143 debug_log_pos++;
144 }
145 /*printk(string, value);*/
146}
147#endif
148
149#ifndef CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS
150/* Default number of timer ticks before flushing rx fifo
151 * When using "little data, low latency applications: use 0
152 * When using "much data applications (PPP)" use ~5
153 */
154#define CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5
155#endif
156
157unsigned long timer_data_to_ns(unsigned long timer_data);
158
159static void change_speed(struct e100_serial *info);
160static void rs_throttle(struct tty_struct * tty);
161static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800162static int rs_write(struct tty_struct *tty,
163 const unsigned char *buf, int count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164#ifdef CONFIG_ETRAX_RS485
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800165static int e100_write_rs485(struct tty_struct *tty,
166 const unsigned char *buf, int count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800168static int get_lsr_info(struct e100_serial *info, unsigned int *value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
170
171#define DEF_BAUD 115200 /* 115.2 kbit/s */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172#define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */
173/* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */
174#define DEF_TX 0x80 /* or SERIAL_CTRL_B */
175
176/* offsets from R_SERIALx_CTRL */
177
178#define REG_DATA 0
179#define REG_DATA_STATUS32 0 /* this is the 32 bit register R_SERIALx_READ */
180#define REG_TR_DATA 0
181#define REG_STATUS 1
182#define REG_TR_CTRL 1
183#define REG_REC_CTRL 2
184#define REG_BAUD 3
185#define REG_XOFF 4 /* this is a 32 bit register */
186
187/* The bitfields are the same for all serial ports */
188#define SER_RXD_MASK IO_MASK(R_SERIAL0_STATUS, rxd)
189#define SER_DATA_AVAIL_MASK IO_MASK(R_SERIAL0_STATUS, data_avail)
190#define SER_FRAMING_ERR_MASK IO_MASK(R_SERIAL0_STATUS, framing_err)
191#define SER_PAR_ERR_MASK IO_MASK(R_SERIAL0_STATUS, par_err)
192#define SER_OVERRUN_MASK IO_MASK(R_SERIAL0_STATUS, overrun)
193
194#define SER_ERROR_MASK (SER_OVERRUN_MASK | SER_PAR_ERR_MASK | SER_FRAMING_ERR_MASK)
195
196/* Values for info->errorcode */
197#define ERRCODE_SET_BREAK (TTY_BREAK)
198#define ERRCODE_INSERT 0x100
199#define ERRCODE_INSERT_BREAK (ERRCODE_INSERT | TTY_BREAK)
200
201#define FORCE_EOP(info) *R_SET_EOP = 1U << info->iseteop;
202
203/*
204 * General note regarding the use of IO_* macros in this file:
205 *
206 * We will use the bits defined for DMA channel 6 when using various
207 * IO_* macros (e.g. IO_STATE, IO_MASK, IO_EXTRACT) and _assume_ they are
208 * the same for all channels (which of course they are).
209 *
210 * We will also use the bits defined for serial port 0 when writing commands
211 * to the different ports, as these bits too are the same for all ports.
212 */
213
214
215/* Mask for the irqs possibly enabled in R_IRQ_MASK1_RD etc. */
216static const unsigned long e100_ser_int_mask = 0
217#ifdef CONFIG_ETRAX_SERIAL_PORT0
218| IO_MASK(R_IRQ_MASK1_RD, ser0_data) | IO_MASK(R_IRQ_MASK1_RD, ser0_ready)
219#endif
220#ifdef CONFIG_ETRAX_SERIAL_PORT1
221| IO_MASK(R_IRQ_MASK1_RD, ser1_data) | IO_MASK(R_IRQ_MASK1_RD, ser1_ready)
222#endif
223#ifdef CONFIG_ETRAX_SERIAL_PORT2
224| IO_MASK(R_IRQ_MASK1_RD, ser2_data) | IO_MASK(R_IRQ_MASK1_RD, ser2_ready)
225#endif
226#ifdef CONFIG_ETRAX_SERIAL_PORT3
227| IO_MASK(R_IRQ_MASK1_RD, ser3_data) | IO_MASK(R_IRQ_MASK1_RD, ser3_ready)
228#endif
229;
230unsigned long r_alt_ser_baudrate_shadow = 0;
231
232/* this is the data for the four serial ports in the etrax100 */
233/* DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */
234/* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */
235
236static struct e100_serial rs_table[] = {
237 { .baud = DEF_BAUD,
Alan Coxd7283352008-08-04 17:21:18 +0100238 .ioport = (unsigned char *)R_SERIAL0_CTRL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 .irq = 1U << 12, /* uses DMA 6 and 7 */
240 .oclrintradr = R_DMA_CH6_CLR_INTR,
241 .ofirstadr = R_DMA_CH6_FIRST,
242 .ocmdadr = R_DMA_CH6_CMD,
243 .ostatusadr = R_DMA_CH6_STATUS,
244 .iclrintradr = R_DMA_CH7_CLR_INTR,
245 .ifirstadr = R_DMA_CH7_FIRST,
246 .icmdadr = R_DMA_CH7_CMD,
247 .idescradr = R_DMA_CH7_DESCR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 .rx_ctrl = DEF_RX,
249 .tx_ctrl = DEF_TX,
250 .iseteop = 2,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800251 .dma_owner = dma_ser0,
252 .io_if = if_serial_0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253#ifdef CONFIG_ETRAX_SERIAL_PORT0
254 .enabled = 1,
255#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
256 .dma_out_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800257 .dma_out_nbr = SER0_TX_DMA_NBR,
258 .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800259 .dma_out_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800260 .dma_out_irq_description = "serial 0 dma tr",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261#else
262 .dma_out_enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800263 .dma_out_nbr = UINT_MAX,
264 .dma_out_irq_nbr = 0,
265 .dma_out_irq_flags = 0,
266 .dma_out_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267#endif
268#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
269 .dma_in_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800270 .dma_in_nbr = SER0_RX_DMA_NBR,
271 .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800272 .dma_in_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800273 .dma_in_irq_description = "serial 0 dma rec",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274#else
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800275 .dma_in_enabled = 0,
276 .dma_in_nbr = UINT_MAX,
277 .dma_in_irq_nbr = 0,
278 .dma_in_irq_flags = 0,
279 .dma_in_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280#endif
281#else
282 .enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800283 .io_if_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 .dma_out_enabled = 0,
285 .dma_in_enabled = 0
286#endif
287
288}, /* ttyS0 */
289#ifndef CONFIG_SVINTO_SIM
290 { .baud = DEF_BAUD,
Alan Coxd7283352008-08-04 17:21:18 +0100291 .ioport = (unsigned char *)R_SERIAL1_CTRL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 .irq = 1U << 16, /* uses DMA 8 and 9 */
293 .oclrintradr = R_DMA_CH8_CLR_INTR,
294 .ofirstadr = R_DMA_CH8_FIRST,
295 .ocmdadr = R_DMA_CH8_CMD,
296 .ostatusadr = R_DMA_CH8_STATUS,
297 .iclrintradr = R_DMA_CH9_CLR_INTR,
298 .ifirstadr = R_DMA_CH9_FIRST,
299 .icmdadr = R_DMA_CH9_CMD,
300 .idescradr = R_DMA_CH9_DESCR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 .rx_ctrl = DEF_RX,
302 .tx_ctrl = DEF_TX,
303 .iseteop = 3,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800304 .dma_owner = dma_ser1,
305 .io_if = if_serial_1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306#ifdef CONFIG_ETRAX_SERIAL_PORT1
307 .enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800308 .io_if_description = "ser1",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
310 .dma_out_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800311 .dma_out_nbr = SER1_TX_DMA_NBR,
312 .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800313 .dma_out_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800314 .dma_out_irq_description = "serial 1 dma tr",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315#else
316 .dma_out_enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800317 .dma_out_nbr = UINT_MAX,
318 .dma_out_irq_nbr = 0,
319 .dma_out_irq_flags = 0,
320 .dma_out_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321#endif
322#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
323 .dma_in_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800324 .dma_in_nbr = SER1_RX_DMA_NBR,
325 .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800326 .dma_in_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800327 .dma_in_irq_description = "serial 1 dma rec",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328#else
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800329 .dma_in_enabled = 0,
330 .dma_in_enabled = 0,
331 .dma_in_nbr = UINT_MAX,
332 .dma_in_irq_nbr = 0,
333 .dma_in_irq_flags = 0,
334 .dma_in_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335#endif
336#else
337 .enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800338 .io_if_description = NULL,
339 .dma_in_irq_nbr = 0,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 .dma_out_enabled = 0,
341 .dma_in_enabled = 0
342#endif
343}, /* ttyS1 */
344
345 { .baud = DEF_BAUD,
Alan Coxd7283352008-08-04 17:21:18 +0100346 .ioport = (unsigned char *)R_SERIAL2_CTRL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 .irq = 1U << 4, /* uses DMA 2 and 3 */
348 .oclrintradr = R_DMA_CH2_CLR_INTR,
349 .ofirstadr = R_DMA_CH2_FIRST,
350 .ocmdadr = R_DMA_CH2_CMD,
351 .ostatusadr = R_DMA_CH2_STATUS,
352 .iclrintradr = R_DMA_CH3_CLR_INTR,
353 .ifirstadr = R_DMA_CH3_FIRST,
354 .icmdadr = R_DMA_CH3_CMD,
355 .idescradr = R_DMA_CH3_DESCR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 .rx_ctrl = DEF_RX,
357 .tx_ctrl = DEF_TX,
358 .iseteop = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800359 .dma_owner = dma_ser2,
360 .io_if = if_serial_2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361#ifdef CONFIG_ETRAX_SERIAL_PORT2
362 .enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800363 .io_if_description = "ser2",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
365 .dma_out_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800366 .dma_out_nbr = SER2_TX_DMA_NBR,
367 .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800368 .dma_out_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800369 .dma_out_irq_description = "serial 2 dma tr",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370#else
371 .dma_out_enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800372 .dma_out_nbr = UINT_MAX,
373 .dma_out_irq_nbr = 0,
374 .dma_out_irq_flags = 0,
375 .dma_out_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376#endif
377#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
378 .dma_in_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800379 .dma_in_nbr = SER2_RX_DMA_NBR,
380 .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800381 .dma_in_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800382 .dma_in_irq_description = "serial 2 dma rec",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383#else
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800384 .dma_in_enabled = 0,
385 .dma_in_nbr = UINT_MAX,
386 .dma_in_irq_nbr = 0,
387 .dma_in_irq_flags = 0,
388 .dma_in_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389#endif
390#else
391 .enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800392 .io_if_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 .dma_out_enabled = 0,
394 .dma_in_enabled = 0
395#endif
396 }, /* ttyS2 */
397
398 { .baud = DEF_BAUD,
Alan Coxd7283352008-08-04 17:21:18 +0100399 .ioport = (unsigned char *)R_SERIAL3_CTRL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 .irq = 1U << 8, /* uses DMA 4 and 5 */
401 .oclrintradr = R_DMA_CH4_CLR_INTR,
402 .ofirstadr = R_DMA_CH4_FIRST,
403 .ocmdadr = R_DMA_CH4_CMD,
404 .ostatusadr = R_DMA_CH4_STATUS,
405 .iclrintradr = R_DMA_CH5_CLR_INTR,
406 .ifirstadr = R_DMA_CH5_FIRST,
407 .icmdadr = R_DMA_CH5_CMD,
408 .idescradr = R_DMA_CH5_DESCR,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 .rx_ctrl = DEF_RX,
410 .tx_ctrl = DEF_TX,
411 .iseteop = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800412 .dma_owner = dma_ser3,
413 .io_if = if_serial_3,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414#ifdef CONFIG_ETRAX_SERIAL_PORT3
415 .enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800416 .io_if_description = "ser3",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
418 .dma_out_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800419 .dma_out_nbr = SER3_TX_DMA_NBR,
420 .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800421 .dma_out_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800422 .dma_out_irq_description = "serial 3 dma tr",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423#else
424 .dma_out_enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800425 .dma_out_nbr = UINT_MAX,
426 .dma_out_irq_nbr = 0,
427 .dma_out_irq_flags = 0,
428 .dma_out_irq_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429#endif
430#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
431 .dma_in_enabled = 1,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800432 .dma_in_nbr = SER3_RX_DMA_NBR,
433 .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR,
Yong Zhang9cfb5c02011-09-22 16:59:15 +0800434 .dma_in_irq_flags = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800435 .dma_in_irq_description = "serial 3 dma rec",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436#else
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800437 .dma_in_enabled = 0,
438 .dma_in_nbr = UINT_MAX,
439 .dma_in_irq_nbr = 0,
440 .dma_in_irq_flags = 0,
441 .dma_in_irq_description = NULL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442#endif
443#else
444 .enabled = 0,
Jesper Nilsson77accbf2007-11-14 17:01:15 -0800445 .io_if_description = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 .dma_out_enabled = 0,
447 .dma_in_enabled = 0
448#endif
449 } /* ttyS3 */
450#endif
451};
452
453
454#define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial))
455
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
457static struct fast_timer fast_timers[NR_PORTS];
458#endif
459
460#ifdef CONFIG_ETRAX_SERIAL_PROC_ENTRY
461#define PROCSTAT(x) x
462struct ser_statistics_type {
463 int overrun_cnt;
464 int early_errors_cnt;
465 int ser_ints_ok_cnt;
466 int errors_cnt;
467 unsigned long int processing_flip;
468 unsigned long processing_flip_still_room;
469 unsigned long int timeout_flush_cnt;
470 int rx_dma_ints;
471 int tx_dma_ints;
472 int rx_tot;
473 int tx_tot;
474};
475
476static struct ser_statistics_type ser_stat[NR_PORTS];
477
478#else
479
480#define PROCSTAT(x)
481
482#endif /* CONFIG_ETRAX_SERIAL_PROC_ENTRY */
483
484/* RS-485 */
485#if defined(CONFIG_ETRAX_RS485)
486#ifdef CONFIG_ETRAX_FAST_TIMER
487static struct fast_timer fast_timers_rs485[NR_PORTS];
488#endif
489#if defined(CONFIG_ETRAX_RS485_ON_PA)
490static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT;
491#endif
492#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
493static int rs485_port_g_bit = CONFIG_ETRAX_RS485_ON_PORT_G_BIT;
494#endif
495#endif
496
497/* Info and macros needed for each ports extra control/status signals. */
498#define E100_STRUCT_PORT(line, pinname) \
499 ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \
500 (R_PORT_PA_DATA): ( \
501 (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \
502 (R_PORT_PB_DATA):&dummy_ser[line]))
503
504#define E100_STRUCT_SHADOW(line, pinname) \
505 ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \
506 (&port_pa_data_shadow): ( \
507 (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \
508 (&port_pb_data_shadow):&dummy_ser[line]))
509#define E100_STRUCT_MASK(line, pinname) \
510 ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \
511 (1<<CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT): ( \
512 (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \
513 (1<<CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT):DUMMY_##pinname##_MASK))
514
515#define DUMMY_DTR_MASK 1
516#define DUMMY_RI_MASK 2
517#define DUMMY_DSR_MASK 4
518#define DUMMY_CD_MASK 8
519static unsigned char dummy_ser[NR_PORTS] = {0xFF, 0xFF, 0xFF,0xFF};
520
521/* If not all status pins are used or disabled, use mixed mode */
522#ifdef CONFIG_ETRAX_SERIAL_PORT0
523
524#define SER0_PA_BITSUM (CONFIG_ETRAX_SER0_DTR_ON_PA_BIT+CONFIG_ETRAX_SER0_RI_ON_PA_BIT+CONFIG_ETRAX_SER0_DSR_ON_PA_BIT+CONFIG_ETRAX_SER0_CD_ON_PA_BIT)
525
526#if SER0_PA_BITSUM != -4
527# if CONFIG_ETRAX_SER0_DTR_ON_PA_BIT == -1
528# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
529# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
530# endif
531# endif
532# if CONFIG_ETRAX_SER0_RI_ON_PA_BIT == -1
533# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
534# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
535# endif
536# endif
537# if CONFIG_ETRAX_SER0_DSR_ON_PA_BIT == -1
538# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
539# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
540# endif
541# endif
542# if CONFIG_ETRAX_SER0_CD_ON_PA_BIT == -1
543# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
544# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
545# endif
546# endif
547#endif
548
549#define SER0_PB_BITSUM (CONFIG_ETRAX_SER0_DTR_ON_PB_BIT+CONFIG_ETRAX_SER0_RI_ON_PB_BIT+CONFIG_ETRAX_SER0_DSR_ON_PB_BIT+CONFIG_ETRAX_SER0_CD_ON_PB_BIT)
550
551#if SER0_PB_BITSUM != -4
552# if CONFIG_ETRAX_SER0_DTR_ON_PB_BIT == -1
553# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
554# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
555# endif
556# endif
557# if CONFIG_ETRAX_SER0_RI_ON_PB_BIT == -1
558# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
559# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
560# endif
561# endif
562# if CONFIG_ETRAX_SER0_DSR_ON_PB_BIT == -1
563# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
564# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
565# endif
566# endif
567# if CONFIG_ETRAX_SER0_CD_ON_PB_BIT == -1
568# ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
569# define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
570# endif
571# endif
572#endif
573
574#endif /* PORT0 */
575
576
577#ifdef CONFIG_ETRAX_SERIAL_PORT1
578
579#define SER1_PA_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PA_BIT+CONFIG_ETRAX_SER1_RI_ON_PA_BIT+CONFIG_ETRAX_SER1_DSR_ON_PA_BIT+CONFIG_ETRAX_SER1_CD_ON_PA_BIT)
580
581#if SER1_PA_BITSUM != -4
582# if CONFIG_ETRAX_SER1_DTR_ON_PA_BIT == -1
583# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
584# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
585# endif
586# endif
587# if CONFIG_ETRAX_SER1_RI_ON_PA_BIT == -1
588# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
589# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
590# endif
591# endif
592# if CONFIG_ETRAX_SER1_DSR_ON_PA_BIT == -1
593# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
594# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
595# endif
596# endif
597# if CONFIG_ETRAX_SER1_CD_ON_PA_BIT == -1
598# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
599# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
600# endif
601# endif
602#endif
603
604#define SER1_PB_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PB_BIT+CONFIG_ETRAX_SER1_RI_ON_PB_BIT+CONFIG_ETRAX_SER1_DSR_ON_PB_BIT+CONFIG_ETRAX_SER1_CD_ON_PB_BIT)
605
606#if SER1_PB_BITSUM != -4
607# if CONFIG_ETRAX_SER1_DTR_ON_PB_BIT == -1
608# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
609# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
610# endif
611# endif
612# if CONFIG_ETRAX_SER1_RI_ON_PB_BIT == -1
613# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
614# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
615# endif
616# endif
617# if CONFIG_ETRAX_SER1_DSR_ON_PB_BIT == -1
618# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
619# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
620# endif
621# endif
622# if CONFIG_ETRAX_SER1_CD_ON_PB_BIT == -1
623# ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
624# define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
625# endif
626# endif
627#endif
628
629#endif /* PORT1 */
630
631#ifdef CONFIG_ETRAX_SERIAL_PORT2
632
633#define SER2_PA_BITSUM (CONFIG_ETRAX_SER2_DTR_ON_PA_BIT+CONFIG_ETRAX_SER2_RI_ON_PA_BIT+CONFIG_ETRAX_SER2_DSR_ON_PA_BIT+CONFIG_ETRAX_SER2_CD_ON_PA_BIT)
634
635#if SER2_PA_BITSUM != -4
636# if CONFIG_ETRAX_SER2_DTR_ON_PA_BIT == -1
637# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
638# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
639# endif
640# endif
641# if CONFIG_ETRAX_SER2_RI_ON_PA_BIT == -1
642# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
643# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
644# endif
645# endif
646# if CONFIG_ETRAX_SER2_DSR_ON_PA_BIT == -1
647# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
648# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
649# endif
650# endif
651# if CONFIG_ETRAX_SER2_CD_ON_PA_BIT == -1
652# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
653# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
654# endif
655# endif
656#endif
657
658#define SER2_PB_BITSUM (CONFIG_ETRAX_SER2_DTR_ON_PB_BIT+CONFIG_ETRAX_SER2_RI_ON_PB_BIT+CONFIG_ETRAX_SER2_DSR_ON_PB_BIT+CONFIG_ETRAX_SER2_CD_ON_PB_BIT)
659
660#if SER2_PB_BITSUM != -4
661# if CONFIG_ETRAX_SER2_DTR_ON_PB_BIT == -1
662# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
663# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
664# endif
665# endif
666# if CONFIG_ETRAX_SER2_RI_ON_PB_BIT == -1
667# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
668# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
669# endif
670# endif
671# if CONFIG_ETRAX_SER2_DSR_ON_PB_BIT == -1
672# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
673# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
674# endif
675# endif
676# if CONFIG_ETRAX_SER2_CD_ON_PB_BIT == -1
677# ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
678# define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
679# endif
680# endif
681#endif
682
683#endif /* PORT2 */
684
685#ifdef CONFIG_ETRAX_SERIAL_PORT3
686
687#define SER3_PA_BITSUM (CONFIG_ETRAX_SER3_DTR_ON_PA_BIT+CONFIG_ETRAX_SER3_RI_ON_PA_BIT+CONFIG_ETRAX_SER3_DSR_ON_PA_BIT+CONFIG_ETRAX_SER3_CD_ON_PA_BIT)
688
689#if SER3_PA_BITSUM != -4
690# if CONFIG_ETRAX_SER3_DTR_ON_PA_BIT == -1
691# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
692# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
693# endif
694# endif
695# if CONFIG_ETRAX_SER3_RI_ON_PA_BIT == -1
696# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
697# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
698# endif
699# endif
700# if CONFIG_ETRAX_SER3_DSR_ON_PA_BIT == -1
701# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
702# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
703# endif
704# endif
705# if CONFIG_ETRAX_SER3_CD_ON_PA_BIT == -1
706# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
707# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
708# endif
709# endif
710#endif
711
712#define SER3_PB_BITSUM (CONFIG_ETRAX_SER3_DTR_ON_PB_BIT+CONFIG_ETRAX_SER3_RI_ON_PB_BIT+CONFIG_ETRAX_SER3_DSR_ON_PB_BIT+CONFIG_ETRAX_SER3_CD_ON_PB_BIT)
713
714#if SER3_PB_BITSUM != -4
715# if CONFIG_ETRAX_SER3_DTR_ON_PB_BIT == -1
716# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
717# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
718# endif
719# endif
720# if CONFIG_ETRAX_SER3_RI_ON_PB_BIT == -1
721# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
722# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
723# endif
724# endif
725# if CONFIG_ETRAX_SER3_DSR_ON_PB_BIT == -1
726# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
727# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
728# endif
729# endif
730# if CONFIG_ETRAX_SER3_CD_ON_PB_BIT == -1
731# ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
732# define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
733# endif
734# endif
735#endif
736
737#endif /* PORT3 */
738
739
740#if defined(CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED) || \
741 defined(CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED) || \
742 defined(CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED) || \
743 defined(CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED)
744#define CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED
745#endif
746
747#ifdef CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED
748/* The pins can be mixed on PA and PB */
749#define CONTROL_PINS_PORT_NOT_USED(line) \
750 &dummy_ser[line], &dummy_ser[line], \
751 &dummy_ser[line], &dummy_ser[line], \
752 &dummy_ser[line], &dummy_ser[line], \
753 &dummy_ser[line], &dummy_ser[line], \
754 DUMMY_DTR_MASK, DUMMY_RI_MASK, DUMMY_DSR_MASK, DUMMY_CD_MASK
755
756
757struct control_pins
758{
759 volatile unsigned char *dtr_port;
760 unsigned char *dtr_shadow;
761 volatile unsigned char *ri_port;
762 unsigned char *ri_shadow;
763 volatile unsigned char *dsr_port;
764 unsigned char *dsr_shadow;
765 volatile unsigned char *cd_port;
766 unsigned char *cd_shadow;
767
768 unsigned char dtr_mask;
769 unsigned char ri_mask;
770 unsigned char dsr_mask;
771 unsigned char cd_mask;
772};
773
774static const struct control_pins e100_modem_pins[NR_PORTS] =
775{
776 /* Ser 0 */
777 {
778#ifdef CONFIG_ETRAX_SERIAL_PORT0
779 E100_STRUCT_PORT(0,DTR), E100_STRUCT_SHADOW(0,DTR),
780 E100_STRUCT_PORT(0,RI), E100_STRUCT_SHADOW(0,RI),
781 E100_STRUCT_PORT(0,DSR), E100_STRUCT_SHADOW(0,DSR),
782 E100_STRUCT_PORT(0,CD), E100_STRUCT_SHADOW(0,CD),
783 E100_STRUCT_MASK(0,DTR),
784 E100_STRUCT_MASK(0,RI),
785 E100_STRUCT_MASK(0,DSR),
786 E100_STRUCT_MASK(0,CD)
787#else
788 CONTROL_PINS_PORT_NOT_USED(0)
789#endif
790 },
791
792 /* Ser 1 */
793 {
794#ifdef CONFIG_ETRAX_SERIAL_PORT1
795 E100_STRUCT_PORT(1,DTR), E100_STRUCT_SHADOW(1,DTR),
796 E100_STRUCT_PORT(1,RI), E100_STRUCT_SHADOW(1,RI),
797 E100_STRUCT_PORT(1,DSR), E100_STRUCT_SHADOW(1,DSR),
798 E100_STRUCT_PORT(1,CD), E100_STRUCT_SHADOW(1,CD),
799 E100_STRUCT_MASK(1,DTR),
800 E100_STRUCT_MASK(1,RI),
801 E100_STRUCT_MASK(1,DSR),
802 E100_STRUCT_MASK(1,CD)
803#else
804 CONTROL_PINS_PORT_NOT_USED(1)
805#endif
806 },
807
808 /* Ser 2 */
809 {
810#ifdef CONFIG_ETRAX_SERIAL_PORT2
811 E100_STRUCT_PORT(2,DTR), E100_STRUCT_SHADOW(2,DTR),
812 E100_STRUCT_PORT(2,RI), E100_STRUCT_SHADOW(2,RI),
813 E100_STRUCT_PORT(2,DSR), E100_STRUCT_SHADOW(2,DSR),
814 E100_STRUCT_PORT(2,CD), E100_STRUCT_SHADOW(2,CD),
815 E100_STRUCT_MASK(2,DTR),
816 E100_STRUCT_MASK(2,RI),
817 E100_STRUCT_MASK(2,DSR),
818 E100_STRUCT_MASK(2,CD)
819#else
820 CONTROL_PINS_PORT_NOT_USED(2)
821#endif
822 },
823
824 /* Ser 3 */
825 {
826#ifdef CONFIG_ETRAX_SERIAL_PORT3
827 E100_STRUCT_PORT(3,DTR), E100_STRUCT_SHADOW(3,DTR),
828 E100_STRUCT_PORT(3,RI), E100_STRUCT_SHADOW(3,RI),
829 E100_STRUCT_PORT(3,DSR), E100_STRUCT_SHADOW(3,DSR),
830 E100_STRUCT_PORT(3,CD), E100_STRUCT_SHADOW(3,CD),
831 E100_STRUCT_MASK(3,DTR),
832 E100_STRUCT_MASK(3,RI),
833 E100_STRUCT_MASK(3,DSR),
834 E100_STRUCT_MASK(3,CD)
835#else
836 CONTROL_PINS_PORT_NOT_USED(3)
837#endif
838 }
839};
840#else /* CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED */
841
842/* All pins are on either PA or PB for each serial port */
843#define CONTROL_PINS_PORT_NOT_USED(line) \
844 &dummy_ser[line], &dummy_ser[line], \
845 DUMMY_DTR_MASK, DUMMY_RI_MASK, DUMMY_DSR_MASK, DUMMY_CD_MASK
846
847
848struct control_pins
849{
850 volatile unsigned char *port;
851 unsigned char *shadow;
852
853 unsigned char dtr_mask;
854 unsigned char ri_mask;
855 unsigned char dsr_mask;
856 unsigned char cd_mask;
857};
858
859#define dtr_port port
860#define dtr_shadow shadow
861#define ri_port port
862#define ri_shadow shadow
863#define dsr_port port
864#define dsr_shadow shadow
865#define cd_port port
866#define cd_shadow shadow
867
868static const struct control_pins e100_modem_pins[NR_PORTS] =
869{
870 /* Ser 0 */
871 {
872#ifdef CONFIG_ETRAX_SERIAL_PORT0
873 E100_STRUCT_PORT(0,DTR), E100_STRUCT_SHADOW(0,DTR),
874 E100_STRUCT_MASK(0,DTR),
875 E100_STRUCT_MASK(0,RI),
876 E100_STRUCT_MASK(0,DSR),
877 E100_STRUCT_MASK(0,CD)
878#else
879 CONTROL_PINS_PORT_NOT_USED(0)
880#endif
881 },
882
883 /* Ser 1 */
884 {
885#ifdef CONFIG_ETRAX_SERIAL_PORT1
886 E100_STRUCT_PORT(1,DTR), E100_STRUCT_SHADOW(1,DTR),
887 E100_STRUCT_MASK(1,DTR),
888 E100_STRUCT_MASK(1,RI),
889 E100_STRUCT_MASK(1,DSR),
890 E100_STRUCT_MASK(1,CD)
891#else
892 CONTROL_PINS_PORT_NOT_USED(1)
893#endif
894 },
895
896 /* Ser 2 */
897 {
898#ifdef CONFIG_ETRAX_SERIAL_PORT2
899 E100_STRUCT_PORT(2,DTR), E100_STRUCT_SHADOW(2,DTR),
900 E100_STRUCT_MASK(2,DTR),
901 E100_STRUCT_MASK(2,RI),
902 E100_STRUCT_MASK(2,DSR),
903 E100_STRUCT_MASK(2,CD)
904#else
905 CONTROL_PINS_PORT_NOT_USED(2)
906#endif
907 },
908
909 /* Ser 3 */
910 {
911#ifdef CONFIG_ETRAX_SERIAL_PORT3
912 E100_STRUCT_PORT(3,DTR), E100_STRUCT_SHADOW(3,DTR),
913 E100_STRUCT_MASK(3,DTR),
914 E100_STRUCT_MASK(3,RI),
915 E100_STRUCT_MASK(3,DSR),
916 E100_STRUCT_MASK(3,CD)
917#else
918 CONTROL_PINS_PORT_NOT_USED(3)
919#endif
920 }
921};
922#endif /* !CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED */
923
924#define E100_RTS_MASK 0x20
925#define E100_CTS_MASK 0x40
926
927/* All serial port signals are active low:
928 * active = 0 -> 3.3V to RS-232 driver -> -12V on RS-232 level
929 * inactive = 1 -> 0V to RS-232 driver -> +12V on RS-232 level
930 *
931 * These macros returns the pin value: 0=0V, >=1 = 3.3V on ETRAX chip
932 */
933
934/* Output */
935#define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK)
936/* Input */
Alan Coxd7283352008-08-04 17:21:18 +0100937#define E100_CTS_GET(info) ((info)->ioport[REG_STATUS] & E100_CTS_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
939/* These are typically PA or PB and 0 means 0V, 1 means 3.3V */
940/* Is an output */
941#define E100_DTR_GET(info) ((*e100_modem_pins[(info)->line].dtr_shadow) & e100_modem_pins[(info)->line].dtr_mask)
942
943/* Normally inputs */
944#define E100_RI_GET(info) ((*e100_modem_pins[(info)->line].ri_port) & e100_modem_pins[(info)->line].ri_mask)
945#define E100_CD_GET(info) ((*e100_modem_pins[(info)->line].cd_port) & e100_modem_pins[(info)->line].cd_mask)
946
947/* Input */
948#define E100_DSR_GET(info) ((*e100_modem_pins[(info)->line].dsr_port) & e100_modem_pins[(info)->line].dsr_mask)
949
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950/* Calculate the chartime depending on baudrate, numbor of bits etc. */
951static void update_char_time(struct e100_serial * info)
952{
Alan Coxadc8d742012-07-14 15:31:47 +0100953 tcflag_t cflags = info->port.tty->termios.c_cflag;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 int bits;
955
956 /* calc. number of bits / data byte */
957 /* databits + startbit and 1 stopbit */
958 if ((cflags & CSIZE) == CS7)
959 bits = 9;
960 else
961 bits = 10;
962
963 if (cflags & CSTOPB) /* 2 stopbits ? */
964 bits++;
965
966 if (cflags & PARENB) /* parity bit ? */
967 bits++;
968
969 /* calc timeout */
970 info->char_time_usec = ((bits * 1000000) / info->baud) + 1;
971 info->flush_time_usec = 4*info->char_time_usec;
972 if (info->flush_time_usec < MIN_FLUSH_TIME_USEC)
973 info->flush_time_usec = MIN_FLUSH_TIME_USEC;
974
975}
976
977/*
978 * This function maps from the Bxxxx defines in asm/termbits.h into real
979 * baud rates.
980 */
981
982static int
983cflag_to_baud(unsigned int cflag)
984{
985 static int baud_table[] = {
986 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
987 4800, 9600, 19200, 38400 };
988
989 static int ext_baud_table[] = {
990 0, 57600, 115200, 230400, 460800, 921600, 1843200, 6250000,
991 0, 0, 0, 0, 0, 0, 0, 0 };
992
993 if (cflag & CBAUDEX)
994 return ext_baud_table[(cflag & CBAUD) & ~CBAUDEX];
995 else
996 return baud_table[cflag & CBAUD];
997}
998
999/* and this maps to an etrax100 hardware baud constant */
1000
1001static unsigned char
1002cflag_to_etrax_baud(unsigned int cflag)
1003{
1004 char retval;
1005
1006 static char baud_table[] = {
1007 -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1, 3, 4, 5, 6, 7 };
1008
1009 static char ext_baud_table[] = {
1010 -1, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1 };
1011
1012 if (cflag & CBAUDEX)
1013 retval = ext_baud_table[(cflag & CBAUD) & ~CBAUDEX];
1014 else
1015 retval = baud_table[cflag & CBAUD];
1016
1017 if (retval < 0) {
1018 printk(KERN_WARNING "serdriver tried setting invalid baud rate, flags %x.\n", cflag);
1019 retval = 5; /* choose default 9600 instead */
1020 }
1021
1022 return retval | (retval << 4); /* choose same for both TX and RX */
1023}
1024
1025
1026/* Various static support functions */
1027
1028/* Functions to set or clear DTR/RTS on the requested line */
1029/* It is complicated by the fact that RTS is a serial port register, while
1030 * DTR might not be implemented in the HW at all, and if it is, it can be on
1031 * any general port.
1032 */
1033
1034
1035static inline void
1036e100_dtr(struct e100_serial *info, int set)
1037{
1038#ifndef CONFIG_SVINTO_SIM
1039 unsigned char mask = e100_modem_pins[info->line].dtr_mask;
1040
1041#ifdef SERIAL_DEBUG_IO
1042 printk("ser%i dtr %i mask: 0x%02X\n", info->line, set, mask);
1043 printk("ser%i shadow before 0x%02X get: %i\n",
1044 info->line, *e100_modem_pins[info->line].dtr_shadow,
1045 E100_DTR_GET(info));
1046#endif
1047 /* DTR is active low */
1048 {
1049 unsigned long flags;
1050
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001051 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 *e100_modem_pins[info->line].dtr_shadow &= ~mask;
1053 *e100_modem_pins[info->line].dtr_shadow |= (set ? 0 : mask);
1054 *e100_modem_pins[info->line].dtr_port = *e100_modem_pins[info->line].dtr_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001055 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 }
1057
1058#ifdef SERIAL_DEBUG_IO
1059 printk("ser%i shadow after 0x%02X get: %i\n",
1060 info->line, *e100_modem_pins[info->line].dtr_shadow,
1061 E100_DTR_GET(info));
1062#endif
1063#endif
1064}
1065
1066/* set = 0 means 3.3V on the pin, bitvalue: 0=active, 1=inactive
1067 * 0=0V , 1=3.3V
1068 */
1069static inline void
1070e100_rts(struct e100_serial *info, int set)
1071{
1072#ifndef CONFIG_SVINTO_SIM
1073 unsigned long flags;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001074 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 info->rx_ctrl &= ~E100_RTS_MASK;
1076 info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */
Alan Coxd7283352008-08-04 17:21:18 +01001077 info->ioport[REG_REC_CTRL] = info->rx_ctrl;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001078 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079#ifdef SERIAL_DEBUG_IO
1080 printk("ser%i rts %i\n", info->line, set);
1081#endif
1082#endif
1083}
1084
1085
1086/* If this behaves as a modem, RI and CD is an output */
1087static inline void
1088e100_ri_out(struct e100_serial *info, int set)
1089{
1090#ifndef CONFIG_SVINTO_SIM
1091 /* RI is active low */
1092 {
1093 unsigned char mask = e100_modem_pins[info->line].ri_mask;
1094 unsigned long flags;
1095
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001096 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 *e100_modem_pins[info->line].ri_shadow &= ~mask;
1098 *e100_modem_pins[info->line].ri_shadow |= (set ? 0 : mask);
1099 *e100_modem_pins[info->line].ri_port = *e100_modem_pins[info->line].ri_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001100 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101 }
1102#endif
1103}
1104static inline void
1105e100_cd_out(struct e100_serial *info, int set)
1106{
1107#ifndef CONFIG_SVINTO_SIM
1108 /* CD is active low */
1109 {
1110 unsigned char mask = e100_modem_pins[info->line].cd_mask;
1111 unsigned long flags;
1112
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001113 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 *e100_modem_pins[info->line].cd_shadow &= ~mask;
1115 *e100_modem_pins[info->line].cd_shadow |= (set ? 0 : mask);
1116 *e100_modem_pins[info->line].cd_port = *e100_modem_pins[info->line].cd_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001117 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 }
1119#endif
1120}
1121
1122static inline void
1123e100_disable_rx(struct e100_serial *info)
1124{
1125#ifndef CONFIG_SVINTO_SIM
1126 /* disable the receiver */
Alan Coxd7283352008-08-04 17:21:18 +01001127 info->ioport[REG_REC_CTRL] =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 (info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
1129#endif
1130}
1131
1132static inline void
1133e100_enable_rx(struct e100_serial *info)
1134{
1135#ifndef CONFIG_SVINTO_SIM
1136 /* enable the receiver */
Alan Coxd7283352008-08-04 17:21:18 +01001137 info->ioport[REG_REC_CTRL] =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 (info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable));
1139#endif
1140}
1141
1142/* the rx DMA uses both the dma_descr and the dma_eop interrupts */
1143
1144static inline void
1145e100_disable_rxdma_irq(struct e100_serial *info)
1146{
1147#ifdef SERIAL_DEBUG_INTR
1148 printk("rxdma_irq(%d): 0\n",info->line);
1149#endif
1150 DINTR1(DEBUG_LOG(info->line,"IRQ disable_rxdma_irq %i\n", info->line));
1151 *R_IRQ_MASK2_CLR = (info->irq << 2) | (info->irq << 3);
1152}
1153
1154static inline void
1155e100_enable_rxdma_irq(struct e100_serial *info)
1156{
1157#ifdef SERIAL_DEBUG_INTR
1158 printk("rxdma_irq(%d): 1\n",info->line);
1159#endif
1160 DINTR1(DEBUG_LOG(info->line,"IRQ enable_rxdma_irq %i\n", info->line));
1161 *R_IRQ_MASK2_SET = (info->irq << 2) | (info->irq << 3);
1162}
1163
1164/* the tx DMA uses only dma_descr interrupt */
1165
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001166static void e100_disable_txdma_irq(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167{
1168#ifdef SERIAL_DEBUG_INTR
1169 printk("txdma_irq(%d): 0\n",info->line);
1170#endif
1171 DINTR1(DEBUG_LOG(info->line,"IRQ disable_txdma_irq %i\n", info->line));
1172 *R_IRQ_MASK2_CLR = info->irq;
1173}
1174
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001175static void e100_enable_txdma_irq(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176{
1177#ifdef SERIAL_DEBUG_INTR
1178 printk("txdma_irq(%d): 1\n",info->line);
1179#endif
1180 DINTR1(DEBUG_LOG(info->line,"IRQ enable_txdma_irq %i\n", info->line));
1181 *R_IRQ_MASK2_SET = info->irq;
1182}
1183
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001184static void e100_disable_txdma_channel(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185{
1186 unsigned long flags;
1187
1188 /* Disable output DMA channel for the serial port in question
Frederik Schwarzer025dfda2008-10-16 19:02:37 +02001189 * ( set to something other than serialX)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001191 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line));
1193 if (info->line == 0) {
1194 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) ==
1195 IO_STATE(R_GEN_CONFIG, dma6, serial0)) {
1196 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
1197 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
1198 }
1199 } else if (info->line == 1) {
1200 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma8)) ==
1201 IO_STATE(R_GEN_CONFIG, dma8, serial1)) {
1202 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
1203 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
1204 }
1205 } else if (info->line == 2) {
1206 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma2)) ==
1207 IO_STATE(R_GEN_CONFIG, dma2, serial2)) {
1208 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
1209 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
1210 }
1211 } else if (info->line == 3) {
1212 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma4)) ==
1213 IO_STATE(R_GEN_CONFIG, dma4, serial3)) {
1214 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4);
1215 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
1216 }
1217 }
1218 *R_GEN_CONFIG = genconfig_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001219 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220}
1221
1222
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001223static void e100_enable_txdma_channel(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224{
1225 unsigned long flags;
1226
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001227 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line));
1229 /* Enable output DMA channel for the serial port in question */
1230 if (info->line == 0) {
1231 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
1232 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, serial0);
1233 } else if (info->line == 1) {
1234 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
1235 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, serial1);
1236 } else if (info->line == 2) {
1237 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
1238 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, serial2);
1239 } else if (info->line == 3) {
1240 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4);
1241 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, serial3);
1242 }
1243 *R_GEN_CONFIG = genconfig_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001244 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245}
1246
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001247static void e100_disable_rxdma_channel(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
1249 unsigned long flags;
1250
1251 /* Disable input DMA channel for the serial port in question
Frederik Schwarzer025dfda2008-10-16 19:02:37 +02001252 * ( set to something other than serialX)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001254 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 if (info->line == 0) {
1256 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) ==
1257 IO_STATE(R_GEN_CONFIG, dma7, serial0)) {
1258 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7);
1259 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, unused);
1260 }
1261 } else if (info->line == 1) {
1262 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma9)) ==
1263 IO_STATE(R_GEN_CONFIG, dma9, serial1)) {
1264 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9);
1265 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, usb);
1266 }
1267 } else if (info->line == 2) {
1268 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma3)) ==
1269 IO_STATE(R_GEN_CONFIG, dma3, serial2)) {
1270 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3);
1271 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0);
1272 }
1273 } else if (info->line == 3) {
1274 if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma5)) ==
1275 IO_STATE(R_GEN_CONFIG, dma5, serial3)) {
1276 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5);
1277 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1);
1278 }
1279 }
1280 *R_GEN_CONFIG = genconfig_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001281 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282}
1283
1284
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001285static void e100_enable_rxdma_channel(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286{
1287 unsigned long flags;
1288
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001289 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 /* Enable input DMA channel for the serial port in question */
1291 if (info->line == 0) {
1292 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7);
1293 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, serial0);
1294 } else if (info->line == 1) {
1295 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9);
1296 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, serial1);
1297 } else if (info->line == 2) {
1298 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3);
1299 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, serial2);
1300 } else if (info->line == 3) {
1301 genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5);
1302 genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3);
1303 }
1304 *R_GEN_CONFIG = genconfig_shadow;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001305 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306}
1307
1308#ifdef SERIAL_HANDLE_EARLY_ERRORS
1309/* in order to detect and fix errors on the first byte
1310 we have to use the serial interrupts as well. */
1311
1312static inline void
1313e100_disable_serial_data_irq(struct e100_serial *info)
1314{
1315#ifdef SERIAL_DEBUG_INTR
1316 printk("ser_irq(%d): 0\n",info->line);
1317#endif
1318 DINTR1(DEBUG_LOG(info->line,"IRQ disable data_irq %i\n", info->line));
1319 *R_IRQ_MASK1_CLR = (1U << (8+2*info->line));
1320}
1321
1322static inline void
1323e100_enable_serial_data_irq(struct e100_serial *info)
1324{
1325#ifdef SERIAL_DEBUG_INTR
1326 printk("ser_irq(%d): 1\n",info->line);
1327 printk("**** %d = %d\n",
1328 (8+2*info->line),
1329 (1U << (8+2*info->line)));
1330#endif
1331 DINTR1(DEBUG_LOG(info->line,"IRQ enable data_irq %i\n", info->line));
1332 *R_IRQ_MASK1_SET = (1U << (8+2*info->line));
1333}
1334#endif
1335
1336static inline void
1337e100_disable_serial_tx_ready_irq(struct e100_serial *info)
1338{
1339#ifdef SERIAL_DEBUG_INTR
1340 printk("ser_tx_irq(%d): 0\n",info->line);
1341#endif
1342 DINTR1(DEBUG_LOG(info->line,"IRQ disable ready_irq %i\n", info->line));
1343 *R_IRQ_MASK1_CLR = (1U << (8+1+2*info->line));
1344}
1345
1346static inline void
1347e100_enable_serial_tx_ready_irq(struct e100_serial *info)
1348{
1349#ifdef SERIAL_DEBUG_INTR
1350 printk("ser_tx_irq(%d): 1\n",info->line);
1351 printk("**** %d = %d\n",
1352 (8+1+2*info->line),
1353 (1U << (8+1+2*info->line)));
1354#endif
1355 DINTR2(DEBUG_LOG(info->line,"IRQ enable ready_irq %i\n", info->line));
1356 *R_IRQ_MASK1_SET = (1U << (8+1+2*info->line));
1357}
1358
1359static inline void e100_enable_rx_irq(struct e100_serial *info)
1360{
1361 if (info->uses_dma_in)
1362 e100_enable_rxdma_irq(info);
1363 else
1364 e100_enable_serial_data_irq(info);
1365}
1366static inline void e100_disable_rx_irq(struct e100_serial *info)
1367{
1368 if (info->uses_dma_in)
1369 e100_disable_rxdma_irq(info);
1370 else
1371 e100_disable_serial_data_irq(info);
1372}
1373
1374#if defined(CONFIG_ETRAX_RS485)
1375/* Enable RS-485 mode on selected port. This is UGLY. */
1376static int
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001377e100_enable_rs485(struct tty_struct *tty, struct serial_rs485 *r)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378{
1379 struct e100_serial * info = (struct e100_serial *)tty->driver_data;
1380
1381#if defined(CONFIG_ETRAX_RS485_ON_PA)
1382 *R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit);
1383#endif
1384#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
1385 REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow,
1386 rs485_port_g_bit, 1);
1387#endif
1388#if defined(CONFIG_ETRAX_RS485_LTC1387)
1389 REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow,
1390 CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 1);
1391 REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow,
1392 CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1);
1393#endif
1394
Jesper Nilssonc7213fc2010-10-28 12:08:27 +02001395 info->rs485 = *r;
1396
1397 /* Maximum delay before RTS equal to 1000 */
1398 if (info->rs485.delay_rts_before_send >= 1000)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 info->rs485.delay_rts_before_send = 1000;
Jesper Nilssonc7213fc2010-10-28 12:08:27 +02001400
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401/* printk("rts: on send = %i, after = %i, enabled = %i",
1402 info->rs485.rts_on_send,
1403 info->rs485.rts_after_sent,
1404 info->rs485.enabled
1405 );
1406*/
1407 return 0;
1408}
1409
1410static int
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001411e100_write_rs485(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 const unsigned char *buf, int count)
1413{
1414 struct e100_serial * info = (struct e100_serial *)tty->driver_data;
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001415 int old_value = (info->rs485.flags) & SER_RS485_ENABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 /* rs485 is always implicitly enabled if we're using the ioctl()
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001418 * but it doesn't have to be set in the serial_rs485
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 * (to be backward compatible with old apps)
1420 * So we store, set and restore it.
1421 */
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001422 info->rs485.flags |= SER_RS485_ENABLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 /* rs_write now deals with RS485 if enabled */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001424 count = rs_write(tty, buf, count);
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001425 if (!old_value)
1426 info->rs485.flags &= ~(SER_RS485_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 return count;
1428}
1429
1430#ifdef CONFIG_ETRAX_FAST_TIMER
1431/* Timer function to toggle RTS when using FAST_TIMER */
1432static void rs485_toggle_rts_timer_function(unsigned long data)
1433{
1434 struct e100_serial *info = (struct e100_serial *)data;
1435
1436 fast_timers_rs485[info->line].function = NULL;
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001437 e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
1439 e100_enable_rx(info);
1440 e100_enable_rx_irq(info);
1441#endif
1442}
1443#endif
1444#endif /* CONFIG_ETRAX_RS485 */
1445
1446/*
1447 * ------------------------------------------------------------
1448 * rs_stop() and rs_start()
1449 *
1450 * This routines are called before setting or resetting tty->stopped.
1451 * They enable or disable transmitter using the XOFF registers, as necessary.
1452 * ------------------------------------------------------------
1453 */
1454
1455static void
1456rs_stop(struct tty_struct *tty)
1457{
1458 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
1459 if (info) {
1460 unsigned long flags;
1461 unsigned long xoff;
1462
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001463 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n",
1465 CIRC_CNT(info->xmit.head,
1466 info->xmit.tail,SERIAL_XMIT_SIZE)));
1467
Takashi Iwaia88487c2008-07-16 21:54:42 +01001468 xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char,
1469 STOP_CHAR(info->port.tty));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop);
Alan Coxadc8d742012-07-14 15:31:47 +01001471 if (tty->termios.c_iflag & IXON ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
1473 }
1474
Alan Coxd7283352008-08-04 17:21:18 +01001475 *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001476 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 }
1478}
1479
1480static void
1481rs_start(struct tty_struct *tty)
1482{
1483 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
1484 if (info) {
1485 unsigned long flags;
1486 unsigned long xoff;
1487
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001488 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n",
1490 CIRC_CNT(info->xmit.head,
1491 info->xmit.tail,SERIAL_XMIT_SIZE)));
1492 xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty));
1493 xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
Alan Coxadc8d742012-07-14 15:31:47 +01001494 if (tty->termios.c_iflag & IXON ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
1496 }
1497
Alan Coxd7283352008-08-04 17:21:18 +01001498 *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 if (!info->uses_dma_out &&
1500 info->xmit.head != info->xmit.tail && info->xmit.buf)
1501 e100_enable_serial_tx_ready_irq(info);
1502
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001503 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 }
1505}
1506
1507/*
1508 * ----------------------------------------------------------------------
1509 *
1510 * Here starts the interrupt handling routines. All of the following
1511 * subroutines are declared as inline and are folded into
1512 * rs_interrupt(). They were separated out for readability's sake.
1513 *
1514 * Note: rs_interrupt() is a "fast" interrupt, which means that it
1515 * runs with interrupts turned off. People who may want to modify
1516 * rs_interrupt() should try to keep the interrupt handler as fast as
1517 * possible. After you are done making modifications, it is not a bad
1518 * idea to do:
1519 *
1520 * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
1521 *
1522 * and look at the resulting assemble code in serial.s.
1523 *
1524 * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
1525 * -----------------------------------------------------------------------
1526 */
1527
1528/*
1529 * This routine is used by the interrupt handler to schedule
1530 * processing in the software interrupt portion of the driver.
1531 */
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001532static void rs_sched_event(struct e100_serial *info, int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533{
1534 if (info->event & (1 << event))
1535 return;
1536 info->event |= 1 << event;
1537 schedule_work(&info->work);
1538}
1539
1540/* The output DMA channel is free - use it to send as many chars as possible
1541 * NOTES:
1542 * We don't pay attention to info->x_char, which means if the TTY wants to
1543 * use XON/XOFF it will set info->x_char but we won't send any X char!
1544 *
1545 * To implement this, we'd just start a DMA send of 1 byte pointing at a
1546 * buffer containing the X char, and skip updating xmit. We'd also have to
1547 * check if the last sent char was the X char when we enter this function
1548 * the next time, to avoid updating xmit with the sent X value.
1549 */
1550
1551static void
1552transmit_chars_dma(struct e100_serial *info)
1553{
1554 unsigned int c, sentl;
1555 struct etrax_dma_descr *descr;
1556
1557#ifdef CONFIG_SVINTO_SIM
1558 /* This will output too little if tail is not 0 always since
1559 * we don't reloop to send the other part. Anyway this SHOULD be a
1560 * no-op - transmit_chars_dma would never really be called during sim
1561 * since rs_write does not write into the xmit buffer then.
1562 */
1563 if (info->xmit.tail)
1564 printk("Error in serial.c:transmit_chars-dma(), tail!=0\n");
1565 if (info->xmit.head != info->xmit.tail) {
1566 SIMCOUT(info->xmit.buf + info->xmit.tail,
1567 CIRC_CNT(info->xmit.head,
1568 info->xmit.tail,
1569 SERIAL_XMIT_SIZE));
1570 info->xmit.head = info->xmit.tail; /* move back head */
1571 info->tr_running = 0;
1572 }
1573 return;
1574#endif
1575 /* acknowledge both dma_descr and dma_eop irq in R_DMA_CHx_CLR_INTR */
1576 *info->oclrintradr =
1577 IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
1578 IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
1579
1580#ifdef SERIAL_DEBUG_INTR
1581 if (info->line == SERIAL_DEBUG_LINE)
1582 printk("tc\n");
1583#endif
1584 if (!info->tr_running) {
1585 /* weirdo... we shouldn't get here! */
1586 printk(KERN_WARNING "Achtung: transmit_chars_dma with !tr_running\n");
1587 return;
1588 }
1589
1590 descr = &info->tr_descr;
1591
1592 /* first get the amount of bytes sent during the last DMA transfer,
1593 and update xmit accordingly */
1594
1595 /* if the stop bit was not set, all data has been sent */
1596 if (!(descr->status & d_stop)) {
1597 sentl = descr->sw_len;
1598 } else
1599 /* otherwise we find the amount of data sent here */
1600 sentl = descr->hw_len;
1601
1602 DFLOW(DEBUG_LOG(info->line, "TX %i done\n", sentl));
1603
1604 /* update stats */
1605 info->icount.tx += sentl;
1606
1607 /* update xmit buffer */
1608 info->xmit.tail = (info->xmit.tail + sentl) & (SERIAL_XMIT_SIZE - 1);
1609
1610 /* if there is only a few chars left in the buf, wake up the blocked
1611 write if any */
1612 if (CIRC_CNT(info->xmit.head,
1613 info->xmit.tail,
1614 SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
1615 rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
1616
1617 /* find out the largest amount of consecutive bytes we want to send now */
1618
1619 c = CIRC_CNT_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
1620
1621 /* Don't send all in one DMA transfer - divide it so we wake up
1622 * application before all is sent
1623 */
1624
1625 if (c >= 4*WAKEUP_CHARS)
1626 c = c/2;
1627
1628 if (c <= 0) {
1629 /* our job here is done, don't schedule any new DMA transfer */
1630 info->tr_running = 0;
1631
1632#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
Claudio Scordino6fd1af42009-04-07 16:48:19 +01001633 if (info->rs485.flags & SER_RS485_ENABLED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 /* Set a short timer to toggle RTS */
1635 start_one_shot_timer(&fast_timers_rs485[info->line],
1636 rs485_toggle_rts_timer_function,
1637 (unsigned long)info,
1638 info->char_time_usec*2,
1639 "RS-485");
1640 }
1641#endif /* RS485 */
1642 return;
1643 }
1644
1645 /* ok we can schedule a dma send of c chars starting at info->xmit.tail */
1646 /* set up the descriptor correctly for output */
1647 DFLOW(DEBUG_LOG(info->line, "TX %i\n", c));
1648 descr->ctrl = d_int | d_eol | d_wait; /* Wait needed for tty_wait_until_sent() */
1649 descr->sw_len = c;
1650 descr->buf = virt_to_phys(info->xmit.buf + info->xmit.tail);
1651 descr->status = 0;
1652
1653 *info->ofirstadr = virt_to_phys(descr); /* write to R_DMAx_FIRST */
1654 *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start);
1655
1656 /* DMA is now running (hopefully) */
1657} /* transmit_chars_dma */
1658
1659static void
1660start_transmit(struct e100_serial *info)
1661{
1662#if 0
1663 if (info->line == SERIAL_DEBUG_LINE)
1664 printk("x\n");
1665#endif
1666
1667 info->tr_descr.sw_len = 0;
1668 info->tr_descr.hw_len = 0;
1669 info->tr_descr.status = 0;
1670 info->tr_running = 1;
1671 if (info->uses_dma_out)
1672 transmit_chars_dma(info);
1673 else
1674 e100_enable_serial_tx_ready_irq(info);
1675} /* start_transmit */
1676
1677#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
1678static int serial_fast_timer_started = 0;
1679static int serial_fast_timer_expired = 0;
1680static void flush_timeout_function(unsigned long data);
1681#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\
1682 unsigned long timer_flags; \
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001683 local_irq_save(timer_flags); \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 if (fast_timers[info->line].function == NULL) { \
1685 serial_fast_timer_started++; \
1686 TIMERD(DEBUG_LOG(info->line, "start_timer %i ", info->line)); \
1687 TIMERD(DEBUG_LOG(info->line, "num started: %i\n", serial_fast_timer_started)); \
1688 start_one_shot_timer(&fast_timers[info->line], \
1689 flush_timeout_function, \
1690 (unsigned long)info, \
1691 (usec), \
1692 string); \
1693 } \
1694 else { \
1695 TIMERD(DEBUG_LOG(info->line, "timer %i already running\n", info->line)); \
1696 } \
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001697 local_irq_restore(timer_flags); \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698}
1699#define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec)
1700
1701#else
1702#define START_FLUSH_FAST_TIMER_TIME(info, string, usec)
1703#define START_FLUSH_FAST_TIMER(info, string)
1704#endif
1705
1706static struct etrax_recv_buffer *
1707alloc_recv_buffer(unsigned int size)
1708{
1709 struct etrax_recv_buffer *buffer;
1710
1711 if (!(buffer = kmalloc(sizeof *buffer + size, GFP_ATOMIC)))
1712 return NULL;
1713
1714 buffer->next = NULL;
1715 buffer->length = 0;
1716 buffer->error = TTY_NORMAL;
1717
1718 return buffer;
1719}
1720
1721static void
1722append_recv_buffer(struct e100_serial *info, struct etrax_recv_buffer *buffer)
1723{
1724 unsigned long flags;
1725
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001726 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727
1728 if (!info->first_recv_buffer)
1729 info->first_recv_buffer = buffer;
1730 else
1731 info->last_recv_buffer->next = buffer;
1732
1733 info->last_recv_buffer = buffer;
1734
1735 info->recv_cnt += buffer->length;
1736 if (info->recv_cnt > info->max_recv_cnt)
1737 info->max_recv_cnt = info->recv_cnt;
1738
Jesper Nilsson77accbf2007-11-14 17:01:15 -08001739 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740}
1741
1742static int
1743add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char flag)
1744{
1745 struct etrax_recv_buffer *buffer;
1746 if (info->uses_dma_in) {
1747 if (!(buffer = alloc_recv_buffer(4)))
1748 return 0;
1749
1750 buffer->length = 1;
1751 buffer->error = flag;
1752 buffer->buffer[0] = data;
1753
1754 append_recv_buffer(info, buffer);
1755
1756 info->icount.rx++;
1757 } else {
Jiri Slaby92a19f92013-01-03 15:53:03 +01001758 tty_insert_flip_char(&info->port, data, flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 info->icount.rx++;
1760 }
1761
1762 return 1;
1763}
1764
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001765static unsigned int handle_descr_data(struct e100_serial *info,
1766 struct etrax_dma_descr *descr,
1767 unsigned int recvl)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768{
1769 struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer;
1770
1771 if (info->recv_cnt + recvl > 65536) {
WANG Cong3d43b7d2011-09-01 16:47:49 +08001772 printk(KERN_WARNING
Harvey Harrison71cc2c22008-04-30 00:55:10 -07001773 "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 return 0;
1775 }
1776
1777 buffer->length = recvl;
1778
1779 if (info->errorcode == ERRCODE_SET_BREAK)
1780 buffer->error = TTY_BREAK;
1781 info->errorcode = 0;
1782
1783 append_recv_buffer(info, buffer);
1784
1785 if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE)))
Harvey Harrison71cc2c22008-04-30 00:55:10 -07001786 panic("%s: Failed to allocate memory for receive buffer!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
1788 descr->buf = virt_to_phys(buffer->buffer);
1789
1790 return recvl;
1791}
1792
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001793static unsigned int handle_all_descr_data(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794{
1795 struct etrax_dma_descr *descr;
1796 unsigned int recvl;
1797 unsigned int ret = 0;
1798
1799 while (1)
1800 {
1801 descr = &info->rec_descr[info->cur_rec_descr];
1802
1803 if (descr == phys_to_virt(*info->idescradr))
1804 break;
1805
1806 if (++info->cur_rec_descr == SERIAL_RECV_DESCRIPTORS)
1807 info->cur_rec_descr = 0;
1808
1809 /* find out how many bytes were read */
1810
1811 /* if the eop bit was not set, all data has been received */
1812 if (!(descr->status & d_eop)) {
1813 recvl = descr->sw_len;
1814 } else {
1815 /* otherwise we find the amount of data received here */
1816 recvl = descr->hw_len;
1817 }
1818
1819 /* Reset the status information */
1820 descr->status = 0;
1821
1822 DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl);
Takashi Iwaia88487c2008-07-16 21:54:42 +01001823 if (info->port.tty->stopped) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 unsigned char *buf = phys_to_virt(descr->buf);
1825 DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]);
1826 DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]);
1827 DEBUG_LOG(info->line, "rx 0x%02X\n", buf[2]);
1828 }
1829 );
1830
1831 /* update stats */
1832 info->icount.rx += recvl;
1833
1834 ret += handle_descr_data(info, descr, recvl);
1835 }
1836
1837 return ret;
1838}
1839
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001840static void receive_chars_dma(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841{
1842 struct tty_struct *tty;
1843 unsigned char rstat;
1844
1845#ifdef CONFIG_SVINTO_SIM
1846 /* No receive in the simulator. Will probably be when the rest of
1847 * the serial interface works, and this piece will just be removed.
1848 */
1849 return;
1850#endif
1851
1852 /* Acknowledge both dma_descr and dma_eop irq in R_DMA_CHx_CLR_INTR */
1853 *info->iclrintradr =
1854 IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
1855 IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
1856
Takashi Iwaia88487c2008-07-16 21:54:42 +01001857 tty = info->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 if (!tty) /* Something wrong... */
1859 return;
1860
1861#ifdef SERIAL_HANDLE_EARLY_ERRORS
1862 if (info->uses_dma_in)
1863 e100_enable_serial_data_irq(info);
1864#endif
1865
1866 if (info->errorcode == ERRCODE_INSERT_BREAK)
1867 add_char_and_flag(info, '\0', TTY_BREAK);
1868
1869 handle_all_descr_data(info);
1870
1871 /* Read the status register to detect errors */
Alan Coxd7283352008-08-04 17:21:18 +01001872 rstat = info->ioport[REG_STATUS];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
1874 DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat));
1875 }
1876
1877 if (rstat & SER_ERROR_MASK) {
1878 /* If we got an error, we must reset it by reading the
1879 * data_in field
1880 */
Alan Coxd7283352008-08-04 17:21:18 +01001881 unsigned char data = info->ioport[REG_DATA];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
1883 PROCSTAT(ser_stat[info->line].errors_cnt++);
1884 DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n",
1885 ((rstat & SER_ERROR_MASK) << 8) | data);
1886
1887 if (rstat & SER_PAR_ERR_MASK)
1888 add_char_and_flag(info, data, TTY_PARITY);
1889 else if (rstat & SER_OVERRUN_MASK)
1890 add_char_and_flag(info, data, TTY_OVERRUN);
1891 else if (rstat & SER_FRAMING_ERR_MASK)
1892 add_char_and_flag(info, data, TTY_FRAME);
1893 }
1894
1895 START_FLUSH_FAST_TIMER(info, "receive_chars");
1896
1897 /* Restart the receiving DMA */
1898 *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart);
1899}
1900
Adrian Bunk41c28ff2006-03-23 03:00:56 -08001901static int start_recv_dma(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902{
1903 struct etrax_dma_descr *descr = info->rec_descr;
1904 struct etrax_recv_buffer *buffer;
1905 int i;
1906
1907 /* Set up the receiving descriptors */
1908 for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) {
1909 if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE)))
Harvey Harrison71cc2c22008-04-30 00:55:10 -07001910 panic("%s: Failed to allocate memory for receive buffer!\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
1912 descr[i].ctrl = d_int;
1913 descr[i].buf = virt_to_phys(buffer->buffer);
1914 descr[i].sw_len = SERIAL_DESCR_BUF_SIZE;
1915 descr[i].hw_len = 0;
1916 descr[i].status = 0;
1917 descr[i].next = virt_to_phys(&descr[i+1]);
1918 }
1919
1920 /* Link the last descriptor to the first */
1921 descr[i-1].next = virt_to_phys(&descr[0]);
1922
1923 /* Start with the first descriptor in the list */
1924 info->cur_rec_descr = 0;
1925
1926 /* Start the DMA */
1927 *info->ifirstadr = virt_to_phys(&descr[info->cur_rec_descr]);
1928 *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start);
1929
1930 /* Input DMA should be running now */
1931 return 1;
1932}
1933
1934static void
1935start_receive(struct e100_serial *info)
1936{
1937#ifdef CONFIG_SVINTO_SIM
1938 /* No receive in the simulator. Will probably be when the rest of
1939 * the serial interface works, and this piece will just be removed.
1940 */
1941 return;
1942#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 if (info->uses_dma_in) {
1944 /* reset the input dma channel to be sure it works */
1945
1946 *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
1947 while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
1948 IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
1949
1950 start_recv_dma(info);
1951 }
1952}
1953
1954
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955/* the bits in the MASK2 register are laid out like this:
1956 DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR
1957 where I is the input channel and O is the output channel for the port.
1958 info->irq is the bit number for the DMAO_DESCR so to check the others we
1959 shift info->irq to the left.
1960*/
1961
1962/* dma output channel interrupt handler
1963 this interrupt is called from DMA2(ser2), DMA4(ser3), DMA6(ser0) or
1964 DMA8(ser1) when they have finished a descriptor with the intr flag set.
1965*/
1966
1967static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +01001968tr_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969{
1970 struct e100_serial *info;
1971 unsigned long ireg;
1972 int i;
1973 int handled = 0;
1974
1975#ifdef CONFIG_SVINTO_SIM
1976 /* No receive in the simulator. Will probably be when the rest of
1977 * the serial interface works, and this piece will just be removed.
1978 */
1979 {
1980 const char *s = "What? tr_interrupt in simulator??\n";
1981 SIMCOUT(s,strlen(s));
1982 }
1983 return IRQ_HANDLED;
1984#endif
1985
1986 /* find out the line that caused this irq and get it from rs_table */
1987
1988 ireg = *R_IRQ_MASK2_RD; /* get the active irq bits for the dma channels */
1989
1990 for (i = 0; i < NR_PORTS; i++) {
1991 info = rs_table + i;
1992 if (!info->enabled || !info->uses_dma_out)
1993 continue;
1994 /* check for dma_descr (don't need to check for dma_eop in output dma for serial */
1995 if (ireg & info->irq) {
1996 handled = 1;
1997 /* we can send a new dma bunch. make it so. */
1998 DINTR2(DEBUG_LOG(info->line, "tr_interrupt %i\n", i));
1999 /* Read jiffies_usec first,
2000 * we want this time to be as late as possible
2001 */
2002 PROCSTAT(ser_stat[info->line].tx_dma_ints++);
2003 info->last_tx_active_usec = GET_JIFFIES_USEC();
2004 info->last_tx_active = jiffies;
2005 transmit_chars_dma(info);
2006 }
2007
2008 /* FIXME: here we should really check for a change in the
2009 status lines and if so call status_handle(info) */
2010 }
2011 return IRQ_RETVAL(handled);
2012} /* tr_interrupt */
2013
2014/* dma input channel interrupt handler */
2015
2016static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +01002017rec_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018{
2019 struct e100_serial *info;
2020 unsigned long ireg;
2021 int i;
2022 int handled = 0;
2023
2024#ifdef CONFIG_SVINTO_SIM
2025 /* No receive in the simulator. Will probably be when the rest of
2026 * the serial interface works, and this piece will just be removed.
2027 */
2028 {
2029 const char *s = "What? rec_interrupt in simulator??\n";
2030 SIMCOUT(s,strlen(s));
2031 }
2032 return IRQ_HANDLED;
2033#endif
2034
2035 /* find out the line that caused this irq and get it from rs_table */
2036
2037 ireg = *R_IRQ_MASK2_RD; /* get the active irq bits for the dma channels */
2038
2039 for (i = 0; i < NR_PORTS; i++) {
2040 info = rs_table + i;
2041 if (!info->enabled || !info->uses_dma_in)
2042 continue;
2043 /* check for both dma_eop and dma_descr for the input dma channel */
2044 if (ireg & ((info->irq << 2) | (info->irq << 3))) {
2045 handled = 1;
2046 /* we have received something */
2047 receive_chars_dma(info);
2048 }
2049
2050 /* FIXME: here we should really check for a change in the
2051 status lines and if so call status_handle(info) */
2052 }
2053 return IRQ_RETVAL(handled);
2054} /* rec_interrupt */
2055
Adrian Bunk41c28ff2006-03-23 03:00:56 -08002056static int force_eop_if_needed(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057{
2058 /* We check data_avail bit to determine if data has
2059 * arrived since last time
2060 */
Alan Coxd7283352008-08-04 17:21:18 +01002061 unsigned char rstat = info->ioport[REG_STATUS];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
2063 /* error or datavail? */
2064 if (rstat & SER_ERROR_MASK) {
2065 /* Some error has occurred. If there has been valid data, an
2066 * EOP interrupt will be made automatically. If no data, the
2067 * normal ser_interrupt should be enabled and handle it.
2068 * So do nothing!
2069 */
2070 DEBUG_LOG(info->line, "timeout err: rstat 0x%03X\n",
2071 rstat | (info->line << 8));
2072 return 0;
2073 }
2074
2075 if (rstat & SER_DATA_AVAIL_MASK) {
2076 /* Ok data, no error, count it */
2077 TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n",
2078 rstat | (info->line << 8)));
2079 /* Read data to clear status flags */
Alan Coxd7283352008-08-04 17:21:18 +01002080 (void)info->ioport[REG_DATA];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
2082 info->forced_eop = 0;
2083 START_FLUSH_FAST_TIMER(info, "magic");
2084 return 0;
2085 }
2086
2087 /* hit the timeout, force an EOP for the input
2088 * dma channel if we haven't already
2089 */
2090 if (!info->forced_eop) {
2091 info->forced_eop = 1;
2092 PROCSTAT(ser_stat[info->line].timeout_flush_cnt++);
2093 TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line));
2094 FORCE_EOP(info);
2095 }
2096
2097 return 1;
2098}
2099
Adrian Bunk41c28ff2006-03-23 03:00:56 -08002100static void flush_to_flip_buffer(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 struct etrax_recv_buffer *buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002105 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106
Alan Cox2090ab02007-10-16 01:26:38 -07002107 while ((buffer = info->first_recv_buffer) != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 unsigned int count = buffer->length;
2109
Jiri Slaby05c7cd32013-01-03 15:53:04 +01002110 tty_insert_flip_string(&info->port, buffer->buffer, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 info->recv_cnt -= count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112
2113 if (count == buffer->length) {
2114 info->first_recv_buffer = buffer->next;
2115 kfree(buffer);
2116 } else {
2117 buffer->length -= count;
2118 memmove(buffer->buffer, buffer->buffer + count, buffer->length);
2119 buffer->error = TTY_NORMAL;
2120 }
2121 }
2122
2123 if (!info->first_recv_buffer)
2124 info->last_recv_buffer = NULL;
2125
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002126 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002128 /* This includes a check for low-latency */
Jiri Slaby2e124b42013-01-03 15:53:06 +01002129 tty_flip_buffer_push(&info->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130}
2131
Adrian Bunk41c28ff2006-03-23 03:00:56 -08002132static void check_flush_timeout(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133{
2134 /* Flip what we've got (if we can) */
2135 flush_to_flip_buffer(info);
2136
2137 /* We might need to flip later, but not to fast
2138 * since the system is busy processing input... */
2139 if (info->first_recv_buffer)
2140 START_FLUSH_FAST_TIMER_TIME(info, "flip", 2000);
2141
2142 /* Force eop last, since data might have come while we're processing
2143 * and if we started the slow timer above, we won't start a fast
2144 * below.
2145 */
2146 force_eop_if_needed(info);
2147}
2148
2149#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
2150static void flush_timeout_function(unsigned long data)
2151{
2152 struct e100_serial *info = (struct e100_serial *)data;
2153
2154 fast_timers[info->line].function = NULL;
2155 serial_fast_timer_expired++;
2156 TIMERD(DEBUG_LOG(info->line, "flush_timout %i ", info->line));
2157 TIMERD(DEBUG_LOG(info->line, "num expired: %i\n", serial_fast_timer_expired));
2158 check_flush_timeout(info);
2159}
2160
2161#else
2162
2163/* dma fifo/buffer timeout handler
2164 forces an end-of-packet for the dma input channel if no chars
2165 have been received for CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS/100 s.
2166*/
2167
2168static struct timer_list flush_timer;
2169
2170static void
2171timed_flush_handler(unsigned long ptr)
2172{
2173 struct e100_serial *info;
2174 int i;
2175
2176#ifdef CONFIG_SVINTO_SIM
2177 return;
2178#endif
2179
2180 for (i = 0; i < NR_PORTS; i++) {
2181 info = rs_table + i;
2182 if (info->uses_dma_in)
2183 check_flush_timeout(info);
2184 }
2185
2186 /* restart flush timer */
2187 mod_timer(&flush_timer, jiffies + CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS);
2188}
2189#endif
2190
2191#ifdef SERIAL_HANDLE_EARLY_ERRORS
2192
2193/* If there is an error (ie break) when the DMA is running and
2194 * there are no bytes in the fifo the DMA is stopped and we get no
2195 * eop interrupt. Thus we have to monitor the first bytes on a DMA
2196 * transfer, and if it is without error we can turn the serial
2197 * interrupts off.
2198 */
2199
2200/*
2201BREAK handling on ETRAX 100:
2202ETRAX will generate interrupt although there is no stop bit between the
2203characters.
2204
2205Depending on how long the break sequence is, the end of the breaksequence
2206will look differently:
2207| indicates start/end of a character.
2208
2209B= Break character (0x00) with framing error.
2210E= Error byte with parity error received after B characters.
2211F= "Faked" valid byte received immediately after B characters.
2212V= Valid byte
2213
22141.
2215 B BL ___________________________ V
2216.._|__________|__________| |valid data |
2217
2218Multiple frame errors with data == 0x00 (B),
2219the timing matches up "perfectly" so no extra ending char is detected.
2220The RXD pin is 1 in the last interrupt, in that case
2221we set info->errorcode = ERRCODE_INSERT_BREAK, but we can't really
2222know if another byte will come and this really is case 2. below
2223(e.g F=0xFF or 0xFE)
2224If RXD pin is 0 we can expect another character (see 2. below).
2225
2226
22272.
2228
2229 B B E or F__________________..__ V
2230.._|__________|__________|______ | |valid data
2231 "valid" or
2232 parity error
2233
2234Multiple frame errors with data == 0x00 (B),
2235but the part of the break trigs is interpreted as a start bit (and possibly
2236some 0 bits followed by a number of 1 bits and a stop bit).
2237Depending on parity settings etc. this last character can be either
2238a fake "valid" char (F) or have a parity error (E).
2239
2240If the character is valid it will be put in the buffer,
2241we set info->errorcode = ERRCODE_SET_BREAK so the receive interrupt
2242will set the flags so the tty will handle it,
2243if it's an error byte it will not be put in the buffer
2244and we set info->errorcode = ERRCODE_INSERT_BREAK.
2245
2246To distinguish a V byte in 1. from an F byte in 2. we keep a timestamp
2247of the last faulty char (B) and compares it with the current time:
2248If the time elapsed time is less then 2*char_time_usec we will assume
2249it's a faked F char and not a Valid char and set
2250info->errorcode = ERRCODE_SET_BREAK.
2251
2252Flaws in the above solution:
2253~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2254We use the timer to distinguish a F character from a V character,
2255if a V character is to close after the break we might make the wrong decision.
2256
2257TODO: The break will be delayed until an F or V character is received.
2258
2259*/
2260
Adrian Bunk41c28ff2006-03-23 03:00:56 -08002261static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
2263{
2264 unsigned long data_read;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002265
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 /* Read data and status at the same time */
Alan Coxd7283352008-08-04 17:21:18 +01002267 data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268more_data:
2269 if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) {
2270 DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
2271 }
2272 DINTR2(DEBUG_LOG(info->line, "ser_rx %c\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)));
2273
2274 if (data_read & ( IO_MASK(R_SERIAL0_READ, framing_err) |
2275 IO_MASK(R_SERIAL0_READ, par_err) |
2276 IO_MASK(R_SERIAL0_READ, overrun) )) {
2277 /* An error */
2278 info->last_rx_active_usec = GET_JIFFIES_USEC();
2279 info->last_rx_active = jiffies;
2280 DINTR1(DEBUG_LOG(info->line, "ser_rx err stat_data %04X\n", data_read));
2281 DLOG_INT_TRIG(
2282 if (!log_int_trig1_pos) {
2283 log_int_trig1_pos = log_int_pos;
2284 log_int(rdpc(), 0, 0);
2285 }
2286 );
2287
2288
2289 if ( ((data_read & IO_MASK(R_SERIAL0_READ, data_in)) == 0) &&
2290 (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) ) {
2291 /* Most likely a break, but we get interrupts over and
2292 * over again.
2293 */
2294
2295 if (!info->break_detected_cnt) {
2296 DEBUG_LOG(info->line, "#BRK start\n", 0);
2297 }
2298 if (data_read & IO_MASK(R_SERIAL0_READ, rxd)) {
2299 /* The RX pin is high now, so the break
2300 * must be over, but....
2301 * we can't really know if we will get another
2302 * last byte ending the break or not.
2303 * And we don't know if the byte (if any) will
2304 * have an error or look valid.
2305 */
2306 DEBUG_LOG(info->line, "# BL BRK\n", 0);
2307 info->errorcode = ERRCODE_INSERT_BREAK;
2308 }
2309 info->break_detected_cnt++;
2310 } else {
2311 /* The error does not look like a break, but could be
2312 * the end of one
2313 */
2314 if (info->break_detected_cnt) {
2315 DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt);
2316 info->errorcode = ERRCODE_INSERT_BREAK;
2317 } else {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002318 unsigned char data = IO_EXTRACT(R_SERIAL0_READ,
2319 data_in, data_read);
2320 char flag = TTY_NORMAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 if (info->errorcode == ERRCODE_INSERT_BREAK) {
Jiri Slaby92a19f92013-01-03 15:53:03 +01002322 tty_insert_flip_char(&info->port, 0, flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 info->icount.rx++;
2324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325
2326 if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) {
2327 info->icount.parity++;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002328 flag = TTY_PARITY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 } else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) {
2330 info->icount.overrun++;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002331 flag = TTY_OVERRUN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 } else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) {
2333 info->icount.frame++;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002334 flag = TTY_FRAME;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 }
Jiri Slaby92a19f92013-01-03 15:53:03 +01002336 tty_insert_flip_char(&info->port, data, flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 info->errorcode = 0;
2338 }
2339 info->break_detected_cnt = 0;
2340 }
2341 } else if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
2342 /* No error */
2343 DLOG_INT_TRIG(
2344 if (!log_int_trig1_pos) {
2345 if (log_int_pos >= log_int_size) {
2346 log_int_pos = 0;
2347 }
2348 log_int_trig0_pos = log_int_pos;
2349 log_int(rdpc(), 0, 0);
2350 }
2351 );
Jiri Slaby92a19f92013-01-03 15:53:03 +01002352 tty_insert_flip_char(&info->port,
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002353 IO_EXTRACT(R_SERIAL0_READ, data_in, data_read),
2354 TTY_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 } else {
2356 DEBUG_LOG(info->line, "ser_rx int but no data_avail %08lX\n", data_read);
2357 }
2358
2359
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 info->icount.rx++;
Alan Coxd7283352008-08-04 17:21:18 +01002361 data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
2363 DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read));
2364 goto more_data;
2365 }
2366
Jiri Slaby2e124b42013-01-03 15:53:06 +01002367 tty_flip_buffer_push(&info->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 return info;
2369}
2370
Adrian Bunk41c28ff2006-03-23 03:00:56 -08002371static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372{
2373 unsigned char rstat;
2374
2375#ifdef SERIAL_DEBUG_INTR
2376 printk("Interrupt from serport %d\n", i);
2377#endif
2378/* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */
2379 if (!info->uses_dma_in) {
2380 return handle_ser_rx_interrupt_no_dma(info);
2381 }
2382 /* DMA is used */
Alan Coxd7283352008-08-04 17:21:18 +01002383 rstat = info->ioport[REG_STATUS];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384 if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
2385 DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
2386 }
2387
2388 if (rstat & SER_ERROR_MASK) {
2389 unsigned char data;
2390
2391 info->last_rx_active_usec = GET_JIFFIES_USEC();
2392 info->last_rx_active = jiffies;
2393 /* If we got an error, we must reset it by reading the
2394 * data_in field
2395 */
Alan Coxd7283352008-08-04 17:21:18 +01002396 data = info->ioport[REG_DATA];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data));
2398 DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat));
2399 if (!data && (rstat & SER_FRAMING_ERR_MASK)) {
2400 /* Most likely a break, but we get interrupts over and
2401 * over again.
2402 */
2403
2404 if (!info->break_detected_cnt) {
2405 DEBUG_LOG(info->line, "#BRK start\n", 0);
2406 }
2407 if (rstat & SER_RXD_MASK) {
2408 /* The RX pin is high now, so the break
2409 * must be over, but....
2410 * we can't really know if we will get another
2411 * last byte ending the break or not.
2412 * And we don't know if the byte (if any) will
2413 * have an error or look valid.
2414 */
2415 DEBUG_LOG(info->line, "# BL BRK\n", 0);
2416 info->errorcode = ERRCODE_INSERT_BREAK;
2417 }
2418 info->break_detected_cnt++;
2419 } else {
2420 /* The error does not look like a break, but could be
2421 * the end of one
2422 */
2423 if (info->break_detected_cnt) {
2424 DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt);
2425 info->errorcode = ERRCODE_INSERT_BREAK;
2426 } else {
2427 if (info->errorcode == ERRCODE_INSERT_BREAK) {
2428 info->icount.brk++;
2429 add_char_and_flag(info, '\0', TTY_BREAK);
2430 }
2431
2432 if (rstat & SER_PAR_ERR_MASK) {
2433 info->icount.parity++;
2434 add_char_and_flag(info, data, TTY_PARITY);
2435 } else if (rstat & SER_OVERRUN_MASK) {
2436 info->icount.overrun++;
2437 add_char_and_flag(info, data, TTY_OVERRUN);
2438 } else if (rstat & SER_FRAMING_ERR_MASK) {
2439 info->icount.frame++;
2440 add_char_and_flag(info, data, TTY_FRAME);
2441 }
2442
2443 info->errorcode = 0;
2444 }
2445 info->break_detected_cnt = 0;
2446 DEBUG_LOG(info->line, "#iERR s d %04X\n",
2447 ((rstat & SER_ERROR_MASK) << 8) | data);
2448 }
2449 PROCSTAT(ser_stat[info->line].early_errors_cnt++);
2450 } else { /* It was a valid byte, now let the DMA do the rest */
2451 unsigned long curr_time_u = GET_JIFFIES_USEC();
2452 unsigned long curr_time = jiffies;
2453
2454 if (info->break_detected_cnt) {
2455 /* Detect if this character is a new valid char or the
2456 * last char in a break sequence: If LSBits are 0 and
2457 * MSBits are high AND the time is close to the
2458 * previous interrupt we should discard it.
2459 */
2460 long elapsed_usec =
2461 (curr_time - info->last_rx_active) * (1000000/HZ) +
2462 curr_time_u - info->last_rx_active_usec;
2463 if (elapsed_usec < 2*info->char_time_usec) {
2464 DEBUG_LOG(info->line, "FBRK %i\n", info->line);
2465 /* Report as BREAK (error) and let
2466 * receive_chars_dma() handle it
2467 */
2468 info->errorcode = ERRCODE_SET_BREAK;
2469 } else {
2470 DEBUG_LOG(info->line, "Not end of BRK (V)%i\n", info->line);
2471 }
2472 DEBUG_LOG(info->line, "num brk %i\n", info->break_detected_cnt);
2473 }
2474
2475#ifdef SERIAL_DEBUG_INTR
2476 printk("** OK, disabling ser_interrupts\n");
2477#endif
2478 e100_disable_serial_data_irq(info);
2479 DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line));
2480 info->break_detected_cnt = 0;
2481
2482 PROCSTAT(ser_stat[info->line].ser_ints_ok_cnt++);
2483 }
2484 /* Restarting the DMA never hurts */
2485 *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart);
2486 START_FLUSH_FAST_TIMER(info, "ser_int");
2487 return info;
2488} /* handle_ser_rx_interrupt */
2489
Adrian Bunk41c28ff2006-03-23 03:00:56 -08002490static void handle_ser_tx_interrupt(struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491{
2492 unsigned long flags;
2493
2494 if (info->x_char) {
2495 unsigned char rstat;
2496 DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char));
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002497 local_irq_save(flags);
Alan Coxd7283352008-08-04 17:21:18 +01002498 rstat = info->ioport[REG_STATUS];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
2500
Alan Coxd7283352008-08-04 17:21:18 +01002501 info->ioport[REG_TR_DATA] = info->x_char;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 info->icount.tx++;
2503 info->x_char = 0;
2504 /* We must enable since it is disabled in ser_interrupt */
2505 e100_enable_serial_tx_ready_irq(info);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002506 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 return;
2508 }
2509 if (info->uses_dma_out) {
2510 unsigned char rstat;
2511 int i;
2512 /* We only use normal tx interrupt when sending x_char */
2513 DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0));
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002514 local_irq_save(flags);
Alan Coxd7283352008-08-04 17:21:18 +01002515 rstat = info->ioport[REG_STATUS];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
2517 e100_disable_serial_tx_ready_irq(info);
Takashi Iwaia88487c2008-07-16 21:54:42 +01002518 if (info->port.tty->stopped)
2519 rs_stop(info->port.tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520 /* Enable the DMA channel and tell it to continue */
2521 e100_enable_txdma_channel(info);
2522 /* Wait 12 cycles before doing the DMA command */
2523 for(i = 6; i > 0; i--)
2524 nop();
2525
2526 *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002527 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 return;
2529 }
2530 /* Normal char-by-char interrupt */
2531 if (info->xmit.head == info->xmit.tail
Jiri Slabyee797062013-03-07 13:12:34 +01002532 || info->port.tty->stopped) {
Takashi Iwaia88487c2008-07-16 21:54:42 +01002533 DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n",
2534 info->port.tty->stopped));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 e100_disable_serial_tx_ready_irq(info);
2536 info->tr_running = 0;
2537 return;
2538 }
2539 DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail]));
2540 /* Send a byte, rs485 timing is critical so turn of ints */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002541 local_irq_save(flags);
Alan Coxd7283352008-08-04 17:21:18 +01002542 info->ioport[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
2544 info->icount.tx++;
2545 if (info->xmit.head == info->xmit.tail) {
2546#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
Claudio Scordino6fd1af42009-04-07 16:48:19 +01002547 if (info->rs485.flags & SER_RS485_ENABLED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 /* Set a short timer to toggle RTS */
2549 start_one_shot_timer(&fast_timers_rs485[info->line],
2550 rs485_toggle_rts_timer_function,
2551 (unsigned long)info,
2552 info->char_time_usec*2,
2553 "RS-485");
2554 }
2555#endif /* RS485 */
2556 info->last_tx_active_usec = GET_JIFFIES_USEC();
2557 info->last_tx_active = jiffies;
2558 e100_disable_serial_tx_ready_irq(info);
2559 info->tr_running = 0;
2560 DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0));
2561 } else {
2562 /* We must enable since it is disabled in ser_interrupt */
2563 e100_enable_serial_tx_ready_irq(info);
2564 }
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002565 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566
2567 if (CIRC_CNT(info->xmit.head,
2568 info->xmit.tail,
2569 SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
2570 rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
2571
2572} /* handle_ser_tx_interrupt */
2573
2574/* result of time measurements:
2575 * RX duration 54-60 us when doing something, otherwise 6-9 us
2576 * ser_int duration: just sending: 8-15 us normally, up to 73 us
2577 */
2578static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +01002579ser_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580{
2581 static volatile int tx_started = 0;
2582 struct e100_serial *info;
2583 int i;
2584 unsigned long flags;
2585 unsigned long irq_mask1_rd;
2586 unsigned long data_mask = (1 << (8+2*0)); /* ser0 data_avail */
2587 int handled = 0;
2588 static volatile unsigned long reentered_ready_mask = 0;
2589
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002590 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591 irq_mask1_rd = *R_IRQ_MASK1_RD;
2592 /* First handle all rx interrupts with ints disabled */
2593 info = rs_table;
2594 irq_mask1_rd &= e100_ser_int_mask;
2595 for (i = 0; i < NR_PORTS; i++) {
2596 /* Which line caused the data irq? */
2597 if (irq_mask1_rd & data_mask) {
2598 handled = 1;
2599 handle_ser_rx_interrupt(info);
2600 }
2601 info += 1;
2602 data_mask <<= 2;
2603 }
2604 /* Handle tx interrupts with interrupts enabled so we
2605 * can take care of new data interrupts while transmitting
2606 * We protect the tx part with the tx_started flag.
2607 * We disable the tr_ready interrupts we are about to handle and
2608 * unblock the serial interrupt so new serial interrupts may come.
2609 *
2610 * If we get a new interrupt:
2611 * - it migth be due to synchronous serial ports.
2612 * - serial irq will be blocked by general irq handler.
2613 * - async data will be handled above (sync will be ignored).
2614 * - tx_started flag will prevent us from trying to send again and
2615 * we will exit fast - no need to unblock serial irq.
2616 * - Next (sync) serial interrupt handler will be runned with
2617 * disabled interrupt due to restore_flags() at end of function,
2618 * so sync handler will not be preempted or reentered.
2619 */
2620 if (!tx_started) {
2621 unsigned long ready_mask;
2622 unsigned long
2623 tx_started = 1;
2624 /* Only the tr_ready interrupts left */
2625 irq_mask1_rd &= (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) |
2626 IO_MASK(R_IRQ_MASK1_RD, ser1_ready) |
2627 IO_MASK(R_IRQ_MASK1_RD, ser2_ready) |
2628 IO_MASK(R_IRQ_MASK1_RD, ser3_ready));
2629 while (irq_mask1_rd) {
2630 /* Disable those we are about to handle */
2631 *R_IRQ_MASK1_CLR = irq_mask1_rd;
2632 /* Unblock the serial interrupt */
2633 *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
2634
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002635 local_irq_enable();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */
2637 info = rs_table;
2638 for (i = 0; i < NR_PORTS; i++) {
2639 /* Which line caused the ready irq? */
2640 if (irq_mask1_rd & ready_mask) {
2641 handled = 1;
2642 handle_ser_tx_interrupt(info);
2643 }
2644 info += 1;
2645 ready_mask <<= 2;
2646 }
2647 /* handle_ser_tx_interrupt enables tr_ready interrupts */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002648 local_irq_disable();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 /* Handle reentered TX interrupt */
2650 irq_mask1_rd = reentered_ready_mask;
2651 }
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002652 local_irq_disable();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653 tx_started = 0;
2654 } else {
2655 unsigned long ready_mask;
2656 ready_mask = irq_mask1_rd & (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) |
2657 IO_MASK(R_IRQ_MASK1_RD, ser1_ready) |
2658 IO_MASK(R_IRQ_MASK1_RD, ser2_ready) |
2659 IO_MASK(R_IRQ_MASK1_RD, ser3_ready));
2660 if (ready_mask) {
2661 reentered_ready_mask |= ready_mask;
2662 /* Disable those we are about to handle */
2663 *R_IRQ_MASK1_CLR = ready_mask;
2664 DFLOW(DEBUG_LOG(SERIAL_DEBUG_LINE, "ser_int reentered with TX %X\n", ready_mask));
2665 }
2666 }
2667
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002668 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 return IRQ_RETVAL(handled);
2670} /* ser_interrupt */
2671#endif
2672
2673/*
2674 * -------------------------------------------------------------------
2675 * Here ends the serial interrupt routines.
2676 * -------------------------------------------------------------------
2677 */
2678
2679/*
2680 * This routine is used to handle the "bottom half" processing for the
2681 * serial driver, known also the "software interrupt" processing.
2682 * This processing is done at the kernel interrupt level, after the
2683 * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
2684 * is where time-consuming activities which can not be done in the
2685 * interrupt driver proper are done; the interrupt driver schedules
2686 * them using rs_sched_event(), and they get done here.
2687 */
2688static void
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002689do_softint(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690{
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002691 struct e100_serial *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 struct tty_struct *tty;
2693
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002694 info = container_of(work, struct e100_serial, work);
2695
Takashi Iwaia88487c2008-07-16 21:54:42 +01002696 tty = info->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 if (!tty)
2698 return;
2699
Jiri Slabyb963a842007-02-10 01:44:55 -08002700 if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
2701 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702}
2703
2704static int
2705startup(struct e100_serial * info)
2706{
2707 unsigned long flags;
2708 unsigned long xmit_page;
2709 int i;
2710
2711 xmit_page = get_zeroed_page(GFP_KERNEL);
2712 if (!xmit_page)
2713 return -ENOMEM;
2714
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002715 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
2717 /* if it was already initialized, skip this */
2718
Jiri Slabyb1d984c2013-03-07 13:12:36 +01002719 if (info->port.flags & ASYNC_INITIALIZED) {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002720 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721 free_page(xmit_page);
2722 return 0;
2723 }
2724
2725 if (info->xmit.buf)
2726 free_page(xmit_page);
2727 else
2728 info->xmit.buf = (unsigned char *) xmit_page;
2729
2730#ifdef SERIAL_DEBUG_OPEN
2731 printk("starting up ttyS%d (xmit_buf 0x%p)...\n", info->line, info->xmit.buf);
2732#endif
2733
2734#ifdef CONFIG_SVINTO_SIM
2735 /* Bits and pieces collected from below. Better to have them
2736 in one ifdef:ed clause than to mix in a lot of ifdefs,
2737 right? */
Takashi Iwaia88487c2008-07-16 21:54:42 +01002738 if (info->port.tty)
2739 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740
2741 info->xmit.head = info->xmit.tail = 0;
2742 info->first_recv_buffer = info->last_recv_buffer = NULL;
2743 info->recv_cnt = info->max_recv_cnt = 0;
2744
2745 for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++)
2746 info->rec_descr[i].buf = NULL;
2747
2748 /* No real action in the simulator, but may set info important
2749 to ioctl. */
2750 change_speed(info);
2751#else
2752
2753 /*
2754 * Clear the FIFO buffers and disable them
2755 * (they will be reenabled in change_speed())
2756 */
2757
2758 /*
2759 * Reset the DMA channels and make sure their interrupts are cleared
2760 */
2761
2762 if (info->dma_in_enabled) {
2763 info->uses_dma_in = 1;
2764 e100_enable_rxdma_channel(info);
2765
2766 *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
2767
2768 /* Wait until reset cycle is complete */
2769 while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
2770 IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
2771
2772 /* Make sure the irqs are cleared */
2773 *info->iclrintradr =
2774 IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
2775 IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
2776 } else {
2777 e100_disable_rxdma_channel(info);
2778 }
2779
2780 if (info->dma_out_enabled) {
2781 info->uses_dma_out = 1;
2782 e100_enable_txdma_channel(info);
2783 *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
2784
2785 while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) ==
2786 IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
2787
2788 /* Make sure the irqs are cleared */
2789 *info->oclrintradr =
2790 IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
2791 IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
2792 } else {
2793 e100_disable_txdma_channel(info);
2794 }
2795
Takashi Iwaia88487c2008-07-16 21:54:42 +01002796 if (info->port.tty)
2797 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798
2799 info->xmit.head = info->xmit.tail = 0;
2800 info->first_recv_buffer = info->last_recv_buffer = NULL;
2801 info->recv_cnt = info->max_recv_cnt = 0;
2802
2803 for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++)
2804 info->rec_descr[i].buf = 0;
2805
2806 /*
2807 * and set the speed and other flags of the serial port
2808 * this will start the rx/tx as well
2809 */
2810#ifdef SERIAL_HANDLE_EARLY_ERRORS
2811 e100_enable_serial_data_irq(info);
2812#endif
2813 change_speed(info);
2814
2815 /* dummy read to reset any serial errors */
2816
Alan Coxd7283352008-08-04 17:21:18 +01002817 (void)info->ioport[REG_DATA];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
2819 /* enable the interrupts */
2820 if (info->uses_dma_out)
2821 e100_enable_txdma_irq(info);
2822
2823 e100_enable_rx_irq(info);
2824
2825 info->tr_running = 0; /* to be sure we don't lock up the transmitter */
2826
2827 /* setup the dma input descriptor and start dma */
2828
2829 start_receive(info);
2830
2831 /* for safety, make sure the descriptors last result is 0 bytes written */
2832
2833 info->tr_descr.sw_len = 0;
2834 info->tr_descr.hw_len = 0;
2835 info->tr_descr.status = 0;
2836
2837 /* enable RTS/DTR last */
2838
2839 e100_rts(info, 1);
2840 e100_dtr(info, 1);
2841
2842#endif /* CONFIG_SVINTO_SIM */
2843
Jiri Slabyb1d984c2013-03-07 13:12:36 +01002844 info->port.flags |= ASYNC_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002846 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 return 0;
2848}
2849
2850/*
2851 * This routine will shutdown a serial port; interrupts are disabled, and
2852 * DTR is dropped if the hangup on close termio flag is on.
2853 */
2854static void
2855shutdown(struct e100_serial * info)
2856{
2857 unsigned long flags;
2858 struct etrax_dma_descr *descr = info->rec_descr;
2859 struct etrax_recv_buffer *buffer;
2860 int i;
2861
2862#ifndef CONFIG_SVINTO_SIM
2863 /* shut down the transmitter and receiver */
2864 DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line));
2865 e100_disable_rx(info);
Alan Coxd7283352008-08-04 17:21:18 +01002866 info->ioport[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867
2868 /* disable interrupts, reset dma channels */
2869 if (info->uses_dma_in) {
2870 e100_disable_rxdma_irq(info);
2871 *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
2872 info->uses_dma_in = 0;
2873 } else {
2874 e100_disable_serial_data_irq(info);
2875 }
2876
2877 if (info->uses_dma_out) {
2878 e100_disable_txdma_irq(info);
2879 info->tr_running = 0;
2880 *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
2881 info->uses_dma_out = 0;
2882 } else {
2883 e100_disable_serial_tx_ready_irq(info);
2884 info->tr_running = 0;
2885 }
2886
2887#endif /* CONFIG_SVINTO_SIM */
2888
Jiri Slabyb1d984c2013-03-07 13:12:36 +01002889 if (!(info->port.flags & ASYNC_INITIALIZED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 return;
2891
2892#ifdef SERIAL_DEBUG_OPEN
2893 printk("Shutting down serial port %d (irq %d)....\n", info->line,
2894 info->irq);
2895#endif
2896
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002897 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898
2899 if (info->xmit.buf) {
2900 free_page((unsigned long)info->xmit.buf);
2901 info->xmit.buf = NULL;
2902 }
2903
2904 for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++)
2905 if (descr[i].buf) {
2906 buffer = phys_to_virt(descr[i].buf) - sizeof *buffer;
2907 kfree(buffer);
2908 descr[i].buf = 0;
2909 }
2910
Alan Coxadc8d742012-07-14 15:31:47 +01002911 if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 /* hang up DTR and RTS if HUPCL is enabled */
2913 e100_dtr(info, 0);
2914 e100_rts(info, 0); /* could check CRTSCTS before doing this */
2915 }
2916
Takashi Iwaia88487c2008-07-16 21:54:42 +01002917 if (info->port.tty)
2918 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919
Jiri Slabyb1d984c2013-03-07 13:12:36 +01002920 info->port.flags &= ~ASYNC_INITIALIZED;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08002921 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922}
2923
2924
2925/* change baud rate and other assorted parameters */
2926
2927static void
2928change_speed(struct e100_serial *info)
2929{
2930 unsigned int cflag;
2931 unsigned long xoff;
2932 unsigned long flags;
2933 /* first some safety checks */
2934
Alan Coxadc8d742012-07-14 15:31:47 +01002935 if (!info->port.tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 return;
Alan Coxd7283352008-08-04 17:21:18 +01002937 if (!info->ioport)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 return;
2939
Alan Coxadc8d742012-07-14 15:31:47 +01002940 cflag = info->port.tty->termios.c_cflag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941
2942 /* possibly, the tx/rx should be disabled first to do this safely */
2943
2944 /* change baud-rate and write it to the hardware */
Jiri Slabyb1d984c2013-03-07 13:12:36 +01002945 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946 /* Special baudrate */
2947 u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */
2948 unsigned long alt_source =
2949 IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) |
2950 IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal);
2951 /* R_ALT_SER_BAUDRATE selects the source */
2952 DBAUD(printk("Custom baudrate: baud_base/divisor %lu/%i\n",
2953 (unsigned long)info->baud_base, info->custom_divisor));
2954 if (info->baud_base == SERIAL_PRESCALE_BASE) {
2955 /* 0, 2-65535 (0=65536) */
2956 u16 divisor = info->custom_divisor;
2957 /* R_SERIAL_PRESCALE (upper 16 bits of R_CLOCK_PRESCALE) */
2958 /* baudrate is 3.125MHz/custom_divisor */
2959 alt_source =
2960 IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, prescale) |
2961 IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, prescale);
2962 alt_source = 0x11;
2963 DBAUD(printk("Writing SERIAL_PRESCALE: divisor %i\n", divisor));
2964 *R_SERIAL_PRESCALE = divisor;
2965 info->baud = SERIAL_PRESCALE_BASE/divisor;
2966 }
2967#ifdef CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED
2968 else if ((info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8 &&
2969 info->custom_divisor == 1) ||
2970 (info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ &&
2971 info->custom_divisor == 8)) {
2972 /* ext_clk selected */
2973 alt_source =
2974 IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, extern) |
2975 IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, extern);
2976 DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8));
2977 info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8;
2978 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979#endif
2980 else
2981 {
2982 /* Bad baudbase, we don't support using timer0
2983 * for baudrate.
2984 */
2985 printk(KERN_WARNING "Bad baud_base/custom_divisor: %lu/%i\n",
2986 (unsigned long)info->baud_base, info->custom_divisor);
2987 }
2988 r_alt_ser_baudrate_shadow &= ~mask;
2989 r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8));
2990 *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow;
2991 } else {
2992 /* Normal baudrate */
2993 /* Make sure we use normal baudrate */
2994 u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */
2995 unsigned long alt_source =
2996 IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) |
2997 IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal);
2998 r_alt_ser_baudrate_shadow &= ~mask;
2999 r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8));
3000#ifndef CONFIG_SVINTO_SIM
3001 *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow;
3002#endif /* CONFIG_SVINTO_SIM */
3003
3004 info->baud = cflag_to_baud(cflag);
3005#ifndef CONFIG_SVINTO_SIM
Alan Coxd7283352008-08-04 17:21:18 +01003006 info->ioport[REG_BAUD] = cflag_to_etrax_baud(cflag);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007#endif /* CONFIG_SVINTO_SIM */
3008 }
3009
3010#ifndef CONFIG_SVINTO_SIM
3011 /* start with default settings and then fill in changes */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003012 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 /* 8 bit, no/even parity */
3014 info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) |
3015 IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) |
3016 IO_MASK(R_SERIAL0_REC_CTRL, rec_par));
3017
3018 /* 8 bit, no/even parity, 1 stop bit, no cts */
3019 info->tx_ctrl &= ~(IO_MASK(R_SERIAL0_TR_CTRL, tr_bitnr) |
3020 IO_MASK(R_SERIAL0_TR_CTRL, tr_par_en) |
3021 IO_MASK(R_SERIAL0_TR_CTRL, tr_par) |
3022 IO_MASK(R_SERIAL0_TR_CTRL, stop_bits) |
3023 IO_MASK(R_SERIAL0_TR_CTRL, auto_cts));
3024
3025 if ((cflag & CSIZE) == CS7) {
3026 /* set 7 bit mode */
3027 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
3028 info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
3029 }
3030
3031 if (cflag & CSTOPB) {
3032 /* set 2 stop bit mode */
3033 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, two_bits);
3034 }
3035
3036 if (cflag & PARENB) {
3037 /* enable parity */
3038 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
3039 info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
3040 }
3041
3042 if (cflag & CMSPAR) {
3043 /* enable stick parity, PARODD mean Mark which matches ETRAX */
3044 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick);
3045 info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick);
3046 }
3047 if (cflag & PARODD) {
3048 /* set odd parity (or Mark if CMSPAR) */
3049 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd);
3050 info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd);
3051 }
3052
3053 if (cflag & CRTSCTS) {
3054 /* enable automatic CTS handling */
3055 DFLOW(DEBUG_LOG(info->line, "FLOW auto_cts enabled\n", 0));
3056 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, active);
3057 }
3058
3059 /* make sure the tx and rx are enabled */
3060
3061 info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable);
3062 info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
3063
3064 /* actually write the control regs to the hardware */
3065
Alan Coxd7283352008-08-04 17:21:18 +01003066 info->ioport[REG_TR_CTRL] = info->tx_ctrl;
3067 info->ioport[REG_REC_CTRL] = info->rx_ctrl;
Takashi Iwaia88487c2008-07-16 21:54:42 +01003068 xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069 xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
Alan Coxadc8d742012-07-14 15:31:47 +01003070 if (info->port.tty->termios.c_iflag & IXON ) {
Takashi Iwaia88487c2008-07-16 21:54:42 +01003071 DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n",
3072 STOP_CHAR(info->port.tty)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
3074 }
3075
Alan Coxd7283352008-08-04 17:21:18 +01003076 *((unsigned long *)&info->ioport[REG_XOFF]) = xoff;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003077 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078#endif /* !CONFIG_SVINTO_SIM */
3079
3080 update_char_time(info);
3081
3082} /* change_speed */
3083
3084/* start transmitting chars NOW */
3085
3086static void
3087rs_flush_chars(struct tty_struct *tty)
3088{
3089 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3090 unsigned long flags;
3091
3092 if (info->tr_running ||
3093 info->xmit.head == info->xmit.tail ||
3094 tty->stopped ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095 !info->xmit.buf)
3096 return;
3097
3098#ifdef SERIAL_DEBUG_FLOW
3099 printk("rs_flush_chars\n");
3100#endif
3101
3102 /* this protection might not exactly be necessary here */
3103
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003104 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 start_transmit(info);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003106 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107}
3108
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003109static int rs_raw_write(struct tty_struct *tty,
Adrian Bunk41c28ff2006-03-23 03:00:56 -08003110 const unsigned char *buf, int count)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111{
3112 int c, ret = 0;
3113 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3114 unsigned long flags;
3115
3116 /* first some sanity checks */
3117
Cong Dingf938f372013-01-16 23:30:44 +01003118 if (!info->xmit.buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 return 0;
3120
3121#ifdef SERIAL_DEBUG_DATA
3122 if (info->line == SERIAL_DEBUG_LINE)
3123 printk("rs_raw_write (%d), status %d\n",
Alan Coxd7283352008-08-04 17:21:18 +01003124 count, info->ioport[REG_STATUS]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125#endif
3126
3127#ifdef CONFIG_SVINTO_SIM
3128 /* Really simple. The output is here and now. */
3129 SIMCOUT(buf, count);
3130 return count;
3131#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003132 local_save_flags(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133 DFLOW(DEBUG_LOG(info->line, "write count %i ", count));
3134 DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty)));
3135
3136
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003137 /* The local_irq_disable/restore_flags pairs below are needed
3138 * because the DMA interrupt handler moves the info->xmit values.
3139 * the memcpy needs to be in the critical region unfortunately,
3140 * because we need to read xmit values, memcpy, write xmit values
3141 * in one atomic operation... this could perhaps be avoided by
3142 * more clever design.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003144 local_irq_disable();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 while (count) {
3146 c = CIRC_SPACE_TO_END(info->xmit.head,
3147 info->xmit.tail,
3148 SERIAL_XMIT_SIZE);
3149
3150 if (count < c)
3151 c = count;
3152 if (c <= 0)
3153 break;
3154
3155 memcpy(info->xmit.buf + info->xmit.head, buf, c);
3156 info->xmit.head = (info->xmit.head + c) &
3157 (SERIAL_XMIT_SIZE-1);
3158 buf += c;
3159 count -= c;
3160 ret += c;
3161 }
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003162 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163
3164 /* enable transmitter if not running, unless the tty is stopped
3165 * this does not need IRQ protection since if tr_running == 0
3166 * the IRQ's are not running anyway for this port.
3167 */
3168 DFLOW(DEBUG_LOG(info->line, "write ret %i\n", ret));
3169
3170 if (info->xmit.head != info->xmit.tail &&
3171 !tty->stopped &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172 !info->tr_running) {
3173 start_transmit(info);
3174 }
3175
3176 return ret;
3177} /* raw_raw_write() */
3178
3179static int
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003180rs_write(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 const unsigned char *buf, int count)
3182{
3183#if defined(CONFIG_ETRAX_RS485)
3184 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3185
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003186 if (info->rs485.flags & SER_RS485_ENABLED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 {
3188 /* If we are in RS-485 mode, we need to toggle RTS and disable
3189 * the receiver before initiating a DMA transfer
3190 */
3191#ifdef CONFIG_ETRAX_FAST_TIMER
3192 /* Abort any started timer */
3193 fast_timers_rs485[info->line].function = NULL;
3194 del_fast_timer(&fast_timers_rs485[info->line]);
3195#endif
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003196 e100_rts(info, (info->rs485.flags & SER_RS485_RTS_ON_SEND));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
3198 e100_disable_rx(info);
3199 e100_enable_rx_irq(info);
3200#endif
Claudio Scordino93f33502011-11-09 15:51:49 +01003201 if (info->rs485.delay_rts_before_send > 0)
3202 msleep(info->rs485.delay_rts_before_send);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 }
3204#endif /* CONFIG_ETRAX_RS485 */
3205
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003206 count = rs_raw_write(tty, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207
3208#if defined(CONFIG_ETRAX_RS485)
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003209 if (info->rs485.flags & SER_RS485_ENABLED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 {
3211 unsigned int val;
3212 /* If we are in RS-485 mode the following has to be done:
3213 * wait until DMA is ready
3214 * wait on transmit shift register
3215 * toggle RTS
3216 * enable the receiver
3217 */
3218
3219 /* Sleep until all sent */
3220 tty_wait_until_sent(tty, 0);
3221#ifdef CONFIG_ETRAX_FAST_TIMER
3222 /* Now sleep a little more so that shift register is empty */
3223 schedule_usleep(info->char_time_usec * 2);
3224#endif
3225 /* wait on transmit shift register */
3226 do{
3227 get_lsr_info(info, &val);
3228 }while (!(val & TIOCSER_TEMT));
3229
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003230 e100_rts(info, (info->rs485.flags & SER_RS485_RTS_AFTER_SEND));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231
3232#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
3233 e100_enable_rx(info);
3234 e100_enable_rxdma_irq(info);
3235#endif
3236 }
3237#endif /* CONFIG_ETRAX_RS485 */
3238
3239 return count;
3240} /* rs_write */
3241
3242
3243/* how much space is available in the xmit buffer? */
3244
3245static int
3246rs_write_room(struct tty_struct *tty)
3247{
3248 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3249
3250 return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
3251}
3252
3253/* How many chars are in the xmit buffer?
3254 * This does not include any chars in the transmitter FIFO.
3255 * Use wait_until_sent for waiting for FIFO drain.
3256 */
3257
3258static int
3259rs_chars_in_buffer(struct tty_struct *tty)
3260{
3261 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3262
3263 return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
3264}
3265
3266/* discard everything in the xmit buffer */
3267
3268static void
3269rs_flush_buffer(struct tty_struct *tty)
3270{
3271 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3272 unsigned long flags;
3273
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003274 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 info->xmit.head = info->xmit.tail = 0;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003276 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
Jiri Slabyb963a842007-02-10 01:44:55 -08003278 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279}
3280
3281/*
3282 * This function is used to send a high-priority XON/XOFF character to
3283 * the device
3284 *
3285 * Since we use DMA we don't check for info->x_char in transmit_chars_dma(),
3286 * but we do it in handle_ser_tx_interrupt().
3287 * We disable DMA channel and enable tx ready interrupt and write the
3288 * character when possible.
3289 */
3290static void rs_send_xchar(struct tty_struct *tty, char ch)
3291{
3292 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3293 unsigned long flags;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003294 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295 if (info->uses_dma_out) {
3296 /* Put the DMA on hold and disable the channel */
3297 *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold);
3298 while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) !=
3299 IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, hold));
3300 e100_disable_txdma_channel(info);
3301 }
3302
3303 /* Must make sure transmitter is not stopped before we can transmit */
3304 if (tty->stopped)
3305 rs_start(tty);
3306
3307 /* Enable manual transmit interrupt and send from there */
3308 DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch));
3309 info->x_char = ch;
3310 e100_enable_serial_tx_ready_irq(info);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003311 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312}
3313
3314/*
3315 * ------------------------------------------------------------
3316 * rs_throttle()
3317 *
3318 * This routine is called by the upper-layer tty layer to signal that
3319 * incoming characters should be throttled.
3320 * ------------------------------------------------------------
3321 */
3322static void
3323rs_throttle(struct tty_struct * tty)
3324{
3325 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3326#ifdef SERIAL_DEBUG_THROTTLE
3327 char buf[64];
3328
3329 printk("throttle %s: %lu....\n", tty_name(tty, buf),
3330 (unsigned long)tty->ldisc.chars_in_buffer(tty));
3331#endif
3332 DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty)));
3333
3334 /* Do RTS before XOFF since XOFF might take some time */
Alan Coxadc8d742012-07-14 15:31:47 +01003335 if (tty->termios.c_cflag & CRTSCTS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 /* Turn off RTS line */
3337 e100_rts(info, 0);
3338 }
3339 if (I_IXOFF(tty))
3340 rs_send_xchar(tty, STOP_CHAR(tty));
3341
3342}
3343
3344static void
3345rs_unthrottle(struct tty_struct * tty)
3346{
3347 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3348#ifdef SERIAL_DEBUG_THROTTLE
3349 char buf[64];
3350
3351 printk("unthrottle %s: %lu....\n", tty_name(tty, buf),
3352 (unsigned long)tty->ldisc.chars_in_buffer(tty));
3353#endif
3354 DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty)));
3355 DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count));
3356 /* Do RTS before XOFF since XOFF might take some time */
Alan Coxadc8d742012-07-14 15:31:47 +01003357 if (tty->termios.c_cflag & CRTSCTS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 /* Assert RTS line */
3359 e100_rts(info, 1);
3360 }
3361
3362 if (I_IXOFF(tty)) {
3363 if (info->x_char)
3364 info->x_char = 0;
3365 else
3366 rs_send_xchar(tty, START_CHAR(tty));
3367 }
3368
3369}
3370
3371/*
3372 * ------------------------------------------------------------
3373 * rs_ioctl() and friends
3374 * ------------------------------------------------------------
3375 */
3376
3377static int
3378get_serial_info(struct e100_serial * info,
3379 struct serial_struct * retinfo)
3380{
3381 struct serial_struct tmp;
3382
3383 /* this is all probably wrong, there are a lot of fields
3384 * here that we don't have in e100_serial and maybe we
3385 * should set them to something else than 0.
3386 */
3387
3388 if (!retinfo)
3389 return -EFAULT;
3390 memset(&tmp, 0, sizeof(tmp));
3391 tmp.type = info->type;
3392 tmp.line = info->line;
Alan Coxd7283352008-08-04 17:21:18 +01003393 tmp.port = (int)info->ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394 tmp.irq = info->irq;
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003395 tmp.flags = info->port.flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396 tmp.baud_base = info->baud_base;
3397 tmp.close_delay = info->close_delay;
3398 tmp.closing_wait = info->closing_wait;
3399 tmp.custom_divisor = info->custom_divisor;
3400 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
3401 return -EFAULT;
3402 return 0;
3403}
3404
3405static int
3406set_serial_info(struct e100_serial *info,
3407 struct serial_struct *new_info)
3408{
3409 struct serial_struct new_serial;
3410 struct e100_serial old_info;
3411 int retval = 0;
3412
3413 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
3414 return -EFAULT;
3415
3416 old_info = *info;
3417
3418 if (!capable(CAP_SYS_ADMIN)) {
3419 if ((new_serial.type != info->type) ||
3420 (new_serial.close_delay != info->close_delay) ||
3421 ((new_serial.flags & ~ASYNC_USR_MASK) !=
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003422 (info->port.flags & ~ASYNC_USR_MASK)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 return -EPERM;
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003424 info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425 (new_serial.flags & ASYNC_USR_MASK));
3426 goto check_and_exit;
3427 }
3428
3429 if (info->count > 1)
3430 return -EBUSY;
3431
3432 /*
3433 * OK, past this point, all the error checking has been done.
3434 * At this point, we start making changes.....
3435 */
3436
3437 info->baud_base = new_serial.baud_base;
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003438 info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439 (new_serial.flags & ASYNC_FLAGS));
3440 info->custom_divisor = new_serial.custom_divisor;
3441 info->type = new_serial.type;
3442 info->close_delay = new_serial.close_delay;
3443 info->closing_wait = new_serial.closing_wait;
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003444 info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445
3446 check_and_exit:
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003447 if (info->port.flags & ASYNC_INITIALIZED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448 change_speed(info);
3449 } else
3450 retval = startup(info);
3451 return retval;
3452}
3453
3454/*
3455 * get_lsr_info - get line status register info
3456 *
3457 * Purpose: Let user call ioctl() to get info when the UART physically
3458 * is emptied. On bus types like RS485, the transmitter must
3459 * release the bus after transmitting. This must be done when
3460 * the transmit shift register is empty, not be done when the
3461 * transmit holding register is empty. This functionality
3462 * allows an RS485 driver to be written in user space.
3463 */
3464static int
3465get_lsr_info(struct e100_serial * info, unsigned int *value)
3466{
3467 unsigned int result = TIOCSER_TEMT;
3468#ifndef CONFIG_SVINTO_SIM
3469 unsigned long curr_time = jiffies;
3470 unsigned long curr_time_usec = GET_JIFFIES_USEC();
3471 unsigned long elapsed_usec =
3472 (curr_time - info->last_tx_active) * 1000000/HZ +
3473 curr_time_usec - info->last_tx_active_usec;
3474
3475 if (info->xmit.head != info->xmit.tail ||
3476 elapsed_usec < 2*info->char_time_usec) {
3477 result = 0;
3478 }
3479#endif
3480
3481 if (copy_to_user(value, &result, sizeof(int)))
3482 return -EFAULT;
3483 return 0;
3484}
3485
3486#ifdef SERIAL_DEBUG_IO
3487struct state_str
3488{
3489 int state;
3490 const char *str;
3491};
3492
3493const struct state_str control_state_str[] = {
3494 {TIOCM_DTR, "DTR" },
3495 {TIOCM_RTS, "RTS"},
3496 {TIOCM_ST, "ST?" },
3497 {TIOCM_SR, "SR?" },
3498 {TIOCM_CTS, "CTS" },
3499 {TIOCM_CD, "CD" },
3500 {TIOCM_RI, "RI" },
3501 {TIOCM_DSR, "DSR" },
3502 {0, NULL }
3503};
3504
3505char *get_control_state_str(int MLines, char *s)
3506{
3507 int i = 0;
3508
3509 s[0]='\0';
3510 while (control_state_str[i].str != NULL) {
3511 if (MLines & control_state_str[i].state) {
3512 if (s[0] != '\0') {
3513 strcat(s, ", ");
3514 }
3515 strcat(s, control_state_str[i].str);
3516 }
3517 i++;
3518 }
3519 return s;
3520}
3521#endif
3522
Alan Coxd7283352008-08-04 17:21:18 +01003523static int
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003524rs_break(struct tty_struct *tty, int break_state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003525{
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003526 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3527 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003528
Alan Coxd7283352008-08-04 17:21:18 +01003529 if (!info->ioport)
3530 return -EIO;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003531
3532 local_irq_save(flags);
3533 if (break_state == -1) {
3534 /* Go to manual mode and set the txd pin to 0 */
3535 /* Clear bit 7 (txd) and 6 (tr_enable) */
3536 info->tx_ctrl &= 0x3F;
3537 } else {
3538 /* Set bit 7 (txd) and 6 (tr_enable) */
3539 info->tx_ctrl |= (0x80 | 0x40);
3540 }
Alan Coxd7283352008-08-04 17:21:18 +01003541 info->ioport[REG_TR_CTRL] = info->tx_ctrl;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003542 local_irq_restore(flags);
Alan Coxd7283352008-08-04 17:21:18 +01003543 return 0;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003544}
3545
3546static int
Alan Cox20b9d172011-02-14 16:26:50 +00003547rs_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003548{
3549 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
Alan Cox978e5952008-04-30 00:53:59 -07003550 unsigned long flags;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003551
Alan Cox978e5952008-04-30 00:53:59 -07003552 local_irq_save(flags);
Alan Cox032c17e2008-04-28 02:13:50 -07003553
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003554 if (clear & TIOCM_RTS)
3555 e100_rts(info, 0);
3556 if (clear & TIOCM_DTR)
3557 e100_dtr(info, 0);
3558 /* Handle FEMALE behaviour */
3559 if (clear & TIOCM_RI)
3560 e100_ri_out(info, 0);
3561 if (clear & TIOCM_CD)
3562 e100_cd_out(info, 0);
3563
3564 if (set & TIOCM_RTS)
3565 e100_rts(info, 1);
3566 if (set & TIOCM_DTR)
3567 e100_dtr(info, 1);
3568 /* Handle FEMALE behaviour */
3569 if (set & TIOCM_RI)
3570 e100_ri_out(info, 1);
3571 if (set & TIOCM_CD)
3572 e100_cd_out(info, 1);
Alan Cox032c17e2008-04-28 02:13:50 -07003573
Alan Cox978e5952008-04-30 00:53:59 -07003574 local_irq_restore(flags);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003575 return 0;
3576}
3577
3578static int
Alan Cox60b33c12011-02-14 16:26:14 +00003579rs_tiocmget(struct tty_struct *tty)
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003580{
3581 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3582 unsigned int result;
Alan Cox978e5952008-04-30 00:53:59 -07003583 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003584
Alan Cox978e5952008-04-30 00:53:59 -07003585 local_irq_save(flags);
3586
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587 result =
3588 (!E100_RTS_GET(info) ? TIOCM_RTS : 0)
3589 | (!E100_DTR_GET(info) ? TIOCM_DTR : 0)
3590 | (!E100_RI_GET(info) ? TIOCM_RNG : 0)
3591 | (!E100_DSR_GET(info) ? TIOCM_DSR : 0)
3592 | (!E100_CD_GET(info) ? TIOCM_CAR : 0)
3593 | (!E100_CTS_GET(info) ? TIOCM_CTS : 0);
3594
Alan Cox978e5952008-04-30 00:53:59 -07003595 local_irq_restore(flags);
Alan Cox032c17e2008-04-28 02:13:50 -07003596
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597#ifdef SERIAL_DEBUG_IO
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003598 printk(KERN_DEBUG "ser%i: modem state: %i 0x%08X\n",
3599 info->line, result, result);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600 {
3601 char s[100];
3602
3603 get_control_state_str(result, s);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003604 printk(KERN_DEBUG "state: %s\n", s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003605 }
3606#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003607 return result;
3608
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609}
3610
3611
3612static int
Alan Cox6caa76b2011-02-14 16:27:22 +00003613rs_ioctl(struct tty_struct *tty,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 unsigned int cmd, unsigned long arg)
3615{
3616 struct e100_serial * info = (struct e100_serial *)tty->driver_data;
3617
3618 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
3619 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
3620 (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
3621 if (tty->flags & (1 << TTY_IO_ERROR))
3622 return -EIO;
3623 }
3624
3625 switch (cmd) {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003626 case TIOCGSERIAL:
3627 return get_serial_info(info,
3628 (struct serial_struct *) arg);
3629 case TIOCSSERIAL:
3630 return set_serial_info(info,
3631 (struct serial_struct *) arg);
3632 case TIOCSERGETLSR: /* Get line status register */
3633 return get_lsr_info(info, (unsigned int *) arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003635 case TIOCSERGSTRUCT:
3636 if (copy_to_user((struct e100_serial *) arg,
3637 info, sizeof(struct e100_serial)))
3638 return -EFAULT;
3639 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640
3641#if defined(CONFIG_ETRAX_RS485)
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003642 case TIOCSERSETRS485:
3643 {
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003644 /* In this ioctl we still use the old structure
3645 * rs485_control for backward compatibility
3646 * (if we use serial_rs485, then old user-level code
3647 * wouldn't work anymore...).
3648 * The use of this ioctl is deprecated: use TIOCSRS485
3649 * instead.*/
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003650 struct rs485_control rs485ctrl;
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003651 struct serial_rs485 rs485data;
3652 printk(KERN_DEBUG "The use of this ioctl is deprecated. Use TIOCSRS485 instead\n");
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003653 if (copy_from_user(&rs485ctrl, (struct rs485_control *)arg,
3654 sizeof(rs485ctrl)))
3655 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003657 rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;
3658 rs485data.flags = 0;
Jesper Nilssonc7213fc2010-10-28 12:08:27 +02003659
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003660 if (rs485ctrl.enabled)
3661 rs485data.flags |= SER_RS485_ENABLED;
3662 else
3663 rs485data.flags &= ~(SER_RS485_ENABLED);
3664
3665 if (rs485ctrl.rts_on_send)
3666 rs485data.flags |= SER_RS485_RTS_ON_SEND;
3667 else
3668 rs485data.flags &= ~(SER_RS485_RTS_ON_SEND);
3669
3670 if (rs485ctrl.rts_after_sent)
3671 rs485data.flags |= SER_RS485_RTS_AFTER_SEND;
3672 else
3673 rs485data.flags &= ~(SER_RS485_RTS_AFTER_SEND);
3674
3675 return e100_enable_rs485(tty, &rs485data);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003676 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003678 case TIOCSRS485:
3679 {
3680 /* This is the new version of TIOCSRS485, with new
3681 * data structure serial_rs485 */
3682 struct serial_rs485 rs485data;
3683 if (copy_from_user(&rs485data, (struct rs485_control *)arg,
3684 sizeof(rs485data)))
3685 return -EFAULT;
3686
3687 return e100_enable_rs485(tty, &rs485data);
3688 }
3689
Claudio Scordinof1d23ed2010-05-31 10:19:09 +02003690 case TIOCGRS485:
3691 {
3692 struct serial_rs485 *rs485data =
3693 &(((struct e100_serial *)tty->driver_data)->rs485);
3694 /* This is the ioctl to get RS485 data from user-space */
3695 if (copy_to_user((struct serial_rs485 *) arg,
3696 rs485data,
Jesper Nilsson94479c02010-10-28 12:04:55 +02003697 sizeof(struct serial_rs485)))
Claudio Scordinof1d23ed2010-05-31 10:19:09 +02003698 return -EFAULT;
3699 break;
3700 }
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003701
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003702 case TIOCSERWRRS485:
3703 {
3704 struct rs485_write rs485wr;
3705 if (copy_from_user(&rs485wr, (struct rs485_write *)arg,
3706 sizeof(rs485wr)))
3707 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003709 return e100_write_rs485(tty, rs485wr.outc, rs485wr.outc_size);
3710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711#endif
3712
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003713 default:
3714 return -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715 }
3716 return 0;
3717}
3718
3719static void
Alan Cox606d0992006-12-08 02:38:45 -08003720rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721{
3722 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3723
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 change_speed(info);
3725
3726 /* Handle turning off CRTSCTS */
3727 if ((old_termios->c_cflag & CRTSCTS) &&
Jiri Slabyee797062013-03-07 13:12:34 +01003728 !(tty->termios.c_cflag & CRTSCTS))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729 rs_start(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003730
3731}
3732
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733/*
3734 * ------------------------------------------------------------
3735 * rs_close()
3736 *
3737 * This routine is called when the serial port gets closed. First, we
3738 * wait for the last remaining data to be sent. Then, we unlink its
3739 * S structure from the interrupt chain if necessary, and we free
3740 * that IRQ if nothing is left in the chain.
3741 * ------------------------------------------------------------
3742 */
3743static void
3744rs_close(struct tty_struct *tty, struct file * filp)
3745{
3746 struct e100_serial * info = (struct e100_serial *)tty->driver_data;
3747 unsigned long flags;
3748
3749 if (!info)
3750 return;
3751
3752 /* interrupts are disabled for this entire function */
3753
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003754 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755
3756 if (tty_hung_up_p(filp)) {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003757 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758 return;
3759 }
3760
3761#ifdef SERIAL_DEBUG_OPEN
3762 printk("[%d] rs_close ttyS%d, count = %d\n", current->pid,
3763 info->line, info->count);
3764#endif
3765 if ((tty->count == 1) && (info->count != 1)) {
3766 /*
3767 * Uh, oh. tty->count is 1, which means that the tty
3768 * structure will be freed. Info->count should always
3769 * be one in these conditions. If it's greater than
3770 * one, we've got real problems, since it means the
3771 * serial port won't be shutdown.
3772 */
WANG Cong3d43b7d2011-09-01 16:47:49 +08003773 printk(KERN_ERR
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 "rs_close: bad serial port count; tty->count is 1, "
3775 "info->count is %d\n", info->count);
3776 info->count = 1;
3777 }
3778 if (--info->count < 0) {
WANG Cong3d43b7d2011-09-01 16:47:49 +08003779 printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780 info->line, info->count);
3781 info->count = 0;
3782 }
3783 if (info->count) {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003784 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785 return;
3786 }
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003787 info->port.flags |= ASYNC_CLOSING;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788 /*
3789 * Save the termios structure, since this port may have
3790 * separate termios for callout and dialin.
3791 */
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003792 if (info->port.flags & ASYNC_NORMAL_ACTIVE)
Alan Coxadc8d742012-07-14 15:31:47 +01003793 info->normal_termios = tty->termios;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794 /*
3795 * Now we wait for the transmit buffer to clear; and we notify
3796 * the line discipline to only process XON/XOFF characters.
3797 */
3798 tty->closing = 1;
3799 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
3800 tty_wait_until_sent(tty, info->closing_wait);
3801 /*
3802 * At this point we stop accepting input. To do this, we
3803 * disable the serial receiver and the DMA receive interrupt.
3804 */
3805#ifdef SERIAL_HANDLE_EARLY_ERRORS
3806 e100_disable_serial_data_irq(info);
3807#endif
3808
3809#ifndef CONFIG_SVINTO_SIM
3810 e100_disable_rx(info);
3811 e100_disable_rx_irq(info);
3812
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003813 if (info->port.flags & ASYNC_INITIALIZED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003814 /*
3815 * Before we drop DTR, make sure the UART transmitter
3816 * has completely drained; this is especially
3817 * important as we have a transmit FIFO!
3818 */
3819 rs_wait_until_sent(tty, HZ);
3820 }
3821#endif
3822
3823 shutdown(info);
Alan Cox978e5952008-04-30 00:53:59 -07003824 rs_flush_buffer(tty);
Alan Cox454aa382008-05-12 12:31:37 +01003825 tty_ldisc_flush(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 tty->closing = 0;
3827 info->event = 0;
Takashi Iwaia88487c2008-07-16 21:54:42 +01003828 info->port.tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829 if (info->blocked_open) {
Nishanth Aravamudan3c76bc52005-11-07 01:01:21 -08003830 if (info->close_delay)
3831 schedule_timeout_interruptible(info->close_delay);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003832 wake_up_interruptible(&info->open_wait);
3833 }
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003834 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 wake_up_interruptible(&info->close_wait);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003836 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837
3838 /* port closed */
3839
3840#if defined(CONFIG_ETRAX_RS485)
Claudio Scordino6fd1af42009-04-07 16:48:19 +01003841 if (info->rs485.flags & SER_RS485_ENABLED) {
3842 info->rs485.flags &= ~(SER_RS485_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843#if defined(CONFIG_ETRAX_RS485_ON_PA)
3844 *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit);
3845#endif
3846#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
3847 REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow,
3848 rs485_port_g_bit, 0);
3849#endif
3850#if defined(CONFIG_ETRAX_RS485_LTC1387)
3851 REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow,
3852 CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 0);
3853 REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow,
3854 CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 0);
3855#endif
3856 }
3857#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003858
3859 /*
3860 * Release any allocated DMA irq's.
3861 */
3862 if (info->dma_in_enabled) {
3863 free_irq(info->dma_in_irq_nbr, info);
3864 cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description);
3865 info->uses_dma_in = 0;
3866#ifdef SERIAL_DEBUG_OPEN
3867 printk(KERN_DEBUG "DMA irq '%s' freed\n",
3868 info->dma_in_irq_description);
3869#endif
3870 }
3871 if (info->dma_out_enabled) {
3872 free_irq(info->dma_out_irq_nbr, info);
3873 cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description);
3874 info->uses_dma_out = 0;
3875#ifdef SERIAL_DEBUG_OPEN
3876 printk(KERN_DEBUG "DMA irq '%s' freed\n",
3877 info->dma_out_irq_description);
3878#endif
3879 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003880}
3881
3882/*
3883 * rs_wait_until_sent() --- wait until the transmitter is empty
3884 */
3885static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
3886{
3887 unsigned long orig_jiffies;
3888 struct e100_serial *info = (struct e100_serial *)tty->driver_data;
3889 unsigned long curr_time = jiffies;
3890 unsigned long curr_time_usec = GET_JIFFIES_USEC();
3891 long elapsed_usec =
3892 (curr_time - info->last_tx_active) * (1000000/HZ) +
3893 curr_time_usec - info->last_tx_active_usec;
3894
3895 /*
3896 * Check R_DMA_CHx_STATUS bit 0-6=number of available bytes in FIFO
3897 * R_DMA_CHx_HWSW bit 31-16=nbr of bytes left in DMA buffer (0=64k)
3898 */
3899 orig_jiffies = jiffies;
3900 while (info->xmit.head != info->xmit.tail || /* More in send queue */
3901 (*info->ostatusadr & 0x007f) || /* more in FIFO */
3902 (elapsed_usec < 2*info->char_time_usec)) {
Nishanth Aravamudan3c76bc52005-11-07 01:01:21 -08003903 schedule_timeout_interruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 if (signal_pending(current))
3905 break;
3906 if (timeout && time_after(jiffies, orig_jiffies + timeout))
3907 break;
3908 curr_time = jiffies;
3909 curr_time_usec = GET_JIFFIES_USEC();
3910 elapsed_usec =
3911 (curr_time - info->last_tx_active) * (1000000/HZ) +
3912 curr_time_usec - info->last_tx_active_usec;
3913 }
3914 set_current_state(TASK_RUNNING);
3915}
3916
3917/*
3918 * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
3919 */
3920void
3921rs_hangup(struct tty_struct *tty)
3922{
3923 struct e100_serial * info = (struct e100_serial *)tty->driver_data;
3924
3925 rs_flush_buffer(tty);
3926 shutdown(info);
3927 info->event = 0;
3928 info->count = 0;
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003929 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
Takashi Iwaia88487c2008-07-16 21:54:42 +01003930 info->port.tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931 wake_up_interruptible(&info->open_wait);
3932}
3933
3934/*
3935 * ------------------------------------------------------------
3936 * rs_open() and friends
3937 * ------------------------------------------------------------
3938 */
3939static int
3940block_til_ready(struct tty_struct *tty, struct file * filp,
3941 struct e100_serial *info)
3942{
3943 DECLARE_WAITQUEUE(wait, current);
3944 unsigned long flags;
3945 int retval;
3946 int do_clocal = 0, extra_count = 0;
3947
3948 /*
3949 * If the device is in the middle of being closed, then block
3950 * until it's done, and then try again.
3951 */
3952 if (tty_hung_up_p(filp) ||
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003953 (info->port.flags & ASYNC_CLOSING)) {
Alan Cox89c8d912012-08-08 16:30:13 +01003954 wait_event_interruptible_tty(tty, info->close_wait,
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003955 !(info->port.flags & ASYNC_CLOSING));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956#ifdef SERIAL_DO_RESTART
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003957 if (info->port.flags & ASYNC_HUP_NOTIFY)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958 return -EAGAIN;
3959 else
3960 return -ERESTARTSYS;
3961#else
3962 return -EAGAIN;
3963#endif
3964 }
3965
3966 /*
3967 * If non-blocking mode is set, or the port is not enabled,
3968 * then make the check up front and then exit.
3969 */
3970 if ((filp->f_flags & O_NONBLOCK) ||
3971 (tty->flags & (1 << TTY_IO_ERROR))) {
Jiri Slabyb1d984c2013-03-07 13:12:36 +01003972 info->port.flags |= ASYNC_NORMAL_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973 return 0;
3974 }
3975
Alan Coxadc8d742012-07-14 15:31:47 +01003976 if (tty->termios.c_cflag & CLOCAL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977 do_clocal = 1;
3978 }
3979
3980 /*
3981 * Block waiting for the carrier detect and the line to become
3982 * free (i.e., not in use by the callout). While we are in
3983 * this loop, info->count is dropped by one, so that
3984 * rs_close() knows when to free things. We restore it upon
3985 * exit, either normal or abnormal.
3986 */
3987 retval = 0;
3988 add_wait_queue(&info->open_wait, &wait);
3989#ifdef SERIAL_DEBUG_OPEN
3990 printk("block_til_ready before block: ttyS%d, count = %d\n",
3991 info->line, info->count);
3992#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003993 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003994 if (!tty_hung_up_p(filp)) {
3995 extra_count++;
3996 info->count--;
3997 }
Jesper Nilsson77accbf2007-11-14 17:01:15 -08003998 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999 info->blocked_open++;
4000 while (1) {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004001 local_irq_save(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002 /* assert RTS and DTR */
4003 e100_rts(info, 1);
4004 e100_dtr(info, 1);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004005 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006 set_current_state(TASK_INTERRUPTIBLE);
4007 if (tty_hung_up_p(filp) ||
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004008 !(info->port.flags & ASYNC_INITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009#ifdef SERIAL_DO_RESTART
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004010 if (info->port.flags & ASYNC_HUP_NOTIFY)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004011 retval = -EAGAIN;
4012 else
4013 retval = -ERESTARTSYS;
4014#else
4015 retval = -EAGAIN;
4016#endif
4017 break;
4018 }
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004019 if (!(info->port.flags & ASYNC_CLOSING) && do_clocal)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004020 /* && (do_clocal || DCD_IS_ASSERTED) */
4021 break;
4022 if (signal_pending(current)) {
4023 retval = -ERESTARTSYS;
4024 break;
4025 }
4026#ifdef SERIAL_DEBUG_OPEN
4027 printk("block_til_ready blocking: ttyS%d, count = %d\n",
4028 info->line, info->count);
4029#endif
Alan Cox89c8d912012-08-08 16:30:13 +01004030 tty_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004031 schedule();
Alan Cox89c8d912012-08-08 16:30:13 +01004032 tty_lock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033 }
4034 set_current_state(TASK_RUNNING);
4035 remove_wait_queue(&info->open_wait, &wait);
4036 if (extra_count)
4037 info->count++;
4038 info->blocked_open--;
4039#ifdef SERIAL_DEBUG_OPEN
4040 printk("block_til_ready after blocking: ttyS%d, count = %d\n",
4041 info->line, info->count);
4042#endif
4043 if (retval)
4044 return retval;
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004045 info->port.flags |= ASYNC_NORMAL_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046 return 0;
4047}
4048
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004049static void
4050deinit_port(struct e100_serial *info)
4051{
4052 if (info->dma_out_enabled) {
4053 cris_free_dma(info->dma_out_nbr, info->dma_out_irq_description);
4054 free_irq(info->dma_out_irq_nbr, info);
4055 }
4056 if (info->dma_in_enabled) {
4057 cris_free_dma(info->dma_in_nbr, info->dma_in_irq_description);
4058 free_irq(info->dma_in_irq_nbr, info);
4059 }
4060}
4061
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062/*
4063 * This routine is called whenever a serial port is opened.
4064 * It performs the serial-specific initialization for the tty structure.
4065 */
4066static int
4067rs_open(struct tty_struct *tty, struct file * filp)
4068{
4069 struct e100_serial *info;
Jiri Slaby410235f2012-03-05 14:52:01 +01004070 int retval;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004071 int allocated_resources = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072
Jiri Slaby410235f2012-03-05 14:52:01 +01004073 info = rs_table + tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004074 if (!info->enabled)
4075 return -ENODEV;
4076
4077#ifdef SERIAL_DEBUG_OPEN
4078 printk("[%d] rs_open %s, count = %d\n", current->pid, tty->name,
4079 info->count);
4080#endif
4081
4082 info->count++;
4083 tty->driver_data = info;
Takashi Iwaia88487c2008-07-16 21:54:42 +01004084 info->port.tty = tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004085
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004086 info->port.low_latency = !!(info->port.flags & ASYNC_LOW_LATENCY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004087
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088 /*
4089 * If the port is in the middle of closing, bail out now
4090 */
4091 if (tty_hung_up_p(filp) ||
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004092 (info->port.flags & ASYNC_CLOSING)) {
Alan Cox89c8d912012-08-08 16:30:13 +01004093 wait_event_interruptible_tty(tty, info->close_wait,
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004094 !(info->port.flags & ASYNC_CLOSING));
Linus Torvalds1da177e2005-04-16 15:20:36 -07004095#ifdef SERIAL_DO_RESTART
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004096 return ((info->port.flags & ASYNC_HUP_NOTIFY) ?
Linus Torvalds1da177e2005-04-16 15:20:36 -07004097 -EAGAIN : -ERESTARTSYS);
4098#else
4099 return -EAGAIN;
4100#endif
4101 }
4102
4103 /*
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004104 * If DMA is enabled try to allocate the irq's.
4105 */
4106 if (info->count == 1) {
4107 allocated_resources = 1;
4108 if (info->dma_in_enabled) {
4109 if (request_irq(info->dma_in_irq_nbr,
4110 rec_interrupt,
4111 info->dma_in_irq_flags,
4112 info->dma_in_irq_description,
4113 info)) {
4114 printk(KERN_WARNING "DMA irq '%s' busy; "
4115 "falling back to non-DMA mode\n",
4116 info->dma_in_irq_description);
4117 /* Make sure we never try to use DMA in */
4118 /* for the port again. */
4119 info->dma_in_enabled = 0;
4120 } else if (cris_request_dma(info->dma_in_nbr,
4121 info->dma_in_irq_description,
4122 DMA_VERBOSE_ON_ERROR,
4123 info->dma_owner)) {
4124 free_irq(info->dma_in_irq_nbr, info);
4125 printk(KERN_WARNING "DMA '%s' busy; "
4126 "falling back to non-DMA mode\n",
4127 info->dma_in_irq_description);
4128 /* Make sure we never try to use DMA in */
4129 /* for the port again. */
4130 info->dma_in_enabled = 0;
4131 }
4132#ifdef SERIAL_DEBUG_OPEN
4133 else
4134 printk(KERN_DEBUG "DMA irq '%s' allocated\n",
4135 info->dma_in_irq_description);
4136#endif
4137 }
4138 if (info->dma_out_enabled) {
4139 if (request_irq(info->dma_out_irq_nbr,
4140 tr_interrupt,
4141 info->dma_out_irq_flags,
4142 info->dma_out_irq_description,
4143 info)) {
4144 printk(KERN_WARNING "DMA irq '%s' busy; "
4145 "falling back to non-DMA mode\n",
4146 info->dma_out_irq_description);
4147 /* Make sure we never try to use DMA out */
4148 /* for the port again. */
4149 info->dma_out_enabled = 0;
4150 } else if (cris_request_dma(info->dma_out_nbr,
4151 info->dma_out_irq_description,
4152 DMA_VERBOSE_ON_ERROR,
4153 info->dma_owner)) {
4154 free_irq(info->dma_out_irq_nbr, info);
4155 printk(KERN_WARNING "DMA '%s' busy; "
4156 "falling back to non-DMA mode\n",
4157 info->dma_out_irq_description);
4158 /* Make sure we never try to use DMA out */
4159 /* for the port again. */
4160 info->dma_out_enabled = 0;
4161 }
4162#ifdef SERIAL_DEBUG_OPEN
4163 else
4164 printk(KERN_DEBUG "DMA irq '%s' allocated\n",
4165 info->dma_out_irq_description);
4166#endif
4167 }
4168 }
4169
4170 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171 * Start up the serial port
4172 */
4173
4174 retval = startup(info);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004175 if (retval) {
4176 if (allocated_resources)
4177 deinit_port(info);
4178
4179 /* FIXME Decrease count info->count here too? */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180 return retval;
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004181 }
4182
Linus Torvalds1da177e2005-04-16 15:20:36 -07004183
4184 retval = block_til_ready(tty, filp, info);
4185 if (retval) {
4186#ifdef SERIAL_DEBUG_OPEN
4187 printk("rs_open returning after block_til_ready with %d\n",
4188 retval);
4189#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004190 if (allocated_resources)
4191 deinit_port(info);
4192
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193 return retval;
4194 }
4195
Jiri Slabyb1d984c2013-03-07 13:12:36 +01004196 if ((info->count == 1) && (info->port.flags & ASYNC_SPLIT_TERMIOS)) {
Alan Coxadc8d742012-07-14 15:31:47 +01004197 tty->termios = info->normal_termios;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004198 change_speed(info);
4199 }
4200
4201#ifdef SERIAL_DEBUG_OPEN
4202 printk("rs_open ttyS%d successful...\n", info->line);
4203#endif
4204 DLOG_INT_TRIG( log_int_pos = 0);
4205
4206 DFLIP( if (info->line == SERIAL_DEBUG_LINE) {
4207 info->icount.rx = 0;
4208 } );
4209
4210 return 0;
4211}
4212
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004213#ifdef CONFIG_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214/*
4215 * /proc fs routines....
4216 */
4217
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004218static void seq_line_info(struct seq_file *m, struct e100_serial *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220 unsigned long tmp;
4221
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004222 seq_printf(m, "%d: uart:E100 port:%lX irq:%d",
4223 info->line, (unsigned long)info->ioport, info->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004224
Alan Coxd7283352008-08-04 17:21:18 +01004225 if (!info->ioport || (info->type == PORT_UNKNOWN)) {
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004226 seq_printf(m, "\n");
4227 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 }
4229
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004230 seq_printf(m, " baud:%d", info->baud);
4231 seq_printf(m, " tx:%lu rx:%lu",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232 (unsigned long)info->icount.tx,
4233 (unsigned long)info->icount.rx);
4234 tmp = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004235 if (tmp)
4236 seq_printf(m, " tx_pend:%lu/%lu",
4237 (unsigned long)tmp,
4238 (unsigned long)SERIAL_XMIT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004240 seq_printf(m, " rx_pend:%lu/%lu",
4241 (unsigned long)info->recv_cnt,
4242 (unsigned long)info->max_recv_cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243
4244#if 1
Takashi Iwaia88487c2008-07-16 21:54:42 +01004245 if (info->port.tty) {
Takashi Iwaia88487c2008-07-16 21:54:42 +01004246 if (info->port.tty->stopped)
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004247 seq_printf(m, " stopped:%i",
4248 (int)info->port.tty->stopped);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249 }
4250
4251 {
Alan Coxd7283352008-08-04 17:21:18 +01004252 unsigned char rstat = info->ioport[REG_STATUS];
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004253 if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect))
4254 seq_printf(m, " xoff_detect:1");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255 }
4256
4257#endif
4258
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259 if (info->icount.frame)
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004260 seq_printf(m, " fe:%lu", (unsigned long)info->icount.frame);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261
4262 if (info->icount.parity)
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004263 seq_printf(m, " pe:%lu", (unsigned long)info->icount.parity);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264
4265 if (info->icount.brk)
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004266 seq_printf(m, " brk:%lu", (unsigned long)info->icount.brk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267
4268 if (info->icount.overrun)
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004269 seq_printf(m, " oe:%lu", (unsigned long)info->icount.overrun);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270
4271 /*
4272 * Last thing is the RS-232 status lines
4273 */
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004274 if (!E100_RTS_GET(info))
4275 seq_puts(m, "|RTS");
4276 if (!E100_CTS_GET(info))
4277 seq_puts(m, "|CTS");
4278 if (!E100_DTR_GET(info))
4279 seq_puts(m, "|DTR");
4280 if (!E100_DSR_GET(info))
4281 seq_puts(m, "|DSR");
4282 if (!E100_CD_GET(info))
4283 seq_puts(m, "|CD");
4284 if (!E100_RI_GET(info))
4285 seq_puts(m, "|RI");
4286 seq_puts(m, "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287}
4288
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004290static int crisv10_proc_show(struct seq_file *m, void *v)
4291{
4292 int i;
4293
4294 seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
4295
4296 for (i = 0; i < NR_PORTS; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297 if (!rs_table[i].enabled)
4298 continue;
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004299 seq_line_info(m, &rs_table[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004300 }
4301#ifdef DEBUG_LOG_INCLUDED
4302 for (i = 0; i < debug_log_pos; i++) {
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004303 seq_printf(m, "%-4i %lu.%lu ",
4304 i, debug_log[i].time,
4305 timer_data_to_ns(debug_log[i].timer_data));
4306 seq_printf(m, debug_log[i].string, debug_log[i].value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307 }
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004308 seq_printf(m, "debug_log %i/%i\n", i, DEBUG_LOG_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309 debug_log_pos = 0;
4310#endif
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004311 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312}
4313
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004314static int crisv10_proc_open(struct inode *inode, struct file *file)
4315{
4316 return single_open(file, crisv10_proc_show, NULL);
4317}
4318
4319static const struct file_operations crisv10_proc_fops = {
4320 .owner = THIS_MODULE,
4321 .open = crisv10_proc_open,
4322 .read = seq_read,
4323 .llseek = seq_lseek,
4324 .release = single_release,
4325};
4326#endif
4327
4328
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329/* Finally, routines used to initialize the serial driver. */
4330
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004331static void show_serial_version(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332{
4333 printk(KERN_INFO
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004334 "ETRAX 100LX serial-driver %s, "
4335 "(c) 2000-2004 Axis Communications AB\r\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336 &serial_version[11]); /* "$Revision: x.yy" */
4337}
4338
4339/* rs_init inits the driver at boot (using the module_init chain) */
4340
Jeff Dikeb68e31d2006-10-02 02:17:18 -07004341static const struct tty_operations rs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342 .open = rs_open,
4343 .close = rs_close,
4344 .write = rs_write,
4345 .flush_chars = rs_flush_chars,
4346 .write_room = rs_write_room,
4347 .chars_in_buffer = rs_chars_in_buffer,
4348 .flush_buffer = rs_flush_buffer,
4349 .ioctl = rs_ioctl,
4350 .throttle = rs_throttle,
4351 .unthrottle = rs_unthrottle,
4352 .set_termios = rs_set_termios,
4353 .stop = rs_stop,
4354 .start = rs_start,
4355 .hangup = rs_hangup,
4356 .break_ctl = rs_break,
4357 .send_xchar = rs_send_xchar,
4358 .wait_until_sent = rs_wait_until_sent,
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004359 .tiocmget = rs_tiocmget,
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004360 .tiocmset = rs_tiocmset,
4361#ifdef CONFIG_PROC_FS
4362 .proc_fops = &crisv10_proc_fops,
4363#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364};
4365
Jesper Nilsson9e040a32009-04-30 15:08:13 -07004366static int __init rs_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367{
4368 int i;
4369 struct e100_serial *info;
4370 struct tty_driver *driver = alloc_tty_driver(NR_PORTS);
4371
4372 if (!driver)
4373 return -ENOMEM;
4374
4375 show_serial_version();
4376
4377 /* Setup the timed flush handler system */
4378
4379#if !defined(CONFIG_ETRAX_SERIAL_FAST_TIMER)
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004380 setup_timer(&flush_timer, timed_flush_handler, 0);
4381 mod_timer(&flush_timer, jiffies + 5);
4382#endif
4383
4384#if defined(CONFIG_ETRAX_RS485)
4385#if defined(CONFIG_ETRAX_RS485_ON_PA)
WANG Cong2f7861d2011-09-01 13:58:29 +08004386 if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit,
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004387 rs485_pa_bit)) {
WANG Cong3d43b7d2011-09-01 16:47:49 +08004388 printk(KERN_ERR "ETRAX100LX serial: Could not allocate "
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004389 "RS485 pin\n");
Julia Lawall41ca7322008-10-13 10:31:37 +01004390 put_tty_driver(driver);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004391 return -EBUSY;
4392 }
4393#endif
4394#if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
WANG Cong2f7861d2011-09-01 13:58:29 +08004395 if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit,
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004396 rs485_port_g_bit)) {
WANG Cong3d43b7d2011-09-01 16:47:49 +08004397 printk(KERN_ERR "ETRAX100LX serial: Could not allocate "
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004398 "RS485 pin\n");
Julia Lawall41ca7322008-10-13 10:31:37 +01004399 put_tty_driver(driver);
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004400 return -EBUSY;
4401 }
4402#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403#endif
4404
4405 /* Initialize the tty_driver structure */
4406
4407 driver->driver_name = "serial";
4408 driver->name = "ttyS";
4409 driver->major = TTY_MAJOR;
4410 driver->minor_start = 64;
4411 driver->type = TTY_DRIVER_TYPE_SERIAL;
4412 driver->subtype = SERIAL_TYPE_NORMAL;
4413 driver->init_termios = tty_std_termios;
4414 driver->init_termios.c_cflag =
4415 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
Alan Cox606d0992006-12-08 02:38:45 -08004416 driver->init_termios.c_ispeed = 115200;
4417 driver->init_termios.c_ospeed = 115200;
Jiri Slabyc4d6ebe2012-08-07 21:47:48 +02004418 driver->flags = TTY_DRIVER_REAL_RAW;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004419
4420 tty_set_operations(driver, &rs_ops);
4421 serial_driver = driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004422
Jiri Slabyb19e2ca2012-08-07 21:47:51 +02004423 /* do some initializing for the separate ports */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004424 for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004425 if (info->enabled) {
4426 if (cris_request_io_interface(info->io_if,
4427 info->io_if_description)) {
WANG Cong3d43b7d2011-09-01 16:47:49 +08004428 printk(KERN_ERR "ETRAX100LX async serial: "
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004429 "Could not allocate IO pins for "
4430 "%s, port %d\n",
4431 info->io_if_description, i);
4432 info->enabled = 0;
4433 }
4434 }
Jiri Slaby953756e2012-04-02 13:53:46 +02004435 tty_port_init(&info->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 info->uses_dma_in = 0;
4437 info->uses_dma_out = 0;
4438 info->line = i;
Takashi Iwaia88487c2008-07-16 21:54:42 +01004439 info->port.tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440 info->type = PORT_ETRAX;
4441 info->tr_running = 0;
4442 info->forced_eop = 0;
4443 info->baud_base = DEF_BAUD_BASE;
4444 info->custom_divisor = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004445 info->close_delay = 5*HZ/10;
4446 info->closing_wait = 30*HZ;
4447 info->x_char = 0;
4448 info->event = 0;
4449 info->count = 0;
4450 info->blocked_open = 0;
4451 info->normal_termios = driver->init_termios;
4452 init_waitqueue_head(&info->open_wait);
4453 init_waitqueue_head(&info->close_wait);
4454 info->xmit.buf = NULL;
4455 info->xmit.tail = info->xmit.head = 0;
4456 info->first_recv_buffer = info->last_recv_buffer = NULL;
4457 info->recv_cnt = info->max_recv_cnt = 0;
4458 info->last_tx_active_usec = 0;
4459 info->last_tx_active = 0;
4460
4461#if defined(CONFIG_ETRAX_RS485)
4462 /* Set sane defaults */
Claudio Scordino6fd1af42009-04-07 16:48:19 +01004463 info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);
4464 info->rs485.flags |= SER_RS485_RTS_AFTER_SEND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465 info->rs485.delay_rts_before_send = 0;
Claudio Scordino6fd1af42009-04-07 16:48:19 +01004466 info->rs485.flags &= ~(SER_RS485_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467#endif
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004468 INIT_WORK(&info->work, do_softint);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469
4470 if (info->enabled) {
Kulikov Vasiliy078dee22010-07-14 22:04:42 +04004471 printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n",
4472 serial_driver->name, info->line, info->ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 }
Jiri Slabyb19e2ca2012-08-07 21:47:51 +02004474 tty_port_link_device(&info->port, driver, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 }
Jiri Slabyb19e2ca2012-08-07 21:47:51 +02004476
4477 if (tty_register_driver(driver))
4478 panic("Couldn't register serial driver\n");
4479
Linus Torvalds1da177e2005-04-16 15:20:36 -07004480#ifdef CONFIG_ETRAX_FAST_TIMER
4481#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
4482 memset(fast_timers, 0, sizeof(fast_timers));
4483#endif
4484#ifdef CONFIG_ETRAX_RS485
4485 memset(fast_timers_rs485, 0, sizeof(fast_timers_rs485));
4486#endif
4487 fast_timer_init();
4488#endif
4489
4490#ifndef CONFIG_SVINTO_SIM
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004491#ifndef CONFIG_ETRAX_KGDB
Linus Torvalds1da177e2005-04-16 15:20:36 -07004492 /* Not needed in simulator. May only complicate stuff. */
4493 /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
4494
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004495 if (request_irq(SERIAL_IRQ_NBR, ser_interrupt,
Yong Zhang9cfb5c02011-09-22 16:59:15 +08004496 IRQF_SHARED, "serial ", driver))
Harvey Harrison71cc2c22008-04-30 00:55:10 -07004497 panic("%s: Failed to request irq8", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498
Linus Torvalds1da177e2005-04-16 15:20:36 -07004499#endif
4500#endif /* CONFIG_SVINTO_SIM */
Jesper Nilsson77accbf2007-11-14 17:01:15 -08004501
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 return 0;
4503}
4504
4505/* this makes sure that rs_init is called during kernel boot */
4506
4507module_init(rs_init);