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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [char/] [or32serial.c] - Blame information for rev 1626

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

Line No. Rev Author Line
1 1626 jcastillo
/* 68328serial.c: Serial port driver for 68328 microcontroller
2
 *
3
 * Copyright (C) 1995       David S. Miller    <davem@caip.rutgers.edu>
4
 * Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
5
 * Copyright (C) 1998, 1999 D. Jeff Dionne     <jeff@rt-control.com>
6
 * Copyright (C) 1999       Vladimir Gurevich  <vgurevic@cisco.com>
7
 *
8
 */
9
#include <linux/module.h>
10
#include <linux/errno.h>
11
#include <linux/signal.h>
12
#include <linux/sched.h>
13
#include <linux/timer.h>
14
#include <linux/interrupt.h>
15
#include <linux/tty.h>
16
#include <linux/tty_flip.h>
17
#include <linux/serial.h>
18
#include <linux/serial_reg.h>
19
#include <linux/config.h>
20
#include <linux/major.h>
21
#include <linux/string.h>
22
#include <linux/fcntl.h>
23
#include <linux/ptrace.h>
24
#include <linux/ioport.h>
25
#include <linux/mm.h>
26
#include <asm/system.h>
27
#include <asm/irq.h>
28
 
29
#include <asm/io.h>
30
 
31
#include <asm/segment.h>
32
#include <asm/bitops.h>
33
 
34
/*
35
#include <linux/errno.h>
36
#include <linux/signal.h>
37
#include <linux/sched.h>
38
#include <linux/timer.h>
39
#include <linux/interrupt.h>
40
#include <linux/tty.h>
41
#include <linux/tty_flip.h>
42
#include <linux/config.h>
43
#include <linux/major.h>
44
#include <linux/string.h>
45
#include <linux/fcntl.h>
46
#include <linux/mm.h>
47
#include <linux/kernel.h>
48
 
49
#include <asm/io.h>
50
#include <asm/irq.h>
51
#include <asm/system.h>
52
#include <asm/segment.h>
53
#include <asm/bitops.h>
54
#include <asm/delay.h>
55
*/
56
 
57
#define NR_PORTS 1
58
#define SERIAL_TYPE_NORMAL 1
59
#define SERIAL_TYPE_CALLOUT 2
60
 
61
#define BASE_BAUD 115200
62
#define STD_COM_FLAGS 0
63
 
64
struct tty_driver serial_driver, callout_driver;
65
 
66
static int serial_refcount;
67
 
68
static struct tty_struct *serial_table[NR_PORTS];
69
static struct termios *serial_termios[NR_PORTS];
70
static struct termios *serial_termios_locked[NR_PORTS];
71
 
72
int rs_console_inited = 0;
73
int rs_console_port = 0;
74
int rs_console_baud = 115200;
75
 
76
DECLARE_TASK_QUEUE(tq_serial);
77
 
78
struct async_struct rs_or32_table[] = {
79
        /* UART CLK   PORT IRQ     FLAGS        */
80
        { 0, BASE_BAUD, 0, 0, STD_COM_FLAGS },/* ttyS0 */
81
};
82
 
83
/*
84
 * or32_console_print is registered for printk.
85
 */
86
void console_print_or32(const char *p)
87
{
88
        char c;
89
        return;
90
}
91
 
92
void rs_console_init(void)
93
{
94
        /* Nothig for now */
95
 
96
        rs_console_inited++;
97
        return;
98
}
99
 
100
/*
101
 * rs_console_print is registered for printk output.
102
 */
103
 
104
void rs_console_print(const char *p)
105
{
106
        char c;
107
 
108
        while ((c = *(p++)) != 0) {
109
/*              if(c == '\n')
110
                        _print("\r");
111
*/
112
                _print("%c", c);
113
        }
114
        return;
115
}
116
 
117
/*
118
 *      Setup for console. Argument comes from the boot command line.
119
 */
