drivers/base/power/runtime.c
Source file repositories/reference/linux-study-clean/drivers/base/power/runtime.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/base/power/runtime.c- Extension
.c- Size
- 59259 bytes
- Lines
- 2119
- Domain
- Driver Families
- Bucket
- drivers/base
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/sched/mm.hlinux/ktime.hlinux/hrtimer.hlinux/export.hlinux/pm_runtime.hlinux/pm_wakeirq.hlinux/rculist.htrace/events/rpm.h../base.hpower.h
Detected Declarations
function get_callback_ptrfunction __rpm_get_driver_callbackfunction __rpm_get_callbackfunction update_pm_runtime_accountingfunction __update_runtime_statusfunction rpm_get_accounted_timefunction pm_runtime_active_timefunction pm_runtime_suspended_timefunction pm_runtime_deactivate_timerfunction pm_runtime_cancel_pendingfunction nanosecondsfunction dev_memalloc_noiofunction pm_runtime_set_memalloc_noiofunction rpm_check_suspend_allowedfunction rpm_get_suppliersfunction list_for_each_entry_rcufunction pm_runtime_release_supplierfunction __rpm_put_suppliersfunction list_for_each_entry_rcufunction rpm_put_suppliersfunction rpm_suspend_suppliersfunction __rpm_callbackfunction rpm_callbackfunction rpm_idlefunction parentfunction rpm_resumefunction pm_runtime_workfunction pm_suspend_timer_fnfunction pm_schedule_suspendfunction rpm_drop_usage_countfunction zerofunction zerofunction pm_runtime_irq_safefunction pm_runtime_get_conditionalfunction atomic_readfunction pm_runtime_get_if_activefunction pm_runtime_get_if_in_usefunction __pm_runtime_set_statusfunction rpm_put_suppliersfunction __pm_runtime_barrierfunction pm_runtime_barrierfunction pm_runtime_block_if_disabledfunction pm_runtime_unblockfunction __pm_runtime_disablefunction pm_runtime_enablefunction pm_runtime_set_suspended_actionfunction devm_pm_runtime_set_active_enabledfunction pm_runtime_disable_action
Annotated Snippet
* The function should be called between device_add() and device_del()
* on the affected device(block/network device).
*/
void pm_runtime_set_memalloc_noio(struct device *dev, bool enable)
{
static DEFINE_MUTEX(dev_hotplug_mutex);
mutex_lock(&dev_hotplug_mutex);
for (;;) {
bool enabled;
/* hold power lock since bitfield is not SMP-safe. */
spin_lock_irq(&dev->power.lock);
enabled = dev->power.memalloc_noio;
dev->power.memalloc_noio = enable;
spin_unlock_irq(&dev->power.lock);
/*
* not need to enable ancestors any more if the device
* has been enabled.
*/
if (enabled && enable)
break;
dev = dev->parent;
/*
* clear flag of the parent device only if all the
* children don't set the flag because ancestor's
* flag was set by any one of the descendants.
*/
if (!dev || (!enable &&
device_for_each_child(dev, NULL, dev_memalloc_noio)))
break;
}
mutex_unlock(&dev_hotplug_mutex);
}
EXPORT_SYMBOL_GPL(pm_runtime_set_memalloc_noio);
/**
* rpm_check_suspend_allowed - Test whether a device may be suspended.
* @dev: Device to test.
*/
static int rpm_check_suspend_allowed(struct device *dev)
{
int retval = 0;
if (dev->power.runtime_error)
retval = -EINVAL;
else if (dev->power.disable_depth > 0)
retval = -EACCES;
else if (atomic_read(&dev->power.usage_count))
retval = -EAGAIN;
else if (!dev->power.ignore_children && atomic_read(&dev->power.child_count))
retval = -EBUSY;
/* Pending resume requests take precedence over suspends. */
else if ((dev->power.deferred_resume &&
dev->power.runtime_status == RPM_SUSPENDING) ||
(dev->power.request_pending && dev->power.request == RPM_REQ_RESUME))
retval = -EAGAIN;
else if (__dev_pm_qos_resume_latency(dev) == 0)
retval = -EPERM;
else if (dev->power.runtime_status == RPM_SUSPENDED)
retval = 1;
return retval;
}
static int rpm_get_suppliers(struct device *dev)
{
struct device_link *link;
list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
device_links_read_lock_held()) {
int retval;
if (!device_link_test(link, DL_FLAG_PM_RUNTIME))
continue;
retval = pm_runtime_get_sync(link->supplier);
/* Ignore suppliers with disabled runtime PM. */
if (retval < 0 && retval != -EACCES) {
pm_runtime_put_noidle(link->supplier);
return retval;
}
refcount_inc(&link->rpm_active);
}
return 0;
}
Annotation
- Immediate include surface: `linux/sched/mm.h`, `linux/ktime.h`, `linux/hrtimer.h`, `linux/export.h`, `linux/pm_runtime.h`, `linux/pm_wakeirq.h`, `linux/rculist.h`, `trace/events/rpm.h`.
- Detected declarations: `function get_callback_ptr`, `function __rpm_get_driver_callback`, `function __rpm_get_callback`, `function update_pm_runtime_accounting`, `function __update_runtime_status`, `function rpm_get_accounted_time`, `function pm_runtime_active_time`, `function pm_runtime_suspended_time`, `function pm_runtime_deactivate_timer`, `function pm_runtime_cancel_pending`.
- Atlas domain: Driver Families / drivers/base.
- 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.