OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [serial_txx9.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  drivers/char/serial_txx9.c
3
 *
4
 *  Copyright (C) 1999 Harald Koerfgen
5
 *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
6
 *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
7
 *  Copyright (C) 2000-2002 Toshiba Corporation
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License version 2 as
11
 * published by the Free Software Foundation.
12
 *
13
 *  Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
14
 */
15
#include <linux/init.h>
16
#include <linux/config.h>
17
#include <linux/tty.h>
18
#include <linux/major.h>
19
#include <linux/ptrace.h>
20
#include <linux/init.h>
21
#include <linux/console.h>
22
#include <linux/fs.h>
23
#include <linux/mm.h>
24
#include <linux/ioport.h>
25
#include <linux/module.h>
26
#include <linux/delay.h>
27
#include <linux/pm.h>
28
#include <asm/io.h>
29
#include <asm/uaccess.h>
30
#include <asm/delay.h>
31
#include <linux/serial.h>
32
#include <linux/generic_serial.h>
33
#include <linux/pci.h>
34
#ifdef CONFIG_MAGIC_SYSRQ
35
#include <linux/sysrq.h>
36
#endif
37
 
38
#define  DEBUG
39
#ifdef  DEBUG
40
#define DBG(x...)       printk(x)
41
#else
42
#define DBG(x...)       
43
#endif
44
 
45
static char *serial_version = "0.30-mvl";
46
static char *serial_name = "TX39/49 Serial driver";
47
 
48
#define GS_INTERNAL_FLAGS (GS_TX_INTEN|GS_RX_INTEN|GS_ACTIVE)
49
 
50
#define TXX9_SERIAL_MAGIC 0x39274927
51
 
52
#ifdef CONFIG_SERIAL
53
/* "ttyS","cua" is used for standard serial driver */
54
#define TXX9_TTY_NAME "ttyTX"
55
#define TXX9_TTY_DEVFS_NAME "tts/TX%d"
56
#define TXX9_TTY_MINOR_START    (64 + 64)       /* ttyTX0(128), ttyTX1(129) */
57
#define TXX9_CU_NAME "cuatx"
58
#define TXX9_CU_DEVFS_NAME "cua/TX%d"
59
#else
60
/* acts like standard serial driver */
61
#define TXX9_TTY_NAME "ttyS"
62
#define TXX9_TTY_DEVFS_NAME "tts/%d"
63
#define TXX9_TTY_MINOR_START    64
64
#define TXX9_CU_NAME "cua"
65
#define TXX9_CU_DEVFS_NAME "cua/%d"
66
#endif
67
#define TXX9_TTY_MAJOR  TTY_MAJOR
68
#define TXX9_TTYAUX_MAJOR       TTYAUX_MAJOR
69
 
70
#define TXX9_SERIAL_HAVE_CTS_LINE       1
71
 
72
#ifdef CONFIG_PCI
73
/* support for Toshiba TC86C001 SIO */
74
#define ENABLE_SERIAL_TXX9_PCI
75
#endif
76
 
77
/*
78
 * Number of serial ports
79
 */
80
#ifdef ENABLE_SERIAL_TXX9_PCI
81
#define NR_PCI_BOARDS   4
82
#define NR_PORTS  (2 + NR_PCI_BOARDS)
83
#else
84
#define NR_PORTS  2
85
#endif
86
 
87
/*
88
 * Hardware specific serial port structure
89
 */
90
static struct rs_port {
91
        struct gs_port          gs;             /* Must be first field! */
92
 
93
        unsigned long           base;
94
        int                     irq;
95
        int                     baud_base;
96
        int                     flags;
97
        struct async_icount     icount;
98
        int                     x_char;         /* XON/XOFF character */
99
        int                     read_status_mask;
100
        int                     ignore_status_mask;
101
        int                     quot;
102
        char                    io_type;
103
#ifdef ENABLE_SERIAL_TXX9_PCI
104
        struct pci_dev *        pci_dev;
105
#endif
106
} rs_ports[NR_PORTS]
107
#ifdef CONFIG_TOSHIBA_RBTX4925
108
= {
109
        /* NR_PORTS = 0 */
110
        {base:          0xff1f0000 + 0xf300,
111
         irq:           36,
112
         baud_base:     40000000 / 16 / 2,
113
         io_type:       -1,             /* virtual memory mapped */
114
         flags:         TXX9_SERIAL_HAVE_CTS_LINE,},
115
        /* NR_PORTS = 1 */
116
        {base:          0xff1f0000 + 0xf400,
117
         irq:           37,
118
         baud_base:     40000000 / 16 / 2,
119
         io_type:       -1,             /* virtual memory mapped */
120
         flags:         TXX9_SERIAL_HAVE_CTS_LINE,}
121
};
122
#endif
123
#ifdef CONFIG_TOSHIBA_RBTX4927
124
= {
125
        /* NR_PORTS = 0 */
126
        {base:          0xff1f0000 + 0xf300,
127
         irq:           32,
128
         baud_base:     50000000 / 16 / 2,
129
         io_type:       -1,             /* virtual memory mapped */
130
         flags:         TXX9_SERIAL_HAVE_CTS_LINE,},
131
        /* NR_PORTS = 1 */
132
        {base:          0xff1f0000 + 0xf400,
133
         irq:           33,
134
         baud_base:     50000000 / 16 / 2,
135
         io_type:       -1,             /* virtual memory mapped */
136
         flags:         TXX9_SERIAL_HAVE_CTS_LINE,}
137
};
138
#endif
139
 
140
/* TXX9 Serial Registers */
141
#define TXX9_SILCR      0x00
142
#define TXX9_SIDICR     0x04
143
#define TXX9_SIDISR     0x08
144
#define TXX9_SICISR     0x0c
145
#define TXX9_SIFCR      0x10
146
#define TXX9_SIFLCR     0x14
147
#define TXX9_SIBGR      0x18
148
#define TXX9_SITFIFO    0x1c
149
#define TXX9_SIRFIFO    0x20
150
 
151
/* SILCR : Line Control */
152
#define TXX9_SILCR_SCS_MASK     0x00000060
153
#define TXX9_SILCR_SCS_IMCLK    0x00000000
154
#define TXX9_SILCR_SCS_IMCLK_BG 0x00000020
155
#define TXX9_SILCR_SCS_SCLK     0x00000040
156
#define TXX9_SILCR_SCS_SCLK_BG  0x00000060
157
#define TXX9_SILCR_UEPS 0x00000010
158
#define TXX9_SILCR_UPEN 0x00000008
159
#define TXX9_SILCR_USBL_MASK    0x00000004
160
//#define TXX9_SILCR_USBL_1BIT  0x00000004
161
//#define TXX9_SILCR_USBL_2BIT  0x00000000
162
#define TXX9_SILCR_USBL_1BIT    0x00000000
163
#define TXX9_SILCR_USBL_2BIT    0x00000004
164
#define TXX9_SILCR_UMODE_MASK   0x00000003
165
#define TXX9_SILCR_UMODE_8BIT   0x00000000
166
#define TXX9_SILCR_UMODE_7BIT   0x00000001
167
 
168
/* SIDICR : DMA/Int. Control */
169
#define TXX9_SIDICR_TDE 0x00008000
170
#define TXX9_SIDICR_RDE 0x00004000
171
#define TXX9_SIDICR_TIE 0x00002000
172
#define TXX9_SIDICR_RIE 0x00001000
173
#define TXX9_SIDICR_SPIE        0x00000800
174
#define TXX9_SIDICR_CTSAC       0x00000600
175
#define TXX9_SIDICR_STIE_MASK   0x0000003f
176
#define TXX9_SIDICR_STIE_OERS           0x00000020
177
#define TXX9_SIDICR_STIE_CTSS           0x00000010
178
#define TXX9_SIDICR_STIE_RBRKD  0x00000008
179
#define TXX9_SIDICR_STIE_TRDY           0x00000004
180
#define TXX9_SIDICR_STIE_TXALS  0x00000002
181
#define TXX9_SIDICR_STIE_UBRKD  0x00000001
182
 
183
/* SIDISR : DMA/Int. Status */
184
#define TXX9_SIDISR_UBRK        0x00008000
185
#define TXX9_SIDISR_UVALID      0x00004000
186
#define TXX9_SIDISR_UFER        0x00002000
187
#define TXX9_SIDISR_UPER        0x00001000
188
#define TXX9_SIDISR_UOER        0x00000800
189
#define TXX9_SIDISR_ERI 0x00000400
190
#define TXX9_SIDISR_TOUT        0x00000200
191
#define TXX9_SIDISR_TDIS        0x00000100
192
#define TXX9_SIDISR_RDIS        0x00000080
193
#define TXX9_SIDISR_STIS        0x00000040
194
#define TXX9_SIDISR_RFDN_MASK   0x0000001f
195
 
196
/* SICISR : Change Int. Status */
197
#define TXX9_SICISR_OERS        0x00000020
198
#define TXX9_SICISR_CTSS        0x00000010
199
#define TXX9_SICISR_RBRKD       0x00000008
200
#define TXX9_SICISR_TRDY        0x00000004
201
#define TXX9_SICISR_TXALS       0x00000002
202
#define TXX9_SICISR_UBRKD       0x00000001
203
 
204
/* SIFCR : FIFO Control */
205
#define TXX9_SIFCR_SWRST        0x00008000
206
#define TXX9_SIFCR_RDIL_MASK    0x00000180
207
#define TXX9_SIFCR_RDIL_1       0x00000000
208
#define TXX9_SIFCR_RDIL_4       0x00000080
209
#define TXX9_SIFCR_RDIL_8       0x00000100
210
#define TXX9_SIFCR_RDIL_12      0x00000180
211
#define TXX9_SIFCR_RDIL_MAX     0x00000180
212
#define TXX9_SIFCR_TDIL_MASK    0x00000018
213
#define TXX9_SIFCR_TDIL_MASK    0x00000018
214
#define TXX9_SIFCR_TDIL_1       0x00000000
215
#define TXX9_SIFCR_TDIL_4       0x00000001
216
#define TXX9_SIFCR_TDIL_8       0x00000010
217
#define TXX9_SIFCR_TDIL_MAX     0x00000010
218
#define TXX9_SIFCR_TFRST        0x00000004
219
#define TXX9_SIFCR_RFRST        0x00000002
220
#define TXX9_SIFCR_FRSTE        0x00000001
221
#define TXX9_SIO_TX_FIFO        8
222
#define TXX9_SIO_RX_FIFO        16
223
 
224
/* SIFLCR : Flow Control */
225
#define TXX9_SIFLCR_RCS 0x00001000
226
#define TXX9_SIFLCR_TES 0x00000800
227
#define TXX9_SIFLCR_RTSSC       0x00000200
228
#define TXX9_SIFLCR_RSDE        0x00000100
229
#define TXX9_SIFLCR_TSDE        0x00000080
230
#define TXX9_SIFLCR_RTSTL_MASK  0x0000001e
231
#define TXX9_SIFLCR_RTSTL_MAX   0x0000001e
232
#define TXX9_SIFLCR_TBRK        0x00000001
233
 
234
/* SIBGR : Baudrate Control */
235
#define TXX9_SIBGR_BCLK_MASK    0x00000300
236
#define TXX9_SIBGR_BCLK_T0      0x00000000
237
#define TXX9_SIBGR_BCLK_T2      0x00000100
238
#define TXX9_SIBGR_BCLK_T4      0x00000200
239
#define TXX9_SIBGR_BCLK_T6      0x00000300
240
#define TXX9_SIBGR_BRD_MASK     0x000000ff
241
 
242
static /*inline*/ unsigned int
243
sio_in(struct rs_port *port, int offset)
244
{
245
        if (port->io_type < 0)
246
                /* don't use __raw_readl that does swapping for big endian */
247
                return (*(volatile unsigned long*)(port->base + offset));
248
        else
249
                return inl(port->base + offset);
250
}
251
 
252
static /*inline*/ void
253
sio_out(struct rs_port *port, int offset, unsigned int value)
254
{
255
        if (port->io_type < 0)
256
                /* don't use __raw_writel that does swapping for big endian */
257
                (*(volatile unsigned long*)(port->base + offset))=(value);
258
        else
259
                outl(value, port->base + offset);
260
}
261
 
262
static inline void
263
sio_mask(struct rs_port *port, int offset, unsigned int value)
264
{
265
        sio_out(port, offset, sio_in(port, offset) & ~value);
266
}
267
static inline void
268
sio_set(struct rs_port *port, int offset, unsigned int value)
269
{
270
        sio_out(port, offset, sio_in(port, offset) | value);
271
}
272
 
273
/*
274
 * Forward declarations for serial routines
275
 */
276
static void rs_disable_tx_interrupts (void * ptr);
277
static void rs_enable_tx_interrupts (void * ptr);
278
static void rs_disable_rx_interrupts (void * ptr);
279
static void rs_enable_rx_interrupts (void * ptr);
280
static int rs_get_CD (void * ptr);
281
static void rs_shutdown_port (void * ptr);
282
static int rs_set_real_termios (void *ptr);
283
static int rs_chars_in_buffer (void * ptr);
284
static void rs_hungup (void *ptr);
285
static void rs_getserial (void*, struct serial_struct *sp);
286
static void rs_close (void *ptr);
287
 
288
/*
289
 * Used by generic serial driver to access hardware
290
 */
291
static struct real_driver rs_real_driver = {
292
        disable_tx_interrupts: rs_disable_tx_interrupts,
293
        enable_tx_interrupts:  rs_enable_tx_interrupts,
294
        disable_rx_interrupts: rs_disable_rx_interrupts,
295
        enable_rx_interrupts:  rs_enable_rx_interrupts,
296
        get_CD:                rs_get_CD,
297
        shutdown_port:         rs_shutdown_port,
298
        set_real_termios:      rs_set_real_termios,
299
        chars_in_buffer:       rs_chars_in_buffer,
300
        close:                 rs_close,
301
        hungup:                rs_hungup,
302
        getserial:             rs_getserial,
303
};
304
 
305
/*
306
 * Structures and such for TTY sessions and usage counts
307
 */
308
static struct tty_driver rs_driver, rs_callout_driver;
309
static struct tty_struct *rs_table[NR_PORTS];
310
static struct termios *rs_termios[NR_PORTS];
311
static struct termios *rs_termios_locked[NR_PORTS];
312
int rs_refcount;
313
int rs_initialized = 0;
314
 
315
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
316
static struct console sercons;
317
#endif
318
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
319
static unsigned long break_pressed; /* break, really ... */
320
#endif
321
 
322
static inline void receive_chars(struct rs_port *port,
323
                                 int *status, struct pt_regs *regs)
324
{
325
        struct tty_struct *tty = port->gs.tty;
326
        unsigned char ch;
327
        struct  async_icount *icount;
328
        int     max_count = 256;
329
 
330
        icount = &port->icount;
331
        do {
332
                if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
333
                        tty->flip.tqueue.routine((void *) tty);
334
                        if (tty->flip.count >= TTY_FLIPBUF_SIZE)
335
                                return;         // if TTY_DONT_FLIP is set
336
                }
337
                ch = sio_in(port, TXX9_SIRFIFO);
338
                *tty->flip.char_buf_ptr = ch;
339
                icount->rx++;
340
 
341
                *tty->flip.flag_buf_ptr = 0;
342
                if (*status & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER |
343
                               TXX9_SIDISR_UFER | TXX9_SIDISR_UOER)) {
344
                        /*
345
                         * For statistics only
346
                         */
347
                        if (*status & TXX9_SIDISR_UBRK) {
348
                                *status &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER);
349
                                icount->brk++;
350
                                /*
351
                                 * We do the SysRQ and SAK checking
352
                                 * here because otherwise the break
353
                                 * may get masked by ignore_status_mask
354
                                 * or read_status_mask.
355
                                 */
356
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
357
                                if (port == &rs_ports[sercons.index]) {
358
                                        if (!break_pressed) {
359
                                                break_pressed = jiffies;
360
                                                goto ignore_char;
361
                                        }
362
                                        break_pressed = 0;
363
                                }
364
#endif
365
                                if (port->gs.flags & ASYNC_SAK)
366
                                        do_SAK(tty);
367
                        } else if (*status & TXX9_SIDISR_UPER)
368
                                icount->parity++;
369
                        else if (*status & TXX9_SIDISR_UFER)
370
                                icount->frame++;
371
                        if (*status & TXX9_SIDISR_UOER)
372
                                icount->overrun++;
373
 
374
                        /*
375
                         * Mask off conditions which should be ignored.
376
                         */
377
                        *status &= port->read_status_mask;
378
 
379
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
380
                        /* Break flag is updated by reading RFIFO. */
381
#endif
382
                        if (*status & (TXX9_SIDISR_UBRK)) {
383
                                *tty->flip.flag_buf_ptr = TTY_BREAK;
384
                        } else if (*status & TXX9_SIDISR_UPER)
385
                                *tty->flip.flag_buf_ptr = TTY_PARITY;
386
                        else if (*status & TXX9_SIDISR_UFER)
387
                                *tty->flip.flag_buf_ptr = TTY_FRAME;
388
                }
