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
4aaa098f
Commit
4aaa098f
authored
May 30, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SPARC]: Do tty_flip_buffer_push outside of port lock.
parent
c6d6857c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
51 additions
and
21 deletions
+51
-21
drivers/serial/sunsab.c
drivers/serial/sunsab.c
+19
-10
drivers/serial/sunsu.c
drivers/serial/sunsu.c
+16
-4
drivers/serial/sunzilog.c
drivers/serial/sunzilog.c
+16
-7
No files found.
drivers/serial/sunsab.c
View file @
4aaa098f
...
@@ -97,9 +97,10 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up)
...
@@ -97,9 +97,10 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up)
udelay
(
1
);
udelay
(
1
);
}
}
static
void
receive_chars
(
struct
uart_sunsab_port
*
up
,
static
struct
tty_struct
*
union
sab82532_irq_status
*
stat
,
receive_chars
(
struct
uart_sunsab_port
*
up
,
struct
pt_regs
*
regs
)
union
sab82532_irq_status
*
stat
,
struct
pt_regs
*
regs
)
{
{
struct
tty_struct
*
tty
=
NULL
;
struct
tty_struct
*
tty
=
NULL
;
unsigned
char
buf
[
32
];
unsigned
char
buf
[
32
];
...
@@ -126,7 +127,7 @@ static void receive_chars(struct uart_sunsab_port *up,
...
@@ -126,7 +127,7 @@ static void receive_chars(struct uart_sunsab_port *up,
if
(
stat
->
sreg
.
isr0
&
SAB82532_ISR0_TIME
)
{
if
(
stat
->
sreg
.
isr0
&
SAB82532_ISR0_TIME
)
{
sunsab_cec_wait
(
up
);
sunsab_cec_wait
(
up
);
writeb
(
SAB82532_CMDR_RFRD
,
&
up
->
regs
->
w
.
cmdr
);
writeb
(
SAB82532_CMDR_RFRD
,
&
up
->
regs
->
w
.
cmdr
);
return
;
return
tty
;
}
}
if
(
stat
->
sreg
.
isr0
&
SAB82532_ISR0_RFO
)
if
(
stat
->
sreg
.
isr0
&
SAB82532_ISR0_RFO
)
...
@@ -153,7 +154,7 @@ static void receive_chars(struct uart_sunsab_port *up,
...
@@ -153,7 +154,7 @@ static void receive_chars(struct uart_sunsab_port *up,
if
(
unlikely
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
))
{
if
(
unlikely
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
))
{
tty
->
flip
.
work
.
func
((
void
*
)
tty
);
tty
->
flip
.
work
.
func
((
void
*
)
tty
);
if
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
)
if
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
)
return
;
// if TTY_DONT_FLIP is set
return
tty
;
// if TTY_DONT_FLIP is set
}
}
*
tty
->
flip
.
char_buf_ptr
=
ch
;
*
tty
->
flip
.
char_buf_ptr
=
ch
;
...
@@ -225,11 +226,10 @@ static void receive_chars(struct uart_sunsab_port *up,
...
@@ -225,11 +226,10 @@ static void receive_chars(struct uart_sunsab_port *up,
}
}
}
}
if
(
tty
)
tty_flip_buffer_push
(
tty
);
if
(
saw_console_brk
)
if
(
saw_console_brk
)
sun_do_break
();
sun_do_break
();
return
tty
;
}
}
static
void
sunsab_stop_tx
(
struct
uart_port
*
,
unsigned
int
);
static
void
sunsab_stop_tx
(
struct
uart_port
*
,
unsigned
int
);
...
@@ -311,6 +311,7 @@ static void check_status(struct uart_sunsab_port *up,
...
@@ -311,6 +311,7 @@ static void check_status(struct uart_sunsab_port *up,
static
irqreturn_t
sunsab_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
irqreturn_t
sunsab_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
struct
uart_sunsab_port
*
up
=
dev_id
;
struct
uart_sunsab_port
*
up
=
dev_id
;
struct
tty_struct
*
tty
;
union
sab82532_irq_status
status
;
union
sab82532_irq_status
status
;
unsigned
long
flags
;
unsigned
long
flags
;
...
@@ -322,10 +323,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -322,10 +323,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if
(
readb
(
&
up
->
regs
->
r
.
gis
)
&
SAB82532_GIS_ISA1
)
if
(
readb
(
&
up
->
regs
->
r
.
gis
)
&
SAB82532_GIS_ISA1
)
status
.
sreg
.
isr1
=
readb
(
&
up
->
regs
->
r
.
isr1
);
status
.
sreg
.
isr1
=
readb
(
&
up
->
regs
->
r
.
isr1
);
tty
=
NULL
;
if
(
status
.
stat
)
{
if
(
status
.
stat
)
{
if
(
status
.
sreg
.
isr0
&
(
SAB82532_ISR0_TCD
|
SAB82532_ISR0_TIME
|
if
(
status
.
sreg
.
isr0
&
(
SAB82532_ISR0_TCD
|
SAB82532_ISR0_TIME
|
SAB82532_ISR0_RFO
|
SAB82532_ISR0_RPF
))
SAB82532_ISR0_RFO
|
SAB82532_ISR0_RPF
))
receive_chars
(
up
,
&
status
,
regs
);
tty
=
receive_chars
(
up
,
&
status
,
regs
);
if
((
status
.
sreg
.
isr0
&
SAB82532_ISR0_CDSC
)
||
if
((
status
.
sreg
.
isr0
&
SAB82532_ISR0_CDSC
)
||
(
status
.
sreg
.
isr1
&
SAB82532_ISR1_CSC
))
(
status
.
sreg
.
isr1
&
SAB82532_ISR1_CSC
))
check_status
(
up
,
&
status
);
check_status
(
up
,
&
status
);
...
@@ -335,6 +337,9 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -335,6 +337,9 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock
(
&
up
->
port
.
lock
);
spin_unlock
(
&
up
->
port
.
lock
);
if
(
tty
)
tty_flip_buffer_push
(
tty
);
up
++
;
up
++
;
spin_lock
(
&
up
->
port
.
lock
);
spin_lock
(
&
up
->
port
.
lock
);
...
@@ -345,10 +350,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -345,10 +350,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if
(
readb
(
&
up
->
regs
->
r
.
gis
)
&
SAB82532_GIS_ISB1
)
if
(
readb
(
&
up
->
regs
->
r
.
gis
)
&
SAB82532_GIS_ISB1
)
status
.
sreg
.
isr1
=
readb
(
&
up
->
regs
->
r
.
isr1
);
status
.
sreg
.
isr1
=
readb
(
&
up
->
regs
->
r
.
isr1
);
tty
=
NULL
;
if
(
status
.
stat
)
{
if
(
status
.
stat
)
{
if
(
status
.
sreg
.
isr0
&
(
SAB82532_ISR0_TCD
|
SAB82532_ISR0_TIME
|
if
(
status
.
sreg
.
isr0
&
(
SAB82532_ISR0_TCD
|
SAB82532_ISR0_TIME
|
SAB82532_ISR0_RFO
|
SAB82532_ISR0_RPF
))
SAB82532_ISR0_RFO
|
SAB82532_ISR0_RPF
))
receive_chars
(
up
,
&
status
,
regs
);
tty
=
receive_chars
(
up
,
&
status
,
regs
);
if
((
status
.
sreg
.
isr0
&
SAB82532_ISR0_CDSC
)
||
if
((
status
.
sreg
.
isr0
&
SAB82532_ISR0_CDSC
)
||
(
status
.
sreg
.
isr1
&
(
SAB82532_ISR1_BRK
|
SAB82532_ISR1_CSC
)))
(
status
.
sreg
.
isr1
&
(
SAB82532_ISR1_BRK
|
SAB82532_ISR1_CSC
)))
check_status
(
up
,
&
status
);
check_status
(
up
,
&
status
);
...
@@ -358,6 +364,9 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -358,6 +364,9 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
if
(
tty
)
tty_flip_buffer_push
(
tty
);
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
...
...
drivers/serial/sunsu.c
View file @
4aaa098f
...
@@ -310,7 +310,7 @@ static void sunsu_enable_ms(struct uart_port *port)
...
@@ -310,7 +310,7 @@ static void sunsu_enable_ms(struct uart_port *port)
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
}
}
static
_INLINE_
void
static
_INLINE_
struct
tty_struct
*
receive_chars
(
struct
uart_sunsu_port
*
up
,
unsigned
char
*
status
,
struct
pt_regs
*
regs
)
receive_chars
(
struct
uart_sunsu_port
*
up
,
unsigned
char
*
status
,
struct
pt_regs
*
regs
)
{
{
struct
tty_struct
*
tty
=
up
->
port
.
info
->
tty
;
struct
tty_struct
*
tty
=
up
->
port
.
info
->
tty
;
...
@@ -322,7 +322,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
...
@@ -322,7 +322,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
if
(
unlikely
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
))
{
if
(
unlikely
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
))
{
tty
->
flip
.
work
.
func
((
void
*
)
tty
);
tty
->
flip
.
work
.
func
((
void
*
)
tty
);
if
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
)
if
(
tty
->
flip
.
count
>=
TTY_FLIPBUF_SIZE
)
return
;
// if TTY_DONT_FLIP is set
return
tty
;
// if TTY_DONT_FLIP is set
}
}
ch
=
serial_inp
(
up
,
UART_RX
);
ch
=
serial_inp
(
up
,
UART_RX
);
*
tty
->
flip
.
char_buf_ptr
=
ch
;
*
tty
->
flip
.
char_buf_ptr
=
ch
;
...
@@ -396,10 +396,11 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
...
@@ -396,10 +396,11 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
ignore_char:
ignore_char:
*
status
=
serial_inp
(
up
,
UART_LSR
);
*
status
=
serial_inp
(
up
,
UART_LSR
);
}
while
((
*
status
&
UART_LSR_DR
)
&&
(
max_count
--
>
0
));
}
while
((
*
status
&
UART_LSR_DR
)
&&
(
max_count
--
>
0
));
tty_flip_buffer_push
(
tty
);
if
(
saw_console_brk
)
if
(
saw_console_brk
)
sun_do_break
();
sun_do_break
();
return
tty
;
}
}
static
_INLINE_
void
transmit_chars
(
struct
uart_sunsu_port
*
up
)
static
_INLINE_
void
transmit_chars
(
struct
uart_sunsu_port
*
up
)
...
@@ -464,12 +465,23 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs
...
@@ -464,12 +465,23 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
do
{
do
{
struct
tty_struct
*
tty
;
status
=
serial_inp
(
up
,
UART_LSR
);
status
=
serial_inp
(
up
,
UART_LSR
);
tty
=
NULL
;
if
(
status
&
UART_LSR_DR
)
if
(
status
&
UART_LSR_DR
)
receive_chars
(
up
,
&
status
,
regs
);
tty
=
receive_chars
(
up
,
&
status
,
regs
);
check_modem_status
(
up
);
check_modem_status
(
up
);
if
(
status
&
UART_LSR_THRE
)
if
(
status
&
UART_LSR_THRE
)
transmit_chars
(
up
);
transmit_chars
(
up
);
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
if
(
tty
)
tty_flip_buffer_push
(
tty
);
spin_lock_irqsave
(
&
up
->
port
.
lock
,
flags
);
}
while
(
!
(
serial_in
(
up
,
UART_IIR
)
&
UART_IIR_NO_INT
));
}
while
(
!
(
serial_in
(
up
,
UART_IIR
)
&
UART_IIR_NO_INT
));
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
up
->
port
.
lock
,
flags
);
...
...
drivers/serial/sunzilog.c
View file @
4aaa098f
...
@@ -313,9 +313,10 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
...
@@ -313,9 +313,10 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
}
}
}
}
static
void
sunzilog_receive_chars
(
struct
uart_sunzilog_port
*
up
,
static
struct
tty_struct
*
struct
zilog_channel
*
channel
,
sunzilog_receive_chars
(
struct
uart_sunzilog_port
*
up
,
struct
pt_regs
*
regs
)
struct
zilog_channel
*
channel
,
struct
pt_regs
*
regs
)
{
{
struct
tty_struct
*
tty
;
struct
tty_struct
*
tty
;
unsigned
char
ch
,
r1
;
unsigned
char
ch
,
r1
;
...
@@ -414,8 +415,7 @@ static void sunzilog_receive_chars(struct uart_sunzilog_port *up,
...
@@ -414,8 +415,7 @@ static void sunzilog_receive_chars(struct uart_sunzilog_port *up,
}
}
}
}
if
(
tty
)
return
tty
;
tty_flip_buffer_push
(
tty
);
}
}
static
void
sunzilog_status_handle
(
struct
uart_sunzilog_port
*
up
,
static
void
sunzilog_status_handle
(
struct
uart_sunzilog_port
*
up
,
...
@@ -550,19 +550,21 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
...
@@ -550,19 +550,21 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
while
(
up
)
{
while
(
up
)
{
struct
zilog_channel
*
channel
struct
zilog_channel
*
channel
=
ZILOG_CHANNEL_FROM_PORT
(
&
up
->
port
);
=
ZILOG_CHANNEL_FROM_PORT
(
&
up
->
port
);
struct
tty_struct
*
tty
;
unsigned
char
r3
;
unsigned
char
r3
;
spin_lock
(
&
up
->
port
.
lock
);
spin_lock
(
&
up
->
port
.
lock
);
r3
=
read_zsreg
(
channel
,
R3
);
r3
=
read_zsreg
(
channel
,
R3
);
/* Channel A */
/* Channel A */
tty
=
NULL
;
if
(
r3
&
(
CHAEXT
|
CHATxIP
|
CHARxIP
))
{
if
(
r3
&
(
CHAEXT
|
CHATxIP
|
CHARxIP
))
{
sbus_writeb
(
RES_H_IUS
,
&
channel
->
control
);
sbus_writeb
(
RES_H_IUS
,
&
channel
->
control
);
ZSDELAY
();
ZSDELAY
();
ZS_WSYNC
(
channel
);
ZS_WSYNC
(
channel
);
if
(
r3
&
CHARxIP
)
if
(
r3
&
CHARxIP
)
sunzilog_receive_chars
(
up
,
channel
,
regs
);
tty
=
sunzilog_receive_chars
(
up
,
channel
,
regs
);
if
(
r3
&
CHAEXT
)
if
(
r3
&
CHAEXT
)
sunzilog_status_handle
(
up
,
channel
,
regs
);
sunzilog_status_handle
(
up
,
channel
,
regs
);
if
(
r3
&
CHATxIP
)
if
(
r3
&
CHATxIP
)
...
@@ -570,18 +572,22 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
...
@@ -570,18 +572,22 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
}
}
spin_unlock
(
&
up
->
port
.
lock
);
spin_unlock
(
&
up
->
port
.
lock
);
if
(
tty
)
tty_flip_buffer_push
(
tty
);
/* Channel B */
/* Channel B */
up
=
up
->
next
;
up
=
up
->
next
;
channel
=
ZILOG_CHANNEL_FROM_PORT
(
&
up
->
port
);
channel
=
ZILOG_CHANNEL_FROM_PORT
(
&
up
->
port
);
spin_lock
(
&
up
->
port
.
lock
);
spin_lock
(
&
up
->
port
.
lock
);
tty
=
NULL
;
if
(
r3
&
(
CHBEXT
|
CHBTxIP
|
CHBRxIP
))
{
if
(
r3
&
(
CHBEXT
|
CHBTxIP
|
CHBRxIP
))
{
sbus_writeb
(
RES_H_IUS
,
&
channel
->
control
);
sbus_writeb
(
RES_H_IUS
,
&
channel
->
control
);
ZSDELAY
();
ZSDELAY
();
ZS_WSYNC
(
channel
);
ZS_WSYNC
(
channel
);
if
(
r3
&
CHBRxIP
)
if
(
r3
&
CHBRxIP
)
sunzilog_receive_chars
(
up
,
channel
,
regs
);
tty
=
sunzilog_receive_chars
(
up
,
channel
,
regs
);
if
(
r3
&
CHBEXT
)
if
(
r3
&
CHBEXT
)
sunzilog_status_handle
(
up
,
channel
,
regs
);
sunzilog_status_handle
(
up
,
channel
,
regs
);
if
(
r3
&
CHBTxIP
)
if
(
r3
&
CHBTxIP
)
...
@@ -589,6 +595,9 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
...
@@ -589,6 +595,9 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
}
}
spin_unlock
(
&
up
->
port
.
lock
);
spin_unlock
(
&
up
->
port
.
lock
);
if
(
tty
)
tty_flip_buffer_push
(
tty
);
up
=
up
->
next
;
up
=
up
->
next
;
}
}
...
...
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