• 驱动开发学习笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇


                        驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇

    下面这段摘自 linux源码里面的文档 :  内核版本2.6.22
    Documentation/driver-model/platform.txt
    找到一篇译文:http://blog.csdn.net/yili_xie/article/details/5193609
    复制代码
    Device Enumeration
      82 ~~~~~~~~~~~~~~~~~~
      83 As a rule, platform specific (and often board-specific) setup code will
      84 register platform devices:
      85
      86        int platform_device_register(struct platform_device *pdev);
      87
      88        int platform_add_devices(struct platform_device **pdevs, int ndev);
      89
      90 The general rule is to register only those devices that actually exist,
      91 but in some cases extra devices might be registered.  For example, a kernel
      92 might be configured to work with an external network adapter that might not
      93 be populated on all boards, or likewise to work with an integrated controller
      94 that some boards might not hook up to any peripherals.
      95
      96 In some cases, boot firmware will export tables describing the devices
      97 that are populated on a given board.   Without such tables, often the
      98 only way for system setup code to set up the correct devices is to build
      99 a kernel for a specific target board.  Such board-specific kernels are
     100 common with embedded and custom systems development.
     101
     102 In many cases, the memory and IRQ resources associated with the platform
     103 device are not enough to let the device's driver work.  Board setup code
     104 will often provide additional information using the device's platform_data
     105 field to hold additional information.
     106
     107 Embedded systems frequently need one or more clocks for platform devices,
     108 which are normally kept off until they're actively needed (to save power).
     109 System setup also associates those clocks with the device, so that that
     110 calls to clk_get(&pdev->dev, clock_name) return them as needed.
     111
     112
     113 Legacy Drivers:  Device Probing
     114 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     115 Some drivers are not fully converted to the driver model, because they take
     116 on a non-driver role:  the driver registers its platform device, rather than
     117 leaving that for system infrastructure.  Such drivers can't be hotplugged
     118 or coldplugged, since those mechanisms require device creation to be in a
     119 different system component than the driver.
     120
     121 The only "good" reason for this is to handle older system designs which, like
     122 original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware
     123 configuration.  Newer systems have largely abandoned that model, in favor of
     124 bus-level support for dynamic configuration (PCI, USB), or device tables
     125 provided by the boot firmware (e.g. PNPACPI on x86).  There are too many
     126 conflicting options about what might be where, and even educated guesses by
     127 an operating system will be wrong often enough to make trouble.
     128
     129 This style of driver is discouraged.  If you're updating such a driver,
     130 please try to move the device enumeration to a more appropriate location,
     131 outside the driver.  This will usually be cleanup, since such drivers
     132 tend to already have "normal" modes, such as ones using device nodes that
     133 were created by PNP or by platform device setup.
     134
     135 None the less, there are some APIs to support such legacy drivers.  Avoid
     136 using these calls except with such hotplug-deficient drivers.
     137
     138        struct platform_device *platform_device_alloc(
     139                        const char *name, int id);
     140
     141 You can use platform_device_alloc() to dynamically allocate a device, which
     142 you will then initialize with resources and platform_device_register().
     143 A better solution is usually:
     144
     145        struct platform_device *platform_device_register_simple(
     146                        const char *name, int id,
     147                        struct resource *res, unsigned int nres);
     148
     149 You can use platform_device_register_simple() as a one-step call to allocate
     150 and register a device.
    复制代码

    上一篇文章讲的是第一种platform设备注册方式http://www.cnblogs.com/simonlin/p/5933010.html

    这一篇讲的是

    Legacy Drivers:  Device Probing

    内核开发者们并不推荐这种方法,但是我们使用这种方法来动态加载platform设备模块
    文档里面提到有两个函数
    struct platform_device *platform_device_alloc(const char *name, int id);

     struct platform_device *platform_device_register_simple(const char *name, int id, struct resource *res, unsigned int nres);


    platform_device_register_simple函数定义(drivers/base/platform.c)

    struct platform_device *platform_device_register_simple(char *name, unsigned int id,
     374                                                        struct resource *res, unsigned int num)
     375{
     376        struct platform_device *pdev;
     377        int retval;
     378
     379        pdev = platform_device_alloc(name, id);
     380        if (!pdev) {
     381                retval = -ENOMEM;
     382                goto error;
     383        }
     384
     385        if (num) {
     386                retval = platform_device_add_resources(pdev, res, num);
     387                if (retval)
     388                        goto error;
     389        }
     390
     391        retval = platform_device_add(pdev);
     392        if (retval)
     393                goto error;
     394
     395        return pdev;
     396
     397 error:
     398        platform_device_put(pdev);
     399        return ERR_PTR(retval);
     400}
    我们发现 原来platform_device_register_simple中调用了platform_device_alloc
    pdev = platform_device_alloc(name, id);

    并且还注册了platform设备
    retval = platform_device_add(pdev);


    所以,我们想要动态的注册platfrom_device 只需调用
    platform_device_register_simple函数即可

    输入参数为 设备名称,id , 资源 和 资源数量
    *      platform_device_register_simple
    *      @name:  base name of the device we're adding
    *      @id:    instance id
    *      @res:   set of resources that needs to be allocated for the device
    *      @num:   number of resources
     



    例子:drivers/leds/leds-net48xx.c
    这是一个led 的 platform 驱动程序
       1/*
       2 * LEDs driver for Soekris net48xx
       3 *
       4 * Copyright (C) 2006 Chris Boot <bootc@bootc.net>
       5 *
       6 * Based on leds-ams-delta.c
       7 *
       8 * This program is free software; you can redistribute it and/or modify
       9 * it under the terms of the GNU General Public License version 2 as
      10 * published by the Free Software Foundation.
      11 */
    ……
    ……
    ……
      56 static int net48xx_led_probe(struct platform_device *pdev)
      57 {
      58        return led_classdev_register(&pdev->dev, &net48xx_error_led);
      59 }
    ……
    ……
    ……

    static int __init net48xx_led_init(void) 79 { 80 int ret; 81 82 /* small hack, but scx200_gpio doesn't set .dev if the probe fails */ 83 if (!scx200_gpio_ops.dev) { 84 ret = -ENODEV; 85 goto out; 86 } 87 88 ret = platform_driver_register(&net48xx_led_driver); 89 if (ret < 0) 90 goto out; 91 92 pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); 93 if (IS_ERR(pdev)) { 94 ret = PTR_ERR(pdev); 95 platform_driver_unregister(&net48xx_led_driver); 96 goto out; 97 } 98 99 out: 100 return ret; 101}
    ……
    ……
    ……
     
    可以看到,led的platform设备是在驱动里面注册的。
    而驱动 的 探测函数 probe 注册了一个led类设备

    注:此函数没有提供添加平台数据的方法。

    可以尝试在注册设备之前手动添加平台数据,但此方法未成验证。




  • 相关阅读:
    L3-013. 非常弹的球
    L2-020. 功夫传人
    L1-039. 古风排版
    Innobackup备份过程
    MySQL物理备份的过程
    数据库表设计
    MySQL启动排错
    redo的类型和作用
    描述undo的三个作用
    redo log和binlog的纠缠
  • 原文地址:https://www.cnblogs.com/simonlin/p/5933748.html
Copyright © 2020-2023  润新知