389
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
390
                if (break_pressed && port == &rs_ports[sercons.index]) {
391
                        if (ch != 0 &&
392
                            time_before(jiffies, break_pressed + HZ*5)) {
393
                                handle_sysrq(ch, regs, NULL, NULL);
394
                                break_pressed = 0;
395
                                goto ignore_char;
396
                        }
397
                        break_pressed = 0;
398
                }
399
#endif
400
                if ((*status & port->ignore_status_mask) == 0) {
401
                        tty->flip.flag_buf_ptr++;
402
                        tty->flip.char_buf_ptr++;
403
                        tty->flip.count++;
404
                }
405
                if ((*status & TXX9_SIDISR_UOER) &&
406
                    (tty->flip.count < TTY_FLIPBUF_SIZE)) {
407
                        /*
408
                         * Overrun is special, since it's reported
409
                         * immediately, and doesn't affect the current
410
                         * character
411
                         */
412
                        *tty->flip.flag_buf_ptr = TTY_OVERRUN;
413
                        tty->flip.count++;
414
                        tty->flip.flag_buf_ptr++;
415
                        tty->flip.char_buf_ptr++;
416
                }
417
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
418
        ignore_char:
419
#endif
420
                *status = sio_in(port, TXX9_SIDISR);
421
        } while ((!(*status & TXX9_SIDISR_UVALID)) && (max_count-- > 0));
