1/* 2 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17#include <asm/firmware.h> 18#include <linux/tick.h> 19#include <linux/cpuidle.h> 20#include <linux/cpu_pm.h> 21#include <linux/kernel.h> 22#include <linux/module.h> 23 24#include <asm/cpuidle.h> 25#include <asm/smp_plat.h> 26#include <asm/suspend.h> 27 28#include "pm.h" 29#include "sleep.h" 30 31#ifdef CONFIG_PM_SLEEP 32#define TEGRA114_MAX_STATES 2 33#else 34#define TEGRA114_MAX_STATES 1 35#endif 36 37#ifdef CONFIG_PM_SLEEP 38static int tegra114_idle_power_down(struct cpuidle_device *dev, 39 struct cpuidle_driver *drv, 40 int index) 41{ 42 local_fiq_disable(); 43 44 tegra_set_cpu_in_lp2(); 45 cpu_pm_enter(); 46 47 tick_broadcast_enter(); 48 49 call_firmware_op(prepare_idle); 50 51 /* Do suspend by ourselves if the firmware does not implement it */ 52 if (call_firmware_op(do_idle, 0) == -ENOSYS) 53 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); 54 55 tick_broadcast_exit(); 56 57 cpu_pm_exit(); 58 tegra_clear_cpu_in_lp2(); 59 60 local_fiq_enable(); 61 62 return index; 63} 64#endif 65 66static struct cpuidle_driver tegra_idle_driver = { 67 .name = "tegra_idle", 68 .owner = THIS_MODULE, 69 .state_count = TEGRA114_MAX_STATES, 70 .states = { 71 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), 72#ifdef CONFIG_PM_SLEEP 73 [1] = { 74 .enter = tegra114_idle_power_down, 75 .exit_latency = 500, 76 .target_residency = 1000, 77 .power_usage = 0, 78 .name = "powered-down", 79 .desc = "CPU power gated", 80 }, 81#endif 82 }, 83}; 84 85int __init tegra114_cpuidle_init(void) 86{ 87 return cpuidle_register(&tegra_idle_driver, NULL); 88} 89