⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omap24xx-uart.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * return */int omap24xx_uart_interrupt(int uart_no, int enable){	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -ENXIO;	}	if (enable)		enable_irq(uart_irq[uart_no]);	else		disable_irq(uart_irq[uart_no]);	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_interrupt);/** * brief omap24xx_uart_reset * resets the UART * param uart_no */int omap24xx_uart_reset(int uart_no){	unsigned long flags;	u32 uart_base = UART_MODULE_BASE(uart_no);	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -ENXIO;	}	spin_lock_irqsave(&(ui[uart_no].uart_lock), flags);	/* UART reset sequence */	writeb(uart_base + REG_LCR, LCR_MODE3);	writeb(uart_base + REG_EFR, BIT_EFR_ENHANCED_EN);	writeb(uart_base + REG_LCR, LCR_MODE1);	writeb(uart_base + REG_IER, DISABLE);	writeb(uart_base + REG_MCR, DISABLE);	writeb(uart_base + REG_MDR1, UART_DISABLE);	spin_unlock_irqrestore(&(ui[uart_no].uart_lock), flags);	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_reset);/** * brief omap24xx_uart_request * Allocates requested UART. * param uart_no * param uart_cback */int omap24xx_uart_request(int uart_no, struct uart_callback *uart_cback){	int err;	u32 uart_base;	u8 sysc_val;	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	spin_lock(&(ui[uart_no].uart_lock));	if (ui[uart_no].in_use) {		printk(KERN_INFO		       "Err!!!!!!!!......Requested UART is not available\n");		spin_unlock(&(ui[uart_no].uart_lock));		FN_OUT(EACCES);		return -EACCES;	}	uart_base = UART_MODULE_BASE(uart_no);	/* Setting UART3 to NoIdle */	sysc_val = readb(uart_base + REG_SYSC);	sysc_val |= (0x1 << 3);	outb(sysc_val, uart_base + REG_SYSC);	spin_unlock(&(ui[uart_no].uart_lock));	printk(KERN_INFO "Error...!!!CONFIG_HS_SERIAL_SUPPORT is not enabled "		"during configuration\n");	return -EPERM;	if ((uart_cb[uart_no].txrx_req_flag == TXRX)	    || (uart_cb[uart_no].txrx_req_flag == RX_ONLY)) {		if (unlikely		    (uart_cback->rx_buf_size < 1		     || uart_cback->rx_buf_size > MAX_BUF_SIZE)) {			printk(KERN_INFO			       "Err!!!! .... Invalid RX buffer size\n");			FN_OUT(0);			return -EACCES;		}	}	if ((uart_cb[uart_no].txrx_req_flag == TXRX)	    || (uart_cb[uart_no].txrx_req_flag == TX_ONLY)) {		if (unlikely		    (uart_cback->tx_buf_size < 1		     || uart_cback->tx_buf_size > MAX_BUF_SIZE)) {			printk(KERN_INFO			       "Err!!!! .... Invalid TX buffer size\n");			FN_OUT(0);			return -EACCES;		}	}	if ((uart_cback->mode != UART_DMA_MODE)	    && (uart_cback->mode != UART_NONDMA_MODE)) {		printk		    ("Error :UART data transfer mode is not defined properly...!!!!\n");		return -EACCES;	}	if (uart_cback->mode == UART_NONDMA_MODE) {		printk("NON DMA mode is supported only in Debug mode. "			"Enable Debug mode in UART library\n");		return -EAGAIN;	}	/* Store the requested mode of tx/rx - DMA/Non DMA */	uart_cb[uart_no].mode = uart_cback->mode;	uart_cb[uart_no].dev = uart_cback->dev;	uart_cb[uart_no].int_callback = uart_cback->int_callback;	uart_cb[uart_no].dev_name = uart_cback->dev_name;	if (request_irq	    (uart_irq[uart_no], (void *)omap24xx_uart_isr, 0,	     uart_cb[uart_no].dev_name, uart_cb[uart_no].dev)) {		printk("Error: IRQ allocation failed\n");		err = -EPERM;		goto exit_path0;	}	spin_lock(&(ui[uart_no].uart_lock));	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		uart_cb[uart_no].mode = uart_cback->mode;		uart_cb[uart_no].txrx_req_flag = uart_cback->txrx_req_flag;		if ((uart_cb[uart_no].txrx_req_flag == TXRX)		    || (uart_cb[uart_no].txrx_req_flag == RX_ONLY)) {			/* Request DMA Channels for requested UART */			err = omap_request_dma			    (uart_dma_rx[uart_no],			     "UART Rx DMA",			     (void *)uart_rx_dma_callback,			     uart_cb[uart_no].dev,			     &(ui[uart_no].rx_dma_channel));			if (err) {				printk(KERN_ERR "Failed to get DMA Channels\n");				goto exit_path1;			}			uart_cb[uart_no].rx_buf_size = uart_cback->rx_buf_size;			uart_cb[uart_no].uart_rx_dma_callback =			    uart_cback->uart_rx_dma_callback;			ui[uart_no].rx_buf_dma_virt =			    dma_alloc_coherent(NULL,					       uart_cb[uart_no].					       rx_buf_size,					       (dma_addr_t *)&(ui						 [uart_no].rx_buf_dma_phys), 0);			if (!ui[uart_no].rx_buf_dma_virt) {				printk(KERN_ERR				       "Failed to allocate DMA Rx Buffer...!!!!\n");				goto exit_path2;			}		}		if ((uart_cb[uart_no].txrx_req_flag == TXRX)		    || (uart_cb[uart_no].txrx_req_flag == TX_ONLY)) {			err = omap_request_dma			    (uart_dma_tx[uart_no],			     "UART Tx DMA",			     (void *)uart_tx_dma_callback,			     uart_cb[uart_no].dev,			     &(ui[uart_no].tx_dma_channel));			if (err) {				printk(KERN_ERR "Failed to get DMA Channels\n");				goto exit_path3;			}			uart_cb[uart_no].tx_buf_size = uart_cback->tx_buf_size;			uart_cb[uart_no].uart_tx_dma_callback =			    uart_cback->uart_tx_dma_callback;			ui[uart_no].tx_buf_dma_virt =			    dma_alloc_coherent(NULL,					       uart_cb[uart_no].					       tx_buf_size,					       (dma_addr_t *)&(ui						 [uart_no].tx_buf_dma_phys), 0);			if (!ui[uart_no].tx_buf_dma_virt) {				printk(KERN_ERR				       "Failed to allocate DMA Tx Buffer...!!!!\n");				goto exit_path4;			}		}	}	/* set timer to use for variable length receive. */	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		ui[uart_no].timeout = 10;		init_timer(&ui[uart_no].timer);		ui[uart_no].timer.function = omap24xx_timeout_isr;		ui[uart_no].timer.expires = jiffies + msecs_to_jiffies(ui[uart_no].timeout);		ui[uart_no].timer.data = uart_no;		ui[uart_no].uart_no = uart_no;		ui[uart_no].timer_active = 0;	}	ui[uart_no].tx_buf_state = FREE;	ui[uart_no].rx_buf_state = FREE;	ui[uart_no].in_use = 1;	spin_unlock(&(ui[uart_no].uart_lock));	constr_handle = constraint_get("hsuart", &cnstr_id);	constraint_set(constr_handle, CO_LATENCY_MPUOFF_COREON);	FN_OUT(0);	return 0;      exit_path4:	omap_free_dma(ui[uart_no].rx_dma_channel);	if ((uart_cb[uart_no].txrx_req_flag == TXRX)	    || (uart_cb[uart_no].txrx_req_flag == TX_ONLY)) {		uart_cb[uart_no].tx_buf_size = 0;		uart_cb[uart_no].uart_tx_dma_callback = NULL;	}      exit_path3:	if ((uart_cb[uart_no].txrx_req_flag == TXRX)	    || (uart_cb[uart_no].txrx_req_flag == RX_ONLY)) {		dma_free_coherent(uart_cb[uart_no].dev,				  uart_cb[uart_no].rx_buf_size,				  ui[uart_no].				  rx_buf_dma_virt, ui[uart_no].rx_buf_dma_phys);		uart_cb[uart_no].rx_buf_size = 0;		uart_cb[uart_no].uart_rx_dma_callback = NULL;	}      exit_path2:	if (uart_cb[uart_no].txrx_req_flag == TXRX	    || (uart_cb[uart_no].txrx_req_flag == RX_ONLY))		omap_free_dma(ui[uart_no].rx_dma_channel);      exit_path1:	free_irq(uart_irq[uart_no], uart_cb[uart_no].dev);      exit_path0:	uart_cb[uart_no].dev = NULL;	uart_cb[uart_no].int_callback = NULL;	spin_unlock(&(ui[uart_no].uart_lock));	FN_OUT(0);	return err;}EXPORT_SYMBOL(omap24xx_uart_request);/** * brief omap24xx_uart_release * release UART * param uart_no * * return */int omap24xx_uart_release(int uart_no){	u32 uart_base;	u8 sysc_val;		FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}		spin_lock(&(ui[uart_no].uart_lock));	if (!ui[uart_no].in_use) {		printk(KERN_INFO "Requested UART is already in free state\n");		spin_unlock(&(ui[uart_no].uart_lock));		FN_OUT(EACCES);		return -EACCES;	}	/* MOVE requested UART to free state.	 * Free DMA channels.	 * Free DMA buffers.	 */	/* Free IRQ, DMA channels and allocated memory. */	free_irq(uart_irq[uart_no], uart_cb[uart_no].dev);	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		omap_free_dma(ui[uart_no].rx_dma_channel);		omap_free_dma(ui[uart_no].tx_dma_channel);		dma_free_coherent(uart_cb[uart_no].dev,				  uart_cb[uart_no].rx_buf_size,				  ui[uart_no].				  rx_buf_dma_virt, ui[uart_no].rx_buf_dma_phys);		dma_free_coherent(uart_cb[uart_no].dev,				  uart_cb[uart_no].tx_buf_size,				  ui[uart_no].				  tx_buf_dma_virt, ui[uart_no].tx_buf_dma_phys);		uart_cb[uart_no].uart_tx_dma_callback = NULL;		uart_cb[uart_no].uart_rx_dma_callback = NULL;	}	uart_cb[uart_no].int_callback = NULL;	uart_cb[uart_no].dev_name = NULL;	uart_cb[uart_no].dev = NULL;	ui[uart_no].in_use = 0;	ui[uart_no].rx_dma_channel = 0;	ui[uart_no].tx_dma_channel = 0;	ui[uart_no].rx_buf_dma_phys = 0;	ui[uart_no].tx_buf_dma_phys = 0;	ui[uart_no].rx_buf_dma_virt = NULL;	ui[uart_no].tx_buf_dma_virt = NULL;	ui[uart_no].rx_buf_state = 0;	ui[uart_no].tx_buf_state = 0;	spin_unlock(&(ui[uart_no].uart_lock));		constraint_remove(constr_handle);	constraint_put(constr_handle);	uart_base = UART_MODULE_BASE(uart_no);	/* Setting UART3 to ForceIdle */	sysc_val = readb(uart_base + REG_SYSC);	sysc_val &= ~(0x3 << 3);	outb(0x0, uart_base + REG_SYSC);	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_release);/** * omap24xx_uart_set_timeout * Set the GP Timer Divisor. * time_ms is in milisecond */int omap24xx_uart_set_timeout(int uart_no, u32 time_ms){	if ((!ui[uart_no].timer_active) && (time_ms != 0)) {		ui[uart_no].timeout = time_ms;		return 0;	}	else {		ui[uart_no].timeout = time_ms;		return -EPERM;	}}EXPORT_SYMBOL(omap24xx_uart_set_timeout);/** * brief console_detect * Detect Console UART using command line parameter. * param str * * return */int console_detect(char *str){	extern char *saved_command_line;	char *next, *start = NULL;	int i;	FN_IN;	i = strlen(CONSOLE_NAME);	next = saved_command_line;	while ((next = strchr(next, 'c')) != NULL) {		if (!strncmp(next, CONSOLE_NAME, i)) {			start = next;			break;		} else {			next++;		}	}	if (!start)		return -EPERM;	i = 0;	start = strchr(start, '=') + 1;	while (*start != ',') {		str[i++] = *start++;		if (i > 6){			printk("Invalid Console Name\n");			return -EPERM;		}	}	str[i] = '\0';	FN_OUT(0);	return 0;}/** * brief omap24xx_init_uart *  UART initialization * return */static int __init omap24xx_uart_init(void){	char str[7];	int i;	FN_IN;	spin_lock_init(&(ui[UART1].uart_lock));	spin_lock_init(&(ui[UART2].uart_lock));	spin_lock_init(&(ui[UART3].uart_lock));	/* Reserve the console uart */        if ( console_detect(str)){                printk("Invalid console paramter....UART Library Init Failed!!!!\n");                return -EPERM;	}	if (!strcmp(str, "ttyS0"))		ui[UART1].in_use = 1;	else if (!strcmp(str, "ttyS1"))		ui[UART2].in_use = 1;	else if (!strcmp(str, "ttyS2"))		ui[UART3].in_use = 1;	else		printk(KERN_INFO		       "!!!!!!!!! Unable to recongnize Console UART........\n");	D3(" Console : %s\n", str);	D3("\n ********** Initial UART States *************\n");	D3(" UART1 : %d\n", ui[UART1].in_use);	D3(" UART2 : %d\n", ui[UART2].in_use);	D3(" UART3 : %d\n", ui[UART3].in_use);	/* initialize tx/rx channel */        for (i = UART1; i <= UART3; i++) {                ui[i].rx_dma_channel = -1;                ui[i].tx_dma_channel = -1;        }	FN_OUT(0);	return 0;}/** * brief omap24xx_init_exit * exit function. * return */static void __exit omap24xx_uart_exit(void){	printk("UART Library Exit\n");}module_init(omap24xx_uart_init);module_exit(omap24xx_uart_exit);MODULE_AUTHOR("Texas Instruments");MODULE_DESCRIPTION("UART Library");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -