Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ee9e2c8a
Commit
ee9e2c8a
authored
Sep 05, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk/linux-2.6-serial
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
07b03017
1e6d9d3c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
96 additions
and
98 deletions
+96
-98
drivers/serial/8250.c
drivers/serial/8250.c
+82
-98
drivers/serial/8250.h
drivers/serial/8250.h
+14
-0
No files found.
drivers/serial/8250.c
View file @
ee9e2c8a
...
...
@@ -130,6 +130,7 @@ struct uart_8250_port {
struct
timer_list
timer
;
/* "no irq" timer */
struct
list_head
list
;
/* ports on this IRQ */
unsigned
int
capabilities
;
/* port capabilities */
unsigned
int
tx_loadsz
;
/* transmit fifo load size */
unsigned
short
rev
;
unsigned
char
acr
;
unsigned
char
ier
;
...
...
@@ -156,23 +157,23 @@ static struct irq_info irq_lists[NR_IRQS];
/*
* Here we define the default xmit fifo size used for each type of UART.
*/
static
const
struct
serial
_uart
_config
uart_config
[
PORT_MAX_8250
+
1
]
=
{
{
"unknown"
,
1
,
0
},
{
"8250"
,
1
,
0
},
{
"16450"
,
1
,
0
},
{
"16550"
,
1
,
0
},
{
"16550A"
,
16
,
UART_CLEAR_FIFO
|
UART_USE
_FIFO
},
{
"Cirrus"
,
1
,
0
},
{
"ST16650"
,
1
,
UART_CLEAR_FIFO
|
UART_STARTECH
},
{
"ST16650V2"
,
32
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
|
UART_STARTECH
},
{
"TI16750"
,
64
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
},
{
"Startech"
,
1
,
0
},
{
"16C950/954"
,
128
,
UART_CLEAR_FIFO
|
UART_USE
_FIFO
},
{
"ST16654"
,
64
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
|
UART_STARTECH
},
{
"XR16850"
,
128
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
|
UART_STARTECH
},
{
"RSA"
,
2048
,
UART_CLEAR_FIFO
|
UART_USE
_FIFO
},
{
"NS16550A"
,
16
,
UART_CLEAR_FIFO
|
UART_USE
_FIFO
|
UART_NATSEMI
},
{
"XScale"
,
32
,
UART_CLEAR_FIFO
|
UART_USE_FIFO
},
static
const
struct
serial
8250
_config
uart_config
[
PORT_MAX_8250
+
1
]
=
{
{
"unknown"
,
1
,
1
,
0
},
{
"8250"
,
1
,
1
,
0
},
{
"16450"
,
1
,
1
,
0
},
{
"16550"
,
1
,
1
,
0
},
{
"16550A"
,
16
,
16
,
UART_CAP
_FIFO
},
{
"Cirrus"
,
1
,
1
,
0
},
{
"ST16650"
,
1
,
1
,
UART_CAP_FIFO
|
UART_CAP_SLEEP
|
UART_CAP_EFR
},
{
"ST16650V2"
,
32
,
16
,
UART_CAP_FIFO
|
UART_CAP_SLEEP
|
UART_CAP_EFR
},
{
"TI16750"
,
64
,
64
,
UART_CAP_FIFO
|
UART_CAP_SLEEP
},
{
"Startech"
,
1
,
1
,
0
},
{
"16C950/954"
,
128
,
128
,
UART_CAP
_FIFO
},
{
"ST16654"
,
64
,
32
,
UART_CAP_FIFO
|
UART_CAP_SLEEP
|
UART_CAP_EFR
},
{
"XR16850"
,
128
,
128
,
UART_CAP_FIFO
|
UART_CAP_SLEEP
|
UART_CAP_EFR
},
{
"RSA"
,
2048
,
2048
,
UART_CAP
_FIFO
},
{
"NS16550A"
,
16
,
16
,
UART_CAP
_FIFO
|
UART_NATSEMI
},
{
"XScale"
,
32
,
32
,
UART_CAP_FIFO
},
};
static
_INLINE_
unsigned
int
serial_in
(
struct
uart_8250_port
*
up
,
int
offset
)
...
...
@@ -243,6 +244,41 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
return
value
;
}
/*
* FIFO support.
*/
static
inline
void
serial8250_clear_fifos
(
struct
uart_8250_port
*
p
)
{
if
(
p
->
capabilities
&
UART_CAP_FIFO
)
{
serial_outp
(
p
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
);
serial_outp
(
p
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
|
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
);
serial_outp
(
p
,
UART_FCR
,
0
);
}
}
/*
* IER sleep support. UARTs which have EFRs need the "extended
* capability" bit enabled. Note that on XR16C850s, we need to
* reset LCR to write to IER.
*/
static
inline
void
serial8250_set_sleep
(
struct
uart_8250_port
*
p
,
int
sleep
)
{
if
(
p
->
capabilities
&
UART_CAP_SLEEP
)
{
if
(
p
->
capabilities
&
UART_CAP_EFR
)
{
serial_outp
(
p
,
UART_LCR
,
0xBF
);
serial_outp
(
p
,
UART_EFR
,
UART_EFR_ECB
);
serial_outp
(
p
,
UART_LCR
,
0
);
}
serial_outp
(
p
,
UART_IER
,
sleep
?
UART_IERX_SLEEP
:
0
);
if
(
p
->
capabilities
&
UART_CAP_EFR
)
{
serial_outp
(
p
,
UART_LCR
,
0xBF
);
serial_outp
(
p
,
UART_EFR
,
0
);
serial_outp
(
p
,
UART_LCR
,
0
);
}
}
}
#ifdef CONFIG_SERIAL_8250_RSA
/*
* Attempts to turn on the RSA FIFO. Returns zero on failure.
...
...
@@ -697,8 +733,9 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
#endif
serial_outp
(
up
,
UART_LCR
,
save_lcr
);
up
->
port
.
fifosize
=
uart_config
[
up
->
port
.
type
].
dfl_xmit_
fifo_size
;
up
->
port
.
fifosize
=
uart_config
[
up
->
port
.
type
].
fifo_size
;
up
->
capabilities
=
uart_config
[
up
->
port
.
type
].
flags
;
up
->
tx_loadsz
=
uart_config
[
up
->
port
.
type
].
tx_loadsz
;
if
(
up
->
port
.
type
==
PORT_UNKNOWN
)
goto
out
;
...
...
@@ -711,10 +748,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
serial_outp
(
up
,
UART_RSA_FRR
,
0
);
#endif
serial_outp
(
up
,
UART_MCR
,
save_mcr
);
serial_outp
(
up
,
UART_FCR
,
(
UART_FCR_ENABLE_FIFO
|
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
));
serial_outp
(
up
,
UART_FCR
,
0
);
serial8250_clear_fifos
(
up
);
(
void
)
serial_in
(
up
,
UART_RX
);
serial_outp
(
up
,
UART_IER
,
0
);
...
...
@@ -923,7 +957,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
return
;
}
count
=
up
->
port
.
fifosize
;
count
=
up
->
tx_loadsz
;
do
{
serial_out
(
up
,
UART_TX
,
xmit
->
buf
[
xmit
->
tail
]);
xmit
->
tail
=
(
xmit
->
tail
+
1
)
&
(
UART_XMIT_SIZE
-
1
);
...
...
@@ -1227,12 +1261,7 @@ static int serial8250_startup(struct uart_port *port)
* Clear the FIFO buffers and disable them.
* (they will be reeanbled in set_termios())
*/
if
(
up
->
capabilities
&
UART_CLEAR_FIFO
)
{
serial_outp
(
up
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
);
serial_outp
(
up
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
|
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
);
serial_outp
(
up
,
UART_FCR
,
0
);
}
serial8250_clear_fifos
(
up
);
/*
* Clear the interrupt registers.
...
...
@@ -1253,6 +1282,23 @@ static int serial8250_startup(struct uart_port *port)
return
-
ENODEV
;
}
/*
* For a XR16C850, we need to set the trigger levels
*/
if
(
up
->
port
.
type
==
PORT_16850
)
{
unsigned
char
fctr
;
serial_outp
(
up
,
UART_LCR
,
0xbf
);
fctr
=
serial_inp
(
up
,
UART_FCTR
)
&
~
(
UART_FCTR_RX
|
UART_FCTR_TX
);
serial_outp
(
up
,
UART_FCTR
,
fctr
|
UART_FCTR_TRGD
|
UART_FCTR_RX
);
serial_outp
(
up
,
UART_TRG
,
UART_TRG_96
);
serial_outp
(
up
,
UART_FCTR
,
fctr
|
UART_FCTR_TRGD
|
UART_FCTR_TX
);
serial_outp
(
up
,
UART_TRG
,
UART_TRG_96
);
serial_outp
(
up
,
UART_LCR
,
0
);
}
/*
* If the "interrupt" for this port doesn't correspond with any
* hardware interrupt, we use a timer-based system. The original
...
...
@@ -1345,10 +1391,7 @@ static void serial8250_shutdown(struct uart_port *port)
* Disable break condition and FIFOs
*/
serial_out
(
up
,
UART_LCR
,
serial_inp
(
up
,
UART_LCR
)
&
~
UART_LCR_SBC
);
serial_outp
(
up
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
|
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
);
serial_outp
(
up
,
UART_FCR
,
0
);
serial8250_clear_fifos
(
up
);
#ifdef CONFIG_SERIAL_8250_RSA
/*
...
...
@@ -1440,7 +1483,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
up
->
rev
==
0x5201
)
quot
++
;
if
(
up
->
capabilities
&
UART_
USE_FIFO
)
{
if
(
up
->
capabilities
&
UART_
CAP_FIFO
&&
up
->
port
.
fifosize
>
1
)
{
if
(
baud
<
2400
)
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_TRIGGER_1
;
#ifdef CONFIG_SERIAL_8250_RSA
...
...
@@ -1514,7 +1557,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
serial_out
(
up
,
UART_IER
,
up
->
ier
);
if
(
up
->
capabilities
&
UART_
STARTECH
)
{
if
(
up
->
capabilities
&
UART_
CAP_EFR
)
{
serial_outp
(
up
,
UART_LCR
,
0xBF
);
serial_outp
(
up
,
UART_EFR
,
termios
->
c_cflag
&
CRTSCTS
?
UART_EFR_CTS
:
0
);
...
...
@@ -1554,71 +1597,12 @@ static void
serial8250_pm
(
struct
uart_port
*
port
,
unsigned
int
state
,
unsigned
int
oldstate
)
{
struct
uart_8250_port
*
up
=
(
struct
uart_8250_port
*
)
port
;
if
(
state
)
{
/* sleep */
if
(
up
->
capabilities
&
UART_STARTECH
)
{
/* Arrange to enter sleep mode */
serial_outp
(
up
,
UART_LCR
,
0xBF
);
serial_outp
(
up
,
UART_EFR
,
UART_EFR_ECB
);
serial_outp
(
up
,
UART_LCR
,
0
);
serial_outp
(
up
,
UART_IER
,
UART_IERX_SLEEP
);
serial_outp
(
up
,
UART_LCR
,
0xBF
);
serial_outp
(
up
,
UART_EFR
,
0
);
serial_outp
(
up
,
UART_LCR
,
0
);
}
if
(
up
->
port
.
type
==
PORT_16750
)
{
/* Arrange to enter sleep mode */
serial_outp
(
up
,
UART_IER
,
UART_IERX_SLEEP
);
}
struct
uart_8250_port
*
p
=
(
struct
uart_8250_port
*
)
port
;
if
(
up
->
pm
)
up
->
pm
(
port
,
state
,
oldstate
);
}
else
{
/* wake */
if
(
up
->
capabilities
&
UART_STARTECH
)
{
/* Wake up UART */
serial_outp
(
up
,
UART_LCR
,
0xBF
);
serial_outp
(
up
,
UART_EFR
,
UART_EFR_ECB
);
/*
* Turn off LCR == 0xBF so we actually set the IER
* register on the XR16C850
*/
serial_outp
(
up
,
UART_LCR
,
0
);
serial_outp
(
up
,
UART_IER
,
0
);
/*
* Now reset LCR so we can turn off the ECB bit
*/
serial_outp
(
up
,
UART_LCR
,
0xBF
);
serial_outp
(
up
,
UART_EFR
,
0
);
/*
* For a XR16C850, we need to set the trigger levels
*/
if
(
up
->
port
.
type
==
PORT_16850
)
{
unsigned
char
fctr
;
fctr
=
serial_inp
(
up
,
UART_FCTR
)
&
~
(
UART_FCTR_RX
|
UART_FCTR_TX
);
serial_outp
(
up
,
UART_FCTR
,
fctr
|
UART_FCTR_TRGD
|
UART_FCTR_RX
);
serial_outp
(
up
,
UART_TRG
,
UART_TRG_96
);
serial_outp
(
up
,
UART_FCTR
,
fctr
|
UART_FCTR_TRGD
|
UART_FCTR_TX
);
serial_outp
(
up
,
UART_TRG
,
UART_TRG_96
);
}
serial_outp
(
up
,
UART_LCR
,
0
);
}
serial8250_set_sleep
(
p
,
state
!=
0
);
if
(
up
->
port
.
type
==
PORT_16750
)
{
/* Wake up UART */
serial_outp
(
up
,
UART_IER
,
0
);
}
if
(
up
->
pm
)
up
->
pm
(
port
,
state
,
oldstate
);
}
if
(
p
->
pm
)
p
->
pm
(
port
,
state
,
oldstate
);
}
/*
...
...
drivers/serial/8250.h
View file @
ee9e2c8a
...
...
@@ -33,6 +33,20 @@ struct old_serial_port {
unsigned
short
iomem_reg_shift
;
};
/*
* This replaces serial_uart_config in include/linux/serial.h
*/
struct
serial8250_config
{
const
char
*
name
;
unsigned
int
fifo_size
;
unsigned
int
tx_loadsz
;
unsigned
int
flags
;
};
#define UART_CAP_FIFO (1 << 8)
/* UART has FIFO */
#define UART_CAP_EFR (1 << 9)
/* UART has EFR */
#define UART_CAP_SLEEP (1 << 10)
/* UART has IER sleep */
#undef SERIAL_DEBUG_PCI
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment