2019-05-19 16:51:34 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-07-08 13:40:12 +04:00
/*
* reset controller for CSR SiRFprimaII
*
* Copyright ( c ) 2011 Cambridge Silicon Radio Limited , a CSR plc group company .
*/
# include <linux/kernel.h>
# include <linux/mutex.h>
# include <linux/io.h>
# include <linux/delay.h>
# include <linux/device.h>
# include <linux/of.h>
# include <linux/of_address.h>
2014-01-10 07:15:42 +04:00
# include <linux/platform_device.h>
2013-07-09 03:01:40 +04:00
# include <linux/reboot.h>
2014-01-10 07:15:42 +04:00
# include <linux/reset-controller.h>
2014-03-11 13:53:31 +04:00
# include <asm/system_misc.h>
2014-01-10 07:15:42 +04:00
# define SIRFSOC_RSTBIT_NUM 64
2011-07-08 13:40:12 +04:00
2014-03-11 13:53:31 +04:00
static void __iomem * sirfsoc_rstc_base ;
2011-07-08 13:40:12 +04:00
static DEFINE_MUTEX ( rstc_lock ) ;
2014-01-10 07:15:42 +04:00
static int sirfsoc_reset_module ( struct reset_controller_dev * rcdev ,
unsigned long sw_reset_idx )
2011-07-08 13:40:12 +04:00
{
2014-01-10 07:15:42 +04:00
u32 reset_bit = sw_reset_idx ;
2011-07-08 13:40:12 +04:00
2014-01-10 07:15:42 +04:00
if ( reset_bit > = SIRFSOC_RSTBIT_NUM )
2012-12-20 13:40:47 +04:00
return - EINVAL ;
2011-07-08 13:40:12 +04:00
mutex_lock ( & rstc_lock ) ;
2015-01-04 09:48:20 +03:00
/*
* Writing 1 to this bit resets corresponding block .
* Writing 0 to this bit de - asserts reset signal of the
* corresponding block . datasheet doesn ' t require explicit
* delay between the set and clear of reset bit . it could
* be shorter if tests pass .
*/
writel ( readl ( sirfsoc_rstc_base +
2014-05-07 11:08:21 +04:00
( reset_bit / 32 ) * 4 ) | ( 1 < < reset_bit ) ,
2015-01-04 09:48:20 +03:00
sirfsoc_rstc_base + ( reset_bit / 32 ) * 4 ) ;
msleep ( 20 ) ;
writel ( readl ( sirfsoc_rstc_base +
2014-05-07 11:08:21 +04:00
( reset_bit / 32 ) * 4 ) & ~ ( 1 < < reset_bit ) ,
2015-01-04 09:48:20 +03:00
sirfsoc_rstc_base + ( reset_bit / 32 ) * 4 ) ;
2011-07-08 13:40:12 +04:00
mutex_unlock ( & rstc_lock ) ;
return 0 ;
}
2011-11-05 14:23:27 +04:00
2014-01-10 07:15:42 +04:00
static struct reset_control_ops sirfsoc_rstc_ops = {
. reset = sirfsoc_reset_module ,
} ;
static struct reset_controller_dev sirfsoc_reset_controller = {
. ops = & sirfsoc_rstc_ops ,
. nr_resets = SIRFSOC_RSTBIT_NUM ,
} ;
2014-03-11 13:53:31 +04:00
# define SIRFSOC_SYS_RST_BIT BIT(31)
static void sirfsoc_restart ( enum reboot_mode mode , const char * cmd )
{
writel ( SIRFSOC_SYS_RST_BIT , sirfsoc_rstc_base ) ;
}
2014-01-10 07:15:42 +04:00
static int sirfsoc_rstc_probe ( struct platform_device * pdev )
{
struct device_node * np = pdev - > dev . of_node ;
sirfsoc_rstc_base = of_iomap ( np , 0 ) ;
if ( ! sirfsoc_rstc_base ) {
dev_err ( & pdev - > dev , " unable to map rstc cpu registers \n " ) ;
return - ENOMEM ;
}
sirfsoc_reset_controller . of_node = np ;
2014-03-11 13:53:31 +04:00
arm_pm_restart = sirfsoc_restart ;
2014-01-10 07:15:42 +04:00
2014-03-11 13:53:31 +04:00
if ( IS_ENABLED ( CONFIG_RESET_CONTROLLER ) )
reset_controller_register ( & sirfsoc_reset_controller ) ;
2014-01-10 07:15:42 +04:00
return 0 ;
}
static const struct of_device_id rstc_ids [ ] = {
{ . compatible = " sirf,prima2-rstc " } ,
{ } ,
} ;
static struct platform_driver sirfsoc_rstc_driver = {
. probe = sirfsoc_rstc_probe ,
. driver = {
. name = " sirfsoc_rstc " ,
. of_match_table = rstc_ids ,
} ,
} ;
static int __init sirfsoc_rstc_init ( void )
{
return platform_driver_register ( & sirfsoc_rstc_driver ) ;
}
subsys_initcall ( sirfsoc_rstc_init ) ;