1 --- a/drivers/tty/serial/ar933x_uart.c
2 +++ b/drivers/tty/serial/ar933x_uart.c
7 +#include <asm/div64.h>
9 #include <asm/mach-ath79/ar933x_uart.h>
10 #include <asm/mach-ath79/ar933x_uart_platform.h>
12 #define DRIVER_NAME "ar933x-uart"
14 +#define AR933X_UART_MAX_SCALE 0xff
15 +#define AR933X_UART_MAX_STEP 0xffff
17 +#define AR933X_UART_MIN_BAUD 300
18 +#define AR933X_UART_MAX_BAUD 3000000
20 #define AR933X_DUMMY_STATUS_RD 0x01
22 static struct uart_driver ar933x_uart_driver;
23 @@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_dr
24 struct ar933x_uart_port {
25 struct uart_port port;
26 unsigned int ier; /* shadow Interrupt Enable Register */
27 + unsigned int min_baud;
28 + unsigned int max_baud;
31 static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
32 @@ -162,6 +172,57 @@ static void ar933x_uart_enable_ms(struct
37 + * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17))
39 +static unsigned long ar933x_uart_get_baud(unsigned int clk,
46 + div = (2 << 16) * (scale + 1);
55 +static void ar933x_uart_get_scale_step(unsigned int clk,
57 + unsigned int *scale,
60 + unsigned int tscale;
67 + for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) {
71 + tstep = baud * (tscale + 1);
75 + if (tstep > AR933X_UART_MAX_STEP)
78 + diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud);
79 + if (diff < min_diff) {
87 static void ar933x_uart_set_termios(struct uart_port *port,
90 @@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(stru
91 struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
94 - unsigned int baud, scale;
95 + unsigned int baud, scale, step;
97 /* Only CS8 is supported */
98 new->c_cflag &= ~CSIZE;
99 @@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(stru
100 /* Mark/space parity is not supported */
101 new->c_cflag &= ~CMSPAR;
103 - baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
104 - scale = (port->uartclk / (16 * baud)) - 1;
105 + baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud);
106 + ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step);
109 * Ok, we're now changing the port state. Do it with
110 @@ -200,6 +261,10 @@ static void ar933x_uart_set_termios(stru
112 spin_lock_irqsave(&up->port.lock, flags);
114 + /* disable the UART */
115 + ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
116 + AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S);
118 /* Update the per-port timeout. */
119 uart_update_timeout(port, new->c_cflag, baud);
121 @@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(stru
122 up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
124 ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
125 - scale << AR933X_UART_CLOCK_SCALE_S | 8192);
126 + scale << AR933X_UART_CLOCK_SCALE_S | step);
128 /* setup configuration register */
129 ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
130 @@ -219,6 +284,11 @@ static void ar933x_uart_set_termios(stru
131 ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
132 AR933X_UART_CS_HOST_INT_EN);
134 + /* reenable the UART */
135 + ar933x_uart_rmw(up, AR933X_UART_CS_REG,
136 + AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S,
137 + AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S);
139 spin_unlock_irqrestore(&up->port.lock, flags);
141 if (tty_termios_baud_rate(new))
142 @@ -401,6 +471,8 @@ static void ar933x_uart_config_port(stru
143 static int ar933x_uart_verify_port(struct uart_port *port,
144 struct serial_struct *ser)
146 + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
148 if (ser->type != PORT_UNKNOWN &&
149 ser->type != PORT_AR933X)
151 @@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struc
152 if (ser->irq < 0 || ser->irq >= NR_IRQS)
155 - if (ser->baud_base < 28800)
156 + if (ser->baud_base < up->min_baud ||
157 + ser->baud_base > up->max_baud)
161 @@ -561,6 +634,7 @@ static int __devinit ar933x_uart_probe(s
162 struct uart_port *port;
163 struct resource *mem_res;
164 struct resource *irq_res;
169 @@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(s
170 port->fifosize = AR933X_UART_FIFO_SIZE;
171 port->ops = &ar933x_uart_ops;
173 + baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
174 + up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
176 + baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
177 + up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
179 ar933x_uart_add_console_port(up);
181 ret = uart_add_one_port(&ar933x_uart_driver, &up->port);