xref: /openbmc/linux/drivers/cpuidle/cpuidle-calxeda.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
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 
calxeda_idle_finish(unsigned long val)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 
calxeda_pwrdown_idle(struct cpuidle_device * dev,struct cpuidle_driver * drv,int index)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 
calxeda_cpuidle_probe(struct platform_device * pdev)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