1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * cpuidle driver for haltpoll governor. 4 * 5 * Copyright 2019 Red Hat, Inc. and/or its affiliates. 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2. See 8 * the COPYING file in the top-level directory. 9 * 10 * Authors: Marcelo Tosatti <mtosatti@redhat.com> 11 */ 12 13 #include <linux/init.h> 14 #include <linux/cpuidle.h> 15 #include <linux/module.h> 16 #include <linux/sched/idle.h> 17 #include <linux/kvm_para.h> 18 #include <linux/cpuidle_haltpoll.h> 19 20 static int default_enter_idle(struct cpuidle_device *dev, 21 struct cpuidle_driver *drv, int index) 22 { 23 if (current_clr_polling_and_test()) { 24 local_irq_enable(); 25 return index; 26 } 27 default_idle(); 28 return index; 29 } 30 31 static struct cpuidle_driver haltpoll_driver = { 32 .name = "haltpoll", 33 .owner = THIS_MODULE, 34 .states = { 35 { /* entry 0 is for polling */ }, 36 { 37 .enter = default_enter_idle, 38 .exit_latency = 1, 39 .target_residency = 1, 40 .power_usage = -1, 41 .name = "haltpoll idle", 42 .desc = "default architecture idle", 43 }, 44 }, 45 .safe_state_index = 0, 46 .state_count = 2, 47 }; 48 49 static int __init haltpoll_init(void) 50 { 51 int ret; 52 struct cpuidle_driver *drv = &haltpoll_driver; 53 54 cpuidle_poll_state_init(drv); 55 56 if (!kvm_para_available()) 57 return 0; 58 59 ret = cpuidle_register(&haltpoll_driver, NULL); 60 if (ret == 0) 61 arch_haltpoll_enable(); 62 63 return ret; 64 } 65 66 static void __exit haltpoll_exit(void) 67 { 68 arch_haltpoll_disable(); 69 cpuidle_unregister(&haltpoll_driver); 70 } 71 72 module_init(haltpoll_init); 73 module_exit(haltpoll_exit); 74 MODULE_LICENSE("GPL"); 75 MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>"); 76