PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/ppc/boot/common/ns16550.c

https://bitbucket.org/evzijst/gittest
C | 99 lines | 63 code | 15 blank | 21 comment | 9 complexity | 6f63292b6bb5055c47eae88e65950051 MD5 | raw file
 1/*
 2 * COM1 NS16550 support
 3 */
 4
 5#include <linux/config.h>
 6#include <linux/types.h>
 7#include <linux/serial.h>
 8#include <linux/serial_reg.h>
 9#include <asm/serial.h>
10
11#include "nonstdio.h"
12#include "serial.h"
13
14#define SERIAL_BAUD	9600
15
16extern unsigned long ISA_io;
17
18static struct serial_state rs_table[RS_TABLE_SIZE] = {
19	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
20};
21
22static int shift;
23
24unsigned long serial_init(int chan, void *ignored)
25{
26	unsigned long com_port;
27	unsigned char lcr, dlm;
28
29	/* We need to find out which type io we're expecting.  If it's
30	 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
31	 * If it's 'SERIAL_IO_MEM', we can the exact location.  -- Tom */
32	switch (rs_table[chan].io_type) {
33		case SERIAL_IO_PORT:
34			com_port = rs_table[chan].port;
35			break;
36		case SERIAL_IO_MEM:
37			com_port = (unsigned long)rs_table[chan].iomem_base;
38			break;
39		default:
40			/* We can't deal with it. */
41			return -1;
42	}
43
44	/* How far apart the registers are. */
45	shift = rs_table[chan].iomem_reg_shift;
46	
47	/* save the LCR */
48	lcr = inb(com_port + (UART_LCR << shift));
49	/* Access baud rate */
50	outb(com_port + (UART_LCR << shift), 0x80);
51	dlm = inb(com_port + (UART_DLM << shift));
52	/*
53	 * Test if serial port is unconfigured.
54	 * We assume that no-one uses less than 110 baud or
55	 * less than 7 bits per character these days.
56	 *  -- paulus.
57	 */
58
59	if ((dlm <= 4) && (lcr & 2))
60		/* port is configured, put the old LCR back */
61		outb(com_port + (UART_LCR << shift), lcr);
62	else {
63		/* Input clock. */
64		outb(com_port + (UART_DLL << shift),
65		     (BASE_BAUD / SERIAL_BAUD) & 0xFF);
66		outb(com_port + (UART_DLM << shift),
67		     (BASE_BAUD / SERIAL_BAUD) >> 8);
68		/* 8 data, 1 stop, no parity */
69		outb(com_port + (UART_LCR << shift), 0x03);
70		/* RTS/DTR */
71		outb(com_port + (UART_MCR << shift), 0x03);
72	}
73	/* Clear & enable FIFOs */
74	outb(com_port + (UART_FCR << shift), 0x07);
75
76	return (com_port);
77}
78
79void
80serial_putc(unsigned long com_port, unsigned char c)
81{
82	while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0)
83		;
84	outb(com_port, c);
85}
86
87unsigned char
88serial_getc(unsigned long com_port)
89{
90	while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0)
91		;
92	return inb(com_port);
93}
94
95int
96serial_tstc(unsigned long com_port)
97{
98	return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
99}