2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2011-07-25 17:36:42 +01:00
/*
* Copyright ( c ) 2011 Picochip Ltd . , Jamie Iles
*
* All enquiries to support @ picochip . com
*/
2011-12-17 13:42:37 +00:00
# include <linux/delay.h>
2011-07-25 17:36:42 +01:00
# include <linux/of.h>
# include <linux/of_address.h>
2013-07-08 16:01:40 -07:00
# include <linux/reboot.h>
2011-07-25 17:36:42 +01:00
# include <asm/mach/arch.h>
2011-12-12 20:21:39 +00:00
# include <asm/mach/map.h>
2011-07-25 17:36:42 +01:00
2012-08-27 00:38:35 -05:00
# define PHYS_TO_IO(x) (((x) & 0x00ffffff) | 0xfe000000)
# define PICOXCELL_PERIPH_BASE 0x80000000
# define PICOXCELL_PERIPH_LENGTH SZ_4M
# define WDT_CTRL_REG_EN_MASK (1 << 0)
# define WDT_CTRL_REG_OFFS (0x00)
# define WDT_TIMEOUT_REG_OFFS (0x04)
2011-12-17 13:42:37 +00:00
static void __iomem * wdt_regs ;
/*
* The machine restart method can be called from an atomic context so we won ' t
* be able to ioremap the regs then .
*/
static void picoxcell_setup_restart ( void )
{
struct device_node * np = of_find_compatible_node ( NULL , NULL ,
" snps,dw-apb-wdg " ) ;
if ( WARN ( ! np , " unable to setup watchdog restart " ) )
return ;
wdt_regs = of_iomap ( np , 0 ) ;
WARN ( ! wdt_regs , " failed to remap watchdog regs " ) ;
}
2011-12-12 20:21:39 +00:00
static struct map_desc io_map __initdata = {
. virtual = PHYS_TO_IO ( PICOXCELL_PERIPH_BASE ) ,
. pfn = __phys_to_pfn ( PICOXCELL_PERIPH_BASE ) ,
. length = PICOXCELL_PERIPH_LENGTH ,
. type = MT_DEVICE ,
} ;
static void __init picoxcell_map_io ( void )
{
iotable_init ( & io_map , 1 ) ;
}
2011-07-25 17:36:42 +01:00
static void __init picoxcell_init_machine ( void )
{
2011-12-17 13:42:37 +00:00
picoxcell_setup_restart ( ) ;
2011-07-25 17:36:42 +01:00
}
static const char * picoxcell_dt_match [ ] = {
" picochip,pc3x2 " ,
" picochip,pc3x3 " ,
NULL
} ;
2013-07-08 16:01:40 -07:00
static void picoxcell_wdt_restart ( enum reboot_mode mode , const char * cmd )
2011-12-17 13:42:37 +00:00
{
/*
* Configure the watchdog to reset with the shortest possible timeout
* and give it chance to do the reset .
*/
if ( wdt_regs ) {
writel_relaxed ( WDT_CTRL_REG_EN_MASK , wdt_regs + WDT_CTRL_REG_OFFS ) ;
writel_relaxed ( 0 , wdt_regs + WDT_TIMEOUT_REG_OFFS ) ;
/* No sleeping, possibly atomic. */
mdelay ( 500 ) ;
}
}
2011-07-25 17:36:42 +01:00
DT_MACHINE_START ( PICOXCELL , " Picochip picoXcell " )
. map_io = picoxcell_map_io ,
. init_machine = picoxcell_init_machine ,
. dt_compat = picoxcell_dt_match ,
2011-12-17 13:42:37 +00:00
. restart = picoxcell_wdt_restart ,
2011-07-25 17:36:42 +01:00
MACHINE_END