120
int rs_console_setup(char *arg)
121
{
122
        int     rc = 0;
123
 
124
        if (!strncmp(arg, "/dev/ttyS", 9)) {
125
                rs_console_port = arg[9] - '0';
126
                arg += 10;
127
                rc = 1;
128
        } else if (!strncmp(arg, "/dev/cua", 8)) {
129
                rs_console_port = arg[8] - '0';
130
                arg += 9;
131
                rc = 1;
132
        }
133
        if (*arg == ',')
134
                rs_console_baud = simple_strtoul(arg+1,NULL,0);
135
        return(rc);
136
}
137
 
138
/*
139
 * This is the serial driver's generic interrupt routine
140
 */
141
static void rs_or32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
142
{
143
        int status;
144
        struct async_struct * info;
145
        int pass_counter = 0;
146
        struct async_struct *end_mark = 0;
147
        int first_multi = 0;
148
        struct rs_multiport_struct *multi;
149
 
150
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
151
printk("   irq=%x info=%x\n", irq, info);
152
        info = &rs_or32_table[irq];
153
        if (!info)
154
                return;
155
/*      queue_task_irq_off(&info->tqueue, &tq_serial);*/
156
        queue_task_irq_off(&info->tty->flip.tqueue, &tq_serial);
157
        mark_bh(SERIAL_BH);
158
}
159
 
160
static void do_or32_serial_bh(void)
161
{
162
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
163
        run_task_queue(&tq_serial);
164
}
165
 
166
static void do_softint(void *private_)
167
{
168
        struct async_struct     *info = (struct async_struct *) private_;
169
        struct tty_struct       *tty;
170
 
171
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
172
        tty = info->tty;
173
        if (!tty)
174
                return;
175
 
176
/*      if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
177
                if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
178
                    tty->ldisc.write_wakeup)
179
                        (tty->ldisc.write_wakeup)(tty);*/
180
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
181
                wake_up_interruptible(&tty->write_wait);
182
/*      }*/
183
}
184
 
185
static void do_serial_hangup(void *private_)
186
{
187
        struct async_struct     *info = (struct async_struct *) private_;
188
        struct tty_struct       *tty;
189
 
190
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
191
        tty = info->tty;
192
        if (!tty)
193
                return;
194
 
195
        tty_hangup(tty);
196
}
197
 
198
void init_port(struct async_struct *info, int num)
199
{
200
  int retval;
201
 
202
  info->magic = SERIAL_MAGIC;
203
  info->line = num;
204
#if 1
205
printk("%s(%d): info=%x num=%x\n", __FILE__, __LINE__, (int) info, num);
206
#endif
207
  info->tty = 0;
208
  info->type = PORT_UNKNOWN;
209
  info->custom_divisor = 0;
210
  info->close_delay = 5*HZ/10;
211
  info->closing_wait = 30*HZ;
212
  info->x_char = 0;
213
  info->event = 0;
214
  info->count = 0;
215
  info->blocked_open = 0;
216
  info->tqueue.routine = do_softint;
217
  info->tqueue.data = info;
218
  info->tqueue_hangup.routine = do_serial_hangup;
219
  info->tqueue_hangup.data = info;
220
  info->callout_termios =callout_driver.init_termios;
221
  info->normal_termios = serial_driver.init_termios;
222
  info->open_wait = 0;
223
  info->close_wait = 0;
224
  info->delta_msr_wait = 0;
225
  info->icount.cts = info->icount.dsr =
226
        info->icount.rng = info->icount.dcd = 0;
227
  info->next_port = 0;
228
  info->prev_port = 0;
229
 
230
  retval = request_irq(info->irq, rs_or32_interrupt, IRQ_FLG_PRI_HI, "serial", NULL);
231
  if (retval)
232
    printk("SERIAL: failed to register interrup %d\n", info->irq);
233
}
234
 
235
/*
236
 * This routine is called whenever a serial port is opened.  It
237
 * enables interrupts for a serial port, linking in its async structure into
238
 * the IRQ chain.   It also performs the serial-specific
239
 * initialization for the tty structure.
240
 */
241
int rs_or32_open(struct tty_struct *tty, struct file * filp)
242
{
243
        struct async_struct     *info;
244
 
245
        info = rs_or32_table;
246
 
247
        info->count++;
248
        tty->driver_data = info;
249
        info->tty = tty;
250
        return 0;
251
}
252
 
