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