18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * OMAP4+ CPU idle Routines
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2011-2013 Texas Instruments, Inc.
68c2ecf20Sopenharmony_ci * Santosh Shilimkar <santosh.shilimkar@ti.com>
78c2ecf20Sopenharmony_ci * Rajendra Nayak <rnayak@ti.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/sched.h>
118c2ecf20Sopenharmony_ci#include <linux/cpuidle.h>
128c2ecf20Sopenharmony_ci#include <linux/cpu_pm.h>
138c2ecf20Sopenharmony_ci#include <linux/export.h>
148c2ecf20Sopenharmony_ci#include <linux/tick.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <asm/cpuidle.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#include "common.h"
198c2ecf20Sopenharmony_ci#include "pm.h"
208c2ecf20Sopenharmony_ci#include "prm.h"
218c2ecf20Sopenharmony_ci#include "soc.h"
228c2ecf20Sopenharmony_ci#include "clockdomain.h"
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define MAX_CPUS	2
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* Machine specific information */
278c2ecf20Sopenharmony_cistruct idle_statedata {
288c2ecf20Sopenharmony_ci	u32 cpu_state;
298c2ecf20Sopenharmony_ci	u32 mpu_logic_state;
308c2ecf20Sopenharmony_ci	u32 mpu_state;
318c2ecf20Sopenharmony_ci	u32 mpu_state_vote;
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistatic struct idle_statedata omap4_idle_data[] = {
358c2ecf20Sopenharmony_ci	{
368c2ecf20Sopenharmony_ci		.cpu_state = PWRDM_POWER_ON,
378c2ecf20Sopenharmony_ci		.mpu_state = PWRDM_POWER_ON,
388c2ecf20Sopenharmony_ci		.mpu_logic_state = PWRDM_POWER_RET,
398c2ecf20Sopenharmony_ci	},
408c2ecf20Sopenharmony_ci	{
418c2ecf20Sopenharmony_ci		.cpu_state = PWRDM_POWER_OFF,
428c2ecf20Sopenharmony_ci		.mpu_state = PWRDM_POWER_RET,
438c2ecf20Sopenharmony_ci		.mpu_logic_state = PWRDM_POWER_RET,
448c2ecf20Sopenharmony_ci	},
458c2ecf20Sopenharmony_ci	{
468c2ecf20Sopenharmony_ci		.cpu_state = PWRDM_POWER_OFF,
478c2ecf20Sopenharmony_ci		.mpu_state = PWRDM_POWER_RET,
488c2ecf20Sopenharmony_ci		.mpu_logic_state = PWRDM_POWER_OFF,
498c2ecf20Sopenharmony_ci	},
508c2ecf20Sopenharmony_ci};
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic struct idle_statedata omap5_idle_data[] = {
538c2ecf20Sopenharmony_ci	{
548c2ecf20Sopenharmony_ci		.cpu_state = PWRDM_POWER_ON,
558c2ecf20Sopenharmony_ci		.mpu_state = PWRDM_POWER_ON,
568c2ecf20Sopenharmony_ci		.mpu_logic_state = PWRDM_POWER_ON,
578c2ecf20Sopenharmony_ci	},
588c2ecf20Sopenharmony_ci	{
598c2ecf20Sopenharmony_ci		.cpu_state = PWRDM_POWER_RET,
608c2ecf20Sopenharmony_ci		.mpu_state = PWRDM_POWER_RET,
618c2ecf20Sopenharmony_ci		.mpu_logic_state = PWRDM_POWER_RET,
628c2ecf20Sopenharmony_ci	},
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic struct powerdomain *mpu_pd, *cpu_pd[MAX_CPUS];
668c2ecf20Sopenharmony_cistatic struct clockdomain *cpu_clkdm[MAX_CPUS];
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic atomic_t abort_barrier;
698c2ecf20Sopenharmony_cistatic bool cpu_done[MAX_CPUS];
708c2ecf20Sopenharmony_cistatic struct idle_statedata *state_ptr = &omap4_idle_data[0];
718c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(mpu_lock);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/* Private functions */
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/**
768c2ecf20Sopenharmony_ci * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
778c2ecf20Sopenharmony_ci * @dev: cpuidle device
788c2ecf20Sopenharmony_ci * @drv: cpuidle driver
798c2ecf20Sopenharmony_ci * @index: the index of state to be entered
808c2ecf20Sopenharmony_ci *
818c2ecf20Sopenharmony_ci * Called from the CPUidle framework to program the device to the
828c2ecf20Sopenharmony_ci * specified low power state selected by the governor.
838c2ecf20Sopenharmony_ci * Returns the amount of time spent in the low power state.
848c2ecf20Sopenharmony_ci */
858c2ecf20Sopenharmony_cistatic int omap_enter_idle_simple(struct cpuidle_device *dev,
868c2ecf20Sopenharmony_ci			struct cpuidle_driver *drv,
878c2ecf20Sopenharmony_ci			int index)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	omap_do_wfi();
908c2ecf20Sopenharmony_ci	return index;
918c2ecf20Sopenharmony_ci}
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_cistatic int omap_enter_idle_smp(struct cpuidle_device *dev,
948c2ecf20Sopenharmony_ci			       struct cpuidle_driver *drv,
958c2ecf20Sopenharmony_ci			       int index)
968c2ecf20Sopenharmony_ci{
978c2ecf20Sopenharmony_ci	struct idle_statedata *cx = state_ptr + index;
988c2ecf20Sopenharmony_ci	unsigned long flag;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	raw_spin_lock_irqsave(&mpu_lock, flag);
1018c2ecf20Sopenharmony_ci	cx->mpu_state_vote++;
1028c2ecf20Sopenharmony_ci	if (cx->mpu_state_vote == num_online_cpus()) {
1038c2ecf20Sopenharmony_ci		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
1048c2ecf20Sopenharmony_ci		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
1058c2ecf20Sopenharmony_ci	}
1068c2ecf20Sopenharmony_ci	raw_spin_unlock_irqrestore(&mpu_lock, flag);
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	raw_spin_lock_irqsave(&mpu_lock, flag);
1118c2ecf20Sopenharmony_ci	if (cx->mpu_state_vote == num_online_cpus())
1128c2ecf20Sopenharmony_ci		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
1138c2ecf20Sopenharmony_ci	cx->mpu_state_vote--;
1148c2ecf20Sopenharmony_ci	raw_spin_unlock_irqrestore(&mpu_lock, flag);
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	return index;
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistatic int omap_enter_idle_coupled(struct cpuidle_device *dev,
1208c2ecf20Sopenharmony_ci			struct cpuidle_driver *drv,
1218c2ecf20Sopenharmony_ci			int index)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	struct idle_statedata *cx = state_ptr + index;
1248c2ecf20Sopenharmony_ci	u32 mpuss_can_lose_context = 0;
1258c2ecf20Sopenharmony_ci	int error;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	/*
1288c2ecf20Sopenharmony_ci	 * CPU0 has to wait and stay ON until CPU1 is OFF state.
1298c2ecf20Sopenharmony_ci	 * This is necessary to honour hardware recommondation
1308c2ecf20Sopenharmony_ci	 * of triggeing all the possible low power modes once CPU1 is
1318c2ecf20Sopenharmony_ci	 * out of coherency and in OFF mode.
1328c2ecf20Sopenharmony_ci	 */
1338c2ecf20Sopenharmony_ci	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
1348c2ecf20Sopenharmony_ci		while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) {
1358c2ecf20Sopenharmony_ci			cpu_relax();
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci			/*
1388c2ecf20Sopenharmony_ci			 * CPU1 could have already entered & exited idle
1398c2ecf20Sopenharmony_ci			 * without hitting off because of a wakeup
1408c2ecf20Sopenharmony_ci			 * or a failed attempt to hit off mode.  Check for
1418c2ecf20Sopenharmony_ci			 * that here, otherwise we could spin forever
1428c2ecf20Sopenharmony_ci			 * waiting for CPU1 off.
1438c2ecf20Sopenharmony_ci			 */
1448c2ecf20Sopenharmony_ci			if (cpu_done[1])
1458c2ecf20Sopenharmony_ci			    goto fail;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci		}
1488c2ecf20Sopenharmony_ci	}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
1518c2ecf20Sopenharmony_ci				 (cx->mpu_logic_state == PWRDM_POWER_OFF);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	/* Enter broadcast mode for periodic timers */
1548c2ecf20Sopenharmony_ci	RCU_NONIDLE(tick_broadcast_enable());
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	/* Enter broadcast mode for one-shot timers */
1578c2ecf20Sopenharmony_ci	RCU_NONIDLE(tick_broadcast_enter());
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	/*
1608c2ecf20Sopenharmony_ci	 * Call idle CPU PM enter notifier chain so that
1618c2ecf20Sopenharmony_ci	 * VFP and per CPU interrupt context is saved.
1628c2ecf20Sopenharmony_ci	 */
1638c2ecf20Sopenharmony_ci	error = cpu_pm_enter();
1648c2ecf20Sopenharmony_ci	if (error)
1658c2ecf20Sopenharmony_ci		goto cpu_pm_out;
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	if (dev->cpu == 0) {
1688c2ecf20Sopenharmony_ci		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
1698c2ecf20Sopenharmony_ci		RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci		/*
1728c2ecf20Sopenharmony_ci		 * Call idle CPU cluster PM enter notifier chain
1738c2ecf20Sopenharmony_ci		 * to save GIC and wakeupgen context.
1748c2ecf20Sopenharmony_ci		 */
1758c2ecf20Sopenharmony_ci		if (mpuss_can_lose_context) {
1768c2ecf20Sopenharmony_ci			error = cpu_cluster_pm_enter();
1778c2ecf20Sopenharmony_ci			if (error) {
1788c2ecf20Sopenharmony_ci				index = 0;
1798c2ecf20Sopenharmony_ci				cx = state_ptr + index;
1808c2ecf20Sopenharmony_ci				pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
1818c2ecf20Sopenharmony_ci				RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state));
1828c2ecf20Sopenharmony_ci				mpuss_can_lose_context = 0;
1838c2ecf20Sopenharmony_ci			}
1848c2ecf20Sopenharmony_ci		}
1858c2ecf20Sopenharmony_ci	}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
1888c2ecf20Sopenharmony_ci	cpu_done[dev->cpu] = true;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	/* Wakeup CPU1 only if it is not offlined */
1918c2ecf20Sopenharmony_ci	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
1948c2ecf20Sopenharmony_ci		    mpuss_can_lose_context)
1958c2ecf20Sopenharmony_ci			gic_dist_disable();
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci		RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1]));
1988c2ecf20Sopenharmony_ci		RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON));
1998c2ecf20Sopenharmony_ci		RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1]));
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) &&
2028c2ecf20Sopenharmony_ci		    mpuss_can_lose_context) {
2038c2ecf20Sopenharmony_ci			while (gic_dist_disabled()) {
2048c2ecf20Sopenharmony_ci				udelay(1);
2058c2ecf20Sopenharmony_ci				cpu_relax();
2068c2ecf20Sopenharmony_ci			}
2078c2ecf20Sopenharmony_ci			gic_timer_retrigger();
2088c2ecf20Sopenharmony_ci		}
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	/*
2128c2ecf20Sopenharmony_ci	 * Call idle CPU cluster PM exit notifier chain
2138c2ecf20Sopenharmony_ci	 * to restore GIC and wakeupgen context.
2148c2ecf20Sopenharmony_ci	 */
2158c2ecf20Sopenharmony_ci	if (dev->cpu == 0 && mpuss_can_lose_context)
2168c2ecf20Sopenharmony_ci		cpu_cluster_pm_exit();
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	/*
2198c2ecf20Sopenharmony_ci	 * Call idle CPU PM exit notifier chain to restore
2208c2ecf20Sopenharmony_ci	 * VFP and per CPU IRQ context.
2218c2ecf20Sopenharmony_ci	 */
2228c2ecf20Sopenharmony_ci	cpu_pm_exit();
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_cicpu_pm_out:
2258c2ecf20Sopenharmony_ci	RCU_NONIDLE(tick_broadcast_exit());
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_cifail:
2288c2ecf20Sopenharmony_ci	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
2298c2ecf20Sopenharmony_ci	cpu_done[dev->cpu] = false;
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	return index;
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic struct cpuidle_driver omap4_idle_driver = {
2358c2ecf20Sopenharmony_ci	.name				= "omap4_idle",
2368c2ecf20Sopenharmony_ci	.owner				= THIS_MODULE,
2378c2ecf20Sopenharmony_ci	.states = {
2388c2ecf20Sopenharmony_ci		{
2398c2ecf20Sopenharmony_ci			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
2408c2ecf20Sopenharmony_ci			.exit_latency = 2 + 2,
2418c2ecf20Sopenharmony_ci			.target_residency = 5,
2428c2ecf20Sopenharmony_ci			.enter = omap_enter_idle_simple,
2438c2ecf20Sopenharmony_ci			.name = "C1",
2448c2ecf20Sopenharmony_ci			.desc = "CPUx ON, MPUSS ON"
2458c2ecf20Sopenharmony_ci		},
2468c2ecf20Sopenharmony_ci		{
2478c2ecf20Sopenharmony_ci			/* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
2488c2ecf20Sopenharmony_ci			.exit_latency = 328 + 440,
2498c2ecf20Sopenharmony_ci			.target_residency = 960,
2508c2ecf20Sopenharmony_ci			.flags = CPUIDLE_FLAG_COUPLED,
2518c2ecf20Sopenharmony_ci			.enter = omap_enter_idle_coupled,
2528c2ecf20Sopenharmony_ci			.name = "C2",
2538c2ecf20Sopenharmony_ci			.desc = "CPUx OFF, MPUSS CSWR",
2548c2ecf20Sopenharmony_ci		},
2558c2ecf20Sopenharmony_ci		{
2568c2ecf20Sopenharmony_ci			/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
2578c2ecf20Sopenharmony_ci			.exit_latency = 460 + 518,
2588c2ecf20Sopenharmony_ci			.target_residency = 1100,
2598c2ecf20Sopenharmony_ci			.flags = CPUIDLE_FLAG_COUPLED,
2608c2ecf20Sopenharmony_ci			.enter = omap_enter_idle_coupled,
2618c2ecf20Sopenharmony_ci			.name = "C3",
2628c2ecf20Sopenharmony_ci			.desc = "CPUx OFF, MPUSS OSWR",
2638c2ecf20Sopenharmony_ci		},
2648c2ecf20Sopenharmony_ci	},
2658c2ecf20Sopenharmony_ci	.state_count = ARRAY_SIZE(omap4_idle_data),
2668c2ecf20Sopenharmony_ci	.safe_state_index = 0,
2678c2ecf20Sopenharmony_ci};
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_cistatic struct cpuidle_driver omap5_idle_driver = {
2708c2ecf20Sopenharmony_ci	.name				= "omap5_idle",
2718c2ecf20Sopenharmony_ci	.owner				= THIS_MODULE,
2728c2ecf20Sopenharmony_ci	.states = {
2738c2ecf20Sopenharmony_ci		{
2748c2ecf20Sopenharmony_ci			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
2758c2ecf20Sopenharmony_ci			.exit_latency = 2 + 2,
2768c2ecf20Sopenharmony_ci			.target_residency = 5,
2778c2ecf20Sopenharmony_ci			.enter = omap_enter_idle_simple,
2788c2ecf20Sopenharmony_ci			.name = "C1",
2798c2ecf20Sopenharmony_ci			.desc = "CPUx WFI, MPUSS ON"
2808c2ecf20Sopenharmony_ci		},
2818c2ecf20Sopenharmony_ci		{
2828c2ecf20Sopenharmony_ci			/* C2 - CPU0 RET + CPU1 RET + MPU CSWR */
2838c2ecf20Sopenharmony_ci			.exit_latency = 48 + 60,
2848c2ecf20Sopenharmony_ci			.target_residency = 100,
2858c2ecf20Sopenharmony_ci			.flags = CPUIDLE_FLAG_TIMER_STOP,
2868c2ecf20Sopenharmony_ci			.enter = omap_enter_idle_smp,
2878c2ecf20Sopenharmony_ci			.name = "C2",
2888c2ecf20Sopenharmony_ci			.desc = "CPUx CSWR, MPUSS CSWR",
2898c2ecf20Sopenharmony_ci		},
2908c2ecf20Sopenharmony_ci	},
2918c2ecf20Sopenharmony_ci	.state_count = ARRAY_SIZE(omap5_idle_data),
2928c2ecf20Sopenharmony_ci	.safe_state_index = 0,
2938c2ecf20Sopenharmony_ci};
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci/* Public functions */
2968c2ecf20Sopenharmony_ci
2978c2ecf20Sopenharmony_ci/**
2988c2ecf20Sopenharmony_ci * omap4_idle_init - Init routine for OMAP4+ idle
2998c2ecf20Sopenharmony_ci *
3008c2ecf20Sopenharmony_ci * Registers the OMAP4+ specific cpuidle driver to the cpuidle
3018c2ecf20Sopenharmony_ci * framework with the valid set of states.
3028c2ecf20Sopenharmony_ci */
3038c2ecf20Sopenharmony_ciint __init omap4_idle_init(void)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	struct cpuidle_driver *idle_driver;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	if (soc_is_omap54xx()) {
3088c2ecf20Sopenharmony_ci		state_ptr = &omap5_idle_data[0];
3098c2ecf20Sopenharmony_ci		idle_driver = &omap5_idle_driver;
3108c2ecf20Sopenharmony_ci	} else {
3118c2ecf20Sopenharmony_ci		state_ptr = &omap4_idle_data[0];
3128c2ecf20Sopenharmony_ci		idle_driver = &omap4_idle_driver;
3138c2ecf20Sopenharmony_ci	}
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	mpu_pd = pwrdm_lookup("mpu_pwrdm");
3168c2ecf20Sopenharmony_ci	cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
3178c2ecf20Sopenharmony_ci	cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
3188c2ecf20Sopenharmony_ci	if ((!mpu_pd) || (!cpu_pd[0]) || (!cpu_pd[1]))
3198c2ecf20Sopenharmony_ci		return -ENODEV;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	cpu_clkdm[0] = clkdm_lookup("mpu0_clkdm");
3228c2ecf20Sopenharmony_ci	cpu_clkdm[1] = clkdm_lookup("mpu1_clkdm");
3238c2ecf20Sopenharmony_ci	if (!cpu_clkdm[0] || !cpu_clkdm[1])
3248c2ecf20Sopenharmony_ci		return -ENODEV;
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	return cpuidle_register(idle_driver, cpu_online_mask);
3278c2ecf20Sopenharmony_ci}
328