Runtime PM

Runtime PM 是Linux内核中设备电源管理的一部分,它允许设备在不需要工作时进入低功耗状态。设备驱动需要提供runtime_suspend、runtime_resume和runtime_idle回调函数。RPM核心通过异步调用来避免在中断处理中执行可能睡眠的操作,同时提供了同步接口供驱动明确控制。当所有子设备idle时,父设备才能idle。设备的active状态由引用计数管理,app的open/close操作或控制文件可控制设备的电源状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RPM:在一个运行的系统中,对某个设备进行休眠和唤醒操作;每个设备(包括CPU)都处理好自身的电源管理工作,尽量在不需要工作的时候进入低功耗状态,尽量不和其它模块有过多耦合。

device driver(或者driver所在的bus、class等)需要提供3个回调函数,runtime_suspend、runtime_resume和runtime_idle,分别用于suspend device、resume device和idle device。

调用时机:
1)主动访问设备时,如写寄存器、发起数据传输等等,get,增加引用计数,告诉RPM core设备active;访问结束后,put,减小引用计数,告诉RPM core设备可能idle。
2)设备有事件通知时,get(可能在中断处理中);driver处理完事件后,put。

举例 bma150.c
bma150_register_polled_device —> input_allocate_device----> device_initialize(&dev->dev);

----> device_pm_init(dev) ----> pm_runtime_init(dev);

void pm_runtime_init(struct device *dev)
{
	dev->power.runtime_status = RPM_SUSPENDED;
	dev->power.idle_notification = false;

	dev->power.disable_depth = 1;   // disable_depth 的初值设定为 1
	atomic_set(&dev->power.usage_count, 0);  //  dev->power.usage_count 的初值设定为 0

	dev->power.runtime_error = 0;

	atomic_set(&dev->power.child_count, 0);   
	pm_suspend_ignore_children(dev, false);
	dev->power.runtime_auto = true;

	dev->power.request_pending = false;
	dev->power.request = RPM_REQ_NONE;
	dev->power.deferred_resume = false;
	dev->power.accounting_timestamp = jiffies;
	INIT_WORK(&dev->power.work, pm_runtime_work); // 使workstruct结构体的func指向pm_runtime_work

	dev->power.timer_expires = 0;
	setup_timer(&dev->power.suspend_timer, pm_suspend_timer_fn,
			(unsigned long)dev); // 初始化 timer_list结构体,并将其 function 指针指向pm_suspend_timer_fn,将其data指针指向 dev

	init_waitqueue_head(&dev->power.wait_queue); // 双向链表初始化
}

在 bma150_probe中有

pm_runtime_enable(&client->dev); // 使能设备的runtime PM

void pm_runtime_enable(struct device *dev)
{
	unsigned long flags;

	spin_lock_irqsave(&dev->power.lock, flags);

	if (dev->power.disable_depth > 0)
		dev->power.disable_depth--;  // 减少disable_depth的计数值,减为0
	else
		dev_warn(dev, "Unbalanced %s!\n", __func__);

	spin_unlock_irqrestore(&dev->power.lock, flags);
}

在 bma150_remove中有
pm_runtime_disable(&client->dev);

 void __pm_runtime_disable(struct device *dev, bool check_resume)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值