11. 2 Platform 总线(2)

466 /**
467 * platform_driver_register - register a driver for platform-level devices
468 * @drv: platform driver structure
469 */

470 int platform_driver_register(struct platform_driver *drv)//注册
471 {
472 drv->driver.bus = &platform_bus_type;
473 if (drv->probe) //编写者实现时,
474 drv->driver.probe = platform_drv_probe; //调用
475 if (drv->remove)
476 drv->driver.remove = platform_drv_remove;
477 if (drv->shutdown)
478 drv->driver.shutdown = platform_drv_shutdown;
479
480 return driver_register(&drv->driver);
481 }

828 struct bus_type platform_bus_type = {   //内核已经实现好了
829 .name = "platform",
830 .dev_attrs = platform_dev_attrs,
831 .match = platform_match,
832 .uevent = platform_uevent,
833 .pm = &platform_dev_pm_ops,
834 };

647 /**
648 * platform_match - bind platform device to platform driver.
649 * @dev: device.
650 * @drv: driver.
651 *
652 * Platform device IDs are assumed to be encoded like this:
653 * "<name><instance>", where <name> is a short description of the type of
654 * device, like "pci" or "floppy", and <instance> is the enumerated
655 * instance of the device, like '0' or '42'. Driver IDs are simply
656 * "<name>". So, extract the <name> from the platform_device structure,
657 * and compare it against the name of the driver. Return whether they
match
658 * or not.
659 */
//3个匹配规则:返回1匹配成功,0失败
660 static int platform_match(struct device *dev, struct device_driver *drv)
661 {
662 struct platform_device *pdev = to_platform_device(dev);
663 struct platform_driver *pdrv = to_platform_driver(drv);
664
665 /* Attempt an OF style match first */    //很少用,建议忘了。。。
666 if (of_driver_match_device(dev, drv))
667 return 1;
668
669 /* Then try to match against the id table */   //使用最多,最灵活,实用
670 if (pdrv->id_table)
671 return platform_match_id(pdrv->id_table, pdev) != NULL;
672
673 /* fall-back to driver name match */    //简单,但是不灵活,常用于一个设备对应一个驱动,
674 return (strcmp(pdev->name, drv->name) == 0);
675 }

 

************************struct platform_driver********************************

164 struct platform_driver {
165 int (*probe)(struct platform_device *);
166 int (*remove)(struct platform_device *);
167 void (*shutdown)(struct platform_device *);
168 int (*suspend)(struct platform_device *, pm_message_t state);
169 int (*resume)(struct platform_device *);
170 struct device_driver driver;  //定义platform_driver大结构体内struct device_driver 类型的driver变量,里面的名字name要参与匹配
171 const struct platform_device_id *id_table;  //!比如定义数组,名字的集合,实现一套驱动匹配对应多个设备
172 };

508 struct platform_device_id {
509 char name[PLATFORM_NAME_SIZE];
510 kernel_ulong_t driver_data
511 __attribute__((aligned(sizeof(kernel_ulong_t))));
512 };

633 static const struct platform_device_id *platform_match_id( //第二种匹配方法
634 const struct platform_device_id *id, //名字们 是个数组/核心
635 struct platform_device *pdev)
636 {
637 while (id->name[0]) {
638 if (strcmp(pdev->name, id->name) == 0) {
639 pdev->id_entry = id;
640 return id;
641 }
642 id++;
643 }
644 return NULL;
645 }

437 static int platform_drv_probe(struct device *_dev) //内核小probe
438 {
439 struct platform_driver *drv = to_platform_driver(_dev->driver);//获取地址
440 struct platform_device *dev = to_platform_device(_dev);
441
442 return drv->probe(dev);
443 }

************************struct platform_device********************************

19 struct platform_device {
20 const char * name;//前5个由我们定义,其余内核自动维护
21 int id;
22 struct device dev;//
23 u32 num_resources;//指向的元素个数
24 struct resource * resource;//可定义数组
25
26 const struct platform_device_id *id_entry;
27
28 /* MFD cell pointer */
29 struct mfd_cell *mfd_cell;
30
31 /* arch specific additions */
32 struct pdev_archdata archdata;
33 };

18 struct resource {
19 resource_size_t start;
20 resource_size_t end;//可表示硬件资源 //比如:中断号
21 const char *name;
22 unsigned long flags;//区分硬件资源
23 struct resource *parent, *sibling, *child;
24 };

