platform_device结构体原型
struct platform_device { const char * name; //名字,在与platform_driver匹配时依据就是此名字 u32 id; //设备id struct device dev; //设备,加载模块的时候需要其中的release函数 u32 num_resources; //设备个数,可用ARRAY_SIZE取得 //#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) struct resource * resource; //资源结构体 };
资源结构体resource
struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; struct resource *parent, *sibling, *child; };
static struct resource led_resource[] = { [0] = { .start = 0x56000050, .end = 0x56000054, .flags = IORESOURCE_MEM, }, [1] = { .start = 5, .end = 5, .flags = IORESOURCE_IRQ, }, };/*下面的资源类型用于标定资源所属的类别*/
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; };
static struct platform_driver led_drv = { .probe = led_drv_probe, //配对成功后会执行此函数 .remove = led_drv_remove, //设备移除的时候执行此函数 .driver = { .name = "by_led", //与platform_device配对 }, };
patform_driver_unregister()进行卸载
int platform_driver_register(struct platform_driver *drv) { drv->driver.bus = &platform_bus_type; if (drv->probe) //如果没有指定,则初始化为默认的函数 drv->driver.probe = platform_drv_probe; if (drv->remove) drv->driver.remove = platform_drv_remove; if (drv->shutdown) drv->driver.shutdown = platform_drv_shutdown; if (drv->suspend) drv->driver.suspend = platform_drv_suspend; if (drv->resume) drv->driver.resume = platform_drv_resume; return driver_register(&drv->driver); }
struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, .suspend = platform_suspend, .suspend_late = platform_suspend_late, .resume_early = platform_resume_early, .resume = platform_resume, };
static int platform_match(struct device * dev, struct device_driver * drv) { struct platform_device *pdev = container_of(dev, struct platform_device, dev); return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); //比较两个分支的名字 }
static struct resource led_resource[] = { [0] = { .start = 0x56000050, .end = 0x56000054, .flags = IORESOURCE_MEM, }, [1] = { .start = 5, .end = 6, .flags = IORESOURCE_IRQ, }, };
static void led_dev_release(struct device * dev) { ; } static struct platform_device led_dev = { .name = "by_led", .id = -1, .num_resources = ARRAY_SIZE(led_resource), .resource = led_resource, .dev = { .release = led_dev_release, }, };
static int led_dev_init(void) { platform_device_register(&led_dev); return 0; } static void led_dev_exit(void) { platform_device_unregister(&led_dev); }
以上为device分支
static int led_drv_probe(struct platform_device *p_dev) { /* 输出打印信息,说明两者成功匹配 */ printk("Found by_led, Connect success\n"); return 0; } static int led_drv_remove(struct platform_device *p_dev) { /* 输出打印信息,说明成功卸载设备 */ printk("Found by_led, Remove success\n"); return 0; } static struct platform_driver led_drv = { .probe = led_drv_probe, .remove = led_drv_remove, .driver = { .name = "by_led", }, };
static int led_drv_init(void) { platform_driver_register(&led_drv); return 0; } static void led_drv_exit(void) { platform_driver_unregister(&led_drv); }