| .. | .. |
|---|
| 17 | 17 | #include <linux/pm_qos.h> |
|---|
| 18 | 18 | #include <linux/cpu.h> |
|---|
| 19 | 19 | #include <linux/cpuidle.h> |
|---|
| 20 | +#include <linux/irq_pipeline.h> |
|---|
| 20 | 21 | #include <linux/ktime.h> |
|---|
| 21 | 22 | #include <linux/hrtimer.h> |
|---|
| 22 | 23 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 219 | 220 | broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP); |
|---|
| 220 | 221 | |
|---|
| 221 | 222 | /* |
|---|
| 223 | + * A companion core running on the oob stage of the IRQ |
|---|
| 224 | + * pipeline may deny switching to a deeper C-state. If so, |
|---|
| 225 | + * call the default idle routine instead. If the core cannot |
|---|
| 226 | + * bear with the latency induced by the default idling |
|---|
| 227 | + * operation, then CPUIDLE is not usable and should be |
|---|
| 228 | + * disabled at build time. The in-band stage is currently |
|---|
| 229 | + * stalled, hard irqs are on. irq_cpuidle_enter() leaves us |
|---|
| 230 | + * stalled but returns with hard irqs off so that no event may |
|---|
| 231 | + * sneak in until we actually go idle. |
|---|
| 232 | + */ |
|---|
| 233 | + if (!irq_cpuidle_enter(dev, target_state)) { |
|---|
| 234 | + default_idle_call(); |
|---|
| 235 | + return -EBUSY; |
|---|
| 236 | + } |
|---|
| 237 | + |
|---|
| 238 | + /* |
|---|
| 222 | 239 | * Tell the time framework to switch to a broadcast timer because our |
|---|
| 223 | 240 | * local timer will be shut down. If a local timer is used from another |
|---|
| 224 | 241 | * CPU as a broadcast timer, this call may fail if it is not available. |
|---|
| .. | .. |
|---|
| 247 | 264 | if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE)) |
|---|
| 248 | 265 | rcu_idle_enter(); |
|---|
| 249 | 266 | entered_state = target_state->enter(dev, drv, index); |
|---|
| 267 | + hard_cond_local_irq_enable(); |
|---|
| 250 | 268 | if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE)) |
|---|
| 251 | 269 | rcu_idle_exit(); |
|---|
| 252 | 270 | start_critical_timings(); |
|---|