You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux设备驱动在系统关机时会调用哪个回调函数

核心结论

用户空间执行poweroff/shutdown命令触发系统关机流程时,你之前使用的struct dev_pm_ops中定义的suspend/resume系列回调不会被调用,设备驱动模型提供了专门的.shutdown回调用于响应关机、重启事件,外部模块形式的驱动也可以正常注册使用。

回调注册方式
  • 设备驱动通用注册方法:无论驱动是编译进内核还是以外部模块加载,只需要在对应驱动的结构体中填充.shutdown成员即可,内核在关机流程中会遍历所有已注册的设备,按设备拓扑顺序调用对应驱动的该回调。
    参考代码示例:
    static void my_dev_shutdown(struct device *dev)
    {
        // 此处填写关机时需要执行的硬件复位、关键状态保存、资源清理逻辑
        pr_info("my device: shutdown callback invoked\n");
    }
    
    static struct dev_pm_ops my_dev_pm_ops = {
        .suspend = my_dev_suspend,
        .resume = my_dev_resume,
        // 原有挂起/恢复回调保持不变
    };
    
    static struct device_driver my_dev_driver = {
        .name = "my_dev",
        .bus = &platform_bus_type, // 根据设备实际挂载的总线类型修改
        .shutdown = my_dev_shutdown, // 注册关机回调
        .pm = &my_dev_pm_ops,
    };
    
  • 子系统封装驱动适配:如果是平台驱动、PCI驱动、USB驱动等内核子系统已经封装好的驱动结构,对应结构中直接提供了同级的.shutdown成员,比如struct platform_driver中,.shutdown和.probe、.remove是同级成员,直接填充后随驱动注册即可生效,不需要手动操作底层device_driver结构。
  • 全局事件通知可选方案:如果你的逻辑不绑定具体硬件设备,需要响应全局关机/重启事件,可以调用register_reboot_notifier()接口注册重启通知链回调,该回调会在设备.shutdown回调之前执行。但设备相关的逻辑优先使用设备自带的.shutdown回调,内核设备模型会保证子设备先于父设备执行回调,避免出现父设备提前下电导致子设备访问异常的问题。
场景区分注意

不要和其他驱动回调的触发场景混淆:

  • 系统挂起到内存(suspend to RAM)、休眠到硬盘(hibernate)、恢复场景,走struct dev_pm_ops中注册的suspend/resume相关回调
  • 系统关机(poweroff/halt)、重启(reboot)场景,走.shutdown回调
  • 驱动手动卸载(执行rmmod/modprobe -r)场景,走.remove回调,和关机流程独立,不要将必须的硬件清理逻辑只放在.remove回调中
外部模块开发注意事项
  • 注册.shutdown回调不需要额外的特殊操作,只要在驱动注册(如platform_driver_register()、driver_register())前完成回调填充,模块加载后回调就会自动被纳入内核关机调用链,行为和内置驱动完全一致。
  • .shutdown回调执行时,内核已经停止了大部分用户态进程和内核线程,内存分配、锁等待等操作很容易失败,回调逻辑要尽量精简,只做必须的硬件操作,不要执行耗时过长、依赖其他服务的逻辑。

内容的提问来源于stack exchange,提问作者fadhel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 09:36:26