// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2017 MediaTek Inc. */ #include #include #include #include #include #include #include #define CREATE_TRACE_POINTS //#include int __attribute__((weak)) mtk_cpuidle_register_driver(void) { return -ENODEV; } void __attribute__((weak)) mtk_cpuidle_unregister_driver(void) { } int __init mtk_acao_cpuidle_init(void) { int cpu, ret; struct cpuidle_device *dev; /* * Initialize idle states data, starting at index 1. * This driver is DT only, if no DT idle states are detected (ret == 0) * let the driver initialization fail accordingly since there is no * reason to initialize the idle driver if only wfi is supported. */ ret = mtk_cpuidle_register_driver(); if (ret) { pr_info("Failed to register mtk cpuidle driver (%d)\n", ret); return ret; } /* * Call arch CPU operations in order to initialize * idle states suspend back-end specific data */ for_each_possible_cpu(cpu) { ret = arm_cpuidle_init(cpu); /* * Skip the cpuidle device initialization if the reported * failure is a HW misconfiguration/breakage (-ENXIO). */ if (ret == -ENXIO) continue; if (ret) { pr_info("CPU %d failed to init idle CPU ops\n", cpu); goto out_fail; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) goto out_fail; dev->cpu = cpu; ret = cpuidle_register_device(dev); if (ret) { pr_info("Failed to register cpuidle device for CPU %d\n", cpu); kfree(dev); goto out_fail; } } return 0; out_fail: while (cpu > 0) { cpu--; dev = per_cpu(cpuidle_devices, cpu); cpuidle_unregister_device(dev); kfree(dev); } mtk_cpuidle_unregister_driver(); return ret; } device_initcall(mtk_acao_cpuidle_init);