static int __init bl_idle_init(void) { int ret; struct device_node *root = of_find_node_by_path("/"); if (!root) return -ENODEV; /* * Initialize the driver just for a compliant set of machines */ if (!of_match_node(compatible_machine_match, root)) return -ENODEV; /* * For now the differentiation between little and big cores * is based on the part number. A7 cores are considered little * cores, A15 are considered big cores. This distinction may * evolve in the future with a more generic matching approach. */ ret = bl_idle_driver_init(&bl_idle_little_driver, ARM_CPU_PART_CORTEX_A7); if (ret) return ret; ret = bl_idle_driver_init(&bl_idle_big_driver, ARM_CPU_PART_CORTEX_A15); if (ret) goto out_uninit_little; /* Start at index 1, index 0 standard WFI */ ret = dt_init_idle_driver(&bl_idle_big_driver, bl_idle_state_match, 1); if (ret < 0) goto out_uninit_big; /* Start at index 1, index 0 standard WFI */ ret = dt_init_idle_driver(&bl_idle_little_driver, bl_idle_state_match, 1); if (ret < 0) goto out_uninit_big; ret = cpuidle_register(&bl_idle_little_driver, NULL); if (ret) goto out_uninit_big; ret = cpuidle_register(&bl_idle_big_driver, NULL); if (ret) goto out_unregister_little; return 0; out_unregister_little: cpuidle_unregister(&bl_idle_little_driver); out_uninit_big: kfree(bl_idle_big_driver.cpumask); out_uninit_little: kfree(bl_idle_little_driver.cpumask); return ret; }
/* * arm64_idle_init * * Registers the arm64 specific cpuidle driver with the cpuidle * framework. It relies on core code to parse the idle states * and initialize them using driver data structures accordingly. */ static int __init arm64_idle_init(void) { int cpu, ret; struct cpuidle_driver *drv = &arm64_idle_driver; /* * 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 = dt_init_idle_driver(drv, arm64_idle_state_match, 1); if (ret <= 0) { if (ret) pr_err("failed to initialize idle states\n"); return ret ? : -ENODEV; } /* * Call arch CPU operations in order to initialize * idle states suspend back-end specific data */ for_each_possible_cpu(cpu) { ret = cpu_init_idle(cpu); if (ret) { pr_err("CPU %d failed to init idle CPU ops\n", cpu); return ret; } } ret = cpuidle_register(drv, NULL); if (ret) { pr_err("failed to register cpuidle driver\n"); return ret; } return 0; }