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