422
        tty_flip_buffer_push(tty);
423
}
424
 
425
static inline void transmit_chars(struct rs_port *port)
426
{
427
        int count;
428
 
429
        if (port->x_char) {
430
                sio_out(port, TXX9_SITFIFO, port->x_char);
431
                port->icount.tx++;
432
                port->x_char = 0;
433
                return;
434
        }
435
        if (port->gs.xmit_cnt <= 0
436
            || port->gs.tty->stopped
437
            || port->gs.tty->hw_stopped) {
438
                rs_disable_tx_interrupts(port);
439
                return;
440
        }
441
 
442
        count = TXX9_SIO_TX_FIFO;
443
        do {
444
                sio_out(port, TXX9_SITFIFO, port->gs.xmit_buf[port->gs.xmit_tail++]);
445
                port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
446
                port->icount.tx++;
447
                if (--port->gs.xmit_cnt <= 0)
448
                        break;
449
        } while (--count > 0);
450
 
451
        if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
452
             port->gs.tty->hw_stopped) {
453
                rs_disable_tx_interrupts(port);
454
        }
455
 
456
        if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
457
                if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
458
                    port->gs.tty->ldisc.write_wakeup)
459
                        (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
460
                wake_up_interruptible(&port->gs.tty->write_wait);
461
        }
462
}
463
 
464
static inline void check_modem_status(struct rs_port *port)
465
{
466
        /* We don't have a carrier detect line - but just respond
467
           like we had one anyways so that open() becomes unblocked */
468
        wake_up_interruptible(&port->gs.open_wait);
469
}
470
 
471
#define RS_ISR_PASS_LIMIT 256
472
 
473
static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
474
{
475
        struct rs_port * port = (struct rs_port *)dev_id;
476
        unsigned long flags;
477
        int status;
478
        int pass_counter = 0;
479
 
480
        local_irq_save(flags);
481
 
482
        if (!port || !port->gs.tty) {
483
                local_irq_restore(flags);
484
                return;
485
        }
486
 
487
        do {
488
                status = sio_in(port, TXX9_SIDISR);
489
                if (!(sio_in(port, TXX9_SIDICR) & TXX9_SIDICR_TIE))
490
                        status &= ~TXX9_SIDISR_TDIS;
491
                if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
492
                                TXX9_SIDISR_TOUT)))
493
                        break;
494
 
495
                if (status & TXX9_SIDISR_RDIS)
496
                        receive_chars(port, &status, regs);
497
#if 0           /* RTS/CTS are controled by HW. (if possible) */
498
                check_modem_status(port);
499
#endif
500
                if (status & TXX9_SIDISR_TDIS)
501
                        transmit_chars(port);
502
                /* Clear TX/RX Int. Status */
503
                sio_mask(port, TXX9_SIDISR,
504
                         TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
505
                         TXX9_SIDISR_TOUT);
506
 
507
                if (pass_counter++ > RS_ISR_PASS_LIMIT) {
508
                        break;
509
                }
510
        } while (1);
511
        local_irq_restore(flags);
512
}
513
 
514
/*
515
 ***********************************************************************
516
 *                Here are the routines that actually                  *
517
 *              interface with the generic_serial driver               *
518
 ***********************************************************************
519
 */
520
static void rs_disable_tx_interrupts (void * ptr)
521
{
522
        struct rs_port *port = ptr;
523
        unsigned long flags;
524
 
525
        local_irq_save(flags);
526
        port->gs.flags &= ~GS_TX_INTEN;
527
        sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_TIE);
528
        local_irq_restore(flags);
529
}
530
 
531
static void rs_enable_tx_interrupts (void * ptr)
532
{
533
        struct rs_port *port = ptr;
534
        unsigned long flags;
535
 
536
        local_irq_save(flags);
537
        sio_set(port, TXX9_SIDICR, TXX9_SIDICR_TIE);
538
        local_irq_restore(flags);
539
}
540
 
541
static void rs_disable_rx_interrupts (void * ptr)
542
{
543
        struct rs_port *port = ptr;
544
        unsigned long flags;
545
 
546
        local_irq_save(flags);
547
        port->read_status_mask &= ~TXX9_SIDISR_RDIS;
548
#if 0
549
        sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_RIE);
550
#endif
551
        local_irq_restore(flags);
552
}
553
 
554
static void rs_enable_rx_interrupts (void * ptr)
555
{
556
        struct rs_port *port = ptr;
557
        sio_set(port, TXX9_SIDICR, TXX9_SIDICR_RIE);
558
}
559
 
560
 
561
static int rs_get_CD (void * ptr)
562
{
563
        /* No Carried Detect in Hardware - just return true */
564
        return (1);
565
}
566
 
