aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/ar933x_uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/ar933x_uart.c')
-rw-r--r--drivers/tty/serial/ar933x_uart.c96
1 files changed, 88 insertions, 8 deletions
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
index e4f60e2b87f3..505c490c0b44 100644
--- a/drivers/tty/serial/ar933x_uart.c
+++ b/drivers/tty/serial/ar933x_uart.c
@@ -25,11 +25,19 @@
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/irq.h> 26#include <linux/irq.h>
27 27
28#include <asm/div64.h>
29
28#include <asm/mach-ath79/ar933x_uart.h> 30#include <asm/mach-ath79/ar933x_uart.h>
29#include <asm/mach-ath79/ar933x_uart_platform.h> 31#include <asm/mach-ath79/ar933x_uart_platform.h>
30 32
31#define DRIVER_NAME "ar933x-uart" 33#define DRIVER_NAME "ar933x-uart"
32 34
35#define AR933X_UART_MAX_SCALE 0xff
36#define AR933X_UART_MAX_STEP 0xffff
37
38#define AR933X_UART_MIN_BAUD 300
39#define AR933X_UART_MAX_BAUD 3000000
40
33#define AR933X_DUMMY_STATUS_RD 0x01 41#define AR933X_DUMMY_STATUS_RD 0x01
34 42
35static struct uart_driver ar933x_uart_driver; 43static struct uart_driver ar933x_uart_driver;
@@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_driver;
37struct ar933x_uart_port { 45struct ar933x_uart_port {
38 struct uart_port port; 46 struct uart_port port;
39 unsigned int ier; /* shadow Interrupt Enable Register */ 47 unsigned int ier; /* shadow Interrupt Enable Register */
48 unsigned int min_baud;
49 unsigned int max_baud;
40}; 50};
41 51
42static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, 52static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
@@ -162,6 +172,57 @@ static void ar933x_uart_enable_ms(struct uart_port *port)
162{ 172{
163} 173}
164 174
175/*
176 * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17))
177 */
178static unsigned long ar933x_uart_get_baud(unsigned int clk,
179 unsigned int scale,
180 unsigned int step)
181{
182 u64 t;
183 u32 div;
184
185 div = (2 << 16) * (scale + 1);
186 t = clk;
187 t *= step;
188 t += (div / 2);
189 do_div(t, div);
190
191 return t;
192}
193
194static void ar933x_uart_get_scale_step(unsigned int clk,
195 unsigned int baud,
196 unsigned int *scale,
197 unsigned int *step)
198{
199 unsigned int tscale;
200 long min_diff;
201
202 *scale = 0;
203 *step = 0;
204
205 min_diff = baud;
206 for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) {
207 u64 tstep;
208 int diff;
209
210 tstep = baud * (tscale + 1);
211 tstep *= (2 << 16);
212 do_div(tstep, clk);
213
214 if (tstep > AR933X_UART_MAX_STEP)
215 break;
216
217 diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud);
218 if (diff < min_diff) {
219 min_diff = diff;
220 *scale = tscale;
221 *step = tstep;
222 }
223 }
224}
225
165static void ar933x_uart_set_termios(struct uart_port *port, 226static void ar933x_uart_set_termios(struct uart_port *port,
166 struct ktermios *new, 227 struct ktermios *new,
167 struct ktermios *old) 228 struct ktermios *old)
@@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(struct uart_port *port,
169 struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; 230 struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
170 unsigned int cs; 231 unsigned int cs;
171 unsigned long flags; 232 unsigned long flags;
172 unsigned int baud, scale; 233 unsigned int baud, scale, step;
173 234
174 /* Only CS8 is supported */ 235 /* Only CS8 is supported */
175 new->c_cflag &= ~CSIZE; 236 new->c_cflag &= ~CSIZE;
@@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(struct uart_port *port,
191 /* Mark/space parity is not supported */ 252 /* Mark/space parity is not supported */
192 new->c_cflag &= ~CMSPAR; 253 new->c_cflag &= ~CMSPAR;
193 254
194 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); 255 baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud);
195 scale = (port->uartclk / (16 * baud)) - 1; 256 ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step);
196 257
197 /* 258 /*
198 * Ok, we're now changing the port state. Do it with 259 * Ok, we're now changing the port state. Do it with
@@ -200,6 +261,10 @@ static void ar933x_uart_set_termios(struct uart_port *port,
200 */ 261 */
201 spin_lock_irqsave(&up->port.lock, flags); 262 spin_lock_irqsave(&up->port.lock, flags);
202 263
264 /* disable the UART */
265 ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
266 AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S);
267
203 /* Update the per-port timeout. */ 268 /* Update the per-port timeout. */
204 uart_update_timeout(port, new->c_cflag, baud); 269 uart_update_timeout(port, new->c_cflag, baud);
205 270
@@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(struct uart_port *port,
210 up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; 275 up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
211 276
212 ar933x_uart_write(up, AR933X_UART_CLOCK_REG, 277 ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
213 scale << AR933X_UART_CLOCK_SCALE_S | 8192); 278 scale << AR933X_UART_CLOCK_SCALE_S | step);
214 279
215 /* setup configuration register */ 280 /* setup configuration register */
216 ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); 281 ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
@@ -219,6 +284,11 @@ static void ar933x_uart_set_termios(struct uart_port *port,
219 ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, 284 ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
220 AR933X_UART_CS_HOST_INT_EN); 285 AR933X_UART_CS_HOST_INT_EN);
221 286
287 /* reenable the UART */
288 ar933x_uart_rmw(up, AR933X_UART_CS_REG,
289 AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S,
290 AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S);
291
222 spin_unlock_irqrestore(&up->port.lock, flags); 292 spin_unlock_irqrestore(&up->port.lock, flags);
223 293
224 if (tty_termios_baud_rate(new)) 294 if (tty_termios_baud_rate(new))
@@ -401,6 +471,8 @@ static void ar933x_uart_config_port(struct uart_port *port, int flags)
401static int ar933x_uart_verify_port(struct uart_port *port, 471static int ar933x_uart_verify_port(struct uart_port *port,
402 struct serial_struct *ser) 472 struct serial_struct *ser)
403{ 473{
474 struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
475
404 if (ser->type != PORT_UNKNOWN && 476 if (ser->type != PORT_UNKNOWN &&
405 ser->type != PORT_AR933X) 477 ser->type != PORT_AR933X)
406 return -EINVAL; 478 return -EINVAL;
@@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struct uart_port *port,
408 if (ser->irq < 0 || ser->irq >= NR_IRQS) 480 if (ser->irq < 0 || ser->irq >= NR_IRQS)
409 return -EINVAL; 481 return -EINVAL;
410 482
411 if (ser->baud_base < 28800) 483 if (ser->baud_base < up->min_baud ||
484 ser->baud_base > up->max_baud)
412 return -EINVAL; 485 return -EINVAL;
413 486
414 return 0; 487 return 0;
@@ -554,13 +627,14 @@ static struct uart_driver ar933x_uart_driver = {
554 .cons = AR933X_SERIAL_CONSOLE, 627 .cons = AR933X_SERIAL_CONSOLE,
555}; 628};
556 629
557static int __devinit ar933x_uart_probe(struct platform_device *pdev) 630static int ar933x_uart_probe(struct platform_device *pdev)
558{ 631{
559 struct ar933x_uart_platform_data *pdata; 632 struct ar933x_uart_platform_data *pdata;
560 struct ar933x_uart_port *up; 633 struct ar933x_uart_port *up;
561 struct uart_port *port; 634 struct uart_port *port;
562 struct resource *mem_res; 635 struct resource *mem_res;
563 struct resource *irq_res; 636 struct resource *irq_res;
637 unsigned int baud;
564 int id; 638 int id;
565 int ret; 639 int ret;
566 640
@@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(struct platform_device *pdev)
611 port->fifosize = AR933X_UART_FIFO_SIZE; 685 port->fifosize = AR933X_UART_FIFO_SIZE;
612 port->ops = &ar933x_uart_ops; 686 port->ops = &ar933x_uart_ops;
613 687
688 baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1);
689 up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD);
690
691 baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
692 up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
693
614 ar933x_uart_add_console_port(up); 694 ar933x_uart_add_console_port(up);
615 695
616 ret = uart_add_one_port(&ar933x_uart_driver, &up->port); 696 ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
@@ -627,7 +707,7 @@ err_free_up:
627 return ret; 707 return ret;
628} 708}
629 709
630static int __devexit ar933x_uart_remove(struct platform_device *pdev) 710static int ar933x_uart_remove(struct platform_device *pdev)
631{ 711{
632 struct ar933x_uart_port *up; 712 struct ar933x_uart_port *up;
633 713
@@ -645,7 +725,7 @@ static int __devexit ar933x_uart_remove(struct platform_device *pdev)
645 725
646static struct platform_driver ar933x_uart_platform_driver = { 726static struct platform_driver ar933x_uart_platform_driver = {
647 .probe = ar933x_uart_probe, 727 .probe = ar933x_uart_probe,
648 .remove = __devexit_p(ar933x_uart_remove), 728 .remove = ar933x_uart_remove,
649 .driver = { 729 .driver = {
650 .name = DRIVER_NAME, 730 .name = DRIVER_NAME,
651 .owner = THIS_MODULE, 731 .owner = THIS_MODULE,