xref: /OK3568_Linux_fs/kernel/arch/mips/bcm47xx/serial.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * 8250 UART probe driver for the BCM47XX platforms
3*4882a593Smuzhiyun  * Author: Aurelien Jarno
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This file is subject to the terms and conditions of the GNU General Public
6*4882a593Smuzhiyun  * License.  See the file "COPYING" in the main directory of this archive
7*4882a593Smuzhiyun  * for more details.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/init.h>
13*4882a593Smuzhiyun #include <linux/serial.h>
14*4882a593Smuzhiyun #include <linux/serial_8250.h>
15*4882a593Smuzhiyun #include <linux/ssb/ssb.h>
16*4882a593Smuzhiyun #include <bcm47xx.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun static struct plat_serial8250_port uart8250_data[5];
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun static struct platform_device uart8250_device = {
21*4882a593Smuzhiyun 	.name			= "serial8250",
22*4882a593Smuzhiyun 	.id			= PLAT8250_DEV_PLATFORM,
23*4882a593Smuzhiyun 	.dev			= {
24*4882a593Smuzhiyun 		.platform_data	= uart8250_data,
25*4882a593Smuzhiyun 	},
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #ifdef CONFIG_BCM47XX_SSB
uart8250_init_ssb(void)29*4882a593Smuzhiyun static int __init uart8250_init_ssb(void)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	int i;
32*4882a593Smuzhiyun 	struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	memset(&uart8250_data, 0,  sizeof(uart8250_data));
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	for (i = 0; i < mcore->nr_serial_ports &&
37*4882a593Smuzhiyun 		    i < ARRAY_SIZE(uart8250_data) - 1; i++) {
38*4882a593Smuzhiyun 		struct plat_serial8250_port *p = &(uart8250_data[i]);
39*4882a593Smuzhiyun 		struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]);
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 		p->mapbase = (unsigned int)ssb_port->regs;
42*4882a593Smuzhiyun 		p->membase = (void *)ssb_port->regs;
43*4882a593Smuzhiyun 		p->irq = ssb_port->irq + 2;
44*4882a593Smuzhiyun 		p->uartclk = ssb_port->baud_base;
45*4882a593Smuzhiyun 		p->regshift = ssb_port->reg_shift;
46*4882a593Smuzhiyun 		p->iotype = UPIO_MEM;
47*4882a593Smuzhiyun 		p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
48*4882a593Smuzhiyun 	}
49*4882a593Smuzhiyun 	return platform_device_register(&uart8250_device);
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun #endif
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #ifdef CONFIG_BCM47XX_BCMA
uart8250_init_bcma(void)54*4882a593Smuzhiyun static int __init uart8250_init_bcma(void)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	int i;
57*4882a593Smuzhiyun 	struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	memset(&uart8250_data, 0,  sizeof(uart8250_data));
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	for (i = 0; i < cc->nr_serial_ports &&
62*4882a593Smuzhiyun 		    i < ARRAY_SIZE(uart8250_data) - 1; i++) {
63*4882a593Smuzhiyun 		struct plat_serial8250_port *p = &(uart8250_data[i]);
64*4882a593Smuzhiyun 		struct bcma_serial_port *bcma_port;
65*4882a593Smuzhiyun 		bcma_port = &(cc->serial_ports[i]);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 		p->mapbase = (unsigned int)bcma_port->regs;
68*4882a593Smuzhiyun 		p->membase = (void *)bcma_port->regs;
69*4882a593Smuzhiyun 		p->irq = bcma_port->irq;
70*4882a593Smuzhiyun 		p->uartclk = bcma_port->baud_base;
71*4882a593Smuzhiyun 		p->regshift = bcma_port->reg_shift;
72*4882a593Smuzhiyun 		p->iotype = UPIO_MEM;
73*4882a593Smuzhiyun 		p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
74*4882a593Smuzhiyun 	}
75*4882a593Smuzhiyun 	return platform_device_register(&uart8250_device);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun #endif
78*4882a593Smuzhiyun 
uart8250_init(void)79*4882a593Smuzhiyun static int __init uart8250_init(void)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	switch (bcm47xx_bus_type) {
82*4882a593Smuzhiyun #ifdef CONFIG_BCM47XX_SSB
83*4882a593Smuzhiyun 	case BCM47XX_BUS_TYPE_SSB:
84*4882a593Smuzhiyun 		return uart8250_init_ssb();
85*4882a593Smuzhiyun #endif
86*4882a593Smuzhiyun #ifdef CONFIG_BCM47XX_BCMA
87*4882a593Smuzhiyun 	case BCM47XX_BUS_TYPE_BCMA:
88*4882a593Smuzhiyun 		return uart8250_init_bcma();
89*4882a593Smuzhiyun #endif
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun 	return -EINVAL;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun device_initcall(uart8250_init);
94