Skip to content

Commit

Permalink
Subject: [PATCH 1/2] serial: Add flush_buffer() operation to uart_ops
Browse files Browse the repository at this point in the history
Serial drivers using DMA (like the atmel_serial driver) tend to get very
confused when the xmit buffer is flushed and nobody told them.  They
also tend to spew a lot of garbage since the DMA engine keeps running
after the buffer is flushed and possibly refilled with unrelated data.

This patch adds a new flush_buffer operation to the uart_ops struct,
along with a call to it from uart_flush_buffer() right after the xmit
buffer has been cleared. The driver can implement this in order to
syncronize its internal DMA state with the xmit buffer when the buffer
is flushed.

Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Acked-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Haavard Skinnemoen authored and Linus Torvalds committed Jul 21, 2008
1 parent 15648f1 commit 6bb0e3a
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 0 deletions.
11 changes: 11 additions & 0 deletions Documentation/serial/driver
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ hardware.
Locking: port_sem taken.
Interrupts: caller dependent.

flush_buffer(port)
Flush any write buffers, reset any DMA state and stop any
ongoing DMA transfers.

This will be called whenever the port->info->xmit circular
buffer is cleared.

Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep

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
Expand Down
2 changes: 2 additions & 0 deletions drivers/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,8 @@ static void uart_flush_buffer(struct tty_struct *tty)

spin_lock_irqsave(&port->lock, flags);
uart_circ_clear(&state->info->xmit);
if (port->ops->flush_buffer)
port->ops->flush_buffer(port);
spin_unlock_irqrestore(&port->lock, flags);
tty_wakeup(tty);
}
Expand Down
1 change: 1 addition & 0 deletions include/linux/serial_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ struct uart_ops {
void (*break_ctl)(struct uart_port *, int ctl);
int (*startup)(struct uart_port *);
void (*shutdown)(struct uart_port *);
void (*flush_buffer)(struct uart_port *);
void (*set_termios)(struct uart_port *, struct ktermios *new,
struct ktermios *old);
void (*set_ldisc)(struct uart_port *);
Expand Down

0 comments on commit 6bb0e3a

Please sign in to comment.