/* * Blackfin On-Chip Serial Driver * * Copyright 2006-2007 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<asm/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 64/* * 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)#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;#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA)unsignedshortier;#endifwhile(!(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);UART_CLEAR_IER(uart,ETBEI);#elseier=UART_GET_IER(uart);ier&=~ETBEI;UART_PUT_IER(uart,ier);#endif#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);#else#ifdef CONFIG_BF54xUART_SET_IER(uart,ETBEI);#elseunsignedshortier;ier=UART_GET_IER(uart);