Skip to content

Commit a1b5fd8

Browse files
committed
Merge branch 'pm-cpuidle'
* pm-cpuidle: cpuidle: Make drivers initialize polling state cpuidle: Move polling state initialization code to separate file cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol cpuidle: Convert to using %pOF instead of full_name
2 parents ab271bc + 1b39e3f commit a1b5fd8

File tree

9 files changed

+82
-66
lines changed

9 files changed

+82
-66
lines changed

drivers/acpi/processor_idle.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
4949
ACPI_MODULE_NAME("processor_idle");
5050

51+
#define ACPI_IDLE_STATE_START (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0)
52+
5153
static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
5254
module_param(max_cstate, uint, 0000);
5355
static unsigned int nocst __read_mostly;
@@ -761,7 +763,7 @@ static int acpi_idle_enter(struct cpuidle_device *dev,
761763

762764
if (cx->type != ACPI_STATE_C1) {
763765
if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) {
764-
index = CPUIDLE_DRIVER_STATE_START;
766+
index = ACPI_IDLE_STATE_START;
765767
cx = per_cpu(acpi_cstate[index], dev->cpu);
766768
} else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) {
767769
if (cx->bm_sts_skip || !acpi_idle_bm_check()) {
@@ -813,7 +815,7 @@ static void acpi_idle_enter_freeze(struct cpuidle_device *dev,
813815
static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
814816
struct cpuidle_device *dev)
815817
{
816-
int i, count = CPUIDLE_DRIVER_STATE_START;
818+
int i, count = ACPI_IDLE_STATE_START;
817819
struct acpi_processor_cx *cx;
818820

819821
if (max_cstate == 0)
@@ -840,14 +842,21 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
840842

841843
static int acpi_processor_setup_cstates(struct acpi_processor *pr)
842844
{
843-
int i, count = CPUIDLE_DRIVER_STATE_START;
845+
int i, count;
844846
struct acpi_processor_cx *cx;
845847
struct cpuidle_state *state;
846848
struct cpuidle_driver *drv = &acpi_idle_driver;
847849

848850
if (max_cstate == 0)
849851
max_cstate = 1;
850852

853+
if (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX)) {
854+
cpuidle_poll_state_init(drv);
855+
count = 1;
856+
} else {
857+
count = 0;
858+
}
859+
851860
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
852861
cx = &pr->power.states[i];
853862

@@ -1291,7 +1300,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
12911300
return -EINVAL;
12921301

12931302
drv->safe_state_index = -1;
1294-
for (i = CPUIDLE_DRIVER_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
1303+
for (i = ACPI_IDLE_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
12951304
drv->states[i].name[0] = '\0';
12961305
drv->states[i].desc[0] = '\0';
12971306
}

drivers/cpuidle/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
66
obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
77
obj-$(CONFIG_DT_IDLE_STATES) += dt_idle_states.o
8+
obj-$(CONFIG_ARCH_HAS_CPU_RELAX) += poll_state.o
89

910
##################################################################################
1011
# ARM SoC drivers

drivers/cpuidle/driver.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -179,36 +179,6 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
179179
}
180180
}
181181

182-
#ifdef CONFIG_ARCH_HAS_CPU_RELAX
183-
static int __cpuidle poll_idle(struct cpuidle_device *dev,
184-
struct cpuidle_driver *drv, int index)
185-
{
186-
local_irq_enable();
187-
if (!current_set_polling_and_test()) {
188-
while (!need_resched())
189-
cpu_relax();
190-
}
191-
current_clr_polling();
192-
193-
return index;
194-
}
195-
196-
static void poll_idle_init(struct cpuidle_driver *drv)
197-
{
198-
struct cpuidle_state *state = &drv->states[0];
199-
200-
snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
201-
snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
202-
state->exit_latency = 0;
203-
state->target_residency = 0;
204-
state->power_usage = -1;
205-
state->enter = poll_idle;
206-
state->disabled = false;
207-
}
208-
#else
209-
static void poll_idle_init(struct cpuidle_driver *drv) {}
210-
#endif /* !CONFIG_ARCH_HAS_CPU_RELAX */
211-
212182
/**
213183
* __cpuidle_register_driver: register the driver
214184
* @drv: a valid pointer to a struct cpuidle_driver
@@ -246,8 +216,6 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)
246216
on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
247217
(void *)1, 1);
248218

249-
poll_idle_init(drv);
250-
251219
return 0;
252220
}
253221

drivers/cpuidle/dt_idle_states.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ static int init_state_node(struct cpuidle_state *idle_state,
5353
err = of_property_read_u32(state_node, "entry-latency-us",
5454
&entry_latency);
5555
if (err) {
56-
pr_debug(" * %s missing entry-latency-us property\n",
57-
state_node->full_name);
56+
pr_debug(" * %pOF missing entry-latency-us property\n",
57+
state_node);
5858
return -EINVAL;
5959
}
6060

6161
err = of_property_read_u32(state_node, "exit-latency-us",
6262
&exit_latency);
6363
if (err) {
64-
pr_debug(" * %s missing exit-latency-us property\n",
65-
state_node->full_name);
64+
pr_debug(" * %pOF missing exit-latency-us property\n",
65+
state_node);
6666
return -EINVAL;
6767
}
6868
/*
@@ -75,8 +75,8 @@ static int init_state_node(struct cpuidle_state *idle_state,
7575
err = of_property_read_u32(state_node, "min-residency-us",
7676
&idle_state->target_residency);
7777
if (err) {
78-
pr_debug(" * %s missing min-residency-us property\n",
79-
state_node->full_name);
78+
pr_debug(" * %pOF missing min-residency-us property\n",
79+
state_node);
8080
return -EINVAL;
8181
}
8282

@@ -186,8 +186,8 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
186186
}
187187

188188
if (!idle_state_valid(state_node, i, cpumask)) {
189-
pr_warn("%s idle state not valid, bailing out\n",
190-
state_node->full_name);
189+
pr_warn("%pOF idle state not valid, bailing out\n",
190+
state_node);
191191
err = -EINVAL;
192192
break;
193193
}
@@ -200,8 +200,8 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
200200
idle_state = &drv->states[state_idx++];
201201
err = init_state_node(idle_state, matches, state_node);
202202
if (err) {
203-
pr_err("Parsing idle state node %s failed with err %d\n",
204-
state_node->full_name, err);
203+
pr_err("Parsing idle state node %pOF failed with err %d\n",
204+
state_node, err);
205205
err = -EINVAL;
206206
break;
207207
}

drivers/cpuidle/governors/ladder.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static int ladder_select_state(struct cpuidle_driver *drv,
6969
struct ladder_device *ldev = this_cpu_ptr(&ladder_devices);
7070
struct ladder_device_state *last_state;
7171
int last_residency, last_idx = ldev->last_state_idx;
72+
int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
7273
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
7374

7475
/* Special case when user has set very strict latency requirement */
@@ -96,21 +97,21 @@ static int ladder_select_state(struct cpuidle_driver *drv,
9697
}
9798

9899
/* consider demotion */
99-
if (last_idx > CPUIDLE_DRIVER_STATE_START &&
100+
if (last_idx > first_idx &&
100101
(drv->states[last_idx].disabled ||
101102
dev->states_usage[last_idx].disable ||
102103
drv->states[last_idx].exit_latency > latency_req)) {
103104
int i;
104105

105-
for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
106+
for (i = last_idx - 1; i > first_idx; i--) {
106107
if (drv->states[i].exit_latency <= latency_req)
107108
break;
108109
}
109110
ladder_do_selection(ldev, last_idx, i);
110111
return i;
111112
}
112113

113-
if (last_idx > CPUIDLE_DRIVER_STATE_START &&
114+
if (last_idx > first_idx &&
114115
last_residency < last_state->threshold.demotion_time) {
115116
last_state->stats.demotion_count++;
116117
last_state->stats.promotion_count = 0;
@@ -133,13 +134,14 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
133134
struct cpuidle_device *dev)
134135
{
135136
int i;
137+
int first_idx = drv->states[0].flags & CPUIDLE_FLAG_POLLING ? 1 : 0;
136138
struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
137139
struct ladder_device_state *lstate;
138140
struct cpuidle_state *state;
139141

140-
ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
142+
ldev->last_state_idx = first_idx;
141143

142-
for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
144+
for (i = first_idx; i < drv->state_count; i++) {
143145
state = &drv->states[i];
144146
lstate = &ldev->states[i];
145147

@@ -151,7 +153,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
151153

152154
if (i < drv->state_count - 1)
153155
lstate->threshold.promotion_time = state->exit_latency;
154-
if (i > CPUIDLE_DRIVER_STATE_START)
156+
if (i > first_idx)
155157
lstate->threshold.demotion_time = state->exit_latency;
156158
}
157159

drivers/cpuidle/governors/menu.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
324324
expected_interval = get_typical_interval(data);
325325
expected_interval = min(expected_interval, data->next_timer_us);
326326

327-
if (CPUIDLE_DRIVER_STATE_START > 0) {
328-
struct cpuidle_state *s = &drv->states[CPUIDLE_DRIVER_STATE_START];
327+
first_idx = 0;
328+
if (drv->states[0].flags & CPUIDLE_FLAG_POLLING) {
329+
struct cpuidle_state *s = &drv->states[1];
329330
unsigned int polling_threshold;
330331

331332
/*
@@ -336,12 +337,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
336337
polling_threshold = max_t(unsigned int, 20, s->target_residency);
337338
if (data->next_timer_us > polling_threshold &&
338339
latency_req > s->exit_latency && !s->disabled &&
339-
!dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable)
340-
first_idx = CPUIDLE_DRIVER_STATE_START;
341-
else
342-
first_idx = CPUIDLE_DRIVER_STATE_START - 1;
343-
} else {
344-
first_idx = 0;
340+
!dev->states_usage[1].disable)
341+
first_idx = 1;
345342
}
346343

347344
/*

drivers/cpuidle/poll_state.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* poll_state.c - Polling idle state
3+
*
4+
* This file is released under the GPLv2.
5+
*/
6+
7+
#include <linux/cpuidle.h>
8+
#include <linux/sched.h>
9+
#include <linux/sched/idle.h>
10+
11+
static int __cpuidle poll_idle(struct cpuidle_device *dev,
12+
struct cpuidle_driver *drv, int index)
13+
{
14+
local_irq_enable();
15+
if (!current_set_polling_and_test()) {
16+
while (!need_resched())
17+
cpu_relax();
18+
}
19+
current_clr_polling();
20+
21+
return index;
22+
}
23+
24+
void cpuidle_poll_state_init(struct cpuidle_driver *drv)
25+
{
26+
struct cpuidle_state *state = &drv->states[0];
27+
28+
snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
29+
snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
30+
state->exit_latency = 0;
31+
state->target_residency = 0;
32+
state->power_usage = -1;
33+
state->enter = poll_idle;
34+
state->disabled = false;
35+
state->flags = CPUIDLE_FLAG_POLLING;
36+
}
37+
EXPORT_SYMBOL_GPL(cpuidle_poll_state_init);

drivers/idle/intel_idle.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,7 @@ static void __init intel_idle_cpuidle_driver_init(void)
13311331

13321332
intel_idle_state_table_update();
13331333

1334+
cpuidle_poll_state_init(drv);
13341335
drv->state_count = 1;
13351336

13361337
for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {

include/linux/cpuidle.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct cpuidle_state {
6363

6464
/* Idle State Flags */
6565
#define CPUIDLE_FLAG_NONE (0x00)
66+
#define CPUIDLE_FLAG_POLLING (0x01) /* polling state */
6667
#define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
6768
#define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */
6869

@@ -224,6 +225,12 @@ static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev,
224225
}
225226
#endif
226227

228+
#ifdef CONFIG_ARCH_HAS_CPU_RELAX
229+
void cpuidle_poll_state_init(struct cpuidle_driver *drv);
230+
#else
231+
static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {}
232+
#endif
233+
227234
/******************************
228235
* CPUIDLE GOVERNOR INTERFACE *
229236
******************************/
@@ -250,12 +257,6 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
250257
{return 0;}
251258
#endif
252259

253-
#ifdef CONFIG_ARCH_HAS_CPU_RELAX
254-
#define CPUIDLE_DRIVER_STATE_START 1
255-
#else
256-
#define CPUIDLE_DRIVER_STATE_START 0
257-
#endif
258-
259260
#define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \
260261
({ \
261262
int __ret; \

0 commit comments

Comments
 (0)