kernel power domain分析

power domain

最近工作上接触到了kernel power domain framework,kernel文档对这块的解释不多,网上的参考资料也很少,不过还是得感谢wowo大神几年前的文章,对自己还是有帮助的。废话不多说,梳理一下,也让自己加深一下印象。

什么是power domain?

电源域(power domain)可以理解为多个模块共用一个电源,比如usb、gpio在soc的内部实现上都属于同一个xxx子系统,那么xxx子系统要进入低功耗状态的前提是什么?就是usb和gpio都得进入低功耗;那反过来,如果要使用usb呢?usb要能上电的前提就是xxx子系统得先上电(即xxx子系统的控制寄存器的enable位需要置1)。

那么usb和gpio在软件实现上需要如何进入低功耗呢?相信大家也能猜到,那就是runtime_pm,所以power domain和runtime_pm是存在耦合关系的,本篇文章不会深入分析runtime_pm,后续有机会再另起一篇分析。

如何使用power domain?

power domian的使用方法非常的简单,如果不想去深入分析power domain如何工作的,只想使用kernel提供的方法,那么只需在dts中定义一个power domain节点,同时在驱动中注册该power domain即可,是不是很简单?

参考:Documentation\devicetree\bindings\power

//DTS中定义power domain节点,这里以内核文档提供的例程
	parent: power-controller@12340000 {
    compatible = "foo,power-controller";
		reg = <0x12340000 0x1000>;
		#power-domain-cells = <1>;   //这里表明parent节点是一个power domain,也就是内核文档所形容的provider,parent管理它下面挂接着的其它模块,为它们提供电源
     };

	child: power-controller@12341000 {
    compatible = "foo,power-controller";
		reg = <0x12341000 0x1000>;
		power-domains = <&parent 0>; //这里表明child节点是parent下面的一个模块,它使用parent提供的电源
		#power-domain-cells = <1>; 
     };

从上面的dts语法中可以看出,一个系统的电源域从dts中可以很容易就看出来,#power-domain-cells声明该节点是一个power domain,power-domains = <&xxx x>表明该节点属于xxx电源域,那么系统中某个电源域下面有多少个模块就从dts中看有多少个节点引用了该电源域即可。

介绍完了dts,那么驱动中如何注册一个电源域呢?

/**
 * pm_genpd_init - Initialize a generic I/O PM domain object.
 * @genpd: PM domain object to initialize.
 * @gov: PM domain governor to associate with the domain (may be NULL).
 * @is_off: Initial value of the domain's power_is_off field.
 *
 * Returns 0 on successful initialization, else a negative error code.
 */
int pm_genpd_init(struct generic_pm_domain *genpd,
		  struct dev_power_governor *gov, bool is_off)  //初始化一个 generic_pm_domain 实例
    
    
/**
 * of_genpd_add_provider_onecell() - Register a onecell PM domain provider
 * @np: Device node pointer associated with the PM domain provider.
 * @data: Pointer to the data associated with the PM domain provider.
 */

//下面两个接口都可以用来向内核注册一个power domian
int of_genpd_add_provider_onecell(struct device_node *np,
				  struct genpd_onecell_data *data)     
int of_genpd_add_provider_simple(struct device_node *np,
				  struct generic_pm_domain *genpd)

可以看到,驱动想要注册一个power domain只需要调用两个函数即可,甚至不需要实现任何具体的函数,so easy吧~

代码分析

接下来进入正题,开始分析内核是如何实现power domain的,为何consumer只需引用power domain节点就可以和provider有耦合。

provider分析

先来看一个非常重要的数据结构,这个数据结构是内核为device电源管理所抽象出来的回调函数,我们关心最后三个即可,即runtime_pm方法,后面的分析我们会发现设备的suspend和resume最终都调用该结构体下的某个函数。

struct dev_pm_ops {
   
	int (*prepare)(struct device *dev);
	void (*complete)(struct device *dev);
	int (*suspend)(struct device *dev);
	int (*resume)(struct device *dev);
	int (*freeze)(struct device *dev);
	int (*thaw)(struct device *dev);
	int (*poweroff)(struct device *dev);
	int (*restore)(struct device *dev);
	int (*suspend_late)(struct device *dev);
	int (*resume_early)(struct device *dev);
	int (*freeze_late)(struct device *dev);
	int (*thaw_early)(struct device *dev);
	int (*poweroff_late)(struct device *dev);
	int (*restore_early)(struct device *dev);
	int (*suspend_noirq)(struct device *dev);
	int (*resume_noirq)(struct device *dev);
	int (*freeze_noirq)(struct device *dev);
	int (*thaw_noirq)(struct device *dev);
	int (*poweroff_noirq)(struct device *dev);
	int (*restore_noirq)(struct device *dev);
	int (*runtime_suspend)(struct device *dev);  //runtime suspend函数
	int (*runtime_resume)(struct 
### 关于RK3566开发板电源配置与DTS文件对应 对于RK3566开发板上遇到的`PLEASE CHECK IO-DOMAIN`错误,通常意味着设备树源(DTS)文件中的IO域设置存在问题或不匹配硬件实际连接情况。具体来说: 在DTS文件中定义的各个IO域应当准确反映底板原理图上的供电设计。例如,在提到vccio4-supply应为1.8V的情况下[^1],如果发现该设定无法正常工作,则可能是由于以下几个方面的原因造成的: #### 1. 设备树配置检查 确保DTS文件内的&io_domains节点下有正确的子节点来描述每一个独立的IO域,并且这些子节点通过compatible属性指定了相应的控制器名称。这有助于内核识别并初始化特定类型的调节器(regulator)[^2]。 ```dts &io_domains { compatible = "rockchip,rk3566-io-domains"; /* Example of an io domain configuration */ vccio4: vccio4-regulator@0 { rockchip,regulators = <&pmc>; regulator-name = "vccio4"; regulator-min-microvolt = <1800000>; /* Set to match hardware spec */ regulator-max-microvolt = <1800000>; status = "okay"; }; }; ``` #### 2. 调节器驱动程序验证 确认所使用的Linux版本包含了支持目标平台PMIC(Power Management IC)芯片所需的全部驱动模块。某些情况下可能需要更新kernel或者添加额外的支持补丁以实现完整的功能覆盖。 #### 3. 硬件一致性审查 仔细对比电路板的实际焊接布局同官方提供的参考设计方案是否存在差异。任何未记录的变化都可能导致预期之外的行为发生。 当上述条件均满足但仍存在警告信息时,可以尝试移除或调整引起冲突的具体条目,但在操作前务必充分理解其影响范围以及潜在风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值