Linux电源管理
电源管理(Power Management)在Linux Kernel中,是一个比较庞大的子系统,涉及到供电(Power Supply)、充电(Charger)、时钟(Clock)、频率(Frequency)、电压(Voltage)、睡眠/唤醒(Suspend/Resume)等方方面面(如下图)
Generic PM
Linux系统中那些常规的电源管理手段,包括关机(Power off)、待机(Standby or Hibernate)、重启(Reboot)等。
Regulator 稳定器
Regulator,中文名翻译为“稳定器”,在电子工程中,是voltage regulator(稳压器)或者current regulator(稳流器)的简称,指可以自动维持恒定电压(或电流)的装置。
但从设备驱动的角度看,regulator的控制应该很简单,就是输出的enable/disable、输出电压或电流的大小的控制
regulator driver
Regulator,即LDO(low dropout regulator),低压差线性稳压器,简称稳压器
作为电源管理中的基础设施,regulator被视作为Linux系统的供电单元;这是一个抽象出来的概念,他的provider可以是PMIC,tpsxx,lpxxx等各种power supply
Linux中Regulator的抽象概念,其最大的意义在于为各consumer的使用提供了统一的接口,例如获取跟设置电压输出,控制其使能等;在不同的场景下动态的调整regulator使能,已达到省电的目的,这一点在移动设备上尤为重要。
kernel/linux-4.9/drivers/regulator/axp2101-regulator.c
kernel/linux-4.9/drivers/regulator$ tree
.
├── 88pm800.c
├── 88pm8607.c
├── aat2870-regulator.c
├── ab3100.c
├── ab8500.c
├── ab8500-ext.c
├── act8865-regulator.c
├── act8945a-regulator.c
├── ad5398.c
├── anatop-regulator.c
├── arizona-ldo1.c
├── arizona-micsupp.c
├── as3711-regulator.c
├── as3722-regulator.c
├── axp20x-regulator.c
├── axp2101-regulator.c
├── axp2101-regulator.o
├── bcm590xx-regulator.c
├── built-in.o
├── core.c
├── core.o
├── da903x.c
├── da9052-regulator.c
├── da9055-regulator.c
├── da9062-regulator.c
├── da9063-regulator.c
├── da9210-regulator.c
├── da9210-regulator.h
├── da9211-regulator.c
├── da9211-regulator.h
├── db8500-prcmu.c
├── dbx500-prcmu.c
├── dbx500-prcmu.h
├── devres.c
├── devres.o
├── dummy.c
├── dummy.h
├── dummy.o
├── fan53555.c
├── fixed.c
├── fixed-helper.c
├── fixed-helper.o
├── fixed.o
├── gpio-regulator.c
├── helpers.c
├── helpers.o
├── hi6421-regulator.c
├── hi655x-regulator.c
├── internal.h
├── isl6271a-regulator.c
├── isl9305.c
├── Kconfig
├── lm363x-regulator.c
├── lp3971.c
├── lp3972.c
├── lp872x.c
├── lp873x-regulator.c
├── lp8755.c
├── lp8788-buck.c
├── lp8788-ldo.c
├── ltc3589.c
├── ltc3676.c
├── Makefile
├── max14577-regulator.c
├── max1586.c
├── max77620-regulator.c
├── max77686-regulator.c
├── max77693-regulator.c
├── max77802-regulator.c
├── max8649.c
├── max8660.c
├── max8907-regulator.c
├── max8925-regulator.c
├── max8952.c
├── max8973-regulator.c
├── max8997-regulator.c
├── max8998.c
├── mc13783-regulator.c
├── mc13892-regulator.c
├── mc13xxx.h
├── mc13xxx-regulator-core.c
├── modules.builtin
├── modules.order
├── mt6311-regulator.c
├── mt6311-regulator.h
├── mt6323-regulator.c
├── mt6397-regulator.c
├── of_regulator.c
├── of_regulator.o
├── palmas-regulator.c
├── pbias-regulator.c
├── pcap-regulator.c
├── pcf50633-regulator.c
├── pfuze100-regulator.c
├── pv88060-regulator.c
├── pv88060-regulator.h
├── pv88080-regulator.c
├── pv88080-regulator.h
├── pv88090-regulator.c
├── pv88090-regulator.h
├── pwm-regulator.c
├── qcom_rpm-regulator.c
├── qcom_smd-regulator.c
├── qcom_spmi-regulator.c
├── rc5t583-regulator.c
├── rk808-regulator.c
├── rn5t618-regulator.c
├── rt5033-regulator.c
├── s2mpa01.c
├── s2mps11.c
├── s5m8767.c
├── sky81452-regulator.c
├── stw481x-vmmc.c
├── ti-abb-regulator.c
├── tps51632-regulator.c
├── tps6105x-regulator.c
├── tps62360-regulator.c
├── tps65023-regulator.c
├── tps6507x-regulator.c
├── tps65086-regulator.c
├── tps65090-regulator.c
├── tps65217-regulator.c
├── tps65218-regulator.c
├── tps6524x-regulator.c
├── tps6586x-regulator.c
├── tps65910-regulator.c
├── tps65912-regulator.c
├── tps80031-regulator.c
├── twl-regulator.c
├── userspace-consumer.c
├── vexpress-regulator.c
├── virtual.c
├── virtual.o
├── wm831x-dcdc.c
├── wm831x-isink.c
├── wm831x-ldo.c
├── wm8350-regulator.c
├── wm8400-regulator.c
└── wm8994-regulator.c
board.dts
- regulator-name : regulator 名称
- regulator-min-microvolt : 可调节的最小电压
- regulator-max-microvolt : 可调节的最大电压
- regulator-microvolt-offset : 电压补偿值
- regulator-min-microamp : 可调节输出的最小电流
- regulator-max-microamp : 可调节输出的最大电流
- regulator-always-on : regulator不能被disable
- regulator-boot-on : 初始化后enable该regulator
-
-supply : 引用为该regulator供电的设备(可以是另一个regulator)的dts节点, - regulator-ramp-delay : 调节的速度(in uV/uS)
regulator0: regulators@0 {
reg_dcdc1: dcdc1 {
regulator-name = "axp803-dcdc1";
regulator-min-microvolt = <1600000>;
regulator-max-microvolt = <3400000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
regulator-boot-on;
regulator-always-on;
};
reg_dcdc2: dcdc2 {
regulator-name = "axp803-dcdc2";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1300000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
regulator-boot-on;
regulator-always-on;
};
reg_dcdc3: dcdc3 {
regulator-name = "axp803-dcdc3";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1300000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
regulator-boot-on;
regulator-always-on;
};
reg_dcdc4: dcdc4 {
regulator-name = "axp803-dcdc4";
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1300000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
regulator-boot-on;
regulator-always-on;
};
reg_dcdc5: dcdc5 {
regulator-name = "axp803-dcdc5";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1840000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
regulator-always-on;
};
reg_dcdc6: dcdc6 {
regulator-name = "axp803-dcdc6";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1520000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
};
reg_dcdc7: dcdc7 {
regulator-name = "axp803-dcdc7";
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <1520000>;
regulator-ramp-delay = <2500>;
regulator-enable-ramp-delay = <1000>;
};
reg_rtcldo: rtcldo {
/* RTC_LDO is a fixed, always-on regulator */
regulator-name = "axp803-rtcldo";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
};
reg_aldo1: aldo1 {
regulator-name = "axp803-aldo1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
regulator-boot-on;
regulator-always-on;
};
reg_aldo2: aldo2 {
regulator-name = "axp803-aldo2";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
regulator-always-on;
};
reg_aldo3: aldo3 {
regulator-name = "axp803-aldo3";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
regulator-always-on;
regulator-boot-on;
};
reg_dldo1: dldo1 {
regulator-name = "axp803-dldo1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
};
reg_dldo2: dldo2 {
regulator-name = "axp803-dldo2";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <4200000>;
regulator-enable-ramp-delay = <1000>;
};
reg_dldo3: dldo3 {
regulator-name = "axp803-dldo3";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
regulator-always-on;
regulator-boot-on;
};
reg_dldo4: dldo4 {
regulator-name = "axp803-dldo4";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
};
reg_eldo1: eldo1 {
regulator-name = "axp803-eldo1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1900000>;
regulator-enable-ramp-delay = <1000>;
};
reg_eldo2: eldo2 {
regulator-name = "axp803-eldo2";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1900000>;
regulator-enable-ramp-delay = <1000>;
};
reg_eldo3: eldo3 {
regulator-name = "axp803-eldo3";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1900000>;
regulator-enable-ramp-delay = <1000>;
};
reg_fldo1: fldo1 {
regulator-name = "axp803-fldo1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1450000>;
regulator-enable-ramp-delay = <1000>;
regulator-always-on;
};
reg_fldo2: fldo2 {
regulator-name = "axp803-fldo2";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1450000>;
regulator-enable-ramp-delay = <1000>;
};
reg_ldoio0: ldoio0 {
regulator-name = "axp803-ldoio0";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
};
reg_ldoio1: ldoio1 {
regulator-name = "axp803-ldoio1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <1000>;
};
reg_dc1sw: dc1sw {
regulator-name = "axp803-dc1sw";
regulator-enable-ramp-delay = <1000>;
};
reg_drivevbus: drivevbus {
regulator-name = "axp803-drivevbus";
regulator-enable-ramp-delay = <1000>;
};
};
调试
$ ls sys/class/regulator/
regulator.0/ regulator.10/ regulator.12/ regulator.14/ regulator.16/ regulator.18/ regulator.2/ regulator.21/ regulator.23/ regulator.25/ regulator.4/ regulator.6/ regulator.8/
regulator.1/ regulator.11/ regulator.13/ regulator.15/ regulator.17/ regulator.19/ regulator.20/ regulator.22/ regulator.24/ regulator.3/ regulator.5/ regulator.7/ regulator.9/
$ ls sys/class/regulator/regulator.1/
5200000.ehci1-controller-drvvbus device name of_node state suspend_disk_state suspend_standby_state uevent
5200000.ohci1-controller-drvvbus microvolts num_users power subsystem suspend_mem_state type
$ cat ./sys/kernel/debug/regulator/regulator_summary
regulator use open bypass voltage current min max
-------------------------------------------------------------------------------
regulator-dummy 0 6 0 0mV 0mA 0mV 0mV
uart3 0mV 0mV
uart2 0mV 0mV
uart1 0mV 0mV
twi3 0mV 0mV
twi1 0mV 0mV
twi6 0mV 0mV
usb1-vbus 1 2 0 5000mV 0mA 5000mV 5000mV
5200000.ohci1-controller 0mV 0mV
5200000.ehci1-controller 0mV 0mV
axp803-dcdc1 0 3 0 3300mV 0mA 1600mV 3400mV
sdc2 0mV 0mV
uart0 0mV 0mV
reg-virt-consumer.1 0mV 0mV
axp803-dcdc2 0 2 0 960mV 0mA 500mV 1300mV
cpu0 960mV 960mV
reg-virt-consumer.2 0mV 0mV
axp803-dcdc3 0 1 0 900mV 0mA 500mV 1300mV
reg-virt-consumer.3 0mV 0mV
axp803-dcdc4 0 2 0 920mV 0mA 500mV 1300mV
gpu 0mV 0mV
reg-virt-consumer.4 0mV 0mV
axp803-dcdc5 0 1 0 1100mV 0mA 800mV 1840mV
reg-virt-consumer.5 0mV 0mV
axp803-dcdc6 0 1 0 900mV 0mA 600mV 1520mV
reg-virt-consumer.6 0mV 0mV
axp803-dcdc7 0 1 0 1280mV 0mA 800mV 1520mV
reg-virt-consumer.7 0mV 0mV
axp803-rtcldo 0 1 0 1800mV 0mA 1800mV 1800mV
reg-virt-consumer.8 0mV 0mV
axp803-aldo1 0 2 0 1800mV 0mA 700mV 3300mV
codec 1800mV 1800mV
reg-virt-consumer.9 0mV 0mV
axp803-aldo2 0 1 0 1800mV 0mA 700mV 3300mV
reg-virt-consumer.10 0mV 0mV
axp803-aldo3 0 1 0 1800mV 0mA 700mV 3300mV
reg-virt-consumer.11 0mV 0mV
axp803-dldo1 1 1 0 1800mV 0mA 700mV 3300mV
reg-virt-consumer.12 0mV 0mV
axp803-dldo2 0 2 0 1800mV 0mA 700mV 4200mV
reg-virt-consumer.13 0mV 0mV
twi2 0mV 0mV
axp803-dldo3 0 1 0 1800mV 0mA 700mV 3300mV
reg-virt-consumer.14 0mV 0mV
axp803-dldo4 0 1 0 1800mV 0mA 700mV 3300mV
reg-virt-consumer.15 0mV 0mV
axp803-eldo1 2 3 0 1800mV 0mA 700mV 1900mV
codec 1800mV 1800mV
sdc2 0mV 0mV
reg-virt-consumer.16 0mV 0mV
axp803-eldo2 0 1 0 1800mV 0mA 700mV 1900mV
reg-virt-consumer.17 0mV 0mV
axp803-eldo3 0 1 0 1800mV 0mA 700mV 1900mV
reg-virt-consumer.18 0mV 0mV
axp803-fldo1 0 1 0 900mV 0mA 700mV 1450mV
reg-virt-consumer.19 0mV 0mV
axp803-fldo2 0 1 0 800mV 0mA 700mV 1450mV
reg-virt-consumer.20 0mV 0mV
axp803-ldoio0 1 2 0 3300mV 0mA 700mV 3300mV
1-005d 3300mV 3300mV
reg-virt-consumer.21 0mV 0mV
axp803-ldoio1 0 1 0 3300mV 0mA 700mV 3300mV
reg-virt-consumer.22 0mV 0mV
axp803-dc1sw 1 1 0 0mV 0mA 0mV 0mV
reg-virt-consumer.23 0mV 0mV
axp803-drivevbus 0 1 0 0mV 0mA 0mV 0mV
reg-virt-consumer.24 0mV 0mV