2009-10-16 14:17:18 +08:00
/*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 2007 Ralf Baechle ( ralf @ linux - mips . org )
*
* Copyright ( C ) 2009 Lemote , Inc .
* Author : Yan hua ( yanhua @ lemote . com )
2010-01-04 17:16:51 +08:00
* Author : Wu Zhangjin ( wuzhangjin @ gmail . com )
2009-10-16 14:17:18 +08:00
*/
# include <linux/io.h>
2015-06-02 16:16:07 -04:00
# include <linux/module.h>
2009-10-16 14:17:18 +08:00
# include <linux/serial_8250.h>
# include <asm/bootinfo.h>
# include <loongson.h>
# include <machine.h>
2014-03-21 18:44:05 +08:00
# define PORT(int, clk) \
2009-10-16 14:17:18 +08:00
{ \
. irq = int , \
2014-03-21 18:44:05 +08:00
. uartclk = clk , \
2009-10-16 14:17:18 +08:00
. iotype = UPIO_PORT , \
. flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST , \
. regshift = 0 , \
}
2014-03-21 18:44:05 +08:00
# define PORT_M(int, clk) \
2009-10-16 14:17:18 +08:00
{ \
. irq = MIPS_CPU_IRQ_BASE + ( int ) , \
2014-03-21 18:44:05 +08:00
. uartclk = clk , \
2009-10-16 14:17:18 +08:00
. iotype = UPIO_MEM , \
. membase = ( void __iomem * ) NULL , \
. flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST , \
. regshift = 0 , \
}
2014-11-04 14:13:27 +08:00
static struct plat_serial8250_port uart8250_data [ ] [ MAX_UARTS + 1 ] = {
2014-11-19 23:52:45 +02:00
[ MACH_LOONGSON_UNKNOWN ] = { } ,
[ MACH_LEMOTE_FL2E ] = { PORT ( 4 , 1843200 ) , { } } ,
[ MACH_LEMOTE_FL2F ] = { PORT ( 3 , 1843200 ) , { } } ,
[ MACH_LEMOTE_ML2F7 ] = { PORT_M ( 3 , 3686400 ) , { } } ,
[ MACH_LEMOTE_YL2F89 ] = { PORT_M ( 3 , 3686400 ) , { } } ,
[ MACH_DEXXON_GDIUM2F10 ] = { PORT_M ( 3 , 3686400 ) , { } } ,
[ MACH_LEMOTE_NAS ] = { PORT_M ( 3 , 3686400 ) , { } } ,
[ MACH_LEMOTE_LL2F ] = { PORT ( 3 , 1843200 ) , { } } ,
[ MACH_LOONGSON_GENERIC ] = { PORT_M ( 2 , 25000000 ) , { } } ,
[ MACH_LOONGSON_END ] = { } ,
2009-10-16 14:17:18 +08:00
} ;
static struct platform_device uart8250_device = {
. name = " serial8250 " ,
. id = PLAT8250_DEV_PLATFORM ,
} ;
static int __init serial_init ( void )
{
2014-11-04 14:13:27 +08:00
int i ;
2009-11-28 14:21:50 +08:00
unsigned char iotype ;
iotype = uart8250_data [ mips_machtype ] [ 0 ] . iotype ;
2014-11-04 14:13:27 +08:00
if ( UPIO_MEM = = iotype ) {
uart8250_data [ mips_machtype ] [ 0 ] . mapbase =
loongson_uart_base [ 0 ] ;
2009-11-06 18:35:34 +08:00
uart8250_data [ mips_machtype ] [ 0 ] . membase =
2014-11-04 14:13:27 +08:00
( void __iomem * ) _loongson_uart_base [ 0 ] ;
}
2009-11-28 14:21:50 +08:00
else if ( UPIO_PORT = = iotype )
2009-11-06 18:35:34 +08:00
uart8250_data [ mips_machtype ] [ 0 ] . iobase =
2014-11-04 14:13:27 +08:00
loongson_uart_base [ 0 ] - LOONGSON_PCIIO_BASE ;
2009-10-16 14:17:18 +08:00
2014-11-04 14:13:27 +08:00
if ( loongson_sysconf . uarts [ 0 ] . uartclk )
uart8250_data [ mips_machtype ] [ 0 ] . uartclk =
loongson_sysconf . uarts [ 0 ] . uartclk ;
for ( i = 1 ; i < loongson_sysconf . nr_uarts ; i + + ) {
iotype = loongson_sysconf . uarts [ i ] . iotype ;
uart8250_data [ mips_machtype ] [ i ] . iotype = iotype ;
loongson_uart_base [ i ] = loongson_sysconf . uarts [ i ] . uart_base ;
if ( UPIO_MEM = = iotype ) {
uart8250_data [ mips_machtype ] [ i ] . irq =
MIPS_CPU_IRQ_BASE + loongson_sysconf . uarts [ i ] . int_offset ;
uart8250_data [ mips_machtype ] [ i ] . mapbase =
loongson_uart_base [ i ] ;
uart8250_data [ mips_machtype ] [ i ] . membase =
ioremap_nocache ( loongson_uart_base [ i ] , 8 ) ;
} else if ( UPIO_PORT = = iotype ) {
uart8250_data [ mips_machtype ] [ i ] . irq =
loongson_sysconf . uarts [ i ] . int_offset ;
uart8250_data [ mips_machtype ] [ i ] . iobase =
loongson_uart_base [ i ] - LOONGSON_PCIIO_BASE ;
}
uart8250_data [ mips_machtype ] [ i ] . uartclk =
loongson_sysconf . uarts [ i ] . uartclk ;
uart8250_data [ mips_machtype ] [ i ] . flags =
UPF_BOOT_AUTOCONF | UPF_SKIP_TEST ;
}
memset ( & uart8250_data [ mips_machtype ] [ loongson_sysconf . nr_uarts ] ,
0 , sizeof ( struct plat_serial8250_port ) ) ;
2009-11-06 18:35:34 +08:00
uart8250_device . dev . platform_data = uart8250_data [ mips_machtype ] ;
2009-10-16 14:17:18 +08:00
2009-11-06 18:35:34 +08:00
return platform_device_register ( & uart8250_device ) ;
2009-10-16 14:17:18 +08:00
}
2015-06-02 16:16:07 -04:00
module_init ( serial_init ) ;
2009-10-16 14:17:18 +08:00
2015-06-02 16:16:07 -04:00
static void __init serial_exit ( void )
{
platform_device_unregister ( & uart8250_device ) ;
}
module_exit ( serial_exit ) ;