arch/powerpc/platforms/powernv/idle.c
Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/powernv/idle.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/platforms/powernv/idle.c- Extension
.c- Size
- 39383 bytes
- Lines
- 1509
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/mm.hlinux/slab.hlinux/sysfs.hlinux/of.hlinux/device.hlinux/cpu.hasm/firmware.hasm/interrupt.hasm/machdep.hasm/opal.hasm/cputhreads.hasm/cpuidle.hasm/text-patching.hasm/smp.hasm/runlatch.hasm/dbell.hpowernv.hsubcore.h
Detected Declarations
struct p7_sprsstruct p9_sprsstruct p10_sprsfunction pnv_save_sprs_for_deep_statesfunction for_each_present_cpufunction pnv_get_supported_cpuidle_statesfunction pnv_fastsleep_workaround_applyfunction show_fastsleep_workaround_applyoncefunction store_fastsleep_workaround_applyoncefunction atomic_start_thread_idlefunction atomic_stop_thread_idlefunction atomic_lock_thread_idlefunction atomic_unlock_and_stop_thread_idlefunction atomic_unlock_thread_idlefunction power7_idle_insnfunction power7_offlinefunction power7_idle_typefunction power7_idlefunction power9_idle_stopfunction MMCR0function POWER9function pnv_power9_force_smt4_releasefunction power10_idle_stopfunction arch300_offline_stopfunction arch300_idle_typefunction arch300_idlefunction pnv_program_cpu_hotplug_lpcrfunction pnv_cpu_offlinefunction Registerfunction GET_PSSCR_ESLfunction pnv_arch300_idle_initfunction pnv_disable_deep_statesfunction pnv_probe_idle_statesfunction pnv_parse_cpuidle_dtfunction pnv_init_idle_statesexport pnv_get_supported_cpuidle_statesexport pnv_power9_force_smt4_catchexport pnv_power9_force_smt4_release
Annotated Snippet
struct p7_sprs {
/* per core */
u64 tscr;
u64 worc;
/* per subcore */
u64 sdr1;
u64 rpr;
/* per thread */
u64 lpcr;
u64 hfscr;
u64 fscr;
u64 purr;
u64 spurr;
u64 dscr;
u64 wort;
/* per thread SPRs that get lost in shallow states */
u64 amr;
u64 iamr;
u64 uamor;
/* amor is restored to constant ~0 */
};
static unsigned long power7_idle_insn(unsigned long type)
{
int cpu = raw_smp_processor_id();
int first = cpu_first_thread_sibling(cpu);
unsigned long *state = &paca_ptrs[first]->idle_state;
unsigned long thread = 1UL << cpu_thread_in_core(cpu);
unsigned long core_thread_mask = (1UL << threads_per_core) - 1;
unsigned long srr1;
bool full_winkle;
struct p7_sprs sprs = {}; /* avoid false use-uninitialised */
bool sprs_saved = false;
int rc;
if (unlikely(type != PNV_THREAD_NAP)) {
atomic_lock_thread_idle();
BUG_ON(!(*state & thread));
*state &= ~thread;
if (power7_fastsleep_workaround_entry) {
if ((*state & core_thread_mask) == 0) {
rc = opal_config_cpu_idle_state(
OPAL_CONFIG_IDLE_FASTSLEEP,
OPAL_CONFIG_IDLE_APPLY);
BUG_ON(rc);
}
}
if (type == PNV_THREAD_WINKLE) {
sprs.tscr = mfspr(SPRN_TSCR);
sprs.worc = mfspr(SPRN_WORC);
sprs.sdr1 = mfspr(SPRN_SDR1);
sprs.rpr = mfspr(SPRN_RPR);
sprs.lpcr = mfspr(SPRN_LPCR);
if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
sprs.hfscr = mfspr(SPRN_HFSCR);
sprs.fscr = mfspr(SPRN_FSCR);
}
sprs.purr = mfspr(SPRN_PURR);
sprs.spurr = mfspr(SPRN_SPURR);
sprs.dscr = mfspr(SPRN_DSCR);
sprs.wort = mfspr(SPRN_WORT);
sprs_saved = true;
/*
* Increment winkle counter and set all winkle bits if
* all threads are winkling. This allows wakeup side to
* distinguish between fast sleep and winkle state
* loss. Fast sleep still has to resync the timebase so
* this may not be a really big win.
*/
*state += 1 << PNV_CORE_IDLE_WINKLE_COUNT_SHIFT;
if ((*state & PNV_CORE_IDLE_WINKLE_COUNT_BITS)
>> PNV_CORE_IDLE_WINKLE_COUNT_SHIFT
== threads_per_core)
*state |= PNV_CORE_IDLE_THREAD_WINKLE_BITS;
WARN_ON((*state & PNV_CORE_IDLE_WINKLE_COUNT_BITS) == 0);
}
atomic_unlock_thread_idle();
}
Annotation
- Immediate include surface: `linux/types.h`, `linux/mm.h`, `linux/slab.h`, `linux/sysfs.h`, `linux/of.h`, `linux/device.h`, `linux/cpu.h`, `asm/firmware.h`.
- Detected declarations: `struct p7_sprs`, `struct p9_sprs`, `struct p10_sprs`, `function pnv_save_sprs_for_deep_states`, `function for_each_present_cpu`, `function pnv_get_supported_cpuidle_states`, `function pnv_fastsleep_workaround_apply`, `function show_fastsleep_workaround_applyonce`, `function store_fastsleep_workaround_applyonce`, `function atomic_start_thread_idle`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.