全景介绍
在设备资源底座里,clock 负责时钟,reset 负责复位线,genpd 负责电源域上下电,opp性能点。还差一块很容易被低估的资源:供电。设备能不能工作、能不能切到更高频率、能不能在 suspend 时安全掉电,最终都绕不开 regulator framework。
Regulator 在硬件上通常对应 PMIC 输出、LDO、DCDC、固定电源、GPIO 控制电源开关,或者板级上某一路共享电源。Linux regulator framework 做的事情,是把这些供电资源统一抽象成内核对象,让 consumer driver 能用标准接口获取供电、打开供电、设置电压或电流限制,同时让 provider driver 和板级约束控制哪些操作允许做、允许做到什么范围。

这套框架的边界很重要。Regulator 不是 opp,opp只是告诉系统某个性能点需要多少电压;Regulator 也不是 genpd,genpd 管一组设备所在电源域是否上电;Regulator 管的是某一路 supply 本身的 enable、disable、voltage、current 和依赖关系。一个设备运行时可能同时受这三类资源影响:power domain 要开,clock 要有,regulator 电压也要满足要求。
实际情况
板级供电配置写错,后果比 clock 配错更明显,clock rate 不对可能表现为设备不工作,regulator 约束错了可能导致电压过高、过低、误关共享电源,甚至影响其他器件稳定性。所以 regulator framework 里有大量 constraint 逻辑,目的不是让 consumer 随便改电压,而是把设备请求限制在硬件允许范围内。
常见设备树配置会写成这样:
vdd_gpu: regulator-vdd-gpu { compatible = "regulator-fixed"; regulator-name = "vdd_gpu"; regulator-min-microvolt = <650000>; regulator-max-microvolt = <950000>; regulator-always-on;};&gpu { mali-supply = <&vdd_gpu>; operating-points-v2 = <&gpu_opp_table>; clocks = <&cru CLK_GPU>; power-domains = <&power RK3588_PD_GPU>;};
这里 mali-supply 把 GPU consumer 和 vdd_gpu 这路 regulator 连接起来。驱动里通过 devm_regulator_get(dev, "mali") 拿到 handle,OPP 或驱动再通过 set voltage/enable 路径控制它。实际项目里,名字对不上、约束范围过窄、共享 rail 被误 disable、always-on/boot-on 配错,都会造成看似和电源无关的问题。
Regulator 还经常作为 opp的执行端。升频前,opp helper 或驱动要先把 regulator 电压拉到目标 opp要求;降频后,才能把电压降下来。这个顺序如果做反,设备就可能在高频低压下运行。
抽象对象
Regulator framework 里有四组对象需要区分:machine constraint、provider driver、core object、consumer handle。

struct regulator_desc 是 provider driver 提供的静态描述。它说明这路 regulator 的名字、类型、可用操作、寄存器位、线性电压表、enable/disable 方法等。PMIC 驱动、fixed regulator 驱动、GPIO regulator 驱动都会提供 desc。
struct regulator_config 是注册时传入的上下文信息,包括设备指针、init_data、driver_data、regmap、of_node 等。provider driver 调用 devm_regulator_register() 时,core 会结合 desc 和 config 创建 struct regulator_dev。
struct regulator_dev 是 core 里的 regulator 设备对象。后续 enable_count、use_count、constraints、supply、consumer list、ops 调用,都围绕 rdev 展开。它对应的是“这一路供电资源”。
struct regulator 是 consumer 拿到的 handle。设备驱动不直接操作 regulator_dev,而是通过 regulator_get() / devm_regulator_get() 得到 struct regulator,再调用 regulator_enable()、regulator_disable()、regulator_set_voltage() 等接口。
struct regulation_constraints 是板级安全边界。它描述最小/最大电压、最小/最大电流、是否允许改变电压、是否允许关闭、boot_on、always_on、valid_ops_mask 等。consumer 的请求必须落在 constraints 范围内。
模型
Regulator framework 可以拆成三层:machine 约束层、provider 执行层、consumer 请求层。

Machine 约束层来自设备树或板级代码。它描述电源轨在板子上的物理连接、允许电压范围、是否必须常开、是否启动时打开、输入 supply 是哪一路。这个层面不是某个设备驱动随意决定的,而是硬件设计约束。
Provider 执行层由 PMIC、GPIO regulator、fixed regulator 或 SoC 内部电源控制驱动提供。它负责把 enable、disable、set_voltage、set_current_limit 等操作翻译成寄存器写入、GPIO 电平或固件调用。
Consumer 请求层由设备驱动、OPP、runtime PM 或子系统框架触发。consumer 只能表达“我需要这路 supply 打开”或者“我希望电压在某个范围”,core 会检查约束,再决定是否调用 provider ops。
这个模型的好处是职责清晰:consumer 不知道 PMIC 寄存器,provider 不知道具体设备负载策略,machine constraints 不参与每次策略决策,但始终作为安全边界存在。
数据流
Provider 注册流程
Regulator provider 通常在 PMIC driver、platform driver 或 fixed regulator driver probe 阶段注册。driver 准备好 regulator_desc 和 regulator_config,调用devm_regulator_register(),core 创建 regulator_dev 并加入全局管理。

