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