253
/*
254
 * ------------------------------------------------------------
255
 * rs_close()
256
 *
257
 * This routine is called when the serial port gets closed.  First, we
258
 * wait for the last remaining data to be sent.  Then, we unlink its
259
 * async structure from the interrupt chain if necessary, and we free
260
 * that IRQ if nothing is left in the chain.
261
 * ------------------------------------------------------------
262
 */
263
static void rs_or32_close(struct tty_struct *tty, struct file * filp)
264
{
265
}
266
 
267
static int rs_or32_write(struct tty_struct * tty, int from_user,
268
                    const unsigned char *buf, int count)
269
{
270
        int     total = count;
271
 
272
        while (count--) {
273
                _print("%c", *buf);
274
                buf++;
275
        }
276
 
277
        return total;
278
}
279
 
280
static void rs_or32_put_char(struct tty_struct *tty, unsigned char ch)
281
{
282
        _print("%c", ch);
283
}
284
 
285
static void rs_or32_flush_chars(struct tty_struct *tty)
286
{
287
}
288
 
289
static int rs_or32_write_room(struct tty_struct *tty)
290
{
291
        return 100;
292
}
293
 
294
static int rs_or32_chars_in_buffer(struct tty_struct *tty)
295
{
296
        return 0;
297
}
298
 
299
static void rs_or32_flush_buffer(struct tty_struct *tty)
300
{
301
}
302
 
303
static int rs_or32_ioctl(struct tty_struct *tty, struct file * file,
304
                    unsigned int cmd, unsigned long arg)
