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

📄 ls_uart.c

📁 linux内核源码
💻 C
字号:
/* * AVR power-management chip interface for the Buffalo Linkstation / * Kurobox Platform. * * Author: 2006 (c) G. Liakhovetski *	 g.liakhovetski@gmx.de * * This file is licensed under the terms of the GNU General Public License * version 2.  This program is licensed "as is" without any warranty of * any kind, whether express or implied. */#include <linux/workqueue.h>#include <linux/string.h>#include <linux/delay.h>#include <linux/serial_reg.h>#include <linux/serial_8250.h>#include <asm/io.h>#include <asm/prom.h>#include <asm/termbits.h>#include "mpc10x.h"static void __iomem *avr_addr;static unsigned long avr_clock;static struct work_struct wd_work;static void wd_stop(struct work_struct *unused){	const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";	int i = 0, rescue = 8;	int len = strlen(string);	while (rescue--) {		int j;		char lsr = in_8(avr_addr + UART_LSR);		if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) {			for (j = 0; j < 16 && i < len; j++, i++)				out_8(avr_addr + UART_TX, string[i]);			if (i == len) {				/* Read "OK" back: 4ms for the last "KKKK"				   plus a couple bytes back */				msleep(7);				printk("linkstation: disarming the AVR watchdog: ");				while (in_8(avr_addr + UART_LSR) & UART_LSR_DR)					printk("%c", in_8(avr_addr + UART_RX));				break;			}		}		msleep(17);	}	printk("\n");}#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)void avr_uart_configure(void){	unsigned char cval = UART_LCR_WLEN8;	unsigned int quot = AVR_QUOT(avr_clock);	if (!avr_addr || !avr_clock)		return;	out_8(avr_addr + UART_LCR, cval);			/* initialise UART */	out_8(avr_addr + UART_MCR, 0);	out_8(avr_addr + UART_IER, 0);	cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR;	out_8(avr_addr + UART_LCR, cval);			/* Set character format */	out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */	out_8(avr_addr + UART_DLL, quot & 0xff);		/* LS of divisor */	out_8(avr_addr + UART_DLM, quot >> 8);			/* MS of divisor */	out_8(avr_addr + UART_LCR, cval);			/* reset DLAB */	out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO);	/* enable FIFO */}void avr_uart_send(const char c){	if (!avr_addr || !avr_clock)		return;	out_8(avr_addr + UART_TX, c);	out_8(avr_addr + UART_TX, c);	out_8(avr_addr + UART_TX, c);	out_8(avr_addr + UART_TX, c);}static void __init ls_uart_init(void){	local_irq_disable();#ifndef CONFIG_SERIAL_8250	out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO);	/* enable FIFO */	out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO |	      UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);	/* clear FIFOs */	out_8(avr_addr + UART_FCR, 0);	out_8(avr_addr + UART_IER, 0);	/* Clear up interrupts */	(void) in_8(avr_addr + UART_LSR);	(void) in_8(avr_addr + UART_RX);	(void) in_8(avr_addr + UART_IIR);	(void) in_8(avr_addr + UART_MSR);#endif	avr_uart_configure();	local_irq_enable();}static int __init ls_uarts_init(void){	struct device_node *avr;	phys_addr_t phys_addr;	int len;	if (!machine_is(linkstation))		return 0;	avr = of_find_node_by_path("/soc10x/serial@80004500");	if (!avr)		return -EINVAL;	avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);	phys_addr = ((u32*)of_get_property(avr, "reg", &len))[0];	if (!avr_clock || !phys_addr)		return -EINVAL;	avr_addr = ioremap(phys_addr, 32);	if (!avr_addr)		return -EFAULT;	ls_uart_init();	INIT_WORK(&wd_work, wd_stop);	schedule_work(&wd_work);	return 0;}late_initcall(ls_uarts_init);

⌨️ 快捷键说明

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