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 33 #define SGI_MASK 0xFFFF 34 35 #ifdef CONFIG_PM_SLEEP 36 static void __iomem *tegra_gic_cpu_base; 37 #endif 38 39 bool tegra_pending_sgi(void) 40 { 41 u32 pending_set; 42 void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); 43 44 pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET); 45 46 if (pending_set & SGI_MASK) 47 return true; 48 49 return false; 50 } 51 52 #ifdef CONFIG_PM_SLEEP 53 static int tegra_gic_notifier(struct notifier_block *self, 54 unsigned long cmd, void *v) 55 { 56 switch (cmd) { 57 case CPU_PM_ENTER: 58 writel_relaxed(0x1E0, tegra_gic_cpu_base + GIC_CPU_CTRL); 59 break; 60 } 61 62 return NOTIFY_OK; 63 } 64 65 static struct notifier_block tegra_gic_notifier_block = { 66 .notifier_call = tegra_gic_notifier, 67 }; 68 69 static const struct of_device_id tegra114_dt_gic_match[] __initconst = { 70 { .compatible = "arm,cortex-a15-gic" }, 71 { } 72 }; 73 74 static void tegra114_gic_cpu_pm_registration(void) 75 { 76 struct device_node *dn; 77 78 dn = of_find_matching_node(NULL, tegra114_dt_gic_match); 79 if (!dn) 80 return; 81 82 tegra_gic_cpu_base = of_iomap(dn, 1); 83 84 cpu_pm_register_notifier(&tegra_gic_notifier_block); 85 } 86 #else 87 static void tegra114_gic_cpu_pm_registration(void) { } 88 #endif 89 90 static const struct of_device_id tegra_ictlr_match[] __initconst = { 91 { .compatible = "nvidia,tegra20-ictlr" }, 92 { .compatible = "nvidia,tegra30-ictlr" }, 93 { } 94 }; 95 96 void __init tegra_init_irq(void) 97 { 98 if (WARN_ON(!of_find_matching_node(NULL, tegra_ictlr_match))) 99 pr_warn("Outdated DT detected, suspend/resume will NOT work\n"); 100 101 tegra114_gic_cpu_pm_registration(); 102 } 103