1*9952f691SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2be6a98d3SRob Herring /* 3be6a98d3SRob Herring * Copyright 2012 Calxeda, Inc. 4be6a98d3SRob Herring * 5a8e39c35SDaniel Lezcano * Based on arch/arm/plat-mxc/cpuidle.c: #v3.7 6be6a98d3SRob Herring * Copyright 2012 Freescale Semiconductor, Inc. 7be6a98d3SRob Herring * Copyright 2012 Linaro Ltd. 8be6a98d3SRob Herring * 9a8e39c35SDaniel Lezcano * Maintainer: Rob Herring <rob.herring@calxeda.com> 10be6a98d3SRob Herring */ 11be6a98d3SRob Herring 12be6a98d3SRob Herring #include <linux/cpuidle.h> 1334a5eeb2SRob Herring #include <linux/cpu_pm.h> 14be6a98d3SRob Herring #include <linux/init.h> 15a410146cSRob Herring #include <linux/mm.h> 1660a66e37SDaniel Lezcano #include <linux/platform_device.h> 17be120397SMark Rutland #include <linux/psci.h> 18be120397SMark Rutland 19be6a98d3SRob Herring #include <asm/cpuidle.h> 20be6a98d3SRob Herring #include <asm/suspend.h> 21be120397SMark Rutland 22be120397SMark Rutland #include <uapi/linux/psci.h> 23be120397SMark Rutland 24be120397SMark Rutland #define CALXEDA_IDLE_PARAM \ 25be120397SMark Rutland ((0 << PSCI_0_2_POWER_STATE_ID_SHIFT) | \ 26be120397SMark Rutland (0 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) | \ 27be120397SMark Rutland (PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT)) 28be6a98d3SRob Herring 29be6a98d3SRob Herring static int calxeda_idle_finish(unsigned long val) 30be6a98d3SRob Herring { 31be120397SMark Rutland return psci_ops.cpu_suspend(CALXEDA_IDLE_PARAM, __pa(cpu_resume)); 32be6a98d3SRob Herring } 33be6a98d3SRob Herring 34be6a98d3SRob Herring static int calxeda_pwrdown_idle(struct cpuidle_device *dev, 35be6a98d3SRob Herring struct cpuidle_driver *drv, 36be6a98d3SRob Herring int index) 37be6a98d3SRob Herring { 3834a5eeb2SRob Herring cpu_pm_enter(); 39be6a98d3SRob Herring cpu_suspend(0, calxeda_idle_finish); 4034a5eeb2SRob Herring cpu_pm_exit(); 4134a5eeb2SRob Herring 42be6a98d3SRob Herring return index; 43be6a98d3SRob Herring } 44be6a98d3SRob Herring 45be6a98d3SRob Herring static struct cpuidle_driver calxeda_idle_driver = { 46be6a98d3SRob Herring .name = "calxeda_idle", 47be6a98d3SRob Herring .states = { 48be6a98d3SRob Herring ARM_CPUIDLE_WFI_STATE, 49be6a98d3SRob Herring { 50be6a98d3SRob Herring .name = "PG", 51be6a98d3SRob Herring .desc = "Power Gate", 52be6a98d3SRob Herring .exit_latency = 30, 53be6a98d3SRob Herring .power_usage = 50, 54be6a98d3SRob Herring .target_residency = 200, 55be6a98d3SRob Herring .enter = calxeda_pwrdown_idle, 56be6a98d3SRob Herring }, 57be6a98d3SRob Herring }, 58be6a98d3SRob Herring .state_count = 2, 59be6a98d3SRob Herring }; 60be6a98d3SRob Herring 615781532eSAndre Przywara static int calxeda_cpuidle_probe(struct platform_device *pdev) 62be6a98d3SRob Herring { 630b210d96SDaniel Lezcano return cpuidle_register(&calxeda_idle_driver, NULL); 64be6a98d3SRob Herring } 6560a66e37SDaniel Lezcano 6660a66e37SDaniel Lezcano static struct platform_driver calxeda_cpuidle_plat_driver = { 6760a66e37SDaniel Lezcano .driver = { 6860a66e37SDaniel Lezcano .name = "cpuidle-calxeda", 6960a66e37SDaniel Lezcano }, 7060a66e37SDaniel Lezcano .probe = calxeda_cpuidle_probe, 7160a66e37SDaniel Lezcano }; 72090d1cf1SPaul Gortmaker builtin_platform_driver(calxeda_cpuidle_plat_driver); 73