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

📄 mv64x60_udbg.c

📁 linux 内核源代码
💻 C
字号:
/* * udbg serial input/output routines for the Marvell MV64x60 (Discovery). * * Author: Dale Farnsworth <dale@farnsworth.org> * * 2007 (c) MontaVista Software, Inc.  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 <asm/io.h>#include <asm/prom.h>#include <asm/udbg.h>#include <sysdev/mv64x60.h>#define MPSC_0_CR1_OFFSET	0x000c#define MPSC_0_CR2_OFFSET	0x0010#define MPSC_CHR_2_TCS		(1 << 9)#define MPSC_0_CHR_10_OFFSET	0x0030#define MPSC_INTR_CAUSE_OFF_0	0x0004#define MPSC_INTR_CAUSE_OFF_1	0x000c#define MPSC_INTR_CAUSE_RCC	(1<<6)static void __iomem *mpsc_base;static void __iomem *mpsc_intr_cause;static void mv64x60_udbg_putc(char c){	if (c == '\n')		mv64x60_udbg_putc('\r');	while(in_le32(mpsc_base + MPSC_0_CR2_OFFSET) & MPSC_CHR_2_TCS)		;	out_le32(mpsc_base + MPSC_0_CR1_OFFSET, c);	out_le32(mpsc_base + MPSC_0_CR2_OFFSET, MPSC_CHR_2_TCS);}static int mv64x60_udbg_testc(void){	return (in_le32(mpsc_intr_cause) & MPSC_INTR_CAUSE_RCC) != 0;}static int mv64x60_udbg_getc(void){	int cause = 0;	int c;	while (!mv64x60_udbg_testc())		;	c = in_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2);	out_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2, c);	out_le32(mpsc_intr_cause, cause & ~MPSC_INTR_CAUSE_RCC);	return c;}static int mv64x60_udbg_getc_poll(void){	if (!mv64x60_udbg_testc())		return -1;	return mv64x60_udbg_getc();}static void mv64x60_udbg_init(void){	struct device_node *np, *mpscintr, *stdout = NULL;	const char *path;	const phandle *ph;	struct resource r[2];	const int *block_index;	int intr_cause_offset;	int err;	path = of_get_property(of_chosen, "linux,stdout-path", NULL);	if (!path)		return;	stdout = of_find_node_by_path(path);	if (!stdout)		return;	for (np = NULL;	     (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); )		if (np == stdout)			break;	of_node_put(stdout);	if (!np)		return;	block_index = of_get_property(np, "block-index", NULL);	if (!block_index)		goto error;	switch (*block_index) {	case 0:		intr_cause_offset = MPSC_INTR_CAUSE_OFF_0;		break;	case 1:		intr_cause_offset = MPSC_INTR_CAUSE_OFF_1;		break;	default:		goto error;	}	err = of_address_to_resource(np, 0, &r[0]);	if (err)		goto error;	ph = of_get_property(np, "mpscintr", NULL);	mpscintr = of_find_node_by_phandle(*ph);	if (!mpscintr)		goto error;	err = of_address_to_resource(mpscintr, 0, &r[1]);	of_node_put(mpscintr);	if (err)		goto error;	of_node_put(np);	mpsc_base = ioremap(r[0].start, r[0].end - r[0].start + 1);	if (!mpsc_base)		return;	mpsc_intr_cause = ioremap(r[1].start, r[1].end - r[1].start + 1);	if (!mpsc_intr_cause) {		iounmap(mpsc_base);		return;	}	mpsc_intr_cause += intr_cause_offset;	udbg_putc = mv64x60_udbg_putc;	udbg_getc = mv64x60_udbg_getc;	udbg_getc_poll = mv64x60_udbg_getc_poll;	return;error:	of_node_put(np);}void mv64x60_init_early(void){	mv64x60_udbg_init();}

⌨️ 快捷键说明

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