2019-06-01 11:08:42 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2017-08-24 00:21:07 +03:00
/*
* poll_state . c - Polling idle state
*/
# include <linux/cpuidle.h>
# include <linux/sched.h>
2018-03-14 17:08:57 +03:00
# include <linux/sched/clock.h>
2017-08-24 00:21:07 +03:00
# include <linux/sched/idle.h>
2018-03-28 00:58:45 +03:00
# define POLL_IDLE_RELAX_COUNT 200
2018-03-14 17:08:57 +03:00
2017-08-24 00:21:07 +03:00
static int __cpuidle poll_idle ( struct cpuidle_device * dev ,
struct cpuidle_driver * drv , int index )
{
2018-03-14 17:08:57 +03:00
u64 time_start = local_clock ( ) ;
2018-10-03 00:42:02 +03:00
dev - > poll_time_limit = false ;
2017-08-24 00:21:07 +03:00
local_irq_enable ( ) ;
if ( ! current_set_polling_and_test ( ) ) {
2018-03-28 00:58:45 +03:00
unsigned int loop_count = 0 ;
2019-07-04 02:51:26 +03:00
u64 limit ;
2018-12-03 15:32:53 +03:00
2019-07-04 02:51:26 +03:00
limit = cpuidle_poll_time ( drv , dev ) ;
2018-03-28 00:58:45 +03:00
2018-03-14 17:08:57 +03:00
while ( ! need_resched ( ) ) {
2017-08-24 00:21:07 +03:00
cpu_relax ( ) ;
2018-03-28 00:58:45 +03:00
if ( loop_count + + < POLL_IDLE_RELAX_COUNT )
continue ;
2018-03-14 17:08:57 +03:00
2018-03-28 00:58:45 +03:00
loop_count = 0 ;
2018-10-03 00:50:30 +03:00
if ( local_clock ( ) - time_start > limit ) {
2018-10-03 00:42:02 +03:00
dev - > poll_time_limit = true ;
2018-03-14 17:08:57 +03:00
break ;
2018-10-03 00:42:02 +03:00
}
2018-03-14 17:08:57 +03:00
}
2017-08-24 00:21:07 +03:00
}
current_clr_polling ( ) ;
return index ;
}
2017-08-29 04:14:37 +03:00
void cpuidle_poll_state_init ( struct cpuidle_driver * drv )
2017-08-24 00:21:07 +03: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 17:25:12 +03:00
state - > exit_latency_ns = 0 ;
state - > target_residency_ns = 0 ;
2017-08-24 00:21:07 +03:00
state - > power_usage = - 1 ;
state - > enter = poll_idle ;
state - > flags = CPUIDLE_FLAG_POLLING ;
}
2017-08-29 04:14:37 +03:00
EXPORT_SYMBOL_GPL ( cpuidle_poll_state_init ) ;