26 /* //硬件资源
27 * IO resources have these defined flags.
28 */
29 #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
30
31 #define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */
32 #define IORESOURCE_IO 0x00000100
33 #define IORESOURCE_MEM 0x00000200
34 #define IORESOURCE_IRQ 0x00000400
35 #define IORESOURCE_DMA 0x00000800
36 #define IORESOURCE_BUS 0x00001000
37
38 #define IORESOURCE_PREFETCH 0x00002000 /* No side effects */
39 #define IORESOURCE_READONLY 0x00004000
40 #define IORESOURCE_CACHEABLE 0x00008000
41 #define IORESOURCE_RANGELENGTH 0x00010000
42 #define IORESOURCE_SHADOWABLE 0x00020000
43
44 #define IORESOURCE_SIZEALIGN 0x00040000 /* size indicates alignment */
45 #define IORESOURCE_STARTALIGN 0x00080000 /* start field is alignment */
46
47 #define IORESOURCE_MEM_64 0x00100000
48 #define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */
49 #define IORESOURCE_MUXED 0x00400000 /* Resource is software muxed */
50
51 #define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this
resource */
52 #define IORESOURCE_DISABLED 0x10000000
53 #define IORESOURCE_UNSET 0x20000000
54 #define IORESOURCE_AUTO 0x40000000
55 #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource
busy */
...............................................

350 /**
351 * platform_device_register - add a platform-level device
352 * @pdev: platform device we're adding
353 */
354 int platform_device_register(struct platform_device *pdev)
355 {
356 device_initialize(&pdev->dev);
357 arch_setup_pdev_archdata(pdev);
358 return platform_device_add(pdev);
359 }

