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
a0e6cf38
Commit
a0e6cf38
authored
Jan 08, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents
456cb076
077746a2
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
422 additions
and
245 deletions
+422
-245
Documentation/serial/driver
Documentation/serial/driver
+32
-10
drivers/serial/21285.c
drivers/serial/21285.c
+42
-13
drivers/serial/8250.c
drivers/serial/8250.c
+36
-24
drivers/serial/amba.c
drivers/serial/amba.c
+27
-16
drivers/serial/anakin.c
drivers/serial/anakin.c
+28
-5
drivers/serial/clps711x.c
drivers/serial/clps711x.c
+29
-16
drivers/serial/core.c
drivers/serial/core.c
+77
-78
drivers/serial/mux.c
drivers/serial/mux.c
+6
-7
drivers/serial/nb85e_uart.c
drivers/serial/nb85e_uart.c
+6
-8
drivers/serial/sa1100.c
drivers/serial/sa1100.c
+45
-24
drivers/serial/sunsab.c
drivers/serial/sunsab.c
+5
-10
drivers/serial/sunsu.c
drivers/serial/sunsu.c
+28
-8
drivers/serial/sunzilog.c
drivers/serial/sunzilog.c
+8
-7
drivers/serial/uart00.c
drivers/serial/uart00.c
+31
-15
include/linux/serial_core.h
include/linux/serial_core.h
+22
-4
No files found.
Documentation/serial/driver
View file @
a0e6cf38
...
...
@@ -176,11 +176,11 @@ hardware.
Locking: port_sem taken.
Interrupts: caller dependent.
change_speed(port,cflag,iflag,quot
)
set_termios(port,termios,oldtermios
)
Change the port parameters, including word length, parity, stop
bits. Update read_status_mask and ignore_status_mask to indicate
the types of events we are interested in receiving. Relevant
cflag bits are:
termios->c_
cflag bits are:
CSIZE - word size
CSTOPB - 2 stop bits
PARENB - parity enable
...
...
@@ -191,7 +191,7 @@ hardware.
CRTSCTS - if set, enable CTS status change reporting
CLOCAL - if not set, enable modem status change
reporting.
Relevant iflag bits are:
Relevant
termios->c_
iflag bits are:
INPCK - enable frame and parity error events to be
passed to the TTY layer.
BRKINT
...
...
@@ -278,6 +278,35 @@ hardware.
Locking: none.
Interrupts: caller dependent.
Other functions
---------------
uart_update_timeout(port,cflag,quot)
Update the FIFO drain timeout, port->timeout, according to the
number of bits, parity, stop bits and quotient.
Locking: caller is expected to take port->lock
Interrupts: n/a
uart_get_baud_rate(port,termios)
Return the numeric baud rate for the specified termios, taking
account of the special 38400 baud "kludge". The B0 baud rate
is mapped to 9600 baud.
Locking: caller dependent.
Interrupts: n/a
uart_get_divisor(port,termios,oldtermios)
Return the divsor (baud_base / baud) for the selected baud rate
specified by termios. If the baud rate is out of range, try
the original baud rate specified by oldtermios (if non-NULL).
If that fails, try 9600 baud.
If 38400 baud and custom divisor is selected, return the
custom divisor instead.
Locking: caller dependent.
Interrupts: n/a
Other notes
-----------
...
...
@@ -292,10 +321,3 @@ thus:
struct uart_port port;
int my_stuff;
};
Todo
----
Please see the BUGS file in CVS at
http://cvs.arm.linux.org.uk/cgi/viewcvs.cgi/serial/BUGS
drivers/serial/21285.c
View file @
a0e6cf38
...
...
@@ -233,12 +233,29 @@ static void serial21285_shutdown(struct uart_port *port)
}
static
void
serial21285_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
serial21285_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
h_lcr
;
unsigned
long
flags
;
unsigned
int
quot
,
h_lcr
;
/*
* We don't support modem control lines.
*/
termios
->
c_cflag
&=
~
(
HUPCL
|
CRTSCTS
|
CMSPAR
);
termios
->
c_cflag
|=
CLOCAL
;
/*
* We don't support BREAK character recognition.
*/
termios
->
c_iflag
&=
~
(
IGNBRK
|
BRKINT
);
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
switch
(
cflag
&
CSIZE
)
{
switch
(
termios
->
c_
cflag
&
CSIZE
)
{
case
CS5
:
h_lcr
=
0x00
;
break
;
...
...
@@ -253,34 +270,44 @@ serial21285_change_speed(struct uart_port *port, unsigned int cflag,
break
;
}
if
(
cflag
&
CSTOPB
)
if
(
termios
->
c_
cflag
&
CSTOPB
)
h_lcr
|=
H_UBRLCR_STOPB
;
if
(
cflag
&
PARENB
)
{
if
(
termios
->
c_
cflag
&
PARENB
)
{
h_lcr
|=
H_UBRLCR_PARENB
;
if
(
!
(
cflag
&
PARODD
))
if
(
!
(
termios
->
c_
cflag
&
PARODD
))
h_lcr
|=
H_UBRLCR_PAREVN
;
}
if
(
port
->
fifosize
)
h_lcr
|=
H_UBRLCR_FIFO
;
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
/*
* Which character status flags are we interested in?
*/
port
->
read_status_mask
=
RXSTAT_OVERRUN
;
if
(
iflag
&
INPCK
)
if
(
termios
->
c_
iflag
&
INPCK
)
port
->
read_status_mask
|=
RXSTAT_FRAME
|
RXSTAT_PARITY
;
/*
*
Characters to ignore
*
Which character status flags should we ignore?
*/
port
->
ignore_status_mask
=
0
;
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
RXSTAT_FRAME
|
RXSTAT_PARITY
;
if
(
iflag
&
IGNBRK
&&
iflag
&
IGNPAR
)
if
(
termios
->
c_iflag
&
IGNBRK
&&
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
RXSTAT_OVERRUN
;
/*
* Ignore all characters if CREAD is not set.
*/
if
((
cflag
&
CREAD
)
==
0
)
if
((
termios
->
c_
cflag
&
CREAD
)
==
0
)
port
->
ignore_status_mask
|=
RXSTAT_DUMMY_READ
;
quot
-=
1
;
...
...
@@ -290,6 +317,8 @@ serial21285_change_speed(struct uart_port *port, unsigned int cflag,
*
CSR_M_UBRLCR
=
(
quot
>>
8
)
&
0x0f
;
*
CSR_H_UBRLCR
=
h_lcr
;
*
CSR_UARTCON
=
1
;
spin_unlock_irqrestore
(
&
port
->
lock
,
flags
);
}
static
const
char
*
serial21285_type
(
struct
uart_port
*
port
)
...
...
@@ -340,7 +369,7 @@ static struct uart_ops serial21285_ops = {
.
break_ctl
=
serial21285_break_ctl
,
.
startup
=
serial21285_startup
,
.
shutdown
=
serial21285_shutdown
,
.
change_speed
=
serial21285_change_speed
,
.
set_termios
=
serial21285_set_termios
,
.
type
=
serial21285_type
,
.
release_port
=
serial21285_release_port
,
.
request_port
=
serial21285_request_port
,
...
...
drivers/serial/8250.c
View file @
a0e6cf38
...
...
@@ -1174,7 +1174,7 @@ static int serial8250_startup(struct uart_port *port)
/*
* Clear the FIFO buffers and disable them.
* (they will be reeanbled in
change_speed
())
* (they will be reeanbled in
set_termios
())
*/
if
(
uart_config
[
up
->
port
.
type
].
flags
&
UART_CLEAR_FIFO
)
{
serial_outp
(
up
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
);
...
...
@@ -1241,7 +1241,7 @@ static int serial8250_startup(struct uart_port *port)
/*
* Finally, enable interrupts. Note: Modem status interrupts
* are set via
change_speed
(), which will be occuring imminently
* are set via
set_termios
(), which will be occuring imminently
* anyway, so we don't enable them here.
*/
up
->
ier
=
UART_IER_RLSI
|
UART_IER_RDI
;
...
...
@@ -1319,14 +1319,15 @@ static void serial8250_shutdown(struct uart_port *port)
}
static
void
serial8250_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
serial8250_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
struct
uart_8250_port
*
up
=
(
struct
uart_8250_port
*
)
port
;
unsigned
char
cval
,
fcr
=
0
;
unsigned
long
flags
;
unsigned
int
quot
;
switch
(
cflag
&
CSIZE
)
{
switch
(
termios
->
c_
cflag
&
CSIZE
)
{
case
CS5
:
cval
=
0x00
;
break
;
...
...
@@ -1342,17 +1343,22 @@ serial8250_change_speed(struct uart_port *port, unsigned int cflag,
break
;
}
if
(
cflag
&
CSTOPB
)
if
(
termios
->
c_
cflag
&
CSTOPB
)
cval
|=
0x04
;
if
(
cflag
&
PARENB
)
if
(
termios
->
c_
cflag
&
PARENB
)
cval
|=
UART_LCR_PARITY
;
if
(
!
(
cflag
&
PARODD
))
if
(
!
(
termios
->
c_
cflag
&
PARODD
))
cval
|=
UART_LCR_EPAR
;
#ifdef CMSPAR
if
(
cflag
&
CMSPAR
)
if
(
termios
->
c_
cflag
&
CMSPAR
)
cval
|=
UART_LCR_SPAR
;
#endif
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
/*
* Work around a bug in the Oxford Semiconductor 952 rev B
* chip which causes it to seriously miscalculate baud rates
...
...
@@ -1375,52 +1381,58 @@ serial8250_change_speed(struct uart_port *port, unsigned int cflag,
if
(
up
->
port
.
type
==
PORT_16750
)
fcr
|=
UART_FCR7_64BYTE
;
/*
* Ok, we're now changing the port state. Do it with
* interrupts disabled.
*/
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
up
->
port
.
read_status_mask
=
UART_LSR_OE
|
UART_LSR_THRE
|
UART_LSR_DR
;
if
(
iflag
&
INPCK
)
if
(
termios
->
c_
iflag
&
INPCK
)
up
->
port
.
read_status_mask
|=
UART_LSR_FE
|
UART_LSR_PE
;
if
(
iflag
&
(
BRKINT
|
PARMRK
))
if
(
termios
->
c_
iflag
&
(
BRKINT
|
PARMRK
))
up
->
port
.
read_status_mask
|=
UART_LSR_BI
;
/*
* Characteres to ignore
*/
up
->
port
.
ignore_status_mask
=
0
;
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
up
->
port
.
ignore_status_mask
|=
UART_LSR_PE
|
UART_LSR_FE
;
if
(
iflag
&
IGNBRK
)
{
if
(
termios
->
c_
iflag
&
IGNBRK
)
{
up
->
port
.
ignore_status_mask
|=
UART_LSR_BI
;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
up
->
port
.
ignore_status_mask
|=
UART_LSR_OE
;
}
/*
* ignore all characters if CREAD is not set
*/
if
((
cflag
&
CREAD
)
==
0
)
if
((
termios
->
c_
cflag
&
CREAD
)
==
0
)
up
->
port
.
ignore_status_mask
|=
UART_LSR_DR
;
/*
* Ok, we're now changing the port state. Do it with
* interrupts disabled.
*/
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
/*
* CTS flow control flag and modem status interrupts
*/
up
->
ier
&=
~
UART_IER_MSI
;
if
(
UART_ENABLE_MS
(
&
up
->
port
,
cflag
))
if
(
UART_ENABLE_MS
(
&
up
->
port
,
termios
->
c_
cflag
))
up
->
ier
|=
UART_IER_MSI
;
serial_out
(
up
,
UART_IER
,
up
->
ier
);
if
(
uart_config
[
up
->
port
.
type
].
flags
&
UART_STARTECH
)
{
serial_outp
(
up
,
UART_LCR
,
0xBF
);
serial_outp
(
up
,
UART_EFR
,
cflag
&
CRTSCTS
?
UART_EFR_CTS
:
0
);
serial_outp
(
up
,
UART_EFR
,
termios
->
c_cflag
&
CRTSCTS
?
UART_EFR_CTS
:
0
);
}
serial_outp
(
up
,
UART_LCR
,
cval
|
UART_LCR_DLAB
);
/* set DLAB */
serial_outp
(
up
,
UART_DLL
,
quot
&
0xff
);
/* LS of divisor */
...
...
@@ -1728,7 +1740,7 @@ static struct uart_ops serial8250_pops = {
.
break_ctl
=
serial8250_break_ctl
,
.
startup
=
serial8250_startup
,
.
shutdown
=
serial8250_shutdown
,
.
change_speed
=
serial8250_change_speed
,
.
set_termios
=
serial8250_set_termios
,
.
pm
=
serial8250_pm
,
.
type
=
serial8250_type
,
.
release_port
=
serial8250_release_port
,
...
...
drivers/serial/amba.c
View file @
a0e6cf38
...
...
@@ -403,14 +403,19 @@ static void ambauart_shutdown(struct uart_port *port)
}
static
void
ambauart_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
ambauart_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
lcr_h
,
old_cr
;
unsigned
long
flags
;
unsigned
int
quot
;
/* byte size and parity */
switch
(
cflag
&
CSIZE
)
{
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
switch
(
termios
->
c_cflag
&
CSIZE
)
{
case
CS5
:
lcr_h
=
AMBA_UARTLCR_H_WLEN_5
;
break
;
...
...
@@ -424,49 +429,55 @@ ambauart_change_speed(struct uart_port *port, unsigned int cflag,
lcr_h
=
AMBA_UARTLCR_H_WLEN_8
;
break
;
}
if
(
cflag
&
CSTOPB
)
if
(
termios
->
c_
cflag
&
CSTOPB
)
lcr_h
|=
AMBA_UARTLCR_H_STP2
;
if
(
cflag
&
PARENB
)
{
if
(
termios
->
c_
cflag
&
PARENB
)
{
lcr_h
|=
AMBA_UARTLCR_H_PEN
;
if
(
!
(
cflag
&
PARODD
))
if
(
!
(
termios
->
c_
cflag
&
PARODD
))
lcr_h
|=
AMBA_UARTLCR_H_EPS
;
}
if
(
port
->
fifosize
>
1
)
lcr_h
|=
AMBA_UARTLCR_H_FEN
;
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
port
->
read_status_mask
=
AMBA_UARTRSR_OE
;
if
(
iflag
&
INPCK
)
if
(
termios
->
c_
iflag
&
INPCK
)
port
->
read_status_mask
|=
AMBA_UARTRSR_FE
|
AMBA_UARTRSR_PE
;
if
(
iflag
&
(
BRKINT
|
PARMRK
))
if
(
termios
->
c_
iflag
&
(
BRKINT
|
PARMRK
))
port
->
read_status_mask
|=
AMBA_UARTRSR_BE
;
/*
* Characters to ignore
*/
port
->
ignore_status_mask
=
0
;
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
AMBA_UARTRSR_FE
|
AMBA_UARTRSR_PE
;
if
(
iflag
&
IGNBRK
)
{
if
(
termios
->
c_
iflag
&
IGNBRK
)
{
port
->
ignore_status_mask
|=
AMBA_UARTRSR_BE
;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
AMBA_UARTRSR_OE
;
}
/*
* Ignore all characters if CREAD is not set.
*/
if
((
cflag
&
CREAD
)
==
0
)
if
((
termios
->
c_
cflag
&
CREAD
)
==
0
)
port
->
ignore_status_mask
|=
UART_DUMMY_RSR_RX
;
/* first, disable everything */
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
old_cr
=
UART_GET_CR
(
port
)
&
~
AMBA_UARTCR_MSIE
;
if
(
UART_ENABLE_MS
(
port
,
cflag
))
if
(
UART_ENABLE_MS
(
port
,
termios
->
c_
cflag
))
old_cr
|=
AMBA_UARTCR_MSIE
;
UART_PUT_CR
(
port
,
0
);
...
...
@@ -546,7 +557,7 @@ static struct uart_ops amba_pops = {
.
break_ctl
=
ambauart_break_ctl
,
.
startup
=
ambauart_startup
,
.
shutdown
=
ambauart_shutdown
,
.
change_speed
=
ambauart_change_speed
,
.
set_termios
=
ambauart_set_termios
,
.
type
=
ambauart_type
,
.
release_port
=
ambauart_release_port
,
.
request_port
=
ambauart_request_port
,
...
...
drivers/serial/anakin.c
View file @
a0e6cf38
...
...
@@ -283,13 +283,36 @@ static void anakin_shutdown(struct uart_port *port)
}
static
void
anakin_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
anakin_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
flags
;
unsigned
long
flags
;
unsigned
int
quot
;
/*
* We don't support parity, stop bits, or anything other
* than 8 bits, so clear these termios flags.
*/
termios
->
c_cflag
&=
~
(
CSIZE
|
CSTOPB
|
PARENB
|
PARODD
|
CREAD
);
termios
->
c_cflag
|=
CS8
;
/*
* We don't appear to support any error conditions either.
*/
termios
->
c_iflag
&=
~
(
INPCK
|
IGNPAR
|
IGNBRK
|
BRKINT
);
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
while
(
!
(
anakin_in
(
port
,
0x10
)
&
TXEMPTY
));
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
while
(
!
(
anakin_in
(
port
,
0x10
)
&
TXEMPTY
))
barrier
();
anakin_out
(
port
,
0x10
,
(
anakin_in
(
port
,
0x10
)
&
~
PRESCALER
)
|
(
quot
<<
3
));
...
...
@@ -314,7 +337,7 @@ static struct uart_ops anakin_pops = {
.
break_ctl
=
anakin_break_ctl
,
.
startup
=
anakin_startup
,
.
shutdown
=
anakin_shutdown
,
.
change_speed
=
anakin_change_speed
,
.
set_termios
=
anakin_set_termios
,
.
type
=
anakin_type
,
};
...
...
drivers/serial/clps711x.c
View file @
a0e6cf38
...
...
@@ -317,14 +317,23 @@ static void clps711xuart_shutdown(struct uart_port *port)
}
static
void
clps711xuart_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
clps711xuart_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
ubrlcr
;
unsigned
int
ubrlcr
,
quot
;
unsigned
long
flags
;
/* byte size and parity */
switch
(
cflag
&
CSIZE
)
{
/*
* We don't implement CREAD.
*/
termios
->
c_cflag
|=
CREAD
;
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
switch
(
termios
->
c_cflag
&
CSIZE
)
{
case
CS5
:
ubrlcr
=
UBRLCR_WRDLEN5
;
break
;
...
...
@@ -338,40 +347,44 @@ clps711xuart_change_speed(struct uart_port *port, unsigned int cflag,
ubrlcr
=
UBRLCR_WRDLEN8
;
break
;
}
if
(
cflag
&
CSTOPB
)
if
(
termios
->
c_
cflag
&
CSTOPB
)
ubrlcr
|=
UBRLCR_XSTOP
;
if
(
cflag
&
PARENB
)
{
if
(
termios
->
c_
cflag
&
PARENB
)
{
ubrlcr
|=
UBRLCR_PRTEN
;
if
(
!
(
cflag
&
PARODD
))
if
(
!
(
termios
->
c_
cflag
&
PARODD
))
ubrlcr
|=
UBRLCR_EVENPRT
;
}
if
(
port
->
fifosize
>
1
)
ubrlcr
|=
UBRLCR_FIFOEN
;
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
port
->
read_status_mask
=
UARTDR_OVERR
;
if
(
iflag
&
INPCK
)
if
(
termios
->
c_
iflag
&
INPCK
)
port
->
read_status_mask
|=
UARTDR_PARERR
|
UARTDR_FRMERR
;
/*
* Characters to ignore
*/
port
->
ignore_status_mask
=
0
;
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
UARTDR_FRMERR
|
UARTDR_PARERR
;
if
(
iflag
&
IGNBRK
)
{
if
(
termios
->
c_
iflag
&
IGNBRK
)
{
/*
* If we're ignoring parity and break indicators,
* ignore overruns to (for real raw support).
*/
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
UARTDR_OVERR
;
}
quot
-=
1
;
/* first, disable everything */
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
clps_writel
(
ubrlcr
|
quot
,
UBRLCR
(
port
));
spin_unlock_irqrestore
(
&
port
->
lock
,
flags
);
...
...
@@ -411,7 +424,7 @@ static struct uart_ops clps711x_pops = {
.
break_ctl
=
clps711xuart_break_ctl
,
.
startup
=
clps711xuart_startup
,
.
shutdown
=
clps711xuart_shutdown
,
.
change_speed
=
clps711xuart_change_speed
,
.
set_termios
=
clps711xuart_set_termios
,
.
type
=
clps711xuart_type
,
.
config_port
=
clps711xuart_config_port
,
.
release_port
=
clps711xuart_release_port
,
...
...
drivers/serial/core.c
View file @
a0e6cf38
...
...
@@ -314,40 +314,68 @@ EXPORT_SYMBOL(uart_update_timeout);
* uart_get_baud_rate - return baud rate for a particular port
* @port: uart_port structure describing the port in question.
* @termios: desired termios settings.
* @old: old termios (or NULL)
* @min: minimum acceptable baud rate
* @max: maximum acceptable baud rate
*
* Decode the termios structure into a numeric baud rate,
* taking account of the magic 38400 baud rate (with spd_*
* flags), and mapping the %B0 rate to 9600 baud.
*/
unsigned
int
uart_get_baud_rate
(
struct
uart_port
*
port
,
struct
termios
*
termios
)
uart_get_baud_rate
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
,
unsigned
int
min
,
unsigned
int
max
)
{
unsigned
int
baud
=
tty_termios_baud_rate
(
termios
);
unsigned
int
try
,
baud
,
altbaud
=
38400
;
unsigned
int
flags
=
port
->
flags
&
UPF_SPD_MASK
;
/*
* The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
* Die! Die! Die!
*/
if
(
baud
==
38400
)
{
unsigned
int
flags
=
port
->
flags
&
UPF_SPD_MASK
;
if
(
flags
==
UPF_SPD_HI
)
baud
=
57600
;
if
(
flags
==
UPF_SPD_VHI
)
baud
=
115200
;
if
(
flags
==
UPF_SPD_SHI
)
baud
=
230400
;
if
(
flags
==
UPF_SPD_WARP
)
baud
=
460800
;
}
if
(
flags
==
UPF_SPD_HI
)
altbaud
=
57600
;
if
(
flags
==
UPF_SPD_VHI
)
altbaud
=
115200
;
if
(
flags
==
UPF_SPD_SHI
)
altbaud
=
230400
;
if
(
flags
==
UPF_SPD_WARP
)
altbaud
=
460800
;
/*
* Special case: B0 rate.
*/
if
(
baud
==
0
)
baud
=
9600
;
for
(
try
=
0
;
try
<
2
;
try
++
)
{
baud
=
tty_termios_baud_rate
(
termios
);
/*
* The spd_hi, spd_vhi, spd_shi, spd_warp kludge...
* Die! Die! Die!
*/
if
(
baud
==
38400
)
baud
=
altbaud
;
/*
* Special case: B0 rate.
*/
if
(
baud
==
0
)
baud
=
9600
;
if
(
baud
>=
min
&&
baud
<=
max
)
return
baud
;
/*
* Oops, the quotient was zero. Try again with
* the old baud rate if possible.
*/
termios
->
c_cflag
&=
~
CBAUD
;
if
(
old
)
{
termios
->
c_cflag
|=
old
->
c_cflag
&
CBAUD
;
old
=
NULL
;
continue
;
}
/*
* As a last resort, if the quotient is zero,
* default to 9600 bps
*/
termios
->
c_cflag
|=
B9600
;
}
return
baud
;
return
0
;
}
EXPORT_SYMBOL
(
uart_get_baud_rate
);
...
...
@@ -355,16 +383,6 @@ EXPORT_SYMBOL(uart_get_baud_rate);
static
inline
unsigned
int
uart_calculate_quot
(
struct
uart_port
*
port
,
unsigned
int
baud
)
{
unsigned
int
quot
;
/*
* Old custom speed handling.
*/
if
(
baud
==
38400
&&
(
port
->
flags
&
UPF_SPD_MASK
)
==
UPF_SPD_CUST
)
quot
=
port
->
custom_divisor
;
else
quot
=
port
->
uartclk
/
(
16
*
baud
);
return
quot
;
}
...
...
@@ -387,34 +405,18 @@ unsigned int
uart_get_divisor
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old_termios
)
{
unsigned
int
quot
,
try
;
for
(
try
=
0
;
try
<
3
;
try
++
)
{
unsigned
int
baud
;
/* Determine divisor based on baud rate */
baud
=
uart_get_baud_rate
(
port
,
termios
);
quot
=
uart_calculate_quot
(
port
,
baud
);
if
(
quot
)
return
quot
;
unsigned
int
quot
,
baud
,
max
=
port
->
uartclk
/
16
;
/*
* Oops, the quotient was zero. Try again with
* the old baud rate if possible.
*/
termios
->
c_cflag
&=
~
CBAUD
;
if
(
old_termios
)
{
termios
->
c_cflag
|=
old_termios
->
c_cflag
&
CBAUD
;
old_termios
=
NULL
;
continue
;
}
/* Determine divisor based on baud rate */
baud
=
uart_get_baud_rate
(
port
,
termios
,
old_termios
,
0
,
max
);
/*
* As a last resort, if the quotient is zero,
* default to 9600 bps
*/
termios
->
c_cflag
|=
B9600
;
}
/*
* Old custom speed handling.
*/
if
(
baud
==
38400
&&
(
port
->
flags
&
UPF_SPD_MASK
)
==
UPF_SPD_CUST
)
quot
=
port
->
custom_divisor
;
else
quot
=
port
->
uartclk
/
(
16
*
baud
);
return
quot
;
}
...
...
@@ -451,10 +453,7 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios)
else
info
->
flags
|=
UIF_CHECK_CD
;
quot
=
uart_get_divisor
(
port
,
termios
,
old_termios
);
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
port
->
ops
->
change_speed
(
port
,
termios
->
c_cflag
,
termios
->
c_iflag
,
quot
);
port
->
ops
->
set_termios
(
port
,
termios
,
old_termios
);
}
static
inline
void
...
...
@@ -827,7 +826,7 @@ uart_set_info(struct uart_info *info, struct serial_struct *newinfo)
port
->
irq
=
new_serial
.
irq
;
port
->
uartclk
=
new_serial
.
baud_base
*
16
;
port
->
flags
=
new_serial
.
flags
&
UPF_
FLAGS
;
port
->
flags
=
new_serial
.
flags
&
UPF_
CHANGE_MASK
;
port
->
custom_divisor
=
new_serial
.
custom_divisor
;
state
->
close_delay
=
new_serial
.
close_delay
*
HZ
/
100
;
state
->
closing_wait
=
new_serial
.
closing_wait
*
HZ
/
100
;
...
...
@@ -1267,7 +1266,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
if
(
tty
->
ldisc
.
flush_buffer
)
tty
->
ldisc
.
flush_buffer
(
tty
);
tty
->
closing
=
0
;
info
->
event
=
0
;
info
->
tty
=
NULL
;
if
(
info
->
blocked_open
)
{
if
(
info
->
state
->
close_delay
)
{
...
...
@@ -1376,7 +1374,6 @@ static void uart_hangup(struct tty_struct *tty)
return
;
}
uart_shutdown
(
info
);
info
->
event
=
0
;
state
->
count
=
0
;
info
->
flags
&=
~
UIF_NORMAL_ACTIVE
;
info
->
tty
=
NULL
;
...
...
@@ -1859,10 +1856,13 @@ int __init
uart_set_options
(
struct
uart_port
*
port
,
struct
console
*
co
,
int
baud
,
int
parity
,
int
bits
,
int
flow
)
{
unsigned
int
cflag
=
CREAD
|
HUPCL
|
CLOCAL
;
unsigned
int
quot
;
struct
termios
termios
;
int
i
;
memset
(
&
termios
,
0
,
sizeof
(
struct
termios
));
termios
.
c_cflag
=
CREAD
|
HUPCL
|
CLOCAL
;
/*
* Construct a cflag setting.
*/
...
...
@@ -1870,28 +1870,27 @@ uart_set_options(struct uart_port *port, struct console *co,
if
(
baud_rates
[
i
].
rate
<=
baud
)
break
;
cflag
|=
baud_rates
[
i
].
cflag
;
termios
.
c_
cflag
|=
baud_rates
[
i
].
cflag
;
if
(
bits
==
7
)
cflag
|=
CS7
;
termios
.
c_
cflag
|=
CS7
;
else
cflag
|=
CS8
;
termios
.
c_
cflag
|=
CS8
;
switch
(
parity
)
{
case
'o'
:
case
'O'
:
cflag
|=
PARODD
;
termios
.
c_
cflag
|=
PARODD
;
/*fall through*/
case
'e'
:
case
'E'
:
cflag
|=
PARENB
;
termios
.
c_
cflag
|=
PARENB
;
break
;
}
if
(
flow
==
'r'
)
cflag
|=
CRTSCTS
;
termios
.
c_
cflag
|=
CRTSCTS
;
co
->
cflag
=
cflag
;
quot
=
(
port
->
uartclk
/
(
16
*
baud
));
port
->
ops
->
change_speed
(
port
,
cflag
,
0
,
quot
);
port
->
ops
->
set_termios
(
port
,
&
termios
,
NULL
);
co
->
cflag
=
termios
.
c_cflag
;
return
0
;
}
...
...
drivers/serial/mux.c
View file @
a0e6cf38
...
...
@@ -268,17 +268,16 @@ static void mux_shutdown(struct uart_port *port)
}
/**
* mux_
change_speed
- Chane port parameters.
* mux_
set_termios
- Chane port parameters.
* @port: Ptr to the uart_port.
* @cflag: character flags.
* @iflag: interrupt flags.
* @quot:
* @termios: new termios settings.
* @old: old termios settings.
*
* The Serial Mux does not support this function.
*/
static
void
mux_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
mux_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
}
...
...
@@ -388,7 +387,7 @@ static struct uart_ops mux_pops = {
.
break_ctl
=
mux_break_ctl
,
.
startup
=
mux_startup
,
.
shutdown
=
mux_shutdown
,
.
change_speed
=
mux_change_speed
,
.
set_termios
=
mux_set_termios
,
.
type
=
mux_type
,
.
release_port
=
mux_release_port
,
.
request_port
=
mux_request_port
,
...
...
drivers/serial/nb85e_uart.c
View file @
a0e6cf38
...
...
@@ -440,15 +440,13 @@ static void nb85e_uart_shutdown (struct uart_port *port)
}
static
void
nb85e_uart_
change_speed
(
struct
uart_port
*
port
,
unsigned
cflag
s
,
unsigned
iflag
,
unsigned
quot
)
nb85e_uart_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termio
s
,
struct
termios
*
old
)
{
/* The serial framework doesn't give us the baud rate directly, but
insists on calculating a `quotient' from it, and giving us that
instead. Get the real baud rate from the tty code instead. */
int
baud
=
tty_get_baud_rate
(
port
->
info
->
tty
);
/* FIXME: Which termios flags does this driver support? --rmk */
nb85e_uart_configure
(
port
->
line
,
cflags
,
baud
);
nb85e_uart_configure
(
port
->
line
,
termios
->
c_cflags
,
uart_get_baud_rate
(
port
,
termios
));
}
static
const
char
*
nb85e_uart_type
(
struct
uart_port
*
port
)
...
...
@@ -483,7 +481,7 @@ static struct uart_ops nb85e_uart_ops = {
.
break_ctl
=
nb85e_uart_break_ctl
,
.
startup
=
nb85e_uart_startup
,
.
shutdown
=
nb85e_uart_shutdown
,
.
change_speed
=
nb85e_uart_change_speed
,
.
set_termios
=
nb85e_uart_set_termios
,
.
type
=
nb85e_uart_type
,
.
release_port
=
nb85e_uart_nop
,
.
request_port
=
nb85e_uart_success
,
...
...
drivers/serial/sa1100.c
View file @
a0e6cf38
...
...
@@ -436,36 +436,50 @@ static void sa1100_shutdown(struct uart_port *port)
}
static
void
sa1100_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
sa1100_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
struct
sa1100_port
*
sport
=
(
struct
sa1100_port
*
)
port
;
unsigned
long
flags
;
unsigned
int
utcr0
,
old_utcr3
;
unsigned
int
utcr0
,
old_utcr3
,
quot
;
unsigned
int
old_csize
=
old
?
old
->
c_cflag
&
CSIZE
:
CS8
;
/*
byte size and parity */
switch
(
cflag
&
CSIZE
)
{
case
CS7
:
utcr0
=
0
;
break
;
default:
utcr0
=
UTCR0_DSS
;
break
;
/*
* We only support CS7 and CS8.
*/
while
((
termios
->
c_cflag
&
CSIZE
)
!=
CS7
&&
(
termios
->
c_cflag
&
CSIZE
)
!=
CS8
)
{
termios
->
c_cflag
&=
~
CSIZE
;
termios
->
c_cflag
|=
old_csize
;
old_csize
=
CS8
;
}
if
(
cflag
&
CSTOPB
)
if
((
termios
->
c_cflag
&
CSIZE
)
==
CS8
)
utcr0
=
UTCR0_DSS
;
else
utcr0
=
0
;
if
(
termios
->
c_cflag
&
CSTOPB
)
utcr0
|=
UTCR0_SBS
;
if
(
cflag
&
PARENB
)
{
if
(
termios
->
c_
cflag
&
PARENB
)
{
utcr0
|=
UTCR0_PE
;
if
(
!
(
cflag
&
PARODD
))
if
(
!
(
termios
->
c_
cflag
&
PARODD
))
utcr0
|=
UTCR0_OES
;
}
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
spin_lock_irqsave
(
&
sport
->
port
.
lock
,
flags
);
sport
->
port
.
read_status_mask
&=
UTSR0_TO_SM
(
UTSR0_TFS
);
sport
->
port
.
read_status_mask
|=
UTSR1_TO_SM
(
UTSR1_ROR
);
if
(
iflag
&
INPCK
)
if
(
termios
->
c_
iflag
&
INPCK
)
sport
->
port
.
read_status_mask
|=
UTSR1_TO_SM
(
UTSR1_FRE
|
UTSR1_PRE
);
if
(
iflag
&
(
BRKINT
|
PARMRK
))
if
(
termios
->
c_
iflag
&
(
BRKINT
|
PARMRK
))
sport
->
port
.
read_status_mask
|=
UTSR0_TO_SM
(
UTSR0_RBB
|
UTSR0_REB
);
...
...
@@ -473,29 +487,36 @@ sa1100_change_speed(struct uart_port *port, unsigned int cflag,
* Characters to ignore
*/
sport
->
port
.
ignore_status_mask
=
0
;
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
sport
->
port
.
ignore_status_mask
|=
UTSR1_TO_SM
(
UTSR1_FRE
|
UTSR1_PRE
);
if
(
iflag
&
IGNBRK
)
{
if
(
termios
->
c_
iflag
&
IGNBRK
)
{
sport
->
port
.
ignore_status_mask
|=
UTSR0_TO_SM
(
UTSR0_RBB
|
UTSR0_REB
);
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
sport
->
port
.
ignore_status_mask
|=
UTSR1_TO_SM
(
UTSR1_ROR
);
}
del_timer_sync
(
&
sport
->
timer
);
/* first, disable interrupts and drain transmitter */
spin_lock_irqsave
(
&
sport
->
port
.
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
/*
* disable interrupts and drain transmitter
*/
old_utcr3
=
UART_GET_UTCR3
(
sport
);
UART_PUT_UTCR3
(
sport
,
old_utcr3
&
~
(
UTCR3_RIE
|
UTCR3_TIE
));
while
(
UART_GET_UTSR1
(
sport
)
&
UTSR1_TBY
);
while
(
UART_GET_UTSR1
(
sport
)
&
UTSR1_TBY
)
barrier
();
/* then, disable everything */
UART_PUT_UTCR3
(
sport
,
0
);
...
...
@@ -512,7 +533,7 @@ sa1100_change_speed(struct uart_port *port, unsigned int cflag,
UART_PUT_UTCR3
(
sport
,
old_utcr3
);
if
(
UART_ENABLE_MS
(
&
sport
->
port
,
cflag
))
if
(
UART_ENABLE_MS
(
&
sport
->
port
,
termios
->
c_
cflag
))
sa1100_enable_ms
(
&
sport
->
port
);
spin_unlock_irqrestore
(
&
sport
->
port
.
lock
,
flags
);
...
...
@@ -597,7 +618,7 @@ static struct uart_ops sa1100_pops = {
.
break_ctl
=
sa1100_break_ctl
,
.
startup
=
sa1100_startup
,
.
shutdown
=
sa1100_shutdown
,
.
change_speed
=
sa1100_change_speed
,
.
set_termios
=
sa1100_set_termios
,
.
type
=
sa1100_type
,
.
release_port
=
sa1100_release_port
,
.
request_port
=
sa1100_request_port
,
...
...
drivers/serial/sunsab.c
View file @
a0e6cf38
...
...
@@ -763,20 +763,15 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla
}
/* port->lock is not held. */
static
void
sunsab_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
static
void
sunsab_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
struct
uart_sunsab_port
*
up
=
(
struct
uart_sunsab_port
*
)
port
;
unsigned
long
flags
;
int
baud
;
int
baud
=
uart_get_baud_rate
(
port
,
termios
)
;
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
/* Undo what generic UART core did. */
baud
=
(
SAB_BASE_BAUD
/
(
quot
*
16
));
sunsab_convert_to_sab
(
up
,
cflag
,
iflag
,
baud
);
sunsab_convert_to_sab
(
up
,
termios
->
c_cflag
,
termios
->
c_iflag
,
baud
);
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
}
...
...
@@ -819,7 +814,7 @@ static struct uart_ops sunsab_pops = {
.
break_ctl
=
sunsab_break_ctl
,
.
startup
=
sunsab_startup
,
.
shutdown
=
sunsab_shutdown
,
.
change_speed
=
sunsab_change_speed
,
.
set_termios
=
sunsab_set_termios
,
.
type
=
sunsab_type
,
.
release_port
=
sunsab_release_port
,
.
request_port
=
sunsab_request_port
,
...
...
drivers/serial/sunsu.c
View file @
a0e6cf38
...
...
@@ -660,7 +660,7 @@ static int sunsu_startup(struct uart_port *port)
/*
* Clear the FIFO buffers and disable them.
* (they will be reeanbled in
change_speed
())
* (they will be reeanbled in
set_termios
())
*/
if
(
uart_config
[
up
->
port
.
type
].
flags
&
UART_CLEAR_FIFO
)
{
serial_outp
(
up
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
);
...
...
@@ -714,7 +714,7 @@ static int sunsu_startup(struct uart_port *port)
/*
* Finally, enable interrupts. Note: Modem status interrupts
* are set via
change_speed
(), which will be occuring imminently
* are set via
set_termios
(), which will be occuring imminently
* anyway, so we don't enable them here.
*/
up
->
ier
=
UART_IER_RLSI
|
UART_IER_RDI
;
...
...
@@ -844,6 +844,17 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
if
(
up
->
port
.
type
==
PORT_16750
)
fcr
|=
UART_FCR7_64BYTE
;
/*
* Ok, we're now changing the port state. Do it with
* interrupts disabled.
*/
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
cflag
,
quot
);
up
->
port
.
read_status_mask
=
UART_LSR_OE
|
UART_LSR_THRE
|
UART_LSR_DR
;
if
(
iflag
&
INPCK
)
up
->
port
.
read_status_mask
|=
UART_LSR_FE
|
UART_LSR_PE
;
...
...
@@ -879,11 +890,6 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
if
(
UART_ENABLE_MS
(
&
up
->
port
,
cflag
))
up
->
ier
|=
UART_IER_MSI
;
/*
* Ok, we're now changing the port state. Do it with
* interrupts disabled.
*/
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
serial_out
(
up
,
UART_IER
,
up
->
ier
);
if
(
uart_config
[
up
->
port
.
type
].
flags
&
UART_STARTECH
)
{
...
...
@@ -910,6 +916,20 @@ sunsu_change_speed(struct uart_port *port, unsigned int cflag,
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
}
static
void
sunsu_set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
quot
;
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
sunsu_change_speed
(
port
,
termios
->
c_cflag
,
termios
->
c_iflag
,
quot
);
}
static
void
sunsu_release_port
(
struct
uart_port
*
port
)
{
}
...
...
@@ -960,7 +980,7 @@ static struct uart_ops sunsu_pops = {
.
break_ctl
=
sunsu_break_ctl
,
.
startup
=
sunsu_startup
,
.
shutdown
=
sunsu_shutdown
,
.
change_speed
=
sunsu_change_speed
,
.
set_termios
=
sunsu_set_termios
,
.
type
=
sunsu_type
,
.
release_port
=
sunsu_release_port
,
.
request_port
=
sunsu_request_port
,
...
...
drivers/serial/sunzilog.c
View file @
a0e6cf38
...
...
@@ -917,26 +917,27 @@ sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
/* The port lock is not held. */
static
void
sunzilog_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
sunzilog_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
struct
uart_sunzilog_port
*
up
=
(
struct
uart_sunzilog_port
*
)
port
;
unsigned
long
flags
;
int
baud
,
brg
;
baud
=
uart_get_baud_rate
(
port
,
termios
);
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
baud
=
(
ZS_CLOCK
/
(
quot
*
16
));
brg
=
BPS_TO_BRG
(
baud
,
ZS_CLOCK
/
ZS_CLOCK_DIVISOR
);
sunzilog_convert_to_zs
(
up
,
cflag
,
iflag
,
brg
);
sunzilog_convert_to_zs
(
up
,
termios
->
c_cflag
,
termios
->
c_
iflag
,
brg
);
if
(
UART_ENABLE_MS
(
&
up
->
port
,
cflag
))
if
(
UART_ENABLE_MS
(
&
up
->
port
,
termios
->
c_
cflag
))
up
->
flags
|=
SUNZILOG_FLAG_MODEM_STATUS
;
else
up
->
flags
&=
~
SUNZILOG_FLAG_MODEM_STATUS
;
up
->
cflag
=
cflag
;
up
->
cflag
=
termios
->
c_
cflag
;
sunzilog_maybe_update_regs
(
up
,
ZILOG_CHANNEL_FROM_PORT
(
port
));
...
...
@@ -982,7 +983,7 @@ static struct uart_ops sunzilog_pops = {
.
break_ctl
=
sunzilog_break_ctl
,
.
startup
=
sunzilog_startup
,
.
shutdown
=
sunzilog_shutdown
,
.
change_speed
=
sunzilog_change_speed
,
.
set_termios
=
sunzilog_set_termios
,
.
type
=
sunzilog_type
,
.
release_port
=
sunzilog_release_port
,
.
request_port
=
sunzilog_request_port
,
...
...
drivers/serial/uart00.c
View file @
a0e6cf38
...
...
@@ -314,14 +314,24 @@ static void uart00_break_ctl(struct uart_port *port, int break_state)
}
static
void
uart00_
change_speed
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
)
uart00_
set_termios
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old
)
{
unsigned
int
uart_mc
,
old_ies
;
unsigned
int
uart_mc
,
old_ies
,
quot
;
unsigned
long
flags
;
/*
* We don't support CREAD (yet)
*/
termios
->
c_cflag
|=
CREAD
;
/*
* Ask the core to calculate the divisor for us.
*/
quot
=
uart_get_divisor
(
port
,
termios
,
old
);
/* byte size and parity */
switch
(
cflag
&
CSIZE
)
{
switch
(
termios
->
c_
cflag
&
CSIZE
)
{
case
CS5
:
uart_mc
=
UART_MC_CLS_CHARLEN_5
;
break
;
...
...
@@ -335,41 +345,47 @@ uart00_change_speed(struct uart_port *port, unsigned int cflag,
uart_mc
=
UART_MC_CLS_CHARLEN_8
;
break
;
}
if
(
cflag
&
CSTOPB
)
if
(
termios
->
c_
cflag
&
CSTOPB
)
uart_mc
|=
UART_MC_ST_TWO
;
if
(
cflag
&
PARENB
)
{
if
(
termios
->
c_
cflag
&
PARENB
)
{
uart_mc
|=
UART_MC_PE_MSK
;
if
(
!
(
cflag
&
PARODD
))
if
(
!
(
termios
->
c_
cflag
&
PARODD
))
uart_mc
|=
UART_MC_EP_MSK
;
}
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
/*
* Update the per-port timeout.
*/
uart_update_timeout
(
port
,
termios
->
c_cflag
,
quot
);
port
->
read_status_mask
=
UART_RDS_OE_MSK
;
if
(
iflag
&
INPCK
)
if
(
termios
->
c_
iflag
&
INPCK
)
port
->
read_status_mask
|=
UART_RDS_FE_MSK
|
UART_RDS_PE_MSK
;
if
(
iflag
&
(
BRKINT
|
PARMRK
))
if
(
termios
->
c_
iflag
&
(
BRKINT
|
PARMRK
))
port
->
read_status_mask
|=
UART_RDS_BI_MSK
;
/*
* Characters to ignore
*/
port
->
ignore_status_mask
=
0
;
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
UART_RDS_FE_MSK
|
UART_RDS_PE_MSK
;
if
(
iflag
&
IGNBRK
)
{
if
(
termios
->
c_
iflag
&
IGNBRK
)
{
port
->
ignore_status_mask
|=
UART_RDS_BI_MSK
;
/*
* If we're ignoring parity and break indicators,
* ignore overruns to (for real raw support).
*/
if
(
iflag
&
IGNPAR
)
if
(
termios
->
c_
iflag
&
IGNPAR
)
port
->
ignore_status_mask
|=
UART_RDS_OE_MSK
;
}
/* first, disable everything */
spin_lock_irqsave
(
&
port
->
lock
,
flags
);
old_ies
=
UART_GET_IES
(
port
);
if
(
UART_ENABLE_MS
(
port
,
cflag
))
if
(
UART_ENABLE_MS
(
port
,
termios
->
c_
cflag
))
old_ies
|=
UART_IES_ME_MSK
;
/* Set baud rate */
...
...
@@ -495,7 +511,7 @@ static struct uart_ops uart00_pops = {
.
break_ctl
=
uart00_break_ctl
,
.
startup
=
uart00_startup
,
.
shutdown
=
uart00_shutdown
,
.
change_speed
=
uart00_change_speed
,
.
set_termios
=
uart00_set_termios
,
.
type
=
uart00_type
,
.
release_port
=
uart00_release_port
,
.
request_port
=
uart00_request_port
,
...
...
include/linux/serial_core.h
View file @
a0e6cf38
...
...
@@ -86,8 +86,8 @@ struct uart_ops {
void
(
*
break_ctl
)(
struct
uart_port
*
,
int
ctl
);
int
(
*
startup
)(
struct
uart_port
*
);
void
(
*
shutdown
)(
struct
uart_port
*
);
void
(
*
change_speed
)(
struct
uart_port
*
,
unsigned
int
cflag
,
unsigned
int
iflag
,
unsigned
int
quot
);
void
(
*
set_termios
)(
struct
uart_port
*
,
struct
termios
*
new
,
struct
termios
*
old
);
void
(
*
pm
)(
struct
uart_port
*
,
unsigned
int
state
,
unsigned
int
oldstate
);
int
(
*
set_wake
)(
struct
uart_port
*
,
unsigned
int
state
);
...
...
@@ -179,7 +179,7 @@ struct uart_port {
#define UPF_RESOURCES (1 << 30)
#define UPF_IOREMAP (1 << 31)
#define UPF_
FLAGS
(0x7fff)
#define UPF_
CHANGE_MASK
(0x7fff)
#define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY)
unsigned
int
mctrl
;
/* current modem ctrl settings */
...
...
@@ -242,7 +242,6 @@ struct uart_info {
unsigned
char
*
tmpbuf
;
struct
semaphore
tmpbuf_sem
;
unsigned
long
event
;
int
blocked_open
;
struct
tasklet_struct
tlet
;
...
...
@@ -275,12 +274,31 @@ struct uart_driver {
};
void
uart_write_wakeup
(
struct
uart_port
*
port
);
/*
* Baud rate helpers.
*/
void
uart_update_timeout
(
struct
uart_port
*
port
,
unsigned
int
cflag
,
unsigned
int
quot
);
unsigned
int
uart_get_baud_rate
(
struct
uart_port
*
port
,
struct
termios
*
termios
struct
termios
*
old
,
unsigned
int
min
,
unsigned
int
max
);
unsigned
int
uart_get_divisor
(
struct
uart_port
*
port
,
struct
termios
*
termios
,
struct
termios
*
old_termios
);
/*
* Console helpers.
*/
struct
uart_port
*
uart_get_console
(
struct
uart_port
*
ports
,
int
nr
,
struct
console
*
c
);
void
uart_parse_options
(
char
*
options
,
int
*
baud
,
int
*
parity
,
int
*
bits
,
int
*
flow
);
int
uart_set_options
(
struct
uart_port
*
port
,
struct
console
*
co
,
int
baud
,
int
parity
,
int
bits
,
int
flow
);
/*
* Port/driver registration/removal
*/
int
uart_register_driver
(
struct
uart_driver
*
uart
);
void
uart_unregister_driver
(
struct
uart_driver
*
uart
);
void
uart_unregister_port
(
struct
uart_driver
*
reg
,
int
line
);
...
...
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