Source
static inline int cpuidle_coupled_no_cpus_waiting(struct cpuidle_coupled *coupled)
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* coupled.c - helper functions to enter the same idle state on multiple cpus
*
* Copyright (c) 2011 Google, Inc.
*
* Author: Colin Cross <ccross@android.com>
*/
/**
* DOC: Coupled cpuidle states
*
* On some ARM SMP SoCs (OMAP4460, Tegra 2, and probably more), the
* cpus cannot be independently powered down, either due to
* sequencing restrictions (on Tegra 2, cpu 0 must be the last to
* power down), or due to HW bugs (on OMAP4460, a cpu powering up
* will corrupt the gic state unless the other cpu runs a work
* around). Each cpu has a power state that it can enter without
* coordinating with the other cpu (usually Wait For Interrupt, or
* WFI), and one or more "coupled" power states that affect blocks
* shared between the cpus (L2 cache, interrupt controller, and
* sometimes the whole SoC). Entering a coupled power state must
* be tightly controlled on both cpus.
*
* This file implements a solution, where each cpu will wait in the
* WFI state until all cpus are ready to enter a coupled state, at
* which point the coupled state function will be called on all
* cpus at approximately the same time.
*
* Once all cpus are ready to enter idle, they are woken by an smp
* cross call. At this point, there is a chance that one of the
* cpus will find work to do, and choose not to enter idle. A
* final pass is needed to guarantee that all cpus will call the
* power state enter function at the same time. During this pass,
* each cpu will increment the ready counter, and continue once the
* ready counter matches the number of online coupled cpus. If any
* cpu exits idle, the other cpus will decrement their counter and
* retry.
*
* requested_state stores the deepest coupled idle state each cpu
* is ready for. It is assumed that the states are indexed from
* shallowest (highest power, lowest exit latency) to deepest
* (lowest power, highest exit latency). The requested_state
* variable is not locked. It is only written from the cpu that
* it stores (or by the on/offlining cpu if that cpu is offline),
* and only read after all the cpus are ready for the coupled idle
* state are are no longer updating it.
*
* Three atomic counters are used. alive_count tracks the number
* of cpus in the coupled set that are currently or soon will be
* online. waiting_count tracks the number of cpus that are in
* the waiting loop, in the ready loop, or in the coupled idle state.
* ready_count tracks the number of cpus that are in the ready loop