--- zzzz-none-000/linux-2.6.28.10/drivers/serial/8250.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/drivers/serial/8250.c 2010-06-15 14:06:46.000000000 +0000 @@ -17,6 +17,25 @@ * mapbase is the physical address of the IO port. * membase is an 'ioremapped' cookie. */ +/* Copyright 2008, Texas Instruments Incorporated + * + * This program has been modified from its original operation by Texas Instruments + * to do the following: + * 1) Set uartclk in serial8250_resume_port to support arm frequency change in + * Puma5. + * + * THIS MODIFIED SOFTWARE AND DOCUMENTATION ARE PROVIDED + * "AS IS," AND TEXAS INSTRUMENTS MAKES NO REPRESENTATIONS + * OR WARRENTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY + * PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR + * DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + * See The GNU General Public License for more details. + * + * These changes are covered under version 2 of the GNU General Public License, + * dated June 1991. + */ #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ @@ -63,6 +82,11 @@ { return (serial8250_reg.minor - 64) + port->line; } +#if defined(CONFIG_SERIAL_8250_CONSOLE_MUTE) +static unsigned int avm_serial_mute_flag = 1; +#else /*--- #if defined(CONFIG_SERIAL_8250_CONSOLE_MUTE) ---*/ +static unsigned int avm_serial_mute_flag = 0; +#endif /*--- #else ---*/ /*--- #if defined(CONFIG_SERIAL_8250_CONSOLE_MUTE) ---*/ /* * Debugging. @@ -124,6 +148,29 @@ static unsigned int probe_rsa_count; #endif /* CONFIG_SERIAL_8250_RSA */ + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +#define USE_TEST_AND_SET +#if defined(USE_TEST_AND_SET) +#if defined(CONFIG_ARM) +#include +#endif /*--- #if defined(CONFIG_ARM) ---*/ +#include +/*--- #include ---*/ + +int atomic_test_and_set(volatile unsigned int *ptr) { + unsigned long flags; + unsigned int old; + raw_local_irq_save(flags); + old = *ptr; + *ptr = 1; + raw_local_irq_restore(flags); + return old; +} + +#endif /*--- #if defined(USE_TEST_AND_SET) ---*/ + struct uart_8250_port { struct uart_port port; struct timer_list timer; /* "no irq" timer */ @@ -147,6 +194,7 @@ unsigned char lsr_saved_flags; #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA unsigned char msr_saved_flags; + volatile unsigned int tx_busy; /* * We provide a per-port pm hook. @@ -197,6 +245,34 @@ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO, }, + [PORT_PUMA5] = { + .name = "PUMA5_UART", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO, + }, + [PORT_OHIO] = { + .name = "OHIO_UART", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, + .flags = UART_CAP_FIFO, + }, + [PORT_UR8] = { + .name = "UR8_UART", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, + .flags = UART_CAP_FIFO, + }, + [PORT_DAVINCI] = { + .name = "DAVINCI_UART", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00 | UART_FCR_DMA_SELECT, + .flags = UART_CAP_FIFO, + }, [PORT_CIRRUS] = { .name = "Cirrus", .fifo_size = 1, @@ -271,14 +347,7 @@ .tx_loadsz = 32, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_UUE, - }, - [PORT_RM9000] = { - .name = "RM9000", - .fifo_size = 16, - .tx_loadsz = 16, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO, - }, + } }; #if defined (CONFIG_SERIAL_8250_AU1X00) @@ -855,7 +924,11 @@ unsigned char status1, status2; unsigned int iersave; +#ifdef CONFIG_ARCH_DAVINCI + up->port.type = PORT_DAVINCI; +#else /*--- #ifdef CONFIG_ARCH_DAVINCI ---*/ up->port.type = PORT_16550A; +#endif /*--- #else ---*/ /*--- #ifdef CONFIG_ARCH_DAVINCI ---*/ up->capabilities |= UART_CAP_FIFO; /* @@ -955,6 +1028,9 @@ return; } +#ifdef CONFIG_ARCH_PUMA5 + up->port.type = PORT_PUMA5; +#else /*--- #ifdef CONFIG_ARCH_PUMA5 ---*/ /* * Try writing and reading the UART_IER_UUE bit (b6). * If it works, this is probably one of the Xscale platform's @@ -977,6 +1053,7 @@ * We'll leave the UART_IER_UUE bit set to 1 (enabled). */ DEBUG_AUTOCONF("Xscale "); + up->port.type = PORT_XSCALE; up->capabilities |= UART_CAP_UUE; return; @@ -989,6 +1066,7 @@ DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); } serial_outp(up, UART_IER, iersave); +#endif /*--- #else ---*/ /*--- #ifdef CONFIG_ARCH_PUMA5 ---*/ } /* @@ -1225,10 +1303,12 @@ static inline void __stop_tx(struct uart_8250_port *p) { +#if !defined(USE_TEST_AND_SET) if (p->ier & UART_IER_THRI) { p->ier &= ~UART_IER_THRI; serial_out(p, UART_IER, p->ier); } +#endif /*--- #if !defined(USE_TEST_AND_SET) ---*/ } static void serial8250_stop_tx(struct uart_port *port) @@ -1252,6 +1332,12 @@ { struct uart_8250_port *up = (struct uart_8250_port *)port; +#if defined(CONFIG_DAVINCI_DRM_KUNDENVERSION) /*--- keine Ausgaben auf der seriellen ---*/ + if (port->irq == IRQ_UARTINT0) + return; +#endif + +#if !defined(USE_TEST_AND_SET) if (!(up->ier & UART_IER_THRI)) { up->ier |= UART_IER_THRI; serial_out(up, UART_IER, up->ier); @@ -1268,6 +1354,16 @@ transmit_chars(up); } } +#else /*--- #if !defined(USE_TEST_AND_SET) ---*/ + if((avm_serial_mute_flag & 0x01) == 0) { + if(atomic_test_and_set(&up->tx_busy) == 0) { + /*--- gpio_set(0); ---*/ + transmit_chars(up); + } + } else { /*--- wird sowieso verworfen ---*/ + transmit_chars(up); + } +#endif /*--- #else ---*/ /*--- #if !defined(USE_TEST_AND_SET) ---*/ /* * Re-enable the transmitter if we disabled it. @@ -1308,9 +1404,9 @@ char flag; do { - if (likely(lsr & UART_LSR_DR)) + if (likely(lsr & UART_LSR_DR)){ ch = serial_inp(up, UART_RX); - else + } else /* * Intel 82571 has a Serial Over Lan device that will * set UART_LSR_BI without setting UART_LSR_DR when @@ -1378,20 +1474,35 @@ static void transmit_chars(struct uart_8250_port *up) { struct circ_buf *xmit = &up->port.info->xmit; - int count; + if((avm_serial_mute_flag & 0x01) == 0) { + int count; + +#if defined(USE_TEST_AND_SET) + up->ier &= ~UART_IER_THRI; + serial_out(up, UART_IER, up->ier); +#endif /*--- #if defined(USE_TEST_AND_SET) ---*/ if (up->port.x_char) { serial_outp(up, UART_TX, up->port.x_char); up->port.icount.tx++; up->port.x_char = 0; +#if defined(USE_TEST_AND_SET) + up->ier |= UART_IER_THRI; + serial_out(up, UART_IER, up->ier); +#endif /*--- #if defined(USE_TEST_AND_SET) ---*/ return; } if (uart_tx_stopped(&up->port)) { serial8250_stop_tx(&up->port); + printk("??? stoped ????\n"); return; } if (uart_circ_empty(xmit)) { __stop_tx(up); +#if defined(USE_TEST_AND_SET) + /*--- gpio_clear(0); ---*/ + up->tx_busy = 0; +#endif /*--- #if defined(USE_TEST_AND_SET) ---*/ return; } @@ -1408,9 +1519,26 @@ uart_write_wakeup(&up->port); DEBUG_INTR("THRE..."); + /*--- printk("[THRE] ..."); ---*/ if (uart_circ_empty(xmit)) __stop_tx(up); + +#if defined(USE_TEST_AND_SET) + up->ier |= UART_IER_THRI; + serial_out(up, UART_IER, up->ier); +#endif /*--- #if defined(USE_TEST_AND_SET) ---*/ + } else { + if (up->port.x_char) { + up->port.icount.tx++; + up->port.x_char = 0; + } + while(xmit->tail != xmit->head) { + up->port.icount.tx++; + xmit->tail++; + xmit->tail &= (UART_XMIT_SIZE - 1); + } + } } static unsigned int check_modem_status(struct uart_8250_port *up) @@ -1609,7 +1737,7 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) { - struct irq_info *i; + struct irq_info *i = NULL; struct hlist_node *n; struct hlist_head *h; @@ -1623,6 +1751,7 @@ break; } + BUG_ON(i == NULL); BUG_ON(n == NULL); BUG_ON(i->head == NULL); @@ -2154,6 +2283,8 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { + +#if !defined(CONFIG_MACH_FUSIV) struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; unsigned long flags; @@ -2325,6 +2456,7 @@ /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); +#endif } static void @@ -2558,10 +2690,12 @@ static int first = 1; int i; + if (!first) return; first = 0; + for (i = 0; i < nr_uarts; i++) { struct uart_8250_port *up = &serial8250_ports[i]; @@ -2617,7 +2751,12 @@ { struct uart_8250_port *up = (struct uart_8250_port *)port; - wait_for_xmitr(up, UART_LSR_THRE); + +#ifdef CONFIG_ARCH_PUMA5 + wait_for_xmitr(up, BOTH_EMPTY); +#else/*--- #ifdef CONFIG_ARCH_PUMA5 ---*/ + wait_for_xmitr(up, UART_LSR_THRE); +#endif/*--- #else ---*//*--- #ifdef CONFIG_ARCH_PUMA5 ---*/ serial_out(up, UART_TX, ch); } @@ -2682,8 +2821,13 @@ static int __init serial8250_console_setup(struct console *co, char *options) { +#if defined(CONFIG_MACH_FUSIV) || defined(CONFIG_MACH_ADI_FUSIV) || defined(CONFIG_MIPS_FUSIV) /*setup in loader */ + /* use whatever bootloader settting */ + return 0; +#else struct uart_port *port; - int baud = 9600; + /*--- int baud = 9600; ---*/ + int baud = 115200; int bits = 8; int parity = 'n'; int flow = 'n'; @@ -2695,6 +2839,7 @@ */ if (co->index >= nr_uarts) co->index = 0; + port = &serial8250_ports[co->index].port; if (!port->iobase && !port->membase) return -ENODEV; @@ -2703,6 +2848,7 @@ uart_parse_options(options, &baud, &parity, &bits, &flow); return uart_set_options(port, co, baud, parity, bits, flow); +#endif } static int serial8250_console_early_setup(void) @@ -2810,6 +2956,10 @@ serial_outp(up, UART_LCR, 0); } +#ifdef CONFIG_ARCH_PUMA5 + extern unsigned int avalanche_get_vbus_freq(void); + up->port.uartclk = avalanche_get_vbus_freq (); +#endif uart_resume_port(&serial8250_reg, &up->port); }