drivers/cpuidle/cpuidle-riscv-sbi.c
Source file repositories/reference/linux-study-clean/drivers/cpuidle/cpuidle-riscv-sbi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cpuidle/cpuidle-riscv-sbi.c- Extension
.c- Size
- 13251 bytes
- Lines
- 580
- Domain
- Driver Families
- Bucket
- drivers/cpuidle
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/cleanup.hlinux/cpuhotplug.hlinux/cpuidle.hlinux/cpumask.hlinux/cpu_pm.hlinux/cpu_cooling.hlinux/kernel.hlinux/module.hlinux/of.hlinux/slab.hlinux/string.hlinux/platform_device.hlinux/pm_domain.hlinux/pm_runtime.hasm/cpuidle.hasm/sbi.hasm/smp.hasm/suspend.hcpuidle.hdt_idle_states.hdt_idle_genpd.h
Detected Declarations
struct sbi_cpuidle_datastruct sbi_domain_statestruct sbi_pd_providerfunction sbi_set_domain_statefunction sbi_get_domain_statefunction sbi_clear_domain_statefunction sbi_is_domain_state_availablefunction sbi_cpuidle_enter_statefunction __sbi_enter_domain_idle_statefunction sbi_enter_domain_idle_statefunction sbi_enter_s2idle_domain_idle_statefunction sbi_cpuidle_cpuhp_upfunction sbi_cpuidle_cpuhp_downfunction sbi_idle_init_cpuhpfunction sbi_dt_parse_state_nodefunction sbi_dt_cpu_init_topologyfunction sbi_cpuidle_dt_init_statesfunction sbi_cpuidle_deinit_cpufunction sbi_cpuidle_init_cpufunction sbi_cpuidle_pd_power_offfunction sbi_pd_initfunction sbi_pd_removefunction list_for_each_entry_safefunction sbi_genpd_probefunction sbi_genpd_probefunction sbi_cpuidle_probefunction sbi_cpuidle_init
Annotated Snippet
struct sbi_cpuidle_data {
u32 *states;
struct device *dev;
};
struct sbi_domain_state {
bool available;
u32 state;
};
static DEFINE_PER_CPU_READ_MOSTLY(struct sbi_cpuidle_data, sbi_cpuidle_data);
static DEFINE_PER_CPU(struct sbi_domain_state, domain_state);
static bool sbi_cpuidle_use_osi;
static bool sbi_cpuidle_use_cpuhp;
static inline void sbi_set_domain_state(u32 state)
{
struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
data->available = true;
data->state = state;
}
static inline u32 sbi_get_domain_state(void)
{
struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
return data->state;
}
static inline void sbi_clear_domain_state(void)
{
struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
data->available = false;
}
static inline bool sbi_is_domain_state_available(void)
{
struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
return data->available;
}
static __cpuidle int sbi_cpuidle_enter_state(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int idx)
{
u32 *states = __this_cpu_read(sbi_cpuidle_data.states);
u32 state = states[idx];
if (state & SBI_HSM_SUSP_NON_RET_BIT)
return CPU_PM_CPU_IDLE_ENTER_PARAM(riscv_sbi_hart_suspend, idx, state);
else
return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(riscv_sbi_hart_suspend,
idx, state);
}
static __cpuidle int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int idx,
bool s2idle)
{
struct sbi_cpuidle_data *data = this_cpu_ptr(&sbi_cpuidle_data);
u32 *states = data->states;
struct device *pd_dev = data->dev;
u32 state;
int ret;
ret = cpu_pm_enter();
if (ret)
return -1;
/* Do runtime PM to manage a hierarchical CPU toplogy. */
if (s2idle)
dev_pm_genpd_suspend(pd_dev);
else
pm_runtime_put_sync_suspend(pd_dev);
ct_cpuidle_enter();
if (sbi_is_domain_state_available())
state = sbi_get_domain_state();
else
state = states[idx];
ret = riscv_sbi_hart_suspend(state) ? -1 : idx;
ct_cpuidle_exit();
if (s2idle)
dev_pm_genpd_resume(pd_dev);
Annotation
- Immediate include surface: `linux/cleanup.h`, `linux/cpuhotplug.h`, `linux/cpuidle.h`, `linux/cpumask.h`, `linux/cpu_pm.h`, `linux/cpu_cooling.h`, `linux/kernel.h`, `linux/module.h`.
- Detected declarations: `struct sbi_cpuidle_data`, `struct sbi_domain_state`, `struct sbi_pd_provider`, `function sbi_set_domain_state`, `function sbi_get_domain_state`, `function sbi_clear_domain_state`, `function sbi_is_domain_state_available`, `function sbi_cpuidle_enter_state`, `function __sbi_enter_domain_idle_state`, `function sbi_enter_domain_idle_state`.
- Atlas domain: Driver Families / drivers/cpuidle.
- Implementation status: source implementation candidate.
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.