Linux设备模型--platform
来源:互联网 发布:mac网页内容抓取工具 编辑:程序博客网 时间:2024/05/02 06:45
http://blog.csdn.net/woshixingaaa/archive/2011/05/21/6436172.aspx
首先看一下我的系统中都有什么设备挂在了platform虚拟总线上:
- hacker@hacker:~/linux-2.6.30.4$ cd /sys/bus/platform/
- hacker@hacker:/sys/bus/platform$ tree
- .
- |-- devices
- | |-- Fixed MDIO bus.0 -> ../../../devices/platform/Fixed MDIO bus.0
- | |-- eisa.0 -> ../../../devices/platform/eisa.0
- | |-- i8042 -> ../../../devices/platform/i8042
- | |-- pcspkr -> ../../../devices/platform/pcspkr
- | |-- rtc_cmos -> ../../../devices/platform/rtc_cmos
- | `-- serial8250 -> ../../../devices/platform/serial8250
- |-- drivers
- | |-- dsa
- | | |-- bind
- | | |-- uevent
- | | `-- unbind
- | |-- i8042
- | | |-- bind
- | | |-- i8042 -> ../../../../devices/platform/i8042
- | | |-- uevent
- | | `-- unbind
- | |-- mdio-gpio
- | | |-- bind
- | | |-- uevent
- | | `-- unbind
- | |-- parport_pc
- | | |-- bind
- | | |-- module -> ../../../../module/parport_pc
- | | |-- uevent
- | | `-- unbind
- | |-- rtc_cmos
- | | |-- bind
- | | |-- rtc_cmos -> ../../../../devices/platform/rtc_cmos
- | | |-- uevent
- | | `-- unbind
- | |-- serial8250
- | | |-- bind
- | | |-- serial8250 -> ../../../../devices/platform/serial8250
- | | |-- uevent
- | | `-- unbind
- | `-- twl4030_reg
- | |-- bind
- | |-- uevent
- | `-- unbind
- |-- drivers_autoprobe
- |-- drivers_probe
- `-- uevent
- 19 directories, 24 files
- struct bus_type platform_bus_type = {
- .name = "platform",
- .dev_attrs = platform_dev_attrs,
- .match = platform_match,
- .uevent = platform_uevent,
- .pm = PLATFORM_PM_OPS_PTR,
- };
- EXPORT_SYMBOL_GPL(platform_bus_type);
- int __init platform_bus_init(void)
- {
- int error;
- early_platform_cleanup();
- error = device_register(&platform_bus);
- if (error)
- return error;
- error = bus_register(&platform_bus_type);
- if (error)
- device_unregister(&platform_bus);
- return error;
- }
- static struct platform_device *smdk2410_devices[] __initdata = {
- &s3c_device_usb,
- &s3c_device_lcd,
- &s3c_device_wdt,
- &s3c_device_i2c0,
- &s3c_device_iis,
- };
- static void __init smdk2410_init(void)
- {
- s3c_i2c0_set_platdata(NULL);
- platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
- smdk_machine_init();
- }
- struct resource {
- resource_size_t start; /*资源的起始物理地址*/
- resource_size_t end; /*资源的结束物理地址*/
- const char *name; /*资源的名称*/
- unsigned long flags; /*资源的类型*/
- struct resource *parent, *sibling, *child; /*资源的链表指针*/
- };
- struct platform_device {
- const char * name; /*设备名*/
- int id; /*设备编号,配合设备名使用*/
- struct device dev;
- u32 num_resources;
- struct resource * resource; /*设备资源*/
- struct platform_device_id *id_entry;
- };
- struct platform_driver {
- int (*probe)(struct platform_device *);
- int (*remove)(struct platform_device *);
- void (*shutdown)(struct platform_device *);
- int (*suspend)(struct platform_device *, pm_message_t state);
- int (*suspend_late)(struct platform_device *, pm_message_t state);
- int (*resume_early)(struct platform_device *);
- int (*resume)(struct platform_device *);
- struct device_driver driver;
- struct platform_device_id *id_table;
- };
struct platform_device *platform_device_alloc(const char *name, int id); //name:设备名,id:设备id,一般为-1
设备的注册:
int platform_device_add(struct platform_device *pdev);
获取资源:
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num); /*dev:资源所属的设备,type:获取的资源类型,num:获取的资源数*/
这里详述platform_device与platform_driver是怎样匹配上的,这里跟踪函数的执行过程,首先是platform_driver_register:
- int platform_driver_register(struct platform_driver *drv)
- {
- 。。。。。。。。。。
- return driver_register(&drv->driver);
- }
- int driver_register(struct device_driver *drv)
- {
- 。。。。。。。。。。。
- ret = bus_add_driver(drv);
- 。。。。。。。。。。。
- }
- int bus_add_driver(struct device_driver *drv)
- {
- 。。。。。。。。。。。。
- if (drv->bus->p->drivers_autoprobe) {
- error = driver_attach(drv);
- if (error)
- goto out_unregister;
- }
- 。。。。。。。。。。。。
- }
- int driver_attach(struct device_driver *drv)
- {
- return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
- }
- static int __driver_attach(struct device *dev, void *data)
- {
- struct device_driver *drv = data;
- /*
- * Lock device and try to bind to it. We drop the error
- * here and always return 0, because we need to keep trying
- * to bind to devices and some drivers will return an error
- * simply if it didn't support the device.
- *
- * driver_probe_device() will spit a warning if there
- * is an error.
- */
- if (!driver_match_device(drv, dev))
- return 0;
- if (dev->parent) /* Needed for USB */
- down(&dev->parent->sem);
- down(&dev->sem);
- if (!dev->driver)
- driver_probe_device(drv, dev);
- up(&dev->sem);
- if (dev->parent)
- up(&dev->parent->sem);
- return 0;
- }
- struct bus_type platform_bus_type = {
- .name = "platform",
- .dev_attrs = platform_dev_attrs,
- .match = platform_match,
- .uevent = platform_uevent,
- .pm = PLATFORM_PM_OPS_PTR,
- };
- static int platform_match(struct device *dev, struct device_driver *drv)
- {
- struct platform_device *pdev = to_platform_device(dev);
- struct platform_driver *pdrv = to_platform_driver(drv);
- /* match against the id table first */
- if (pdrv->id_table)
- return platform_match_id(pdrv->id_table, pdev) != NULL;
- /* fall-back to driver name match */
- return (strcmp(pdev->name, drv->name) == 0);
- }
- int driver_probe_device(struct device_driver *drv, struct device *dev)
- {
- 。。。。。。。。。
- ret = really_probe(dev, drv);
- 。。。。。。。。
- }
- static int really_probe(struct device *dev, struct device_driver *drv)
- {
- 。。。。。。。。
- if (dev->bus->probe) {
- ret = dev->bus->probe(dev);
- if (ret)
- goto probe_failed;
- } else if (drv->probe) {
- ret = drv->probe(dev);
- if (ret)
- goto probe_failed;
- }
- 。。。。。。。。
- }
由relly_probe函数可以看出,如果bus定义了probe函数,则调用bus的probe函数;如果bus,没有定义而driver定义了probe函数,则调用driver的probe函数。由上边的platform_bus_type可以看出bus并没有定义probe函数,所以调用driver的probe函数。
测试程序:device.c
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/device.h>
- #include <linux/string.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- static struct platform_device *my_device;
- static int __init platform_dev_init(void) {
- int ret;
- //分配结构
- my_device = platform_device_alloc("my_dev", -1);
- //注册设备
- ret = platform_device_add(my_device);
- if(ret)
- printk("platform_device_add failed!/n");
- return ret;
- }
- static void __exit platform_dev_exit(void) {
- platform_device_unregister(my_device);//卸载设备
- }
- module_init(platform_dev_init);
- module_exit(platform_dev_exit);
- MODULE_LICENSE("GPL");
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/device.h>
- #include <linux/string.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- static int my_probe(struct device *dev) {
- printk("Driver found device!/n");
- return 0;
- }
- static int my_remove(struct device *dev) {
- printk("Driver found device unpluged!/n");
- return 0;
- }
- //定义platform_driver结构体
- static struct platform_driver my_driver = {
- .probe = my_probe,
- .remove = my_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "my_dev",
- },
- };
- static int __init my_driver_init(void) {
- return platform_driver_register(&my_driver);
- }
- static void __exit my_driver_exit(void) {
- platform_driver_unregister(&my_driver);
- }
- module_init(my_driver_init);
- module_exit(my_driver_exit);
- MODULE_LICENSE("GPL");
- root@hacker:/home/hacker/platform# insmod driver.ko
- root@hacker:/home/hacker/platform# insmod device.ko
- root@hacker:/home/hacker/platform# dmesg
- [ 4499.724439] Driver found device!
- root@hacker:/home/hacker/platform# rmmod driver.ko
- root@hacker:/home/hacker/platform# dmesg
- [ 4499.724439] Driver found device!
- [ 4513.368712] Driver found device unpluged!
- root@hacker:/home/hacker/platform# rmmod device.ko
- root@hacker:/home/hacker/platform# insmod device.ko
- root@hacker:/home/hacker/platform# insmod driver.ko
- root@hacker:/home/hacker/platform# dmesg
- [ 4540.509227] Driver found device!
- root@hacker:/home/hacker/platform# rmmod device.ko
- root@hacker:/home/hacker/platform# dmesg
- [ 4540.509227] Driver found device!
- [ 4545.786076] Driver found device unpluged!
- root@hacker:/home/hacker/platform# rmmod driver.ko
- root@hacker:/home/hacker/platform# dmesg
- [ 4540.509227] Driver found device!
- [ 4545.786076] Driver found device unpluged!
- Linux设备模型--platform
- Linux设备模型--platform
- Linux设备模型--platform
- linux设备模型之platform
- Linux 设备模型 --- Platform 驱动程序
- 【linux设备模型】之platform设备驱动
- Linux设备模型之platform总线
- Linux设备驱动模型之platform总线
- Linux设备模型之platform总线
- Linux设备驱动模型之platform总线
- Linux设备模型之platform总线
- Linux设备模型之platform总线
- linux设备模型之platform总线
- linux设备模型之platform总线
- Linux驱动之设备模型(9)-platform
- Linux驱动之设备模型(9)-platform
- Linux设备模型之platform总线
- Linux设备模型(下)之Platform
- Linux设备模型--总线
- Linux设备模型--设备
- Linux设备模型--驱动
- Linux设备模型--kobject&kset
- linux下bus、devices和platform的基础模型
- Linux设备模型--platform
- Linux设备模型组件-类设备-设备类及subsystem
- Linux内核访问外设I O资源的方式
- 内核启动时clock system的初始化过程
- 网络设备驱动基本原理和框架
- 网卡驱动程序之编写虚拟网卡
- dm9000网卡驱动程序分析
- CS8900a网卡驱动程序分析
- 输入子系统架构分析