567
static void rs_shutdown_port (void * ptr)
568
{
569
        struct rs_port *port = ptr;
570
 
571
        port->gs.flags &= ~GS_ACTIVE;
572
 
573
        free_irq(port->irq, port);
574
        sio_out(port, TXX9_SIDICR, 0);   /* disable all intrs */
575
        /* disable break condition */
576
        sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
577
 
578
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
579
        if (port == &rs_ports[sercons.index]) {
580
#endif
581
        if (!port->gs.tty || (port->gs.tty->termios->c_cflag & HUPCL)) {
582
                /* drop RTS */
583
                sio_set(port, TXX9_SIFLCR,
584
                        TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
585
                /* TXX9-SIO can not control DTR... */
586
        }
587
 
588
        /* reset FIFO's */
589
        sio_set(port, TXX9_SIFCR,
590
                TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
591
        /* clear reset */
592
        sio_mask(port, TXX9_SIFCR,
593
                 TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
594
        /* Disable RX/TX */
595
        sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
596
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
597
        }
598
#endif
599
}
600
 
601
static int rs_set_real_termios (void *ptr)
602
{
603
        struct rs_port *port = ptr;
604
        int     quot = 0, baud_base, baud;
605
        unsigned cflag, cval, fcr = 0;
606
        int     bits;
607
        unsigned long   flags;
608
 
609
        if (!port->gs.tty || !port->gs.tty->termios)
610
                return 0;
611
        cflag = port->gs.tty->termios->c_cflag;
612
        cval = sio_in(port, TXX9_SILCR);
613
        /* byte size and parity */
614
        cval &= ~TXX9_SILCR_UMODE_MASK;
615
        switch (cflag & CSIZE) {
616
        case CS7:
617
                cval |= TXX9_SILCR_UMODE_7BIT;
618
                bits = 9;
619
                break;
620
        case CS5:       /* not supported */
621
        case CS6:       /* not supported */
622
        case CS8:
623
        default:
624
                cval |= TXX9_SILCR_UMODE_8BIT;
625
                bits = 10;
626
                break;
627
        }
628
        cval &= ~TXX9_SILCR_USBL_MASK;
629
        if (cflag & CSTOPB) {
630
                cval |= TXX9_SILCR_USBL_2BIT;
631
                bits++;
632
        } else {
633
                cval |= TXX9_SILCR_USBL_1BIT;
634
        }
635
 
636
        cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS);
637
        if (cflag & PARENB) {
638
                cval |= TXX9_SILCR_UPEN;
639
                bits++;
640
        }
641
        if (!(cflag & PARODD))
642
                cval |= TXX9_SILCR_UEPS;
643
 
644
        /* Determine divisor based on baud rate */
645
        baud = tty_get_baud_rate(port->gs.tty);
646
        if (!baud)
647
                baud = 9600;    /* B0 transition handled in rs_set_termios */
648
        baud_base = port->baud_base;
649
        quot = (baud_base + baud / 2) / baud;
650
        /* As a last resort, if the quotient is zero, default to 9600 bps */
651
        if (!quot)
652
                quot = (baud_base + 9600 / 2) / 9600;
653
        port->quot = quot;
654
 
655
        /* Set up FIFO's */
656
        /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
657
        fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1;
658
 
659
        /* CTS flow control flag */
660
        if (cflag & CRTSCTS) {
661
                port->gs.flags |= ASYNC_CTS_FLOW;
662
                if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE)
663
                        sio_out(port, TXX9_SIFLCR,
664
                                TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES |
665
                                TXX9_SIFLCR_RTSTL_MAX /* 15 */);
666
        } else {
667
                port->gs.flags &= ~ASYNC_CTS_FLOW;
668
                sio_mask(port, TXX9_SIFLCR,
669
                         TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES |
670
                         TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
671
        }
672
 
673
        /*
674
         * Set up parity check flag
675
         */
676
#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
677
 
678
        port->read_status_mask = TXX9_SIDISR_UOER |
679
                TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS;
680
        if (I_INPCK(port->gs.tty))
681
                port->read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER;
682
        if (I_BRKINT(port->gs.tty) || I_PARMRK(port->gs.tty))
683
                port->read_status_mask |= TXX9_SIDISR_UBRK;
684
 
685
        /*
686
         * Characters to ignore
687
         */
688
        port->ignore_status_mask = 0;
689
        if (I_IGNPAR(port->gs.tty))
690
                port->ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER;
691
        if (I_IGNBRK(port->gs.tty)) {
692
                port->ignore_status_mask |= TXX9_SIDISR_UBRK;
693
                /*
694
                 * If we're ignore parity and break indicators, ignore
695
                 * overruns too.  (For real raw support).
696
                 */
697
                if (I_IGNPAR(port->gs.tty))
698
                        port->ignore_status_mask |= TXX9_SIDISR_UOER;
699
        }
700
#if 0   /* XXX: This cause problem with some programs(init, mingetty, etc) */
701
        /*
702
         * !!! ignore all characters if CREAD is not set
703
         */
704
        if ((cflag & CREAD) == 0)
705
                port->ignore_status_mask |= TXX9_SIDISR_RDIS;
706
#endif
707
        local_irq_save(flags);
708
        cval &= ~TXX9_SILCR_SCS_IMCLK;
709
        sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG);
710
        sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0);
711
        sio_out(port, TXX9_SIFCR, fcr);
712
        local_irq_restore(flags);
713
        return 0;
714
}
715
 
716
static int rs_chars_in_buffer (void * ptr)
717
{
718
        struct rs_port *port = ptr;
719
 
720
        /* return 0 if transmitter disabled. */
721
        if (sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_TSDE)
722
                return 0;
723
        return (sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS) ? 0 : 1;
724
}
725
 
726
/* ********************************************************************** *
727
 *                Here are the routines that actually                     *
728
 *               interface with the rest of the system                    *
729
 * ********************************************************************** */
730
static int rs_open (struct tty_struct * tty, struct file * filp)
731
{
732
        struct rs_port *port;
733
        int retval, line;
734
 
735
        if (!rs_initialized) {
736
                return -EIO;
737
        }
738
 
739
        line = MINOR(tty->device) - tty->driver.minor_start;
740
 
741
        if ((line < 0) || (line >= NR_PORTS))
742
                return -ENODEV;
743
 
744
        /* Pre-initialized already */
745
        port = & rs_ports[line];
746
 
747
        if (!port->base)
748
                return -ENODEV;
749
 
750
        tty->driver_data = port;
751
        port->gs.tty = tty;
752
        port->gs.count++;
753
 
754
        /*
755
         * Start up serial port
756
         */
757
        retval = gs_init_port(&port->gs);
758
        if (retval) {
759
                port->gs.count--;
760
                return retval;
761
        }
762
 
763
        port->gs.flags |= GS_ACTIVE;
764
 
765
        if (port->gs.count == 1) {
766
                MOD_INC_USE_COUNT;
767
 
768
                /*
769
                 * Clear the FIFO buffers and disable them
770
                 * (they will be reenabled in rs_set_real_termios())
771
                 */
772
                sio_set(port, TXX9_SIFCR,
773
                        TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST |
774
                        TXX9_SIFCR_FRSTE);
775
                /* clear reset */
776
                sio_mask(port, TXX9_SIFCR,
777
                         TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST |
778
                         TXX9_SIFCR_FRSTE);
779
                sio_out(port, TXX9_SIDICR, 0);
780
 
781
                retval = request_irq(port->irq, rs_interrupt, SA_SHIRQ,
782
                                     "serial_txx9", port);
783
                if (retval) {
784
                        printk(KERN_ERR "serial_txx9: request_irq: err %d\n",
785
                               retval);
786
                        MOD_DEC_USE_COUNT;
787
                        port->gs.count--;
788
                        return retval;
789
                }
790
                /*
791
                 * Clear the interrupt registers.
792
                 */
793
                sio_out(port, TXX9_SIDISR, 0);
794
 
795
                /* HW RTS/CTS control */
796
                if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE)
797
                        sio_out(port, TXX9_SIFLCR,
798
                                TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES |
799
                                TXX9_SIFLCR_RTSTL_MAX /* 15 */);
800
        }
801
 
802
        /* Enable RX/TX */
803
        sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
804
 
805
        /*
806
         * Finally, enable interrupts
807
         */
808
        rs_enable_rx_interrupts(port);
809
 
810
        /*
811
         * and set the speed of the serial port
812
         */
813
        rs_set_real_termios(port);
814
 
815
        retval = gs_block_til_ready(&port->gs, filp);
816
 
817
        if (retval) {
818
                if (port->gs.count == 1) {
819
                        free_irq(port->irq, port);
820
                        MOD_DEC_USE_COUNT;
821
                }
822
                port->gs.count--;
823
                return retval;
824
        }
825
        /* tty->low_latency = 1; */
826
 
827
        if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
828
                if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
829
                        *tty->termios = port->gs.normal_termios;
830
                else
831
                        *tty->termios = port->gs.callout_termios;
832
                rs_set_real_termios(port);
833
        }
834
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
835
        if (sercons.cflag && sercons.index == line) {
836
                tty->termios->c_cflag = sercons.cflag;
837
                sercons.cflag = 0;
838
                rs_set_real_termios(port);
839
        }
840
#endif
841
        port->gs.session = current->session;
842
        port->gs.pgrp = current->pgrp;
843
        return 0;
844
}
845
 
846
/*
847
 * /proc fs routines....
848
 */
849
 
