Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201479
b: refs/heads/master
c: ac3e3fb
h: refs/heads/master
i:
  201477: f3e9b58
  201475: 53d9da1
  201471: a90e296
v: v3
  • Loading branch information
Linus Walleij authored and Russell King committed Jul 27, 2010
1 parent c11fe6e commit 4b34b57
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ec489aa8f993f8d2ec962ce113071faac482aa27
refs/heads/master: ac3e3fb424d44109dda3b1a3459e1b30fa60ac4a
27 changes: 25 additions & 2 deletions trunk/drivers/serial/amba-pl011.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct uart_amba_port {
unsigned int ifls; /* vendor-specific */
unsigned int lcrh_tx; /* vendor-specific */
unsigned int lcrh_rx; /* vendor-specific */
bool oversampling; /* vendor-specific */
bool autorts;
};

Expand All @@ -83,20 +84,23 @@ struct vendor_data {
unsigned int fifosize;
unsigned int lcrh_tx;
unsigned int lcrh_rx;
bool oversampling;
};

static struct vendor_data vendor_arm = {
.ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
.fifosize = 16,
.lcrh_tx = UART011_LCRH,
.lcrh_rx = UART011_LCRH,
.oversampling = false,
};

static struct vendor_data vendor_st = {
.ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF,
.fifosize = 64,
.lcrh_tx = ST_UART011_LCRH_TX,
.lcrh_rx = ST_UART011_LCRH_RX,
.oversampling = true,
};

static void pl011_stop_tx(struct uart_port *port)
Expand Down Expand Up @@ -499,8 +503,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = port->uartclk * 4 / baud;
baud = uart_get_baud_rate(port, termios, old, 0,
port->uartclk/(uap->oversampling ? 8 : 16));

if (baud > port->uartclk/16)
quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);
else
quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud);

switch (termios->c_cflag & CSIZE) {
case CS5:
Expand Down Expand Up @@ -579,6 +588,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
uap->autorts = false;
}

if (uap->oversampling) {
if (baud > port->uartclk/16)
old_cr |= ST_UART011_CR_OVSFACT;
else
old_cr &= ~ST_UART011_CR_OVSFACT;
}

/* Set baud rate */
writew(quot & 0x3f, port->membase + UART011_FBRD);
writew(quot >> 6, port->membase + UART011_IBRD);
Expand Down Expand Up @@ -744,6 +760,12 @@ pl011_console_get_options(struct uart_amba_port *uap, int *baud,
fbrd = readw(uap->port.membase + UART011_FBRD);

*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);

if (uap->oversampling) {
if (readw(uap->port.membase + UART011_CR)
& ST_UART011_CR_OVSFACT)
*baud *= 2;
}
}
}

Expand Down Expand Up @@ -839,6 +861,7 @@ static int pl011_probe(struct amba_device *dev, struct amba_id *id)
uap->ifls = vendor->ifls;
uap->lcrh_rx = vendor->lcrh_rx;
uap->lcrh_tx = vendor->lcrh_tx;
uap->oversampling = vendor->oversampling;
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/amba/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#define UART010_CR_TIE 0x0020
#define UART010_CR_RIE 0x0010
#define UART010_CR_MSIE 0x0008
#define ST_UART011_CR_OVSFACT 0x0008 /* Oversampling factor */
#define UART01x_CR_IIRLP 0x0004 /* SIR low power mode */
#define UART01x_CR_SIREN 0x0002 /* SIR enable */
#define UART01x_CR_UARTEN 0x0001 /* UART enable */
Expand Down

0 comments on commit 4b34b57

Please sign in to comment.