/* * Blackfin On-Chip Serial Driver * * Copyright 2006-2008 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ * * Licensed under the GPL-2 or later. */#if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)#define SUPPORT_SYSRQ#endif#include<linux/module.h>#include<linux/ioport.h>#include<linux/init.h>#include<linux/console.h>#include<linux/sysrq.h>#include<linux/platform_device.h>#include<linux/tty.h>#include<linux/tty_flip.h>#include<linux/serial_core.h>#ifdef CONFIG_KGDB_UART#include<linux/kgdb.h>#include<asm/irq_regs.h>#endif#include<asm/gpio.h>#include<mach/bfin_serial_5xx.h>#ifdef CONFIG_SERIAL_BFIN_DMA#include<linux/dma-mapping.h>#include<asm/io.h>#include<asm/irq.h>#include<asm/cacheflush.h>#endif/* UART name and device definitions */#define BFIN_SERIAL_NAME "ttyBF"#define BFIN_SERIAL_MAJOR 204#define BFIN_SERIAL_MINOR 64staticstructbfin_serial_portbfin_serial_ports[BFIN_UART_NR_PORTS];staticintnr_active_ports=ARRAY_SIZE(bfin_serial_resource);/* * Setup for console. Argument comes from the menuconfig */#define DMA_RX_XCOUNT 512#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT)#define DMA_RX_FLUSH_JIFFIES (HZ / 50)#define CTS_CHECK_JIFFIES (HZ / 50)#ifdef CONFIG_SERIAL_BFIN_DMAstaticvoidbfin_serial_dma_tx_chars(structbfin_serial_port*uart);#elsestaticvoidbfin_serial_tx_chars(structbfin_serial_port*uart);#endifstaticvoidbfin_serial_mctrl_check(structbfin_serial_port*uart);/* * interrupts are disabled on entry */staticvoidbfin_serial_stop_tx(structuart_port*port){structbfin_serial_port*uart=(structbfin_serial_port*)port;structcirc_buf*xmit=&uart->port.info->xmit;while(!(UART_GET_LSR(uart)&TEMT))cpu_relax();#ifdef CONFIG_SERIAL_BFIN_DMAdisable_dma(uart->tx_dma_channel);xmit->tail=(xmit->tail+uart->tx_count)&(UART_XMIT_SIZE-1);uart->port.icount.tx+=uart->tx_count;uart->tx_count=0;uart->tx_done=1;#else#ifdef CONFIG_BF54x/* Clear TFI bit */UART_PUT_LSR(uart,TFI);#endifUART_CLEAR_IER(uart,ETBEI);#endif}/* * port is locked and interrupts are disabled */staticvoidbfin_serial_start_tx(structuart_port*port){structbfin_serial_port*uart=(structbfin_serial_port*)port;#ifdef CONFIG_SERIAL_BFIN_DMAif(uart->tx_done)bfin_serial_dma_tx_chars(uart);#elseUART_SET_IER(uart,ETBEI);bfin_serial_tx_chars(uart);#endif}/* * Interrupts are enabled */staticvoidbfin_serial_stop_rx(structuart_port*port){structbfin_serial_port*uart=(structbfin_serial_port*)port;#ifdef CONFIG_KGDB_UARTif(uart->port.line