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

📄 mpc52xx_uart.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static struct console mpc52xx_console = {	.name	= "ttyPSC",	.write	= mpc52xx_console_write,	.device	= uart_console_device,	.setup	= mpc52xx_console_setup,	.flags	= CON_PRINTBUFFER,	.index	= -1,	/* Specified on the cmdline (e.g. console=ttyPSC0 ) */	.data	= &mpc52xx_uart_driver,};static int __initmpc52xx_console_init(void){#if defined(CONFIG_PPC_MERGE)	mpc52xx_uart_of_enumerate();#endif	register_console(&mpc52xx_console);	return 0;}console_initcall(mpc52xx_console_init);#define MPC52xx_PSC_CONSOLE &mpc52xx_console#else#define MPC52xx_PSC_CONSOLE NULL#endif/* ======================================================================== *//* UART Driver                                                              *//* ======================================================================== */static struct uart_driver mpc52xx_uart_driver = {	.owner		= THIS_MODULE,	.driver_name	= "mpc52xx_psc_uart",	.dev_name	= "ttyPSC",	.major		= SERIAL_PSC_MAJOR,	.minor		= SERIAL_PSC_MINOR,	.nr		= MPC52xx_PSC_MAXNUM,	.cons		= MPC52xx_PSC_CONSOLE,};#if !defined(CONFIG_PPC_MERGE)/* ======================================================================== *//* Platform Driver                                                          *//* ======================================================================== */static int __devinitmpc52xx_uart_probe(struct platform_device *dev){	struct resource *res = dev->resource;	struct uart_port *port = NULL;	int i, idx, ret;	/* Check validity & presence */	idx = dev->id;	if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)		return -EINVAL;	if (!mpc52xx_match_psc_function(idx,"uart"))		return -ENODEV;	/* Init the port structure */	port = &mpc52xx_uart_ports[idx];	spin_lock_init(&port->lock);	port->uartclk	= __res.bi_ipbfreq / 2; /* Look at CTLR doc */	port->fifosize	= 512;	port->iotype	= UPIO_MEM;	port->flags	= UPF_BOOT_AUTOCONF |			  ( uart_console(port) ? 0 : UPF_IOREMAP );	port->line	= idx;	port->ops	= &mpc52xx_uart_ops;	port->dev	= &dev->dev;	/* Search for IRQ and mapbase */	for (i=0 ; i<dev->num_resources ; i++, res++) {		if (res->flags & IORESOURCE_MEM)			port->mapbase = res->start;		else if (res->flags & IORESOURCE_IRQ)			port->irq = res->start;	}	if (!port->irq || !port->mapbase)		return -EINVAL;	/* Add the port to the uart sub-system */	ret = uart_add_one_port(&mpc52xx_uart_driver, port);	if (!ret)		platform_set_drvdata(dev, (void*)port);	return ret;}static intmpc52xx_uart_remove(struct platform_device *dev){	struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);	platform_set_drvdata(dev, NULL);	if (port)		uart_remove_one_port(&mpc52xx_uart_driver, port);	return 0;}#ifdef CONFIG_PMstatic intmpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state){	struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);	if (port)		uart_suspend_port(&mpc52xx_uart_driver, port);	return 0;}static intmpc52xx_uart_resume(struct platform_device *dev){	struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);	if (port)		uart_resume_port(&mpc52xx_uart_driver, port);	return 0;}#endifstatic struct platform_driver mpc52xx_uart_platform_driver = {	.probe		= mpc52xx_uart_probe,	.remove		= mpc52xx_uart_remove,#ifdef CONFIG_PM	.suspend	= mpc52xx_uart_suspend,	.resume		= mpc52xx_uart_resume,#endif	.driver		= {		.name	= "mpc52xx-psc",	},};#endif /* !defined(CONFIG_PPC_MERGE) */#if defined(CONFIG_PPC_MERGE)/* ======================================================================== *//* OF Platform Driver                                                       *//* ======================================================================== */static int __devinitmpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match){	int idx = -1;	unsigned int ipb_freq;	struct uart_port *port = NULL;	struct resource res;	int ret;	dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match);	/* Check validity & presence */	for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++)		if (mpc52xx_uart_nodes[idx] == op->node)			break;	if (idx >= MPC52xx_PSC_MAXNUM)		return -EINVAL;	pr_debug("Found %s assigned to ttyPSC%x\n",	         mpc52xx_uart_nodes[idx]->full_name, idx);	/* Search for bus-frequency property in this node or a parent */	if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) {		dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");		return -EINVAL;	}	/* Init the port structure */	port = &mpc52xx_uart_ports[idx];	spin_lock_init(&port->lock);	port->uartclk	= ipb_freq / 2;	port->fifosize	= 512;	port->iotype	= UPIO_MEM;	port->flags	= UPF_BOOT_AUTOCONF |			  ( uart_console(port) ? 0 : UPF_IOREMAP );	port->line	= idx;	port->ops	= &mpc52xx_uart_ops;	port->dev	= &op->dev;	/* Search for IRQ and mapbase */	if ((ret = of_address_to_resource(op->node, 0, &res)) != 0)		return ret;	port->mapbase = res.start;	port->irq = irq_of_parse_and_map(op->node, 0);	dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n",	        (void*)port->mapbase, port->irq, port->uartclk);	if ((port->irq==NO_IRQ) || !port->mapbase) {		printk(KERN_ERR "Could not allocate resources for PSC\n");		return -EINVAL;	}	/* Add the port to the uart sub-system */	ret = uart_add_one_port(&mpc52xx_uart_driver, port);	if (!ret)		dev_set_drvdata(&op->dev, (void*)port);	return ret;}static intmpc52xx_uart_of_remove(struct of_device *op){	struct uart_port *port = dev_get_drvdata(&op->dev);	dev_set_drvdata(&op->dev, NULL);	if (port) {		uart_remove_one_port(&mpc52xx_uart_driver, port);		irq_dispose_mapping(port->irq);	}	return 0;}#ifdef CONFIG_PMstatic intmpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state){	struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);	if (port)		uart_suspend_port(&mpc52xx_uart_driver, port);	return 0;}static intmpc52xx_uart_of_resume(struct of_device *op){	struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);	if (port)		uart_resume_port(&mpc52xx_uart_driver, port);	return 0;}#endifstatic voidmpc52xx_uart_of_assign(struct device_node *np, int idx){	int free_idx = -1;	int i;	/* Find the first free node */	for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {		if (mpc52xx_uart_nodes[i] == NULL) {			free_idx = i;			break;		}	}	if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM))		idx = free_idx;	if (idx < 0)		return; /* No free slot; abort */	/* If the slot is already occupied, then swap slots */	if (mpc52xx_uart_nodes[idx] && (free_idx != -1))		mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx];	mpc52xx_uart_nodes[idx] = np;}static voidmpc52xx_uart_of_enumerate(void){	static int enum_done = 0;	struct device_node *np;	const unsigned int *devno;	int i;	if (enum_done)		return;	for_each_node_by_type(np, "serial") {		if (!of_match_node(mpc52xx_uart_of_match, np))			continue;		/* Is a particular device number requested? */		devno = of_get_property(np, "port-number", NULL);		mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1);	}	enum_done = 1;	for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {		if (mpc52xx_uart_nodes[i])			pr_debug("%s assigned to ttyPSC%x\n",			         mpc52xx_uart_nodes[i]->full_name, i);	}}MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match);static struct of_platform_driver mpc52xx_uart_of_driver = {	.owner		= THIS_MODULE,	.name		= "mpc52xx-psc-uart",	.match_table	= mpc52xx_uart_of_match,	.probe		= mpc52xx_uart_of_probe,	.remove		= mpc52xx_uart_of_remove,#ifdef CONFIG_PM	.suspend	= mpc52xx_uart_of_suspend,	.resume		= mpc52xx_uart_of_resume,#endif	.driver		= {		.name	= "mpc52xx-psc-uart",	},};#endif /* defined(CONFIG_PPC_MERGE) *//* ======================================================================== *//* Module                                                                   *//* ======================================================================== */static int __initmpc52xx_uart_init(void){	int ret;	printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n");	if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) {		printk(KERN_ERR "%s: uart_register_driver failed (%i)\n",		       __FILE__, ret);		return ret;	}#if defined(CONFIG_PPC_MERGE)	mpc52xx_uart_of_enumerate();	ret = of_register_platform_driver(&mpc52xx_uart_of_driver);	if (ret) {		printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n",		       __FILE__, ret);		uart_unregister_driver(&mpc52xx_uart_driver);		return ret;	}#else	ret = platform_driver_register(&mpc52xx_uart_platform_driver);	if (ret) {		printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",		       __FILE__, ret);		uart_unregister_driver(&mpc52xx_uart_driver);		return ret;	}#endif	return 0;}static void __exitmpc52xx_uart_exit(void){#if defined(CONFIG_PPC_MERGE)	of_unregister_platform_driver(&mpc52xx_uart_of_driver);#else	platform_driver_unregister(&mpc52xx_uart_platform_driver);#endif	uart_unregister_driver(&mpc52xx_uart_driver);}module_init(mpc52xx_uart_init);module_exit(mpc52xx_uart_exit);MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");MODULE_DESCRIPTION("Freescale MPC52xx PSC UART");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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