850
static inline int line_info(char *buf, struct rs_port *port)
851
{
852
        char    stat_buf[30];
853
        int     ret;
854
        unsigned long flags;
855
 
856
        ret = sprintf(buf, "%d: uart:txx9 io%s:%lx irq:%d",
857
                      port - &rs_ports[0],
858
                      port->io_type < 0 ? "mem" : "port",
859
                      port->base, port->irq);
860
 
861
        if (!port->base) {
862
                ret += sprintf(buf+ret, "\n");
863
                return ret;
864
        }
865
 
866
        /*
867
         * Figure out the current RS-232 lines
868
         */
869
        stat_buf[0] = 0;
870
        stat_buf[1] = 0;
871
        local_irq_save(flags);
872
        if (!(sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC))
873
                strcat(stat_buf, "|RTS");
874
        if (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS))
875
                strcat(stat_buf, "|CTS");
876
        local_irq_restore(flags);
877
 
878
        if (port->quot) {
879
                ret += sprintf(buf+ret, " baud:%d",
880
                               port->baud_base / port->quot);
881
        }
882
 
883
        ret += sprintf(buf+ret, " tx:%d rx:%d",
884
                       port->icount.tx, port->icount.rx);
885
 
886
        if (port->icount.frame)
887
                ret += sprintf(buf+ret, " fe:%d", port->icount.frame);
888
 
889
        if (port->icount.parity)
890
                ret += sprintf(buf+ret, " pe:%d", port->icount.parity);
891
 
892
        if (port->icount.brk)
893
                ret += sprintf(buf+ret, " brk:%d", port->icount.brk);
894
 
895
        if (port->icount.overrun)
896
                ret += sprintf(buf+ret, " oe:%d", port->icount.overrun);
897
 
898
        /*
899
         * Last thing is the RS-232 status lines
900
         */
901
        ret += sprintf(buf+ret, " %s\n", stat_buf+1);
902
        return ret;
903
}
904
 
905
static int rs_read_proc(char *page, char **start, off_t off, int count,
906
                        int *eof, void *data)
907
{
908
        int i, len = 0, l;
909
        off_t   begin = 0;
910
 
911
        len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
912
        for (i = 0; i < NR_PORTS && len < 4000; i++) {
913
                l = line_info(page + len, &rs_ports[i]);
914
                len += l;
915
                if (len+begin > off+count)
916
                        goto done;
917
                if (len+begin < off) {
918
                        begin += len;
919
                        len = 0;
920
                }
921
        }
922
        *eof = 1;
923
done:
924
        if (off >= len+begin)
925
                return 0;
926
        *start = page + (begin-off);
927
        return ((count < begin+len-off) ? count : begin+len-off);
928
}
929
 
930
static void rs_close (void *ptr)
931
{
932
#if 0
933
        struct rs_port *port = ptr;
934
        free_irq(port->irq, port);
935
#endif
936
        MOD_DEC_USE_COUNT;
937
}
938
 
939
/* I haven't the foggiest why the decrement use count has to happen
940
   here. The whole linux serial drivers stuff needs to be redesigned.
941
   My guess is that this is a hack to minimize the impact of a bug
942
   elsewhere. Thinking about it some more. (try it sometime) Try
943
   running minicom on a serial port that is driven by a modularized
944
   driver. Have the modem hangup. Then remove the driver module. Then
945
   exit minicom.  I expect an "oops".  -- REW */
946
static void rs_hungup (void *ptr)
947
{
948
        MOD_DEC_USE_COUNT;
949
}
950
 
951
static void rs_getserial (void *ptr, struct serial_struct *sp)
952
{
953
        struct rs_port *port = ptr;
954
        struct tty_struct *tty = port->gs.tty;
955
        /* some applications (busybox, dbootstrap, etc.) look this */
956
        sp->line = MINOR(tty->device) - tty->driver.minor_start;
957
}
958
 
959
/*
960
 * rs_break() --- routine which turns the break handling on or off
961
 */
962
static void rs_break(struct tty_struct *tty, int break_state)
963
{
964
        struct rs_port *port = tty->driver_data;
965
        unsigned long flags;
966
 
967
        if (!port->base)
968
                return;
969
        local_irq_save(flags);
970
        if (break_state == -1)
971
                sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
972
        else
973
                sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
974
        local_irq_restore(flags);
975
}
976
 
