xref: /linux/arch/mips/loongson2ef/common/serial.c (revision 26fbb4c8c7c3ee9a4c3b4de555a8587b5a19154e)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
7  *
8  * Copyright (C) 2009 Lemote, Inc.
9  * Author: Yan hua (yanhua@lemote.com)
10  * Author: Wu Zhangjin (wuzhangjin@gmail.com)
11  */
12 
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/serial_8250.h>
16 
17 #include <asm/bootinfo.h>
18 
19 #include <loongson.h>
20 #include <machine.h>
21 
22 #define PORT(int, clk)			\
23 {								\
24 	.irq		= int,					\
25 	.uartclk	= clk,					\
26 	.iotype		= UPIO_PORT,				\
27 	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
28 	.regshift	= 0,					\
29 }
30 
31 #define PORT_M(int, clk)				\
32 {								\
33 	.irq		= MIPS_CPU_IRQ_BASE + (int),		\
34 	.uartclk	= clk,					\
35 	.iotype		= UPIO_MEM,				\
36 	.membase	= (void __iomem *)NULL,			\
37 	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
38 	.regshift	= 0,					\
39 }
40 
41 static struct plat_serial8250_port uart8250_data[MACH_LOONGSON_END + 1] = {
42 	[MACH_LOONGSON_UNKNOWN]	= {},
43 	[MACH_LEMOTE_FL2E]	= PORT(4, 1843200),
44 	[MACH_LEMOTE_FL2F]	= PORT(3, 1843200),
45 	[MACH_LEMOTE_ML2F7]	= PORT_M(3, 3686400),
46 	[MACH_LEMOTE_YL2F89]	= PORT_M(3, 3686400),
47 	[MACH_DEXXON_GDIUM2F10]	= PORT_M(3, 3686400),
48 	[MACH_LEMOTE_NAS]	= PORT_M(3, 3686400),
49 	[MACH_LEMOTE_LL2F]	= PORT(3, 1843200),
50 	[MACH_LOONGSON_END]	= {},
51 };
52 
53 static struct platform_device uart8250_device = {
54 	.name = "serial8250",
55 	.id = PLAT8250_DEV_PLATFORM,
56 };
57 
58 static int __init serial_init(void)
59 {
60 	unsigned char iotype;
61 
62 	iotype = uart8250_data[mips_machtype].iotype;
63 
64 	if (UPIO_MEM == iotype) {
65 		uart8250_data[mips_machtype].mapbase =
66 			loongson_uart_base;
67 		uart8250_data[mips_machtype].membase =
68 			(void __iomem *)_loongson_uart_base;
69 	}
70 	else if (UPIO_PORT == iotype)
71 		uart8250_data[mips_machtype].iobase =
72 			loongson_uart_base - LOONGSON_PCIIO_BASE;
73 
74 	memset(&uart8250_data[mips_machtype + 1], 0,
75 			sizeof(struct plat_serial8250_port));
76 	uart8250_device.dev.platform_data = &uart8250_data[mips_machtype];
77 
78 	return platform_device_register(&uart8250_device);
79 }
80 module_init(serial_init);
81 
82 static void __exit serial_exit(void)
83 {
84 	platform_device_unregister(&uart8250_device);
85 }
86 module_exit(serial_exit);
87