305
{
306
        int error;
307
        struct async_struct * info = (struct async_struct *)tty->driver_data;
308
        int retval;
309
 
310
        if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
311
            (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
312
            (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
313
            (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
314
                if (tty->flags & (1 << TTY_IO_ERROR))
315
                    return -EIO;
316
        }
317
 
318
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
319
 
320
        switch (cmd) {
321
                case TIOCSBRK:  /* Turn break on, unconditionally */
322
printk("   TIOCSBRK\n");
323
                        return 0;
324
                case TIOCCBRK:  /* Turn break off, unconditionally */
325
printk("   TIOCCBRK\n");
326
                        return 0;
327
                case TCSBRK:    /* SVID version: non-zero arg --> no break */
328
printk("   TCSBRK\n");
329
                        return 0;
330
                case TCSBRKP:   /* support for POSIX tcsendbreak() */
331
printk("   TCSBRKP\n");
332
                        return 0;
333
                case TIOCGSOFTCAR:
334
printk("   TIOCGSOFTCAR\n");
335
                        return 0;
336
                case TIOCSSOFTCAR:
337
printk("   TIOCSSOFTCAR\n");
338
                        return 0;
339
                case TIOCMGET:
340
printk("   TIOCMGET\n");
341
                        sizeof(unsigned int);
342
                case TIOCMBIS:
343
                case TIOCMBIC:
344
                case TIOCMSET:
345
printk("   TIOCMSET\n");
346
                        return 0;
347
                case TIOCGSERIAL:
348
printk("   TIOCGSERIAL\n");
349
                        return 0;
350
                case TIOCSSERIAL:
351
printk("   TIOCSSERIAL\n");
352
                        return 0;
353
                case TIOCSERCONFIG:
354
printk("   TIOCSERCONFIG\n");
355
                        return 0;
356
 
357
                case TIOCSERGETLSR: /* Get line status register */
358
printk("   TIOCSERGETLSR\n");
359
                        return 0;
360
 
361
                case TIOCSERGSTRUCT:
362
printk("   TIOCSERGSTRUCT\n");
363
                        return 0;
364
 
365
                /*
366
                 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
367
                 * - mask passed in arg for lines of interest
368
                 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
369
                 * Caller should use TIOCGICOUNT to see which one it was
370
                 */
371
                 case TIOCMIWAIT:
372
printk("   TIOCMIWAIT\n");
373
                        return 0;
374
                case TIOCGICOUNT:
375
printk("   TIOCGICOUNT\n");
376
                        return 0;
377
 
378
                default:
379
printk("   default\n");
380
                        return -ENOIOCTLCMD;
381
                }
382
        return 0;
383
}
384
 
385
/*
386
 * ------------------------------------------------------------
387
 * rs_throttle()
388
 *
389
 * This routine is called by the upper-layer tty layer to signal that
390
 * incoming characters should be throttled.
391
 * ------------------------------------------------------------
392
 */
393
static void rs_or32_throttle(struct tty_struct * tty)
394
{
395
}
396
 
397
static void rs_or32_unthrottle(struct tty_struct * tty)
398
{
399
}
400
 
401
static void rs_or32_set_termios(struct tty_struct *tty, struct termios *old_termios)
402
{
403
}
404
 
405
/*
406
 * ------------------------------------------------------------
407
 * rs_stop() and rs_start()
408
 *
409
 * This routines are called before setting or resetting tty->stopped.
410
 * They enable or disable transmitter interrupts, as necessary.
411
 * ------------------------------------------------------------
412
 */
413
static void rs_or32_stop(struct tty_struct *tty)
414
{
415
}
416
 
417
static void rs_or32_start(struct tty_struct *tty)
418
{
419
}
420
 
421
/*
422
 * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
423
 */
424
void rs_or32_hangup(struct tty_struct *tty)
425
{
426
}
427
 
428
/*
429
 * The serial driver boot-time initialization code!
430
 */
431
 
432
int rs_or32_init(void)
433
{
434
        int i;
435
        struct async_struct * info;
436
 
437
        init_bh(SERIAL_BH, do_or32_serial_bh);
438
 
439
        /* Initialize the tty_driver structure */
440
 
441
        memset(&serial_driver, 0, sizeof(struct tty_driver));
442
        serial_driver.magic = TTY_DRIVER_MAGIC;
443
        serial_driver.name = "tty";
444
        serial_driver.major = TTY_MAJOR;
445
        serial_driver.minor_start = 64;
446
        serial_driver.num = NR_PORTS;
447
        serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
448
        serial_driver.subtype = SERIAL_TYPE_NORMAL;
449
        serial_driver.init_termios = tty_std_termios;
450
        serial_driver.init_termios.c_cflag =
451
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
452
        serial_driver.flags = TTY_DRIVER_REAL_RAW;
453
        serial_driver.refcount = &serial_refcount;
454
        serial_driver.table = serial_table;
455
        serial_driver.termios = serial_termios;
456
        serial_driver.termios_locked = serial_termios_locked;
457
 
458
        serial_driver.open = rs_or32_open;
459
        serial_driver.close = rs_or32_close;
460
        serial_driver.write = rs_or32_write;
461
        serial_driver.put_char = rs_or32_put_char;
462
        serial_driver.flush_chars = rs_or32_flush_chars;
463
        serial_driver.write_room = rs_or32_write_room;
464
        serial_driver.chars_in_buffer = rs_or32_chars_in_buffer;
465
        serial_driver.flush_buffer = rs_or32_flush_buffer;
466
        serial_driver.ioctl = rs_or32_ioctl;
467
        serial_driver.throttle = rs_or32_throttle;
468
        serial_driver.unthrottle = rs_or32_unthrottle;
469
        serial_driver.set_termios = rs_or32_set_termios;
470
        serial_driver.stop = rs_or32_stop;
471
        serial_driver.start = rs_or32_start;
472
        serial_driver.hangup = rs_or32_hangup;
473
 
474
        /*
475
         * The callout device is just like normal device except for
476
         * major number and the subtype code.
477
         */
478
        callout_driver = serial_driver;
479
        callout_driver.name = "cua";
480
        callout_driver.major = TTYAUX_MAJOR;
481
        callout_driver.subtype = SERIAL_TYPE_CALLOUT;
482
 
483
        if (tty_register_driver(&serial_driver))
484
                panic("Couldn't register serial driver\n");
485
        if (tty_register_driver(&callout_driver))
486
                panic("Couldn't register callout driver\n");
487
 
488
        for (i = 0, info = rs_or32_table; i < NR_PORTS; i++,info++) {
489
                                init_port(info, i);
490
        }
491
 
492
 
493
        return 0;
494
}
495
 
496
 

powered by: WebSVN 2.1.0

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