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

📄 uartlite.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct uart_port *port = &ulite_ports[co->index];	unsigned long flags;	unsigned int ier;	int locked = 1;	if (oops_in_progress) {		locked = spin_trylock_irqsave(&port->lock, flags);	} else		spin_lock_irqsave(&port->lock, flags);	/* save and disable interrupt */	ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;	writeb(0, port->membase + ULITE_CONTROL);	uart_console_write(port, s, count, ulite_console_putchar);	ulite_console_wait_tx(port);	/* restore interrupt state */	if (ier)		writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);	if (locked)		spin_unlock_irqrestore(&port->lock, flags);}#if defined(CONFIG_OF)static inline void __init ulite_console_of_find_device(int id){	struct device_node *np;	struct resource res;	const unsigned int *of_id;	int rc;	for_each_compatible_node(np, NULL, "xilinx,uartlite") {		of_id = of_get_property(np, "port-number", NULL);		if ((!of_id) || (*of_id != id))			continue;		rc = of_address_to_resource(np, 0, &res);		if (rc)			continue;		ulite_ports[id].mapbase = res.start;		of_node_put(np);		return;	}}#else /* CONFIG_OF */static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ }#endif /* CONFIG_OF */static int __init ulite_console_setup(struct console *co, char *options){	struct uart_port *port;	int baud = 9600;	int bits = 8;	int parity = 'n';	int flow = 'n';	if (co->index < 0 || co->index >= ULITE_NR_UARTS)		return -EINVAL;	port = &ulite_ports[co->index];	/* Check if it is an OF device */	if (!port->mapbase)		ulite_console_of_find_device(co->index);	/* Do we have a device now? */	if (!port->mapbase) {		pr_debug("console on ttyUL%i not present\n", co->index);		return -ENODEV;	}	/* not initialized yet? */	if (!port->membase) {		if (ulite_request_port(port))			return -ENODEV;	}	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	return uart_set_options(port, co, baud, parity, bits, flow);}static struct uart_driver ulite_uart_driver;static struct console ulite_console = {	.name	= ULITE_NAME,	.write	= ulite_console_write,	.device	= uart_console_device,	.setup	= ulite_console_setup,	.flags	= CON_PRINTBUFFER,	.index	= -1, /* Specified on the cmdline (e.g. console=ttyUL0 ) */	.data	= &ulite_uart_driver,};static int __init ulite_console_init(void){	register_console(&ulite_console);	return 0;}console_initcall(ulite_console_init);#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */static struct uart_driver ulite_uart_driver = {	.owner		= THIS_MODULE,	.driver_name	= "uartlite",	.dev_name	= ULITE_NAME,	.major		= ULITE_MAJOR,	.minor		= ULITE_MINOR,	.nr		= ULITE_NR_UARTS,#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE	.cons		= &ulite_console,#endif};/* --------------------------------------------------------------------- * Port assignment functions (mapping devices to uart_port structures) *//** ulite_assign: register a uartlite device with the driver * * @dev: pointer to device structure * @id: requested id number.  Pass -1 for automatic port assignment * @base: base address of uartlite registers * @irq: irq number for uartlite * * Returns: 0 on success, <0 otherwise */static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq){	struct uart_port *port;	int rc;	/* if id = -1; then scan for a free id and use that */	if (id < 0) {		for (id = 0; id < ULITE_NR_UARTS; id++)			if (ulite_ports[id].mapbase == 0)				break;	}	if (id < 0 || id >= ULITE_NR_UARTS) {		dev_err(dev, "%s%i too large\n", ULITE_NAME, id);		return -EINVAL;	}	if ((ulite_ports[id].mapbase) && (ulite_ports[id].mapbase != base)) {		dev_err(dev, "cannot assign to %s%i; it is already in use\n",			ULITE_NAME, id);		return -EBUSY;	}	port = &ulite_ports[id];	spin_lock_init(&port->lock);	port->fifosize = 16;	port->regshift = 2;	port->iotype = UPIO_MEM;	port->iobase = 1; /* mark port in use */	port->mapbase = base;	port->membase = NULL;	port->ops = &ulite_ops;	port->irq = irq;	port->flags = UPF_BOOT_AUTOCONF;	port->dev = dev;	port->type = PORT_UNKNOWN;	port->line = id;	dev_set_drvdata(dev, port);	/* Register the port */	rc = uart_add_one_port(&ulite_uart_driver, port);	if (rc) {		dev_err(dev, "uart_add_one_port() failed; err=%i\n", rc);		port->mapbase = 0;		dev_set_drvdata(dev, NULL);		return rc;	}	return 0;}/** ulite_release: register a uartlite device with the driver * * @dev: pointer to device structure */static int __devinit ulite_release(struct device *dev){	struct uart_port *port = dev_get_drvdata(dev);	int rc = 0;	if (port) {		rc = uart_remove_one_port(&ulite_uart_driver, port);		dev_set_drvdata(dev, NULL);		port->mapbase = 0;	}	return rc;}/* --------------------------------------------------------------------- * Platform bus binding */static int __devinit ulite_probe(struct platform_device *pdev){	struct resource *res, *res2;	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	if (!res)		return -ENODEV;	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);	if (!res2)		return -ENODEV;	return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start);}static int ulite_remove(struct platform_device *pdev){	return ulite_release(&pdev->dev);}static struct platform_driver ulite_platform_driver = {	.probe	= ulite_probe,	.remove	= ulite_remove,	.driver	= {		   .owner = THIS_MODULE,		   .name  = "uartlite",		   },};/* --------------------------------------------------------------------- * OF bus bindings */#if defined(CONFIG_OF)static int __devinitulite_of_probe(struct of_device *op, const struct of_device_id *match){	struct resource res;	const unsigned int *id;	int irq, rc;	dev_dbg(&op->dev, "%s(%p, %p)\n", __FUNCTION__, op, match);	rc = of_address_to_resource(op->node, 0, &res);	if (rc) {		dev_err(&op->dev, "invalid address\n");		return rc;	}	irq = irq_of_parse_and_map(op->node, 0);	id = of_get_property(op->node, "port-number", NULL);	return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq);}static int __devexit ulite_of_remove(struct of_device *op){	return ulite_release(&op->dev);}/* Match table for of_platform binding */static struct of_device_id __devinit ulite_of_match[] = {	{ .type = "serial", .compatible = "xilinx,uartlite", },	{},};MODULE_DEVICE_TABLE(of, ulite_of_match);static struct of_platform_driver ulite_of_driver = {	.owner = THIS_MODULE,	.name = "uartlite",	.match_table = ulite_of_match,	.probe = ulite_of_probe,	.remove = __devexit_p(ulite_of_remove),	.driver = {		.name = "uartlite",	},};/* Registration helpers to keep the number of #ifdefs to a minimum */static inline int __init ulite_of_register(void){	pr_debug("uartlite: calling of_register_platform_driver()\n");	return of_register_platform_driver(&ulite_of_driver);}static inline void __exit ulite_of_unregister(void){	of_unregister_platform_driver(&ulite_of_driver);}#else /* CONFIG_OF *//* CONFIG_OF not enabled; do nothing helpers */static inline int __init ulite_of_register(void) { return 0; }static inline void __exit ulite_of_unregister(void) { }#endif /* CONFIG_OF *//* --------------------------------------------------------------------- * Module setup/teardown */int __init ulite_init(void){	int ret;	pr_debug("uartlite: calling uart_register_driver()\n");	ret = uart_register_driver(&ulite_uart_driver);	if (ret)		goto err_uart;	ret = ulite_of_register();	if (ret)		goto err_of;	pr_debug("uartlite: calling platform_driver_register()\n");	ret = platform_driver_register(&ulite_platform_driver);	if (ret)		goto err_plat;	return 0;err_plat:	ulite_of_unregister();err_of:	uart_unregister_driver(&ulite_uart_driver);err_uart:	printk(KERN_ERR "registering uartlite driver failed: err=%i", ret);	return ret;}void __exit ulite_exit(void){	platform_driver_unregister(&ulite_platform_driver);	ulite_of_unregister();	uart_unregister_driver(&ulite_uart_driver);}module_init(ulite_init);module_exit(ulite_exit);MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");MODULE_DESCRIPTION("Xilinx uartlite serial driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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