977
static int get_modem_info(struct rs_port *port, unsigned int *value)
978
{
979
        unsigned int result;
980
        unsigned long flags;
981
 
982
        local_irq_save(flags);
983
        result =  ((sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
984
                | ((sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
985
        local_irq_restore(flags);
986
        return put_user(result,value);
987
}
988
 
989
static int set_modem_info(struct rs_port *port, unsigned int cmd,
990
                          unsigned int *value)
991
{
992
        int error = 0;
993
        unsigned int arg;
994
        unsigned long flags;
995
 
996
        if (copy_from_user(&arg, value, sizeof(int)))
997
                return -EFAULT;
998
 
999
        local_irq_save(flags);
1000
        switch (cmd) {
1001
        case TIOCMBIS:
1002
                if (arg & TIOCM_RTS)
1003
                        sio_mask(port, TXX9_SIFLCR,
1004
                                 TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
1005
                break;
1006
        case TIOCMBIC:
1007
                if (arg & TIOCM_RTS)
1008
                        sio_set(port, TXX9_SIFLCR,
1009
                                TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
1010
                break;
1011
        case TIOCMSET:
1012
                if (arg & TIOCM_RTS)
1013
                        sio_mask(port, TXX9_SIFLCR,
1014
                                 TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
1015
                else
1016
                        sio_set(port, TXX9_SIFLCR,
1017
                                TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
1018
                break;
1019
        default:
1020
                error = -EINVAL;
1021
        }
1022
        local_irq_restore(flags);
1023
        return error;
1024
}
1025
 
1026
static int rs_ioctl (struct tty_struct * tty, struct file * filp,
1027
                     unsigned int cmd, unsigned long arg)
1028
{
1029
        int rc;
1030
        struct rs_port *port = tty->driver_data;
1031
        int ival;
1032
 
1033
        rc = 0;
1034
        switch (cmd) {
1035
        case TIOCMGET:
1036
                return get_modem_info(port, (unsigned int *) arg);
1037
        case TIOCMBIS:
1038
        case TIOCMBIC:
1039
        case TIOCMSET:
1040
                return set_modem_info(port, cmd, (unsigned int *) arg);
1041
                return 0;
1042
        case TIOCGSOFTCAR:
1043
                rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
1044
                              (unsigned int *) arg);
1045
                break;
1046
        case TIOCSSOFTCAR:
1047
                if ((rc = verify_area(VERIFY_READ, (void *) arg,
1048
                                      sizeof(int))) == 0) {
1049
                        get_user(ival, (unsigned int *) arg);
1050
                        tty->termios->c_cflag =
1051
                                (tty->termios->c_cflag & ~CLOCAL) |
1052
                                (ival ? CLOCAL : 0);
1053
                }
1054
                break;
1055
        case TIOCGSERIAL:
1056
                if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1057
                                      sizeof(struct serial_struct))) == 0)
1058
                        rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
1059
                break;
1060
        case TIOCSSERIAL:
1061
                if ((rc = verify_area(VERIFY_READ, (void *) arg,
1062
                                      sizeof(struct serial_struct))) == 0)
1063
                        rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
1064
                break;
1065
        default:
1066
                rc = -ENOIOCTLCMD;
1067
                break;
1068
        }
1069
 
1070
        return rc;
1071
}
1072
 
1073
 
1074
/*
1075
 * This function is used to send a high-priority XON/XOFF character to
1076
 * the device
1077
 */
1078
static void rs_send_xchar(struct tty_struct * tty, char ch)
1079
{
1080
        struct rs_port *port = (struct rs_port *)tty->driver_data;
1081
 
1082
        port->x_char = ch;
1083
        if (ch) {
1084
                /* Make sure transmit interrupts are on */
1085
                rs_enable_tx_interrupts(tty);
1086
        }
1087
}
1088
 
1089
 
1090
/*
1091
 * ------------------------------------------------------------
1092
 * rs_throttle()
1093
 *
1094
 * This routine is called by the upper-layer tty layer to signal that
1095
 * incoming characters should be throttled.
1096
 * ------------------------------------------------------------
1097
 */
1098
static void rs_throttle(struct tty_struct * tty)
1099
{
1100
        struct rs_port *port = (struct rs_port *)tty->driver_data;
1101
        unsigned long flags;
1102
 
1103
        if (I_IXOFF(tty))
1104
                rs_send_xchar(tty, STOP_CHAR(tty));
1105
        if (tty->termios->c_cflag & CRTSCTS) {
1106
                local_irq_save(flags);
1107
                /* drop RTS */
1108
                sio_set(port, TXX9_SIFLCR,
1109
                        TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
1110
                local_irq_restore(flags);
1111
        }
1112
}
1113
 
1114
static void rs_unthrottle(struct tty_struct * tty)
1115
{
1116
        struct rs_port *port = tty->driver_data;
1117
        unsigned long flags;
1118
 
1119
        if (I_IXOFF(tty)) {
1120
                if (port->x_char)
1121
                        port->x_char = 0;
1122
                else
1123
                        rs_send_xchar(tty, START_CHAR(tty));
1124
        }
1125
        if (tty->termios->c_cflag & CRTSCTS) {
1126
                local_irq_save(flags);
1127
                sio_mask(port, TXX9_SIFLCR,
1128
                         TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
1129
                local_irq_restore(flags);
1130
        }
1131
}
1132
 
1133
/* ********************************************************************** *
1134
 *                    Here are the initialization routines.               *
1135
 * ********************************************************************** */
1136
 
1137
static inline void show_serial_version(void)
1138
{
1139
        printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
1140
}
1141
 
1142
static int rs_init_portstructs(void)
1143
{
1144
        struct rs_port *port;
1145
        int i;
1146
 
1147
        /* Adjust the values in the "driver" */
1148
        rs_driver.termios = rs_termios;
1149
        rs_driver.termios_locked = rs_termios_locked;
1150
 
1151
        port = rs_ports;
1152
        for (i=0; i < NR_PORTS;i++) {
1153
                port->gs.callout_termios = tty_std_termios;
1154
                port->gs.normal_termios = tty_std_termios;
1155
                port->gs.magic = TXX9_SERIAL_MAGIC;
1156
                port->gs.close_delay = HZ/2;
1157
                port->gs.closing_wait = 30 * HZ;
1158
                port->gs.rd = &rs_real_driver;
1159
#ifdef NEW_WRITE_LOCKING
1160
                port->gs.port_write_sem = MUTEX;
1161
#endif
1162
#ifdef DECLARE_WAITQUEUE
1163
                init_waitqueue_head(&port->gs.open_wait);
1164
                init_waitqueue_head(&port->gs.close_wait);
1165
#endif
1166
                port++;
1167
        }
1168
 
1169
        return 0;
1170
}
1171
 
1172
static int rs_init_drivers(void)
1173
{
1174
        int error;
1175
 
1176
        memset(&rs_driver, 0, sizeof(rs_driver));
1177
        rs_driver.magic = TTY_DRIVER_MAGIC;
1178
        rs_driver.driver_name = "serial_txx9";
1179
#if defined(CONFIG_DEVFS_FS)
1180
        rs_driver.name = TXX9_TTY_DEVFS_NAME;
1181
#else
1182
        rs_driver.name = TXX9_TTY_NAME;
1183
#endif
1184
        rs_driver.major = TXX9_TTY_MAJOR;
1185
        rs_driver.minor_start = TXX9_TTY_MINOR_START;
1186
        rs_driver.num = NR_PORTS;
1187
        rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
1188
        rs_driver.subtype = SERIAL_TYPE_NORMAL;
1189
        rs_driver.init_termios = tty_std_termios;
1190
        rs_driver.init_termios.c_cflag =
1191
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1192
        rs_driver.refcount = &rs_refcount;
1193
        rs_driver.table = rs_table;
1194
        rs_driver.termios = rs_termios;
1195
        rs_driver.termios_locked = rs_termios_locked;
1196
 
1197
        rs_driver.open  = rs_open;
1198
        rs_driver.close = gs_close;
1199
        rs_driver.write = gs_write;
1200
        rs_driver.put_char = gs_put_char;
1201
        rs_driver.flush_chars = gs_flush_chars;
1202
        rs_driver.write_room = gs_write_room;
1203
        rs_driver.chars_in_buffer = gs_chars_in_buffer;
1204
        rs_driver.flush_buffer = gs_flush_buffer;
1205
        rs_driver.ioctl = rs_ioctl;
1206
        rs_driver.throttle = rs_throttle;
1207
        rs_driver.unthrottle = rs_unthrottle;
1208
        rs_driver.set_termios = gs_set_termios;
1209
        rs_driver.stop = gs_stop;
1210
        rs_driver.start = gs_start;
1211
        rs_driver.hangup = gs_hangup;
1212
        rs_driver.break_ctl = rs_break;
1213
        rs_driver.read_proc = rs_read_proc;
1214
 
1215
        rs_callout_driver = rs_driver;
1216
#if defined(CONFIG_DEVFS_FS)
1217
        rs_callout_driver.name = TXX9_CU_DEVFS_NAME;
1218
#else
1219
        rs_callout_driver.name = TXX9_CU_NAME;
1220
#endif
1221
        rs_callout_driver.major = TXX9_TTYAUX_MAJOR;
1222
        rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
1223
        rs_callout_driver.read_proc = 0;
1224
        rs_callout_driver.proc_entry = 0;
1225
 
1226
        if ((error = tty_register_driver(&rs_driver))) {
1227
                printk(KERN_ERR
1228
                       "Couldn't register serial driver, error = %d\n",
1229
                       error);
1230
                return 1;
1231
        }
1232
        if ((error = tty_register_driver(&rs_callout_driver))) {
1233
                tty_unregister_driver(&rs_driver);
1234
                printk(KERN_ERR
1235
                       "Couldn't register callout driver, error = %d\n",
1236
                       error);
1237
                return 1;
1238
        }
1239
 
1240
        return 0;
1241
}
1242
 
1243
/*
1244
 * This routine is called by txx9_rs_init() to initialize a specific serial
1245
 * port.
1246
 */
1247
static void txx9_config(struct rs_port *port)
1248
{
1249
        unsigned long flags;
1250
 
1251
        if (port - &rs_ports[0] != sercons.index) {
1252
                local_irq_save(flags);
1253
                /*
1254
                 * Reset the UART.
1255
                 */
1256
                sio_out(port, TXX9_SIFCR, TXX9_SIFCR_SWRST);
1257
#ifdef CONFIG_CPU_TX49XX
1258
                /* TX4925 BUG WORKAROUND.  Accessing SIOC register
1259
                 * immediately after soft reset causes bus error. */
1260
                wbflush();/* change iob(); */
1261
                udelay(1);
1262
#endif
1263
                while (sio_in(port, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
1264
                        ;
1265
                /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
1266
                sio_set(port, TXX9_SIFCR,
1267
                        TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
1268
                /* initial settings */
1269
                sio_out(port, TXX9_SILCR,
1270
                        TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
1271
                        TXX9_SILCR_SCS_IMCLK_BG);
1272
                sio_out(port, TXX9_SIBGR,
1273
                        ((port->baud_base + 9600 / 2) / 9600) |
1274
                        TXX9_SIBGR_BCLK_T0);
1275
                local_irq_restore(flags);
1276
        }
1277
        DBG("txx9_config: port->io_type is %d\n", port->io_type);
1278
        if (port->io_type < 0)
1279
                request_mem_region(port->base, 36, "serial_txx9");
1280
        else
1281
                request_region(port->base, 36, "serial_txx9");
1282
}
1283
 
1284
#ifdef ENABLE_SERIAL_TXX9_PCI
1285
static int __devinit serial_txx9_init_one(struct pci_dev *dev,
1286
                                          const struct pci_device_id *ent)
1287
{
1288
        int rc, i;
1289
        struct rs_port *port;
1290
 
1291
        rc = pci_enable_device(dev);
1292
        if (rc) return rc;
1293
 
1294
        /* find empty slot */
1295
        for (i = 0; i < NR_PORTS && rs_ports[i].base; i++)
1296
                ;
1297
        if (i == NR_PORTS)
1298
                return -ENODEV;
1299
        port = &rs_ports[i];
1300
        DBG("port number is %d\n",i);
1301
 
1302
        port->pci_dev = dev;
1303
        port->base = pci_resource_start(dev, 1);
1304
 
1305
        DBG("port->base is %x\n",(u32)port->base);
1306
        port->io_type = SERIAL_IO_PORT;
1307
        port->irq = dev->irq;
1308
        port->flags |= TXX9_SERIAL_HAVE_CTS_LINE;
1309
        port->baud_base = 66670000 / 16 / 2;    /* 66.67MHz */
1310
        DBG("port->baud_base %x\n",port->baud_base);
1311
 
1312
        txx9_config(port);
1313
 
1314
        printk(KERN_INFO
1315
                "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n",
1316
                TXX9_TTY_NAME, i, port->base, port->irq);
1317
        return 0;
1318
}
1319
 
1320
static void __devexit serial_txx9_remove_one(struct pci_dev *dev)
1321
{
1322
        int i;
1323
        for (i = 0; i < NR_PORTS; i++) {
1324
                if (rs_ports[i].pci_dev == dev) {
1325
                        rs_ports[i].irq = 0;
1326
                        rs_ports[i].base = 0;
1327
                        rs_ports[i].pci_dev = 0;
1328
                        /* XXX NOT IMPLEMENTED YET */
1329
                        break;
1330
                }
1331
        }
1332
}
1333
 
1334
static struct pci_device_id serial_txx9_pci_tbl[] __devinitdata = {
1335
#ifdef PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC
1336
        {       PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC,
1337
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1338
 
1339
#endif
1340
       { 0, }
1341
};
1342
 
1343
MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
1344
 
1345
static struct pci_driver serial_txx9_pci_driver = {
1346
       name:           "serial_txx9",
1347
       probe:          serial_txx9_init_one,
1348
       remove:         __devexit_p(serial_txx9_remove_one),
1349
       id_table:       serial_txx9_pci_tbl,
1350
};
1351
 
1352
/*
1353
 * Query PCI space for known serial boards
1354
 * If found, add them to the PCI device space in rs_table[]
1355
 */
1356
static void __devinit probe_serial_txx9_pci(void)
1357
{
1358
        /* Register call PCI serial devices.  Null out
1359
         * the driver name upon failure, as a signal
1360
         * not to attempt to unregister the driver later
1361
         */
1362
        if (pci_module_init (&serial_txx9_pci_driver) != 0)
1363
                serial_txx9_pci_driver.name = "";
1364
 
1365
        return;
1366
}
1367
#endif /* ENABLE_SERIAL_TXX9_PCI */
1368
 
1369
static int __init txx9_rs_init(void)
1370
{
1371
        int rc;
1372
        struct rs_port *port;
1373
        int i;
1374
 
1375
#ifndef ENABLE_SERIAL_TXX9_PCI
1376
        for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) {
1377
                if (port->base)
1378
                        goto config_ok;
1379
        }
1380
        return -ENODEV;
1381
 config_ok:
1382
#endif
1383
 
1384
        show_serial_version();
1385
        rc = rs_init_portstructs ();
1386
        rs_init_drivers ();
1387
        for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) {
1388
                if (!port->base)
1389
                        continue;
1390
                if (port->io_type < 0) {
1391
                        if (check_mem_region(port->base, 36))
1392
                                continue;
1393
                } else {
1394
                        if (check_region(port->base, 36))
1395
                                continue;
1396
                }
1397
                txx9_config(port);
1398
                printk(KERN_INFO
1399
                       "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n",
1400
                       TXX9_TTY_NAME, i, port->base, port->irq);
1401
        }
1402
 
1403
        /* Note: I didn't do anything to enable the second UART */
1404
        if (rc >= 0)
1405
                rs_initialized++;
1406
 
1407
#ifdef ENABLE_SERIAL_TXX9_PCI
1408
        probe_serial_txx9_pci();
1409
#endif
1410
        return 0;
1411
}
1412
 
1413
/*
1414
 * This is for use by architectures that know their serial console
1415
 * attributes only at run time. Not to be invoked after rs_init().
1416
 */
1417
int __init early_serial_txx9_setup(int line, unsigned long base, int irq,
1418
                                   int baud_base, int have_cts)
1419
{
1420
        if (line >= NR_PORTS)
1421
                return(-ENOENT);
1422
        rs_ports[line].base = base;
1423
        rs_ports[line].irq = irq;
1424
        rs_ports[line].baud_base = baud_base;
1425
        rs_ports[line].io_type = -1;    /* virtual memory mapped */
1426
        if (have_cts)
1427
                rs_ports[line].flags |= TXX9_SERIAL_HAVE_CTS_LINE;
1428
        return(0);
1429
}
1430
 
1431
static void __exit txx9_rs_fini(void)
1432
{
1433
        unsigned long flags;
1434
        int e1, e2;
1435
        int i;
1436
 
1437
        local_irq_save(flags);
1438
        if ((e1 = tty_unregister_driver(&rs_driver)))
1439
                printk("serial: failed to unregister serial driver (%d)\n",
1440
                       e1);
1441
        if ((e2 = tty_unregister_driver(&rs_callout_driver)))
1442
                printk("serial: failed to unregister callout driver (%d)\n",
1443
                       e2);
1444
        local_irq_restore(flags);
1445
 
1446
        for (i = 0; i < NR_PORTS; i++) {
1447
                if (!rs_ports[i].base)
1448
                        continue;
1449
                if (rs_ports[i].io_type < 0)
1450
                        release_mem_region(rs_ports[i].base, 36);
1451
                else
1452
                        release_region(rs_ports[i].base, 36);
1453
        }
1454
 
1455
#ifdef ENABLE_SERIAL_PCI
1456
        if (serial_txx9_pci_driver.name[0])
1457
                pci_unregister_driver (&serial_txx9_pci_driver);
1458
#endif
1459
}
1460
 
1461
module_init(txx9_rs_init);
1462
module_exit(txx9_rs_fini);
1463
MODULE_DESCRIPTION("TX39/49 serial driver");
1464
MODULE_AUTHOR("TOSHIBA Corporation");
1465
MODULE_LICENSE("GPL");
1466
 
1467
/*
1468
 * Begin serial console routines
1469
 */
1470
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
1471
 
1472
/*
1473
 *      Wait for transmitter & holding register to empty
1474
 */
1475
static inline void wait_for_xmitr(struct rs_port *port)
1476
{
1477
        unsigned int tmout = 1000000;
1478
 
1479
        do {
1480
                if (--tmout == 0) break;
1481
        } while (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS));
1482
 
1483
        /* Wait for flow control if necessary */
1484
#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0     /* check conflict... */
1485
        if (port->gs.flags & ASYNC_CONS_FLOW) {
1486
                tmout = 1000000;
1487
                while (--tmout &&
1488
                       (sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS));
1489
        }
1490
#endif
1491
}
1492
 
1493
/*
1494
 *      Print a string to the serial port trying not to disturb
1495
 *      any possible real use of the port...
1496
 *
1497
 *      The console_lock must be held when we get here.
1498
 */
1499
static void serial_console_write(struct console *co, const char *s,
1500
                                 unsigned count)
1501
{
1502
        struct rs_port *port = &rs_ports[co->index];
1503
        int ier;
1504
        unsigned i;
1505
 
1506
        /*
1507
         *      First save the IER then disable the interrupts
1508
         */
1509
        ier = sio_in(port, TXX9_SIDICR);
1510
        sio_out(port, TXX9_SIDICR, 0);
1511
 
1512
        /*
1513
         *      Now, do each character
1514
         */
1515
        for (i = 0; i < count; i++, s++) {
1516
                wait_for_xmitr(port);
1517
 
1518
                /*
1519
                 *      Send the character out.
1520
                 *      If a LF, also do CR...
1521
                 */
1522
                sio_out(port, TXX9_SITFIFO, *s);
1523
                if (*s == 10) {
1524
                        wait_for_xmitr(port);
1525
                        sio_out(port, TXX9_SITFIFO, 13);
1526
                }
1527
        }
1528
 
1529
        /*
1530
         *      Finally, Wait for transmitter & holding register to empty
1531
         *      and restore the IER
1532
         */
1533
        wait_for_xmitr(port);
1534
        sio_out(port, TXX9_SIDICR, ier);
1535
}
1536
 
1537
static kdev_t serial_console_device(struct console *c)
1538
{
1539
        return MKDEV(TXX9_TTY_MAJOR, TXX9_TTY_MINOR_START + c->index);
1540
}
1541
 
1542
static __init int serial_console_setup(struct console *co, char *options)
1543
{
1544
        struct rs_port *port;
1545
        unsigned cval;
1546
        int     baud = 9600;
1547
        int     bits = 8;
1548
        int     parity = 'n';
1549
        int     doflow = 0;
1550
        int     cflag = CREAD | HUPCL | CLOCAL;
1551
        int     quot = 0;
1552
        char    *s;
1553
 
1554
        if (co->index < 0 || co->index >= NR_PORTS)
1555
                return -1;
1556
        if (options) {
1557
                baud = simple_strtoul(options, NULL, 10);
1558
                s = options;
1559
                while(*s >= '0' && *s <= '9')
1560
                        s++;
1561
                if (*s) parity = *s++;
1562
                if (*s) bits   = *s - '0';
1563
                if (*s) doflow = (*s++ == 'r');
1564
        }
1565
 
1566
        /*
1567
         *      Now construct a cflag setting.
1568
         */
1569
        switch(baud) {
1570
        case 1200:      cflag |= B1200; break;
1571
        case 2400:      cflag |= B2400; break;
1572
        case 4800:      cflag |= B4800; break;
1573
        case 19200:     cflag |= B19200;        break;
1574
        case 38400:     cflag |= B38400;        break;
1575
        case 57600:     cflag |= B57600;        break;
1576
        case 115200:    cflag |= B115200;       break;
1577
        default:
1578
                /*
1579
                 * Set this to a sane value to prevent a divide error
1580
                 */
1581
                baud  = 9600;
1582
        case 9600:      cflag |= B9600;         break;
1583
        }
1584
 
1585
        switch(bits) {
1586
        case 7:         cflag |= CS7;   break;
1587
        default:
1588
        case 8:         cflag |= CS8;   break;
1589
        }
1590
        switch(parity) {
1591
        case 'o': case 'O':     cflag |= PARODD;        break;
1592
        case 'e': case 'E':     cflag |= PARENB;        break;
1593
        }
1594
        co->cflag = cflag;
1595
 
1596
        port = &rs_ports[co->index];
1597
        if (!port->base)
1598
                return -1;
1599
 
1600
        /*
1601
         *      Divisor, bytesize and parity
1602
         */
1603
#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0     /* check conflict... */
1604
        if (doflow)
1605
                port->gs.flags |= ASYNC_CONS_FLOW;
1606
#endif
1607
        quot = port->baud_base / baud;
1608
        switch (cflag & CSIZE) {
1609
        case CS7: cval = TXX9_SILCR_UMODE_7BIT; break;
1610
        default:
1611
        case CS8: cval = TXX9_SILCR_UMODE_8BIT; break;
1612
        }
1613
        if (cflag & CSTOPB)
1614
                cval |= TXX9_SILCR_USBL_2BIT;
1615
        else
1616
                cval |= TXX9_SILCR_USBL_1BIT;
1617
        if (cflag & PARENB)
1618
                cval |= TXX9_SILCR_UPEN;
1619
        if (!(cflag & PARODD))
1620
                cval |= TXX9_SILCR_UEPS;
1621
 
1622
        /*
1623
         *      Disable UART interrupts, set DTR and RTS high
1624
         *      and set speed.
1625
         */
1626
        sio_out(port, TXX9_SIDICR, 0);
1627
        sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG);
1628
        sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0);
1629
        /* no RTS/CTS control */
1630
        sio_out(port, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
1631
        /* Enable RX/TX */
1632
        sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
1633
 
1634
        /* console port should not use RTC/CTS. */
1635
        port->flags &= ~TXX9_SERIAL_HAVE_CTS_LINE;
1636
        return 0;
1637
}
1638
 
1639
static struct console sercons = {
1640
        name:           TXX9_TTY_NAME,
1641
        write:          serial_console_write,
1642
        device:         serial_console_device,
1643
        setup:          serial_console_setup,
1644
        flags:          CON_PRINTBUFFER,
1645
        index:          -1,
1646
};
1647
 
1648
void __init txx9_serial_console_init(void)
1649
{
1650
        register_console(&sercons);
1651
}
1652
 
1653
#endif
1654
 
1655
/******************************************************************************/
1656
/* BEG: KDBG Routines                                                         */
1657
/******************************************************************************/
1658
 
1659
#ifdef CONFIG_KGDB
1660
int kgdb_init_count = 0;
1661
#endif
1662
 
1663
#ifdef CONFIG_KGDB
1664
void txx9_sio_kgdb_hook(unsigned int port, unsigned int baud_rate)
1665
{
1666
        static struct resource kgdb_resource;
1667
        int ret;
1668
 
1669
        /* prevent initialization by driver */
1670
        kgdb_resource.name = "serial_txx9(debug)";
1671
        kgdb_resource.start = rs_ports[port].base;
1672
        kgdb_resource.end = rs_ports[port].base + 36 - 1;
1673
        kgdb_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
1674
 
1675
        ret = request_resource(&iomem_resource, &kgdb_resource);
1676
        if(ret == -EBUSY)
1677
                printk(" serial_txx9(debug): request_resource failed\n");
1678
 
1679
        return;
1680
}
1681
#endif /* CONFIG_KGDB */
1682
 
1683
#ifdef CONFIG_KGDB
1684
void
1685
txx9_sio_kdbg_init( unsigned int port_number )
1686
{
1687
  if ( port_number == 1 ) {
1688
    txx9_sio_kgdb_hook( port_number, 38400 );
1689
  } else {
1690
        printk("Bad Port Number [%u] != [1]\n",port_number);
1691
  }
1692
  return;
1693
}
1694
#endif /* CONFIG_KGDB */
1695
 
1696
#ifdef CONFIG_KGDB
1697
u8
1698
txx9_sio_kdbg_rd( void )
1699
{
1700
    unsigned int status,ch;
1701
 
1702
  if ( kgdb_init_count == 0 )
1703
  {
1704
    txx9_sio_kdbg_init( 1 );
1705
    kgdb_init_count = 1;
1706
  }
1707
 
1708
  while ( 1 )
1709
  {
1710
    status = sio_in(&rs_ports[1], TXX9_SIDISR);
1711
    if ( status & 0x1f )
1712
    {
1713
      ch = sio_in(&rs_ports[1], TXX9_SIRFIFO );
1714
      break;
1715
    }
1716
  }
1717
 
1718
  return( ch );
1719
}
1720
#endif /* CONFIG_KGDB */
1721
 
1722
#ifdef CONFIG_KGDB
1723
int
1724
txx9_sio_kdbg_wr( u8 ch )
1725
{
1726
    unsigned int status;
1727
 
1728
  if ( kgdb_init_count == 0 )
1729
  {
1730
    txx9_sio_kdbg_init( 1 );
1731
    kgdb_init_count = 1;
1732
  }
1733
 
1734
  while ( 1 )
1735
  {
1736
    status = sio_in(&rs_ports[1], TXX9_SICISR);
1737
    if (status & TXX9_SICISR_TRDY)
1738
    {
1739
      if ( ch == '\n' )
1740
      {
1741
        txx9_sio_kdbg_wr( '\r' );
1742
      }
1743
      sio_out(&rs_ports[1], TXX9_SITFIFO, (u32)ch );
1744
 
1745
      break;
1746
    }
1747
  }
1748
 
1749
  return( 1 );
1750
}
1751
#endif /* CONFIG_KGDB */
1752
 
1753
/******************************************************************************/
1754
/* END: KDBG Routines                                                         */
1755
/******************************************************************************/
1756
 
1757
void txx9_raw_output(char c)
1758
{
1759
        struct rs_port *port = &rs_ports[0];
1760
        if ( c == '\n' )
1761
        {
1762
          sio_out(port, TXX9_SITFIFO, '\r');
1763
          wait_for_xmitr(port);
1764
        }
1765
        sio_out(port, TXX9_SITFIFO, c);
1766
        wait_for_xmitr(port);
1767
        return;
1768
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.