linux 平台设备、平台驱动和平台总线
一、简介
设备树上的设备节点都是以platform_device的形式加载到系统中的,内核中有设备对应的驱动platform_driver 。
linux 自动注册了一个平台总线和平台设备分别平台总线是/sys/bus/platform,平台设备是/sys/devices/platform。其实平台总线就是个bus_type,平台设备 就是个device类型。注册过程如下所示:
平台设备注册:
平台设备定义在kernel/drivers/base/platfrom.c中,
kernel/drivers/base/platfrom.c
-->platform_bus_init
-->device_register
平台总线注册:
平台总线定义在kernel/drivers/base/platfrom.c中,
kernel/drivers/base/platfrom.c
-->platform_bus_init
-->bus_register
下面的例子是向系统注册一个yy_uu的平台设备和平台驱动
#include <linux/init.h> #include <linux/platform_device.h> #include <linux/module.h> #include <linux/ioport.h> #include <asm/io.h> #include <linux/cdev.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("yyfage"); static struct platform_device yy_uu_dev = { .name = "yy_uu", .dev = { .release = yy_uu_device_release, }, .id = PLATFORM_DEVID_NONE, .num_resources = YY_REGISTER_NUM, .resource = yy_uu_dev_resource, }; static struct platform_driver yy_uu_drv = { .driver = { .name = "yy_uu", }, .probe = yy_uu_probe, .remove = yy_uu_remove, }; static void yy_uu_device_release(struct device *pdev) { printk("yy_uu_device_release is run\n"); } static int yy_uu_probe(struct platform_device *pdev) { int i = 0; struct resource *resource[YY_REGISTER_NUM]; printk("yy_uu_probe is run\n"); return 0; } static int yy_uu_remove(struct platform_device *pdev) { printk("yy_uu_remove is run\n"); iounmap(YY_REGISTER_IO_1); iounmap(YY_REGISTER_IO_2); iounmap(YY_REGISTER_IO_3); yy_uu_cdev_release(); return 0; } static int __init yy_uu_init_module(void) { printk("yy_uu_init_module is run\n"); platform_device_register(&yy_uu_dev); platform_driver_register(&yy_uu_drv); return 0; /* succeed */ } static void __exit yy_uu_exit_module(void) { printk("yy_uu_exit_module is run\n"); platform_driver_unregister(&yy_uu_drv); platform_device_unregister(&yy_uu_dev); } module_init(yy_uu_init_module);
module_exit(yy_uu_exit_module);
编译后执行insmod yy_uu.ko 会在/sys/devices/platfrom下生成yy_uu设备,在/sys/bus/platfrom/drivers下生成yy_uu驱动。
也可以通过设备树增加平台设备,以hi3559为例。在Hi3559AV100_SDK_V2.0.3.0\package\osdrv\opensource\kernel\linux-4.9.y\arch\arm64\boot\dts\hisilicon\hi3559av100-demb.dts设备树中增加两个设备节点yy_scull和yy_sucll_2如下所示:
系统启动后会在/sys/devices/platform目录下生成yy_scull和yy_sucll_2设备,如下所示: