2011-07-25 17:36:42 +01:00
/*
* Copyright ( c ) 2011 Picochip Ltd . , Jamie Iles
*
* 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 .
*
* 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/irq.h>
# include <linux/irqdomain.h>
# include <linux/of.h>
# include <linux/of_address.h>
2011-11-03 17:29:03 +00:00
# include <linux/of_irq.h>
2011-07-25 17:36:42 +01:00
# include <linux/of_platform.h>
# include <asm/mach/arch.h>
# include <asm/hardware/vic.h>
2011-12-12 20:21:39 +00:00
# include <asm/mach/map.h>
2011-07-25 17:36:42 +01:00
# include <mach/map.h>
# include <mach/picoxcell_soc.h>
# include "common.h"
2011-12-17 13:42:37 +00:00
# define WDT_CTRL_REG_EN_MASK (1 << 0)
# define WDT_CTRL_REG_OFFS (0x00)
# define WDT_TIMEOUT_REG_OFFS (0x04)
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 )
{
of_platform_populate ( NULL , of_default_bus_match_table , NULL , NULL ) ;
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
} ;
static const struct of_device_id vic_of_match [ ] __initconst = {
2011-11-03 17:29:03 +00:00
{ . compatible = " arm,pl192-vic " , . data = vic_of_init , } ,
2011-07-25 17:36:42 +01:00
{ /* Sentinel */ }
} ;
static void __init picoxcell_init_irq ( void )
{
2011-11-03 17:29:03 +00:00
of_irq_init ( vic_of_match ) ;
2011-07-25 17:36:42 +01:00
}
2011-12-17 13:42:37 +00:00
static void picoxcell_wdt_restart ( char mode , const char * cmd )
{
/*
* 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 ,
2011-12-12 20:17:37 +00:00
. nr_irqs = NR_IRQS_LEGACY ,
2011-07-25 17:36:42 +01:00
. init_irq = picoxcell_init_irq ,
2011-11-03 17:29:03 +00:00
. handle_irq = vic_handle_irq ,
2011-07-25 17:36:42 +01:00
. timer = & picoxcell_timer ,
. 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