257 /**
258 * platform_device_add - add a platform device to device hierarchy
259 * @pdev: platform device we're adding
260 *
261 * This is part 2 of platform_device_register(), though may be called
262 * separately _iff_ pdev was allocated by platform_device_alloc().
263 */
264 int platform_device_add(struct platform_device *pdev)
265 {
266 int i, ret = 0;
267
268 if (!pdev)
269 return -EINVAL;
270
271 if (!pdev->dev.parent)
272 pdev->dev.parent = &platform_bus;
273
274 pdev->dev.bus = &platform_bus_type;
275
276 if (pdev->id != -1)
277 dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
278 else
279 dev_set_name(&pdev->dev, "%s", pdev->name);
280
281 for (i = 0; i < pdev->num_resources; i++) {
282 struct resource *p, *r = &pdev->resource[i];
283
284 if (r->name == NULL)
285 r->name = dev_name(&pdev->dev);

实验目的是了解匹配规则, 结构体代表硬件设备

 

198 #define module_platform_driver(__platform_driver) \
199 module_driver(__platform_driver, platform_driver_register, \
200 platform_driver_unregister)


ls /sys/bus/platform/*

 

53 /**
54 * platform_get_resource - get a resource for a device
55 * @dev: platform device
56 * @type: resource type
57 * @num: resource index
58 */

59 struct resource *platform_get_resource(struct platform_device *dev,
60 unsigned int type, unsigned int num)//分类/标记第几个
61 {
62 int i;
63
64 for (i = 0; i < dev->num_resources; i++) {
65 struct resource *r = &dev->resource[i];
66
67 if (type == resource_type(r) && num-- == 0) //
68 return r;
69 }
70 return NULL;
71 }

167 static inline unsigned long resource_type(const struct resource *res)
168 {
169 return res->flags & IORESOURCE_TYPE_BITS;
170 }

87 /**
88 * platform_get_resource_byname - get a resource for a device by name
89 * @dev: platform device
90 * @type: resource type
91 * @name: resource name
92 */

93 struct resource *platform_get_resource_byname(struct platform_device *dev,
94 unsigned int type,//
95 const char *name) //
96 {
97 int i;
98
99 for (i = 0; i < dev->num_resources; i++) {
100 struct resource *r = &dev->resource[i];
101
102 if (type == resource_type(r) && !strcmp(r->name, name))
103 return r;
104 }
105 return NULL;
106 }

modprobe:

[root@localhost uea_drv]# ls /lib/modules/2.6.32-358.el6.i686/extra/
secbulk.ko
[root@localhost modules_4]# vim /lib/modules/2.6.32-358.el6.i686/modules.dep

[root@localhost modules_4]# modprobe -r demo2.ko

========================================================================================

match2

Makefile

1 obj-m    := dev.o drv.o 
2 
3 KERNEL    := /linux-3.5
4 
5 all:
6     make -C $(KERNEL) M=`pwd`
7 clean:
8     make -C $(KERNEL) M=`pwd` clean

dev.c

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/platform_device.h>
 4 
 5 static  void  hehe_release(struct device *dev)
 6 {
 7     struct platform_device *pdev = to_platform_device(dev);
 8 
 9     printk("%s platdevice is release!\n", pdev->name);
10 }
11 
12 
13 static struct platform_device hehedev = {
14     .id    = -1,
15     .name    =  "shy_bee",//设备名
16     .dev    = {
17         .release    = hehe_release,
18     },
19 }; 
20 
21 module_driver(hehedev, platform_device_register, platform_device_unregister);
22 
23 MODULE_LICENSE("GPL");
24 
25 MODULE_AUTHOR("millet9527");
26 MODULE_VERSION("millet plus 18");
27 MODULE_DESCRIPTION("example for driver module arch");

drv.c

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/platform_device.h>
 4 
 5 static int hehe_probe(struct platform_device *pdev)
 6 {
 7     printk("%s platdevice match %s platdriver ok!\n", pdev->name,
 8             pdev->dev.driver->name);
 9 
10     return 0;
11 }
12 
13 static int hehe_remove(struct platform_device *pdev)
14 {
15     printk("%s platdevice dismatch %s platdriver ok!\n", pdev->name,
16             pdev->dev.driver->name);
17 
18     return 0;
19 }
20 
21 const struct platform_device_id hehetable[] = {        //第二种匹配方法
22     { "bee_shy",},
23     { "shybee", },
24     { "shy_bee", }, 
25     {},    
26 };
27 
28 static struct platform_driver hehedriver = {
29     .probe    = hehe_probe,
30     .remove    = hehe_remove,
31     .driver    = {
32         .name    =    "embsky",
33     },
34     .id_table = hehetable,
35 };
36 
37 module_platform_driver(hehedriver);
38 
39 MODULE_LICENSE("GPL");
40 
41 MODULE_AUTHOR("millet9527");
42 MODULE_VERSION("millet plus 18");
43 MODULE_DESCRIPTION("example for driver module arch");

 

match3

dev.c

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/platform_device.h>
 4 
 5 static  void  hehe_release(struct device *dev)//移除
 6 {
 7     struct platform_device *pdev = to_platform_device(dev);//获取设备大结构体地址
 8 
 9     printk("%s platdevice is release!\n", pdev->name);//设备名
10 }
11 
12 
13 static struct platform_device hehedev = {//定义设备对象
14     .id    = -1,
15     .name    =  "embsky",//用名字匹配
16     .dev    = {
17         .release    = hehe_release,
18     },
19 }; 
20 
21 module_driver(hehedev, platform_device_register, platform_device_unregister);//设备的注册和移除
22 
23 MODULE_LICENSE("GPL");
24 
25 MODULE_AUTHOR("millet9527");
26 MODULE_VERSION("millet plus 18");
27 MODULE_DESCRIPTION("example for driver module arch");

drv.c

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <linux/platform_device.h>
 4 
 5 static int hehe_probe(struct platform_device *pdev)//匹配成功后该驱动函数的probe成功接收匹配设备的地址
 6 {
 7     printk("%s platdevice match %s platdriver ok!\n", pdev->name,
 8             pdev->dev.driver->name);//用设备去匹配驱动
 9 
10     return 0;
11 }
12 
13 static int hehe_remove(struct platform_device *pdev)
14 {
15     printk("%s platdevice dismatch %s platdriver ok!\n", pdev->name,
16             pdev->dev.driver->name);
17 
18     return 0;
19 }
20 
21 static struct platform_driver hehedriver = {//定义驱动对象
22     .probe    = hehe_probe,//探测函数
23     .remove    = hehe_remove,
24     .driver    = {
25         .name    =    "embsky",
26     }
27 };
28 
29 module_platform_driver(hehedriver);
30 
31 MODULE_LICENSE("GPL");
32 
33 MODULE_AUTHOR("millet9527");
34 MODULE_VERSION("millet plus 18");
35 MODULE_DESCRIPTION("example for driver module arch");

posted @ 2017-06-16 09:07  bkycrmn  阅读(131)  评论(0)    收藏  举报