2013-01-20 22:00:57 +01:00
/*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation .
*
* Copyright ( C ) 2008 - 2009 Gabor Juhos < juhosg @ openwrt . org >
* Copyright ( C ) 2008 Imre Kaloz < kaloz @ openwrt . org >
2016-05-05 09:57:56 +02:00
* Copyright ( C ) 2013 John Crispin < john @ phrozen . org >
2013-01-20 22:00:57 +01:00
*/
# include <linux/pm.h>
# include <linux/io.h>
2013-09-04 00:16:59 +02:00
# include <linux/of.h>
2015-11-04 11:50:13 +01:00
# include <linux/delay.h>
2013-09-04 00:16:59 +02:00
# include <linux/reset-controller.h>
2013-01-20 22:00:57 +01:00
# include <asm/reboot.h>
# include <asm/mach-ralink/ralink_regs.h>
/* Reset Control */
2015-11-04 11:50:13 +01:00
# define SYSC_REG_RESET_CTRL 0x034
# define RSTCTL_RESET_PCI BIT(26)
# define RSTCTL_RESET_SYSTEM BIT(0)
2013-01-20 22:00:57 +01:00
2013-09-04 00:16:59 +02:00
static int ralink_assert_device ( struct reset_controller_dev * rcdev ,
unsigned long id )
{
u32 val ;
if ( id < 8 )
return - 1 ;
val = rt_sysc_r32 ( SYSC_REG_RESET_CTRL ) ;
val | = BIT ( id ) ;
rt_sysc_w32 ( val , SYSC_REG_RESET_CTRL ) ;
return 0 ;
}
static int ralink_deassert_device ( struct reset_controller_dev * rcdev ,
unsigned long id )
{
u32 val ;
if ( id < 8 )
return - 1 ;
val = rt_sysc_r32 ( SYSC_REG_RESET_CTRL ) ;
val & = ~ BIT ( id ) ;
rt_sysc_w32 ( val , SYSC_REG_RESET_CTRL ) ;
return 0 ;
}
static int ralink_reset_device ( struct reset_controller_dev * rcdev ,
unsigned long id )
{
ralink_assert_device ( rcdev , id ) ;
return ralink_deassert_device ( rcdev , id ) ;
}
2016-02-25 10:45:47 +01:00
static const struct reset_control_ops reset_ops = {
2013-09-04 00:16:59 +02:00
. reset = ralink_reset_device ,
. assert = ralink_assert_device ,
. deassert = ralink_deassert_device ,
} ;
static struct reset_controller_dev reset_dev = {
. ops = & reset_ops ,
. owner = THIS_MODULE ,
. nr_resets = 32 ,
. of_reset_n_cells = 1 ,
} ;
void ralink_rst_init ( void )
{
reset_dev . of_node = of_find_compatible_node ( NULL , NULL ,
" ralink,rt2880-reset " ) ;
if ( ! reset_dev . of_node )
pr_err ( " Failed to find reset controller node " ) ;
else
reset_controller_register ( & reset_dev ) ;
}
2013-01-20 22:00:57 +01:00
static void ralink_restart ( char * command )
{
2015-11-04 11:50:13 +01:00
if ( IS_ENABLED ( CONFIG_PCI ) ) {
rt_sysc_m32 ( 0 , RSTCTL_RESET_PCI , SYSC_REG_RESET_CTRL ) ;
mdelay ( 50 ) ;
}
2013-01-20 22:00:57 +01:00
local_irq_disable ( ) ;
rt_sysc_w32 ( RSTCTL_RESET_SYSTEM , SYSC_REG_RESET_CTRL ) ;
unreachable ( ) ;
}
static int __init mips_reboot_setup ( void )
{
_machine_restart = ralink_restart ;
return 0 ;
}
arch_initcall ( mips_reboot_setup ) ;