2010-03-15 23:04:46 -07:00
/*
2011-05-01 14:10:10 -07:00
* Copyright ( C ) 2011 Google , Inc .
2010-03-15 23:04:46 -07:00
*
* Author :
2011-05-01 14:10:10 -07:00
* Colin Cross < ccross @ android . com >
2010-03-15 23:04:46 -07:00
*
2013-04-03 19:31:45 +08:00
* Copyright ( C ) 2010 , 2013 , NVIDIA Corporation
2010-04-05 20:30:59 -07:00
*
2010-03-15 23:04:46 -07:00
* This software is licensed under the terms of the GNU General Public
* License version 2 , as published by the Free Software Foundation , and
* may be copied , distributed , and modified under those terms .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
*/
2013-07-19 17:25:24 +08:00
# include <linux/cpu_pm.h>
2010-03-15 23:04:46 -07:00
# include <linux/interrupt.h>
# include <linux/io.h>
2012-12-27 13:10:24 -06:00
# include <linux/irqchip/arm-gic.h>
2014-07-11 09:44:49 +02:00
# include <linux/irq.h>
# include <linux/kernel.h>
# include <linux/of_address.h>
# include <linux/of.h>
2013-04-03 19:31:45 +08:00
# include <linux/syscore_ops.h>
2010-03-15 23:04:46 -07:00
# include "board.h"
2012-10-04 14:24:09 -06:00
# include "iomap.h"
2010-03-15 23:04:46 -07:00
2013-01-15 22:10:26 +00:00
# define SGI_MASK 0xFFFF
2013-04-03 19:31:45 +08:00
# ifdef CONFIG_PM_SLEEP
2013-07-19 17:25:24 +08:00
static void __iomem * tegra_gic_cpu_base ;
2013-04-03 19:31:45 +08:00
# endif
2013-01-15 22:10:26 +00:00
bool tegra_pending_sgi ( void )
{
u32 pending_set ;
void __iomem * distbase = IO_ADDRESS ( TEGRA_ARM_INT_DIST_BASE ) ;
pending_set = readl_relaxed ( distbase + GIC_DIST_PENDING_SET ) ;
if ( pending_set & SGI_MASK )
return true ;
return false ;
}
2013-04-03 19:31:45 +08:00
# ifdef CONFIG_PM_SLEEP
2013-07-19 17:25:24 +08:00
static int tegra_gic_notifier ( struct notifier_block * self ,
unsigned long cmd , void * v )
{
switch ( cmd ) {
case CPU_PM_ENTER :
writel_relaxed ( 0x1E0 , tegra_gic_cpu_base + GIC_CPU_CTRL ) ;
break ;
}
return NOTIFY_OK ;
}
static struct notifier_block tegra_gic_notifier_block = {
. notifier_call = tegra_gic_notifier ,
} ;
static const struct of_device_id tegra114_dt_gic_match [ ] __initconst = {
{ . compatible = " arm,cortex-a15-gic " } ,
{ }
} ;
static void tegra114_gic_cpu_pm_registration ( void )
{
struct device_node * dn ;
dn = of_find_matching_node ( NULL , tegra114_dt_gic_match ) ;
if ( ! dn )
return ;
tegra_gic_cpu_base = of_iomap ( dn , 1 ) ;
cpu_pm_register_notifier ( & tegra_gic_notifier_block ) ;
}
2013-04-03 19:31:45 +08:00
# else
2013-07-19 17:25:24 +08:00
static void tegra114_gic_cpu_pm_registration ( void ) { }
2013-04-03 19:31:45 +08:00
# endif
2015-03-11 15:43:00 +00:00
static const struct of_device_id tegra_ictlr_match [ ] __initconst = {
{ . compatible = " nvidia,tegra20-ictlr " } ,
{ . compatible = " nvidia,tegra30-ictlr " } ,
{ }
} ;
2010-03-15 23:04:46 -07:00
void __init tegra_init_irq ( void )
{
2015-03-11 15:43:03 +00:00
if ( WARN_ON ( ! of_find_matching_node ( NULL , tegra_ictlr_match ) ) )
pr_warn ( " Outdated DT detected, suspend/resume will NOT work \n " ) ;
2011-05-01 14:10:10 -07:00
2013-07-19 17:25:24 +08:00
tegra114_gic_cpu_pm_registration ( ) ;
2010-04-05 20:30:59 -07:00
}