电源管理

一、PM 框架

System Sleep (suspend-to-RAM / disk)
   ↓
CPU Idle (cpuidle)
   ↓
Runtime PM (设备空闲自动断电)
   ↓
Regulator(电压调节)
   ↓
Clock(门控)
   ↓
硬件

二、Runtime PM

设备运行时电源管理:
- pm_runtime_get_sync(dev):增加引用计数 + 恢复设备
- pm_runtime_put(dev):减少引用计数
- 引用归零后自动 suspend

// 在 driver 中:
pm_runtime_enable(dev);

// 业务中使用:
pm_runtime_get_sync(dev);
// 访问硬件
pm_runtime_put(dev);

// 回调
static int my_runtime_suspend(struct device *dev)
{
    // 关时钟、断电
    return 0;
}
static int my_runtime_resume(struct device *dev)
{
    // 开时钟、上电
    return 0;
}
static const struct dev_pm_ops my_pm_ops = {
    SET_RUNTIME_PM_OPS(my_runtime_suspend, my_runtime_resume, NULL)
};

static struct platform_driver my_driver = {
    .driver = {
        .pm = &my_pm_ops,
        // ...
    },
};

sysfs 控制:

ls /sys/devices/.../power/
echo enabled > /sys/devices/.../power/runtime_control
echo auto > /sys/devices/.../power/runtime_status

三、System Suspend / Resume

static int my_suspend(struct device *dev)
{
    // 保存上下文、关设备
    return 0;
}

static int my_resume(struct device *dev)
{
    // 恢复上下文、唤醒设备
    return 0;
}

static const struct dev_pm_ops my_pm_ops = {
    SET_SYSTEM_SLEEP_PM_OPS(my_suspend, my_resume)
};

挂起类型:
- MEM(suspend-to-RAM):保留内存,断电其他
- STANDY:浅挂起
- DISK(Hibernate):保存到磁盘
- FREEZE:冻结进程,调度器停

操作:

echo mem > /sys/power/state
echo standby > /sys/power/state

四、CPU Idle

查看:

cpuidle-info
cat /sys/devices/system/cpu/cpu0/cpuidle/*

关闭空闲:

echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state0/disable

五、CPU 热插拔

echo 0 > /sys/devices/system/cpu/cpu1/online     # 关 CPU1
echo 1 > /sys/devices/system/cpu/cpu1/online     # 开

自动管理:CONFIG_HOTPLUG_CPU=yCPU_FREQ_GOV_ONDEMAND

六、CPUFreq(频率调节)

governor(策略):
- performance:一直最高频
- powersave:一直最低频
- ondemand:按负载升降
- conservative:保守升降
- schedutil:由调度器决定(默认)

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

七、Regulator(电压调节)

struct regulator *vreg = devm_regulator_get(dev, "vdd");
regulator_enable(vreg);
regulator_disable(vreg);
int v = regulator_get_voltage(vreg);
regulator_set_voltage(vreg, 1200000, 1200000);   // uV

设备树:

mydevice {
    vdd-supply = <&reg_vdd>;
};

八、Clock(时钟)

struct clk *clk = devm_clk_get(dev, "ipg");
clk_prepare_enable(clk);
clk_disable_unprepare(clk);
unsigned long rate = clk_get_rate(clk);
clk_set_rate(clk, 100000000);

设备树:

mydevice {
    clocks = <&clks IMX6UL_CLK_UART1_IPG>;
    clock-names = "ipg";
};

九、Thermal(热管理)

cat /sys/class/thermal/thermal_zone0/temp      # 毫摄氏度
cat /sys/class/thermal/cooling_device0/cur_state

十、嵌入式 PM 注意点