详解Linux2.6内核中基于platform机制的驱动模型 (经典) (4)


316/**
 317 * platform_device_register - add a platform-level device
 318 * @pdev: platform device we\'re adding
 319 */
 320int platform_device_register(struct platform_device *pdev)
 321{
 322        device_initialize(&pdev->dev);
 323        return platform_device_add(pdev);
 324}
 325EXPORT_SYMBOL_GPL(platform_device_register);

我们看到注册一个platform device分为了两部分,初始化这个platform_device,然后将此platform_device添加到platform总线中。输入参数platform_device可以是静态的全局设备。

另外一种机制就是动态申请platform_device_alloc一个platform_device设备,然后通过platform_device_add_resources及platform_device_add_data等添加相关资源和属性。

无论哪一种platform_device,最终都将通过platform_device_add注册到platform总线上。

229/**
 230 * platform_device_add - add a platform device to device hierarchy
 231 * @pdev: platform device we\'re adding
 232 *
 233 * This is part 2 of platform_device_register(), though may be called
 234 * separately _iff_ pdev was allocated by platform_device_alloc().
 235 */
 236int platform_device_add(struct platform_device *pdev)
 237{
 238        int i, ret = 0;
 239
 240        if (!pdev)
 241                return -EINVAL;
 242
               初始化设备的parent为platform_bus,初始化设备的总线为platform_bus_type。
 243        if (!pdev->dev.parent)
 244                pdev->dev.parent = &platform_bus;
 245
 246        pdev->dev.bus = &platform_bus_type;
 247
/*++++++++++++++
The platform_device.dev.bus_id is the canonical name for the devices.
It\'s built from two components:

* platform_device.name ... which is also used to for driver matching.
* platform_device.id ... the device instance number, or else "-1"
to indicate there\'s only one.

These are concatenated, so name/id "serial"/0 indicates bus_id "serial.0", and
"serial/3" indicates bus_id "serial.3"; both would use the platform_driver
named "serial". While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id)
and use the platform_driver called "my_rtc".
++++++++++++++*/
 248        if (pdev->id != -1)
 249                snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,
 250                         pdev->id);
 251        else
 252                strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
 253
                设置设备struct device 的bus_id成员,留心这个地方,在以后还需要用到这个的。
 254        for (i = 0; i < pdev->num_resources; i++) {
 255                struct resource *p, *r = &pdev->resource[i];
 256
 257                if (r->name == NULL)
 258                        r->name = pdev->dev.bus_id;
 259
 260                p = r->parent;
 261                if (!p) {
 262                        if (r->flags & IORESOURCE_MEM)
 263                                p = &iomem_resource;
 264                        else if (r->flags & IORESOURCE_IO)
 265                                p = &ioport_resource;
 266                }
                       //resources分为两种IORESOURCE_MEM和IORESOURCE_IO
                      //CPU对外设IO端口物理地址的编址方式有两种:I/O映射方式和内存映射方式
 267
 268                if (p && insert_resource(p, r)) {
 269                        printk(KERN_ERR
 270                               "%s: failed to claim resource %d/n",
 271                               pdev->dev.bus_id, i);
 272                        ret = -EBUSY;
 273                        goto failed;
 274                }
 275        }
 276
 277        pr_debug("Registering platform device \'%s\'. Parent at %s/n",
 278                 pdev->dev.bus_id, pdev->dev.parent->bus_id);
 279
 280        ret = device_add(&pdev->dev);
 281        if (ret == 0)
 282                return ret;
 283
 284 failed:
 285        while (--i >= 0)
 286                if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))
 287                        release_resource(&pdev->resource[i]);
 288        return ret;
 289}
 290EXPORT_SYMBOL_GPL(platform_device_add);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjjds.html