Date:2010-01-11 04:29:44 (10 years 4 months ago)
Author:Lars C.
Commit:9005746d81c36afa38c4a2e9339149e9c7b7f0e0
Message:From 5b3f9de4171368d9a99fa4c8b8b1bcc8505fb3c6 Mon Sep 17 00:00:00 2001 Subject: [PATCH] /opt/Projects/openwrt/target/linux/xburst/patches-2.6.31/103-serial.p atch

Files: drivers/serial/8250.c (8 diffs)

Change Details

drivers/serial/8250.c
199199    [PORT_16550A] = {
200200        .name = "16550A",
201201        .fifo_size = 16,
202        .tx_loadsz = 16,
202        .tx_loadsz = 8,
203203        .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
204204        .flags = UART_CAP_FIFO,
205205    },
...... 
406406static void mem_serial_out(struct uart_port *p, int offset, int value)
407407{
408408    offset = map_8250_out_reg(p, offset) << p->regshift;
409#if defined(CONFIG_JZSOC)
410        if (offset == (UART_FCR << p->regshift))
411            value |= 0x10; /* set FCR.UUE */
412#endif
409413    writeb(value, p->membase + offset);
410414}
411415
...... 
22142218        serial_unlink_irq_chain(up);
22152219}
22162220
2221#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
2222static unsigned short quot1[3] = {0}; /* quot[0]:baud_div, quot[1]:umr, quot[2]:uacr */
2223static unsigned short * serial8250_get_divisor(struct uart_port *port, unsigned int baud)
2224{
2225    int err, sum, i, j;
2226    int a[12], b[12];
2227    unsigned short div, umr, uacr;
2228    unsigned short umr_best, div_best, uacr_best;
2229    long long t0, t1, t2, t3;
2230
2231    sum = 0;
2232    umr_best = div_best = uacr_best = 0;
2233    div = 1;
2234
2235    if ((port->uartclk % (16 * baud)) == 0) {
2236        quot1[0] = port->uartclk / (16 * baud);
2237        quot1[1] = 16;
2238        quot1[2] = 0;
2239        return quot1;
2240    }
2241
2242    while (1) {
2243        umr = port->uartclk / (baud * div);
2244          if (umr > 32) {
2245            div++;
2246            continue;
2247        }
2248        if (umr < 4) {
2249            break;
2250        }
2251        for (i = 0; i < 12; i++) {
2252            a[i] = umr;
2253            b[i] = 0;
2254            sum = 0;
2255            for (j = 0; j <= i; j++) {
2256                sum += a[j];
2257            }
2258
2259                        /* the precision could be 1/2^(36) due to the value of t0 */
2260            t0 = 0x1000000000LL;
2261            t1 = (i + 1) * t0;
2262            t2 = (sum * div) * t0;
2263            t3 = div * t0;
2264            do_div(t1, baud);
2265            do_div(t2, port->uartclk);
2266            do_div(t3, (2 * port->uartclk));
2267            err = t1 - t2 - t3;
2268
2269            if (err > 0) {
2270                a[i] += 1;
2271                b[i] = 1;
2272            }
2273        }
2274
2275        uacr = 0;
2276        for (i = 0; i < 12; i++) {
2277            if (b[i] == 1) {
2278                uacr |= 1 << i;
2279            }
2280        }
2281
2282                /* the best value of umr should be near 16, and the value of uacr should better be smaller */
2283        if (abs(umr - 16) < abs(umr_best - 16) || (abs(umr - 16) == abs(umr_best - 16) && uacr_best > uacr)) {
2284            div_best = div;
2285            umr_best = umr;
2286            uacr_best = uacr;
2287        }
2288        div++;
2289    }
2290
2291    quot1[0] = div_best;
2292    quot1[1] = umr_best;
2293    quot1[2] = uacr_best;
2294
2295    return quot1;
2296}
2297#else
22172298static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
22182299{
22192300    unsigned int quot;
...... 
22332314
22342315    return quot;
22352316}
2317#endif
22362318
22372319static void
22382320serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
...... 
22422324    unsigned char cval, fcr = 0;
22432325    unsigned long flags;
22442326    unsigned int baud, quot;
2327#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
2328    unsigned short *quot1;
2329#endif
22452330
22462331    switch (termios->c_cflag & CSIZE) {
22472332    case CS5:
...... 
22762361    baud = uart_get_baud_rate(port, termios, old,
22772362                  port->uartclk / 16 / 0xffff,
22782363                  port->uartclk / 16);
2364#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
2365    quot1 = serial8250_get_divisor(port, baud);
2366    quot = quot1[0]; /* not usefull, just let gcc happy */
2367#else
22792368    quot = serial8250_get_divisor(port, baud);
2369#endif
22802370
22812371    /*
22822372     * Oxford Semi 952 rev B workaround
...... 
23542444    if (up->capabilities & UART_CAP_UUE)
23552445        up->ier |= UART_IER_UUE | UART_IER_RTOIE;
23562446
2447#ifdef CONFIG_JZSOC
2448    up->ier |= UART_IER_RTOIE; /* Set this flag, or very slow */
2449#endif
2450
23572451    serial_out(up, UART_IER, up->ier);
23582452
23592453    if (up->capabilities & UART_CAP_EFR) {
...... 
23882482        serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
23892483    }
23902484
2485#if defined(CONFIG_JZSOC) && !defined(CONFIG_SOC_JZ4730)
2486#define UART_UMR 9
2487#define UART_UACR 10
2488    serial_dl_write(up, quot1[0]);
2489    serial_outp(up, UART_UMR, quot1[1]);
2490    serial_outp(up, UART_UACR, quot1[2]);
2491#else
23912492    serial_dl_write(up, quot);
2493#endif
23922494
23932495    /*
23942496     * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR

Archive Download the corresponding diff file



interactive