1 /* 2 * Copyright (C) 2011 Google, Inc. 3 * 4 * Author: 5 * Colin Cross <ccross@android.com> 6 * 7 * Copyright (C) 2010,2013, NVIDIA Corporation 8 * 9 * This software is licensed under the terms of the GNU General Public 10 * License version 2, as published by the Free Software Foundation, and 11 * may be copied, distributed, and modified under those terms. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 */ 19 20 #include <linux/cpu_pm.h> 21 #include <linux/interrupt.h> 22 #include <linux/io.h> 23 #include <linux/irqchip/arm-gic.h> 24 #include <linux/irq.h> 25 #include <linux/kernel.h> 26 #include <linux/of_address.h> 27 #include <linux/of.h> 28 #include <linux/syscore_ops.h> 29 30 #include "board.h" 31 #include "iomap.h" 32 #include "irq.h" 33 34 #define SGI_MASK 0xFFFF 35 36 #ifdef CONFIG_PM_SLEEP 37 static void __iomem *tegra_gic_cpu_base; 38 #endif 39 40 bool tegra_pending_sgi(void) 41 { 42 u32 pending_set; 43 void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); 44 45 pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET); 46 47 if (pending_set & SGI_MASK) 48 return true; 49 50 return false; 51 } 52 53 #ifdef CONFIG_PM_SLEEP 54 static int tegra_gic_notifier(struct notifier_block *self, 55 unsigned long cmd, void *v) 56 { 57 switch (cmd) { 58 case CPU_PM_ENTER: 59 writel_relaxed(0x1E0, tegra_gic_cpu_base + GIC_CPU_CTRL); 60 break; 61 } 62 63 return NOTIFY_OK; 64 } 65 66 static struct notifier_block tegra_gic_notifier_block = { 67 .notifier_call = tegra_gic_notifier, 68 }; 69 70 static const struct of_device_id tegra114_dt_gic_match[] __initconst = { 71 { .compatible = "arm,cortex-a15-gic" }, 72 { } 73 }; 74 75 static void __init tegra114_gic_cpu_pm_registration(void) 76 { 77 struct device_node *dn; 78 79 dn = of_find_matching_node(NULL, tegra114_dt_gic_match); 80 if (!dn) 81 return; 82 83 tegra_gic_cpu_base = of_iomap(dn, 1); 84 85 cpu_pm_register_notifier(&tegra_gic_notifier_block); 86 } 87 #else 88 static void __init tegra114_gic_cpu_pm_registration(void) { } 89 #endif 90 91 static const struct of_device_id tegra_ictlr_match[] __initconst = { 92 { .compatible = "nvidia,tegra20-ictlr" }, 93 { .compatible = "nvidia,tegra30-ictlr" }, 94 { } 95 }; 96 97 void __init tegra_init_irq(void) 98 { 99 if (WARN_ON(!of_find_matching_node(NULL, tegra_ictlr_match))) 100 pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); 101 102 tegra114_gic_cpu_pm_registration(); 103 } 104