惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
Intezer
V
Vulnerabilities – Threatpost
Google Online Security Blog
Google Online Security Blog
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
AWS News Blog
AWS News Blog
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
Cybersecurity and Infrastructure Security Agency CISA
N
News | PayPal Newsroom
T
Tenable Blog
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Secure Thoughts
P
Privacy International News Feed
IT之家
IT之家
Project Zero
Project Zero
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
博客园_首页
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
量子位
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
Hacker News: Ask HN
Hacker News: Ask HN
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
NISL@THU
NISL@THU
I
InfoQ
D
DataBreaches.Net
有赞技术团队
有赞技术团队
K
Kaspersky official blog
Security Latest
Security Latest
The Register - Security
The Register - Security
Hugging Face - Blog
Hugging Face - Blog
S
Security @ Cisco Blogs
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
AI
AI
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic

博客园 - woaiusd

claude各种客户端的关系 pytorch对大模型推理,实现简单的对话 Agent原理与模拟 为红米Note 5 Pro编译Lineage OS 15.1的各种坑 C语言调用DIRECT3D的实例代码,通过lpVtbl字段进行 OBS插件学习入门:一个非常简单的、调节音量的filter 从工程角度看C++观察者模式中的接口是否需要提供默认的实现 Windows音频SDK的发展历程 闲话__stdcall, __cdecl, __fastcall出现的历史背景以及各自解决的问题 为什么需要超出48K的音频采样率,以及PCM到DSD的演进 wireshark使用笔记 managed_shared_memory.construct造成的性能损失 java.lang.NullPointerException Ubuntu中QT使用FFmpeg的奇怪问题 QT开启C++11的支持 尝鲜CodeBlocks ops中set_sysclk set_clkdiv set_pll详解 在内核中异步请求设备固件firmware的测试代码 探究MaxxBass音效 Alsa驱动snd_soc_read的底层实现 Device Drivers Should Not Do Power Management 探究platform_driver中“多态”思想
探究platform_driver中的shutdown用途
woaiusd · 2015-01-19 · via 博客园 - woaiusd

我们看到很多驱动中都没有设置shutdown回调函数,只提供了probe和remove回调函数:

static struct platform_driver wm8400_codec_driver = {
    .driver = {
           .name = "wm8400-codec",
           .owner = THIS_MODULE,
           },
    .probe = wm8400_probe,
    .remove = __devexit_p(wm8400_remove),
};
static struct platform_driver pcm3008_codec_driver = {
    .probe        = pcm3008_codec_probe,
    .remove        = __devexit_p(pcm3008_codec_remove),
    .driver        = {
        .name    = "pcm3008-codec",
        .owner    = THIS_MODULE,
    },
};

但是platform_driver中是有shutdown字段的,http://www.makelinux.net/ldd3/chp-14-sect-4 中有如下的描述:

Once again, several of the structure's fields have been omitted (see <linux/device.h> for the full story). Here, name is the name of the driver (it shows up in sysfs), bus is the type of bus this driver works with, kobj is the inevitable kobject, devices is a list of all devices currently bound to this driver, probe is a function called to query the existence of a specific device (and whether this driver can work with it), remove is called when the device is removed from the system, and shutdown is called at shutdown time to quiesce the device.

“quiesce” 说的也不太明确,我的猜测是:比如系统中有一个大功率的设备,在“软关机”的时候,会调用这个函数,可以在这个函数中切断这个设备的电源,从而省电。因为软关机后,机器本身是还有电的,并没有拔电源。

在内核中找了一个例子drivers/char/sonypi.c:

static struct platform_driver sonypi_driver = {
    .driver        = {
        .name    = "sonypi",
        .owner    = THIS_MODULE,
    },
    .probe        = sonypi_probe,
    .remove        = __devexit_p(sonypi_remove),
    .shutdown    = sonypi_shutdown,
    .suspend    = sonypi_suspend,
    .resume        = sonypi_resume,
};

其remove, shutdown, suspend的实现都差不多,就是禁用设备:

static int sonypi_suspend(struct platform_device *dev, pm_message_t state)
{
    old_camera_power = sonypi_device.camera_power;
    sonypi_disable();

    return 0;
}
static void sonypi_shutdown(struct platform_device *dev)
{
    sonypi_disable();
}
static int __devexit sonypi_remove(struct platform_device *dev)
{
    sonypi_disable();

    synchronize_irq(sonypi_device.irq);
    flush_work_sync(&sonypi_device.input_work);

    if (useinput) {
        input_unregister_device(sonypi_device.input_key_dev);
        input_unregister_device(sonypi_device.input_jog_dev);
        kfifo_free(&sonypi_device.input_fifo);
    }

    misc_deregister(&sonypi_misc_device);

    free_irq(sonypi_device.irq, sonypi_irq);
    release_region(sonypi_device.ioport1, sonypi_device.region_size);

    if (sonypi_device.dev) {
        pci_disable_device(sonypi_device.dev);
        pci_dev_put(sonypi_device.dev);
    }

    kfifo_free(&sonypi_device.fifo);

    return 0;
}


三个函数都调用了sony_disable函数,remove做了更多的清理工作。

有一个驱动更绝drivers/char/ps3flash.c,其remove和shudown函数是公用的。

static struct ps3_system_bus_driver ps3flash = {
    .match_id    = PS3_MATCH_ID_STOR_FLASH,
    .core.name    = DEVICE_NAME,
    .core.owner    = THIS_MODULE,
    .probe        = ps3flash_probe,
    .remove        = ps3flash_remove,
    .shutdown    = ps3flash_remove,
};

难怪大部分的驱动都不提供这个shutdown函数,一方面是确实没有必要,另一方面关机后就什么都不管了:)

看了另外一篇文章后,补充一点:

shutdown: 彻底关电

suspend:休眠,可能是低功耗状态

resume:唤醒