]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/serial/mfd.c
Merge tag 'v2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / serial / mfd.c
index 5dff45c76d32c5f026dc1ae408166a4f5e9ac6d2..d40010a22ecd788e6d90c69337333c7bed0bfc7b 100644 (file)
@@ -172,6 +172,9 @@ static ssize_t port_show_regs(struct file *file, char __user *user_buf,
        len += snprintf(buf + len, HSU_REGS_BUFSIZE - len,
                        "DIV: \t\t0x%08x\n", serial_in(up, UART_DIV));
 
+       if (len > HSU_REGS_BUFSIZE)
+               len = HSU_REGS_BUFSIZE;
+
        ret =  simple_read_from_buffer(user_buf, count, ppos, buf, len);
        kfree(buf);
        return ret;
@@ -219,6 +222,9 @@ static ssize_t dma_show_regs(struct file *file, char __user *user_buf,
        len += snprintf(buf + len, HSU_REGS_BUFSIZE - len,
                        "D0TSR: \t\t0x%08x\n", chan_readl(chan, HSU_CH_D3TSR));
 
+       if (len > HSU_REGS_BUFSIZE)
+               len = HSU_REGS_BUFSIZE;
+
        ret =  simple_read_from_buffer(user_buf, count, ppos, buf, len);
        kfree(buf);
        return ret;
@@ -228,12 +234,14 @@ static const struct file_operations port_regs_ops = {
        .owner          = THIS_MODULE,
        .open           = hsu_show_regs_open,
        .read           = port_show_regs,
+       .llseek         = default_llseek,
 };
 
 static const struct file_operations dma_regs_ops = {
        .owner          = THIS_MODULE,
        .open           = hsu_show_regs_open,
        .read           = dma_show_regs,
+       .llseek         = default_llseek,
 };
 
 static int hsu_debugfs_init(struct hsu_port *hsu)
@@ -892,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
-       u32 mul = 0x3600;
-       u32 ps = 0x10;
+       u32 ps, mul;
 
        switch (termios->c_cflag & CSIZE) {
        case CS5:
@@ -923,39 +930,45 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
                cval |= UART_LCR_EPAR;
 
        /*
+        * The base clk is 50Mhz, and the baud rate come from:
+        *      baud = 50M * MUL / (DIV * PS * DLAB)
+        *
         * For those basic low baud rate we can get the direct
-        * scalar from 2746800, like 115200 = 2746800/24, for those
-        * higher baud rate, we have to handle them case by case,
-        * but DIV reg is never touched as its default value 0x3d09
+        * scalar from 2746800, like 115200 = 2746800/24. For those
+        * higher baud rate, we handle them case by case, mainly by
+        * adjusting the MUL/PS registers, and DIV register is kept
+        * as default value 0x3d09 to make things simple
         */
        baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
-       quot = uart_get_divisor(port, baud);
 
+       quot = 1;
+       ps = 0x10;
+       mul = 0x3600;
        switch (baud) {
        case 3500000:
                mul = 0x3345;
                ps = 0xC;
-               quot = 1;
-               break;
-       case 2500000:
-               mul = 0x2710;
-               ps = 0x10;
-               quot = 1;
                break;
-       case 18432000:
+       case 1843200:
                mul = 0x2400;
-               ps = 0x10;
-               quot = 1;
                break;
+       case 3000000:
+       case 2500000:
+       case 2000000:
        case 1500000:
-               mul = 0x1D4C;
-               ps = 0xc;
-               quot = 1;
+       case 1000000:
+       case 500000:
+               /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */
+               mul = baud / 500000 * 0x9C4;
                break;
        default:
-               ;
+               /* Use uart_get_divisor to get quot for other baud rates */
+               quot = 0;
        }
 
+       if (!quot)
+               quot = uart_get_divisor(port, baud);
+
        if ((up->port.uartclk / quot) < (2400 * 16))
                fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_1B;
        else if ((up->port.uartclk / quot) < (230400 * 16))