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
nexedi
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