2019-06-01 10:08:42 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2017-08-23 23:21:07 +02:00
/*
* poll_state . c - Polling idle state
*/
# include <linux/cpuidle.h>
# include <linux/sched.h>
2018-03-14 15:08:57 +01:00
# include <linux/sched/clock.h>
2017-08-23 23:21:07 +02:00
# include <linux/sched/idle.h>
2018-03-27 23:58:45 +02:00
# define POLL_IDLE_RELAX_COUNT 200
2018-03-14 15:08:57 +01:00
2017-08-23 23:21:07 +02:00
static int __cpuidle poll_idle ( struct cpuidle_device * dev ,
struct cpuidle_driver * drv , int index )
{
2023-01-12 20:43:30 +01:00
u64 time_start ;
time_start = local_clock ( ) ;
2018-03-14 15:08:57 +01:00
2018-10-02 23:42:02 +02:00
dev - > poll_time_limit = false ;
2023-01-12 20:43:17 +01:00
raw_local_irq_enable ( ) ;
2017-08-23 23:21:07 +02:00
if ( ! current_set_polling_and_test ( ) ) {
2018-03-27 23:58:45 +02:00
unsigned int loop_count = 0 ;
2019-07-03 20:51:26 -03:00
u64 limit ;
2018-12-03 13:32:53 +01:00
2019-07-03 20:51:26 -03:00
limit = cpuidle_poll_time ( drv , dev ) ;
2018-03-27 23:58:45 +02:00
2018-03-14 15:08:57 +01:00
while ( ! need_resched ( ) ) {
2017-08-23 23:21:07 +02:00
cpu_relax ( ) ;
2018-03-27 23:58:45 +02:00
if ( loop_count + + < POLL_IDLE_RELAX_COUNT )
continue ;
2018-03-14 15:08:57 +01:00
2018-03-27 23:58:45 +02:00
loop_count = 0 ;
2018-10-02 23:50:30 +02:00
if ( local_clock ( ) - time_start > limit ) {
2018-10-02 23:42:02 +02:00
dev - > poll_time_limit = true ;
2018-03-14 15:08:57 +01:00
break ;
2018-10-02 23:42:02 +02:00
}
2018-03-14 15:08:57 +01:00
}
2017-08-23 23:21:07 +02:00
}
2023-01-12 20:43:17 +01:00
raw_local_irq_disable ( ) ;
2017-08-23 23:21:07 +02:00
current_clr_polling ( ) ;
return index ;
}
2017-08-29 03:14:37 +02:00
void cpuidle_poll_state_init ( struct cpuidle_driver * drv )
2017-08-23 23:21:07 +02:00
{
struct cpuidle_state * state = & drv - > states [ 0 ] ;
snprintf ( state - > name , CPUIDLE_NAME_LEN , " POLL " ) ;
snprintf ( state - > desc , CPUIDLE_DESC_LEN , " CPUIDLE CORE POLL IDLE " ) ;
state - > exit_latency = 0 ;
state - > target_residency = 0 ;
2019-11-07 15:25:12 +01:00
state - > exit_latency_ns = 0 ;
state - > target_residency_ns = 0 ;
2017-08-23 23:21:07 +02:00
state - > power_usage = - 1 ;
state - > enter = poll_idle ;
state - > flags = CPUIDLE_FLAG_POLLING ;
}
2017-08-29 03:14:37 +02:00
EXPORT_SYMBOL_GPL ( cpuidle_poll_state_init ) ;