drivers/base/power/wakeup.c

Source file repositories/reference/linux-study-clean/drivers/base/power/wakeup.c

File Facts

System
Linux kernel
Corpus path
drivers/base/power/wakeup.c
Extension
.c
Size
33542 bytes
Lines
1246
Domain
Driver Families
Bucket
drivers/base
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations wakeup_sources_stats_fops = {
	.owner = THIS_MODULE,
	.open = wakeup_sources_stats_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release_private,
};

#ifdef CONFIG_BPF_SYSCALL
#include <linux/btf.h>

__bpf_kfunc_start_defs();

/**
 * bpf_wakeup_sources_read_lock - Acquire the SRCU lock for wakeup sources
 *
 * The underlying SRCU lock returns an integer index. However, the BPF verifier
 * requires a pointer (PTR_TO_BTF_ID) to strictly track the state of acquired
 * resources using KF_ACQUIRE and KF_RELEASE semantics. We use an opaque
 * structure pointer (struct bpf_ws_lock *) to satisfy the verifier while
 * safely encoding the integer index within the pointer address itself.
 *
 * Return: An opaque pointer encoding the SRCU lock index + 1 (to avoid NULL).
 */
__bpf_kfunc struct bpf_ws_lock *bpf_wakeup_sources_read_lock(void)
{
	return (struct bpf_ws_lock *)(long)(wakeup_sources_read_lock() + 1);
}

/**
 * bpf_wakeup_sources_read_unlock - Release the SRCU lock for wakeup sources
 * @lock: The opaque pointer returned by bpf_wakeup_sources_read_lock()
 *
 * The BPF verifier guarantees that @lock is a valid, unreleased pointer from
 * the acquire function. We decode the pointer back into the integer SRCU index
 * by subtracting 1 and release the lock.
 */
__bpf_kfunc void bpf_wakeup_sources_read_unlock(struct bpf_ws_lock *lock)
{
	wakeup_sources_read_unlock((int)(long)lock - 1);
}

/**
 * bpf_wakeup_sources_get_head - Get the head of the wakeup sources list
 *
 * Return: The head of the wakeup sources list.
 */
__bpf_kfunc void *bpf_wakeup_sources_get_head(void)
{
	return &wakeup_sources;
}

__bpf_kfunc_end_defs();

BTF_KFUNCS_START(wakeup_source_kfunc_ids)
BTF_ID_FLAGS(func, bpf_wakeup_sources_read_lock, KF_ACQUIRE)
BTF_ID_FLAGS(func, bpf_wakeup_sources_read_unlock, KF_RELEASE)
BTF_ID_FLAGS(func, bpf_wakeup_sources_get_head)
BTF_KFUNCS_END(wakeup_source_kfunc_ids)

static const struct btf_kfunc_id_set wakeup_source_kfunc_set = {
	.set   = &wakeup_source_kfunc_ids,
};

static void __init wakeup_sources_bpf_init(void)
{
	if (register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &wakeup_source_kfunc_set))
		pm_pr_dbg("Wakeup: failed to register BTF kfuncs\n");
}
#else
static inline void wakeup_sources_bpf_init(void) {}
#endif /* CONFIG_BPF_SYSCALL */

static int __init wakeup_sources_init(void)
{
	debugfs_create_file("wakeup_sources", 0444, NULL, NULL,
			    &wakeup_sources_stats_fops);
	wakeup_sources_bpf_init();

	return 0;
}

postcore_initcall(wakeup_sources_init);

Annotation

Implementation Notes