The governors are defined as module in the code, but the Kconfig options do not allow to compile them as module. This is not really a problem but the init order is: the cpuidle init functions (framework and driver) and then the governors. That leads to some weirdness in the cpuidle framework because the function cpuidle_register_device calls cpuidle_enable_device which in turns fails at the first attempt because no governor is registered. When the governor is registered, the framework calls cpuidle_enable_device again which will invoke the __cpuidle_register_device function. Of course, in order to make this to work, the return code of cpuidle_enable_device is not checked by the caller in cpuidle_register_device. Instead of having this cyclic call graph and relying on a positive side effect of the hackish back and forth call to cpuidle_enable_device, let's change the init order for the governor in order to clean up the cpuidle_enable_device function. Signed-off-by: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx> --- drivers/cpuidle/Makefile | 2 +- drivers/cpuidle/governors/ladder.c | 14 ++------------ drivers/cpuidle/governors/menu.c | 14 ++------------ 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index 0d8bd55..05e2035 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile @@ -2,7 +2,7 @@ # Makefile for cpuidle. # -obj-y += cpuidle.o driver.o governor.o sysfs.o governors/ +obj-y += governors/ cpuidle.o driver.o governor.o sysfs.o obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 9b78405..928dc59 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c @@ -187,19 +187,9 @@ static struct cpuidle_governor ladder_governor = { /** * init_ladder - initializes the governor */ -static int __init init_ladder(void) +static int __init ladder_init(void) { return cpuidle_register_governor(&ladder_governor); } -/** - * exit_ladder - exits the governor - */ -static void __exit exit_ladder(void) -{ - cpuidle_unregister_governor(&ladder_governor); -} - -MODULE_LICENSE("GPL"); -module_init(init_ladder); -module_exit(exit_ladder); +core_initcall(ladder_init); diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index fe343a0..483bac1 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -535,19 +535,9 @@ static struct cpuidle_governor menu_governor = { /** * init_menu - initializes the governor */ -static int __init init_menu(void) +static int __init menu_init(void) { return cpuidle_register_governor(&menu_governor); } -/** - * exit_menu - exits the governor - */ -static void __exit exit_menu(void) -{ - cpuidle_unregister_governor(&menu_governor); -} - -MODULE_LICENSE("GPL"); -module_init(init_menu); -module_exit(exit_menu); +core_initcall(menu_init); -- 1.7.9.5