典型路径是:
rdev = devm_regulator_register(dev, &desc, &config);
注册时 core 会解析 init data 和 constraints,建立 supply parent 关系,初始化引用计数和 sysfs/debugfs 信息。注册完成后,consumer 才能通过 supply 名称找到对应 regulator。
Consumer 获取与启停流程
设备驱动通常通过 supply 名称获取 regulator:
vdd = devm_regulator_get(dev, "vdd");regulator_enable(vdd);...regulator_disable(vdd);

devm_regulator_get() 会根据设备节点里的 vdd-supply、mali-supply、avdd-supply 等属性查找 provider。拿到 handle 后,enable/disable 并不一定直接对应硬件开关。core 会维护 use_count 和 enable_count,多 consumer 共享同一路 supply 时,等所有 consumer 都释放后才允许执行 disable。
电压设置流程
电压设置比enable 更敏感。consumer 调用 regulator_set_voltage(min_uV, max_uV) 时,core 先检查 constraints,再从 provider 支持的电压表或线性范围里选择合适 selector,最后调用 provider ops。

如果请求范围不在 constraints 内,或者 provider 没有可匹配电压,set_voltage 应该失败。驱动不能忽略这个错误继续设置高频。opp切换链路里,电压设置失败通常意味着目标性能点不可用。
级联和共享电源
Regulator 常常不是单层结构。一颗 PMIC 的 DCDC 可能给多个 LDO 供电,某个 LDO 又给多个设备供电。Linux 通过 supply parent 描述这种关系。

当子 regulator enable 时,core 可能需要先 enable 上游 supply。disable 时则要考虑下游还有没有 consumer。共享电源轨尤其容易误判:某个设备 suspend 后调用 disable,并不代表这路电源马上会被关闭,因为其他 consumer 可能仍在使用。
运行
Regulator 在运行期主要出现在三类路径:设备 probe、runtime PM/system sleep、OPP/DVFS。
设备 probe 阶段,驱动获取并打开必要供电,之后才能访问寄存器或启动硬件。很多外设驱动的初始化顺序是 regulator enable → clock prepare/enable → reset deassert → 访问硬件寄存器。顺序错了,可能表现为总线访问超时或设备 ID 读取失败。
Runtime PM 阶段,驱动可以在 runtime_suspend 中关闭非必须供电,在 runtime_resume 中重新打开。这里要注意共享 supply 和 wakeup 需求。如果某路电源供给多个设备,单个设备 runtime_suspend 不应该破坏其他设备运行。
OPP/DVFS 阶段,regulator 提供目标电压。升频前先升压,降频后再降压,是为了避免高频低压。OPP 只给出目标电压,regulator 负责检查是否能设置到这个范围。
System sleep 阶段,regulator 还要处理 suspend state。有些 regulator 在 suspend 中保持打开,有些可以切换到低功耗模式,有些必须关闭。具体行为由 constraints、driver ops 和平台 suspend 配置共同决定。
Image调试 regulator 问题时,regulator_summary 是最直接入口:
cat /sys/kernel/debug/regulator/regulator_summary
它能看到 regulator 名称、use_count、open_count、当前电压、约束范围、consumer 列表。结合 clk_summary、pm_genpd_summary、devfreq/cpufreq 节点,可以判断设备不工作是供电没开、时钟没开、电源域没开,还是 OPP 目标点被限制。
案例:RK3588 板级供电链路
以 RK3588 这类平台为例,CPU、GPU、NPU、VOP、ISP 等模块通常有不同供电 rail,有的来自 PMIC DCDC,有的来自 LDO 或固定电源。设备树会用 *-supply 把设备和 regulator provider 连接起来。
ImageGPU 的运行链路里,regulator、OPP、clock、genpd 会同时出现。设备 runtime_resume 前,power domain 要保证上电;设置高频 OPP 前,regulator 要把电压拉到目标范围;clock 才能切到目标 rate。任何一环失败,最终表现都可能只是“频率上不去”或“设备 resume 失败”。
调试时可以按这个顺序看:
# 供电是否存在、是否打开、电压范围是否正确cat /sys/kernel/debug/regulator/regulator_summary# clock 是否 enable,rate 是否符合预期cat /sys/kernel/debug/clk/clk_summary# power domain 是否上电cat /sys/kernel/debug/pm_genpd/pm_genpd_summary# OPP / devfreq 是否限制了目标频率ls /sys/kernel/debug/opp/ls /sys/class/devfreq/
如果 regulator_summary 里某一路 supply 的 use_count 为 0,但设备已经在访问硬件,优先怀疑驱动 probe/runtime PM 顺序。若 use_count 正常但电压不对,再看 constraints、OPP entry 和 provider 是否支持目标 selector。若电压设置失败却继续切频,问题就不在 regulator framework,而在调用方错误处理。
总结
Regulator framework 是 Linux 设备资源底座里负责供电约束的部分。它把 PMIC、LDO、DCDC、fixed supply、GPIO power switch 等硬件差异统一成 regulator provider,再通过 consumer handle 给设备驱动使用。
它的核心不是简单 enable/disable,而是把板级安全约束放进内核路径里。consumer 可以请求电压和开关状态,但能不能执行,必须经过 constraints、provider 能力、引用计数和级联关系共同判断。
到这里,设备资源管理层的主线就完整了:clock 管时钟,reset 管复位,regulator 管供电,genpd 管电源域,OPP 管性能点。下一篇进入 Runtime PM,开始看设备在运行期如何进入 suspend/resume,以及这些资源框架如何被统一调用。