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

📄 bfin_5xx.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
{}/* * Request the memory region(s) being used by 'port'. */static int bfin_serial_request_port(struct uart_port *port){	return 0;}/* * Configure/autoconfigure the port. */static void bfin_serial_config_port(struct uart_port *port, int flags){	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;	if (flags & UART_CONFIG_TYPE &&	    bfin_serial_request_port(&uart->port) == 0)		uart->port.type = PORT_BFIN;}/* * Verify the new serial_struct (for TIOCSSERIAL). * The only change we allow are to the flags and type, and * even then only between PORT_BFIN and PORT_UNKNOWN */static intbfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser){	return 0;}static struct uart_ops bfin_serial_pops = {	.tx_empty	= bfin_serial_tx_empty,	.set_mctrl	= bfin_serial_set_mctrl,	.get_mctrl	= bfin_serial_get_mctrl,	.stop_tx	= bfin_serial_stop_tx,	.start_tx	= bfin_serial_start_tx,	.stop_rx	= bfin_serial_stop_rx,	.enable_ms	= bfin_serial_enable_ms,	.break_ctl	= bfin_serial_break_ctl,	.startup	= bfin_serial_startup,	.shutdown	= bfin_serial_shutdown,	.set_termios	= bfin_serial_set_termios,	.type		= bfin_serial_type,	.release_port	= bfin_serial_release_port,	.request_port	= bfin_serial_request_port,	.config_port	= bfin_serial_config_port,	.verify_port	= bfin_serial_verify_port,};static void __init bfin_serial_init_ports(void){	static int first = 1;	int i;	if (!first)		return;	first = 0;	for (i = 0; i < nr_ports; i++) {		bfin_serial_ports[i].port.uartclk   = get_sclk();		bfin_serial_ports[i].port.ops       = &bfin_serial_pops;		bfin_serial_ports[i].port.line      = i;		bfin_serial_ports[i].port.iotype    = UPIO_MEM;		bfin_serial_ports[i].port.membase   =			(void __iomem *)bfin_serial_resource[i].uart_base_addr;		bfin_serial_ports[i].port.mapbase   =			bfin_serial_resource[i].uart_base_addr;		bfin_serial_ports[i].port.irq       =			bfin_serial_resource[i].uart_irq;		bfin_serial_ports[i].port.flags     = UPF_BOOT_AUTOCONF;#ifdef CONFIG_SERIAL_BFIN_DMA		bfin_serial_ports[i].tx_done	    = 1;		bfin_serial_ports[i].tx_count	    = 0;		bfin_serial_ports[i].tx_dma_channel =			bfin_serial_resource[i].uart_tx_dma_channel;		bfin_serial_ports[i].rx_dma_channel =			bfin_serial_resource[i].uart_rx_dma_channel;		init_timer(&(bfin_serial_ports[i].rx_dma_timer));#else		INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work);#endif#ifdef CONFIG_SERIAL_BFIN_CTSRTS		bfin_serial_ports[i].cts_pin	    =			bfin_serial_resource[i].uart_cts_pin;		bfin_serial_ports[i].rts_pin	    =			bfin_serial_resource[i].uart_rts_pin;#endif		bfin_serial_hw_init(&bfin_serial_ports[i]);	}}#ifdef CONFIG_SERIAL_BFIN_CONSOLE/* * If the port was already initialised (eg, by a boot loader), * try to determine the current setup. */static void __initbfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,			   int *parity, int *bits){	unsigned short status;	status = UART_GET_IER(uart) & (ERBFI | ETBEI);	if (status == (ERBFI | ETBEI)) {		/* ok, the port was enabled */		unsigned short lcr, val;		unsigned short dlh, dll;		lcr = UART_GET_LCR(uart);		*parity = 'n';		if (lcr & PEN) {			if (lcr & EPS)				*parity = 'e';			else				*parity = 'o';		}		switch (lcr & 0x03) {			case 0:	*bits = 5; break;			case 1:	*bits = 6; break;			case 2:	*bits = 7; break;			case 3:	*bits = 8; break;		}#ifndef CONFIG_BF54x		/* Set DLAB in LCR to Access DLL and DLH */		val = UART_GET_LCR(uart);		val |= DLAB;		UART_PUT_LCR(uart, val);#endif		dll = UART_GET_DLL(uart);		dlh = UART_GET_DLH(uart);#ifndef CONFIG_BF54x		/* Clear DLAB in LCR to Access THR RBR IER */		val = UART_GET_LCR(uart);		val &= ~DLAB;		UART_PUT_LCR(uart, val);#endif		*baud = get_sclk() / (16*(dll | dlh << 8));	}	pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);}#endif#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)static struct uart_driver bfin_serial_reg;static int __initbfin_serial_console_setup(struct console *co, char *options){	struct bfin_serial_port *uart;# ifdef CONFIG_SERIAL_BFIN_CONSOLE	int baud = 57600;	int bits = 8;	int parity = 'n';#  ifdef CONFIG_SERIAL_BFIN_CTSRTS	int flow = 'r';#  else	int flow = 'n';#  endif# endif	/*	 * Check whether an invalid uart number has been specified, and	 * if so, search for the first available port that does have	 * console support.	 */	if (co->index == -1 || co->index >= nr_ports)		co->index = 0;	uart = &bfin_serial_ports[co->index];# ifdef CONFIG_SERIAL_BFIN_CONSOLE	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	else		bfin_serial_console_get_options(uart, &baud, &parity, &bits);	return uart_set_options(&uart->port, co, baud, parity, bits, flow);# else	return 0;# endif}#endif /* defined (CONFIG_SERIAL_BFIN_CONSOLE) ||				 defined (CONFIG_EARLY_PRINTK) */#ifdef CONFIG_SERIAL_BFIN_CONSOLEstatic void bfin_serial_console_putchar(struct uart_port *port, int ch){	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;	while (!(UART_GET_LSR(uart) & THRE))		barrier();	UART_PUT_CHAR(uart, ch);	SSYNC();}/* * Interrupts are disabled on entering */static voidbfin_serial_console_write(struct console *co, const char *s, unsigned int count){	struct bfin_serial_port *uart = &bfin_serial_ports[co->index];	int flags = 0;	spin_lock_irqsave(&uart->port.lock, flags);	uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);	spin_unlock_irqrestore(&uart->port.lock, flags);}static struct console bfin_serial_console = {	.name		= BFIN_SERIAL_NAME,	.write		= bfin_serial_console_write,	.device		= uart_console_device,	.setup		= bfin_serial_console_setup,	.flags		= CON_PRINTBUFFER,	.index		= -1,	.data		= &bfin_serial_reg,};static int __init bfin_serial_rs_console_init(void){	bfin_serial_init_ports();	register_console(&bfin_serial_console);#ifdef CONFIG_KGDB_UART	kgdb_entry_state = 0;	init_kgdb_uart();#endif	return 0;}console_initcall(bfin_serial_rs_console_init);#define BFIN_SERIAL_CONSOLE	&bfin_serial_console#else#define BFIN_SERIAL_CONSOLE	NULL#endif /* CONFIG_SERIAL_BFIN_CONSOLE */#ifdef CONFIG_EARLY_PRINTKstatic __init void early_serial_putc(struct uart_port *port, int ch){	unsigned timeout = 0xffff;	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;	while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)		cpu_relax();	UART_PUT_CHAR(uart, ch);}static __init void early_serial_write(struct console *con, const char *s,					unsigned int n){	struct bfin_serial_port *uart = &bfin_serial_ports[con->index];	unsigned int i;	for (i = 0; i < n; i++, s++) {		if (*s == '\n')			early_serial_putc(&uart->port, '\r');		early_serial_putc(&uart->port, *s);	}}static struct __init console bfin_early_serial_console = {	.name = "early_BFuart",	.write = early_serial_write,	.device = uart_console_device,	.flags = CON_PRINTBUFFER,	.setup = bfin_serial_console_setup,	.index = -1,	.data  = &bfin_serial_reg,};struct console __init *bfin_earlyserial_init(unsigned int port,						unsigned int cflag){	struct bfin_serial_port *uart;	struct ktermios t;	if (port == -1 || port >= nr_ports)		port = 0;	bfin_serial_init_ports();	bfin_early_serial_console.index = port;	uart = &bfin_serial_ports[port];	t.c_cflag = cflag;	t.c_iflag = 0;	t.c_oflag = 0;	t.c_lflag = ICANON;	t.c_line = port;	bfin_serial_set_termios(&uart->port, &t, &t);	return &bfin_early_serial_console;}#endif /* CONFIG_SERIAL_BFIN_CONSOLE */static struct uart_driver bfin_serial_reg = {	.owner			= THIS_MODULE,	.driver_name		= "bfin-uart",	.dev_name		= BFIN_SERIAL_NAME,	.major			= BFIN_SERIAL_MAJOR,	.minor			= BFIN_SERIAL_MINOR,	.nr			= NR_PORTS,	.cons			= BFIN_SERIAL_CONSOLE,};static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state){	struct bfin_serial_port *uart = platform_get_drvdata(dev);	if (uart)		uart_suspend_port(&bfin_serial_reg, &uart->port);	return 0;}static int bfin_serial_resume(struct platform_device *dev){	struct bfin_serial_port *uart = platform_get_drvdata(dev);	if (uart)		uart_resume_port(&bfin_serial_reg, &uart->port);	return 0;}static int bfin_serial_probe(struct platform_device *dev){	struct resource *res = dev->resource;	int i;	for (i = 0; i < dev->num_resources; i++, res++)		if (res->flags & IORESOURCE_MEM)			break;	if (i < dev->num_resources) {		for (i = 0; i < nr_ports; i++, res++) {			if (bfin_serial_ports[i].port.mapbase != res->start)				continue;			bfin_serial_ports[i].port.dev = &dev->dev;			uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);			platform_set_drvdata(dev, &bfin_serial_ports[i]);		}	}	return 0;}static int bfin_serial_remove(struct platform_device *pdev){	struct bfin_serial_port *uart = platform_get_drvdata(pdev);#ifdef CONFIG_SERIAL_BFIN_CTSRTS	gpio_free(uart->cts_pin);	gpio_free(uart->rts_pin);#endif	platform_set_drvdata(pdev, NULL);	if (uart)		uart_remove_one_port(&bfin_serial_reg, &uart->port);	return 0;}static struct platform_driver bfin_serial_driver = {	.probe		= bfin_serial_probe,	.remove		= bfin_serial_remove,	.suspend	= bfin_serial_suspend,	.resume		= bfin_serial_resume,	.driver		= {		.name	= "bfin-uart",	},};static int __init bfin_serial_init(void){	int ret;#ifdef CONFIG_KGDB_UART	struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];	struct ktermios t;#endif	pr_info("Serial: Blackfin serial driver\n");	bfin_serial_init_ports();	ret = uart_register_driver(&bfin_serial_reg);	if (ret == 0) {		ret = platform_driver_register(&bfin_serial_driver);		if (ret) {			pr_debug("uart register failed\n");			uart_unregister_driver(&bfin_serial_reg);		}	}#ifdef CONFIG_KGDB_UART	if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {		request_irq(uart->port.irq, bfin_serial_rx_int,			IRQF_DISABLED, "BFIN_UART_RX", uart);		pr_info("Request irq for kgdb uart port\n");#ifdef CONFIG_BF54x		UART_SET_IER(uart, ERBFI);#else		UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);#endif		SSYNC();		t.c_cflag = CS8|B57600;		t.c_iflag = 0;		t.c_oflag = 0;		t.c_lflag = ICANON;		t.c_line = CONFIG_KGDB_UART_PORT;		bfin_serial_set_termios(&uart->port, &t, &t);	}#endif	return ret;}static void __exit bfin_serial_exit(void){	platform_driver_unregister(&bfin_serial_driver);	uart_unregister_driver(&bfin_serial_reg);}module_init(bfin_serial_init);module_exit(bfin_serial_exit);MODULE_AUTHOR("Aubrey.Li <aubrey.li@analog.com>");MODULE_DESCRIPTION("Blackfin generic serial port driver");MODULE_LICENSE("GPL");MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR);

⌨️ 快捷键说明

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