zoukankan      html  css  js  c++  java
  • 探究platform_driver中的shutdown用途

    我们看到很多驱动中都没有设置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:唤醒

  • 相关阅读:
    [Zjoi2014]力(FFT,卷积)
    LOJ 6240. 仙人掌
    Web 服务编程技巧和诀窍: 将 <xsd:any/> 元素用于自定义序列化(转)
    Ant工具使用说明(转)
    Web 服务编程技巧与窍门: 用 SAAJ 和 JAXRPC 构建 SOAP 响应信封(转)
    Axis2 quick start 中文版
    使用SOAP开发java web服务Axis开发方案(转)
    k 动画脚本很有算法 同时可以借鉴这里的画圆
    ui 界面美观化 (多维子材质脚本)
    系类函数介绍 之中可能没有一些预订变量 应用时要自己加上。
  • 原文地址:https://www.cnblogs.com/swnuwangyun/p/4233672.html
Copyright © 2011-2022 走看看