驱动的注册过程和设备的注册过程(转载)

作者:Dongas

日期:08-06-28

platform_device_register()注册过程

------------------------------------

/* arch/arm/mach-s3c2410/mach-smdk2410.c */

struct platform_device s3c_device_i2c = {

         .name                  = "s3c2410-i2c",

         .id                     = -1,

         .num_resources          = ARRAY_SIZE(s3c_i2c_resource),

         .resource   = s3c_i2c_resource,

};

/*

* platform_device_register - add a platform-level device

* @pdev: platform device we're adding**/

int platform_device_register(struct platform_device * pdev)

{

    device_initialize(&pdev->dev);        //初始化设备结构

    return platform_device_add(pdev); //添加一个片上的设备到设备层

}

/**

 * platform_device_add - add a platform device to device hierarchy

 * @pdev: platform device we're adding *

 * This is part 2 of platform_device_register(), though may be called

 * separately _iff_ pdev was allocated by platform_device_alloc().

 */

int platform_device_add(struct platform_device *pdev)

{

         int i, ret = 0;

         if (!pdev)

         return -EINVAL;

         if (!pdev->dev.parent)

         pdev->dev.parent = &platform_bus;

         pdev->dev.bus = &platform_bus_type;

         if (pdev->id != -1)

                   snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,

                             pdev->id);       /* 若支持同类多个设备,则用pdev->namepdev->id在总线上标识该设备  */

         else

                   strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE); /* 否则,用pdev->name("s3c2410-i2c")在总线上标识该设备 */

 

         for (i = 0; i < pdev->num_resources; i++) {       /*  遍历资源数,并为各自在总线地址空间请求分配 */

                   struct resource *p, *r = &pdev->resource[i];

                   if (r->name == NULL)

                            r->name = pdev->dev.bus_id;

                   p = r->parent;

                   if (!p) {

                            if (r->flags & IORESOURCE_MEM)

                                     p = &iomem_resource;   /*  作为IO内存资源分配   */

                            else if (r->flags & IORESOURCE_IO)

                                     p = &ioport_resource;     /*  作为IO Port资源分配   */

                   }

                  if (p && insert_resource(p, r)) {       /*   将新的resource插入内核resource tree */

                            printk(KERN_ERR

                                   "%s: failed to claim resource %d/n",

                                   pdev->dev.bus_id, i);

                            ret = -EBUSY;

                            goto failed;

                   }

         }

         pr_debug("Registering platform device '%s'. Parent at %s/n",

                    pdev->dev.bus_id, pdev->dev.parent->bus_id);

         ret = device_add(&pdev->dev);

         if (ret == 0)

                   return ret;

 failed:

         while (--i >= 0)

                   if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))

                            release_resource(&pdev->resource[i]);

         return ret;

}

这里发现,添加device到内核最终还是调用的device_add函数。Platform_device_adddevice_add最主要的区别是多了一步insert_resource(p, r)即将platform资源(resource)添加进内核,由内核统一管理。

platform_driver_register()注册过程

--------------------------------------

static struct platform_driver s3c2410_i2c_driver = {

         .probe                = s3c24xx_i2c_probe,

         .remove              = s3c24xx_i2c_remove,

         .resume              = s3c24xx_i2c_resume,

         .driver                = {

                   .owner     = THIS_MODULE,

                   .name       = "s3c2410-i2c",

         },

};

platform_driver_register(&s3c2410fb_driver)----->

driver_register(&drv->driver)----->

bus_add_driver(drv)----->

driver_attach(drv)----->

bus_for_each_dev(drv->bus, NULL, drv, __driver_attach)----->

__driver_attach(struct device * dev, void * data)----->

driver_probe_device(drv, dev)----->

really_probe(dev, drv)----->

really_probe()中:为设备指派管理该设备的驱动:dev->driver = drv, 调用probe()函数初始化设备:drv->probe(dev)

注:Platform_devicePlatform_driver的使用请参考这篇文章:

Linux Platform Device and Driver

http://blog.chinaunix.net/u2/60011/showart.php?id=1018502

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核UART设备驱动注册流程如下: 1. 分配tty_driver结构体 在驱动初始化时,首先需要分配一个tty_driver结构体,该结构体描述了tty设备驱动属性信息,包括驱动名称、打开、关闭、读写等操作的回调函数指针等。 2. 注册tty_driver 调用tty_register_driver函数,将tty_driver结构体注册到内核中,该函数会将tty_driver结构体添加到tty_drivers链表中,同时会创建一个tty_class结构体和一个tty_class_dev结构体,并将其关联起来。 3. 创建tty设备节点 调用tty_register_device函数,该函数会根据tty_driver结构体中的信息创建tty设备节点,并将其添加到tty_drivers链表中。 4. 设置tty设备驱动回调函数 在tty_driver结构体中设置相应的驱动回调函数,例如open、close、read、write等操作的回调函数指针。 5. 注册tty设备驱动与硬件设备的关联 在驱动初始化时,需要将tty设备驱动与硬件设备进行关联,通常是通过platform_device_register函数将platform_device结构体注册到内核中,并调用platform_driver_register函数将platform_driver结构体注册到内核中。 6. 实现tty设备驱动回调函数 在驱动初始化时,需要实现相应的tty设备驱动回调函数,例如open、close、read、write等操作的回调函数。当用户调用相应的操作时,内核会自动调用相应的回调函数执行相应的操作。 7. 注销tty设备驱动驱动卸载时,需要调用tty_unregister_driver函数注销tty_driver结构体,并释放相关资源。同时也需要注销与硬件设备的关联关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值