【linux】简述device和driver匹配方式

文章目录

  • 0.env
  • 10. 简述
  • 20. 测试源码
    • 1. driver
    • 2. device
      • 2.1 方式一:DTS
      • 2.2 方式二:ACPI
      • 2.3 方式三:id table
      • 2.4 方式四:NAME
    • 3. 测试log


0.env

ARM 32bit
linux4.4.60

10. 简述

  1. 主要讲述了几种device和driver匹配的方式以及demo框架
  2. 文章不涉及数据处理部分,resource部分后续再补充
  1. 匹配DTS (目前主流方式)
  2. 匹配ACPI
  3. 匹配id table
    3.1 . driver提供id table的数据,device提供一个id变量,遍历drvier中的id table来匹配
    3.2. device中platform_device.name 和 id_entry,name 要一致
  4. 匹配name
    4.1. 四种优先级中最低的一层,也是默认的方式,尽量在device中都放进去。

20. 测试源码

1. driver

  1. id table这个成员不为空时,
    platfrom match就只能匹配前三种方式,默认的name就没法匹配了
  2. 可以通过打开如下四个宏来查看各类匹配方式的区别

#define SUPPORT_DTS
#define SUPPORT_ACPI
#define SUPPORT_ID_TABLE
#define SUPPORT_DEV_NAME

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SUPPORT_DTS
#define SUPPORT_ACPI
#define SUPPORT_ID_TABLE
#define SUPPORT_DEV_NAME

#ifndef SUPPORT_DEV_NAME
#define SUPPORT_DEV_NAME
#endif

/* Add platform driver */
static int sc_liam_dri_probe(struct platform_device *pdev)
{
    pr_info("----- driver probe  -----\n");
    pr_info("dev id = %d\n", pdev->id);
    return 0;
}
static int sc_liam_dri_remove(struct platform_device *pdev)
{
    pr_info("----- driver remove -----\n");
    return 0;
}

#ifdef SUPPORT_DTS
static const struct of_device_id sc_liam_of_match[] = {
    {   .compatible = "xxxx,sc_liam_dev"    },
    {   }
};
#endif
#ifdef SUPPORT_ACPI
#endif
#ifdef SUPPORT_ID_TABLE
static const struct platform_device_id sc_liam_id[] = {
    {   .name = "sc_liam_id_1", 0},
    {   .name = "sc_liam_id_2", 0},
    {   .name = "sc_liam_id_3", 0},
    {   }
};
#endif

static struct platform_driver sc_liam_driver = {
    .probe = sc_liam_dri_probe,
    .remove = sc_liam_dri_remove,
    .driver     = {
        .name = "sc_liam",
#ifdef SUPPORT_DTS
        .of_match_table = sc_liam_of_match,
#endif
#ifdef SUPPORT_ACPI
#endif
    },
#ifdef SUPPORT_ID_TABLE
    .id_table   = sc_liam_id,
#endif
};

#if 0
module_platform_driver(sc_liam_driver);
#else
static int __init sc_liam_dri_init(void)
{
    int err;
    pr_info("--- driver init ---\n");
    err = platform_driver_register(&sc_liam_driver);
    if (err){
        pr_info("--- driver init : fail ---\n");
    }
    return err;
}

static void __exit sc_liam_dri_exit(void)
{
    pr_info("--- driver exit ---\n");
    platform_driver_unregister(&sc_liam_driver);
}

module_init(sc_liam_dri_init);
module_exit(sc_liam_dri_exit);
#endif

/* 5. module info */
MODULE_LICENSE("GPL v2"); 
MODULE_AUTHOR("liam"); 

2. device

2.1 方式一:DTS

  1. DTS文件中:

1.1 在根节点(或者其他地方)添加一个node,
1.2 最基础的需要添加compatible 来匹配driver,
1.3 关于status:只有显式定义status状态为disabled才不使能这个设备,其他情况(包括不定义)都默认使能该设备。
【linux】简述device和driver匹配方式_第1张图片

2.2 方式二:ACPI

2.3 方式三:id table

  1. #define SUPPORT_ID_TABLE,调试dev_1
  2. 定义platform_device_id
  3. name相同
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SUPPORT_ID_TABLE

static void sc_liam_dev_release(struct device * dev)
{
    return ;
}

#ifdef SUPPORT_ID_TABLE
static const struct platform_device_id sc_liam_id = {
    .name = "sc_liam_id_1" , // same with platform_device.name 
};
#endif

static struct platform_device sc_liam_dev_1 = {
    .id = 1,
#ifdef SUPPORT_ID_TABLE
    .id_entry = &sc_liam_id,
    .name = "sc_liam_id_1",
#else
    .name = "sc_liam",
#endif
    .dev = {
        /* FIX : add release() if xxx_register() */
        .release = sc_liam_dev_release,
    }
};

static struct platform_device sc_liam_dev_9 = {
    .id = 9,
    .name = "sc_liam",
    .dev = {
        /* FIX : add release() if xxx_register() */
        .release = sc_liam_dev_release,
    }
};

/* mod_init */
static int __init sc_liam_dev_init(void)
{
    int err;
	printk("--- device init ---\n");
    err = platform_device_register(&sc_liam_dev_1);
    if (err){
        printk("--- device init : fail ---\n");
#ifdef SUPPORT_ID_TABLE
    }else{
        printk("device id_table.name = %s\n", sc_liam_dev_1.id_entry->name);
#endif
    }
    err = platform_device_register(&sc_liam_dev_9);
    if (err){
        printk("--- device init : fail ---\n");
    }
	return 0;
}

/* mod_exit */
static void __exit sc_liam_dev_exit(void)
{
    platform_device_unregister(&sc_liam_dev_1);
    platform_device_unregister(&sc_liam_dev_9);
	printk("--- device exit ---\n");
}

module_init(sc_liam_dev_init);
module_exit(sc_liam_dev_exit);

/* module info */
MODULE_LICENSE("GPL v2"); 
MODULE_AUTHOR("liam"); 

2.4 方式四:NAME

  1. name:
    上述源码中,打开/#define SUPPORT_ID_TABLE,调试dev_9

3. 测试log

使用的是id table来匹配的log

root@OpenWrt:/# 
root@OpenWrt:/# insmod sc_liam_driver.ko 
[ 3118.526703] --- driver init ---
root@OpenWrt:/# 
root@OpenWrt:/# insmod sc_liam_device.ko 
[ 3123.622959] --- device init ---
[ 3123.623265] ----- driver probe  -----
[ 3123.624902] dev id = 1
[ 3123.628770] device id_table.name = sc_liam_id_1
root@OpenWrt:/# 
root@OpenWrt:/# rmmod sc_liam_driver.ko 
module is not loaded
root@OpenWrt:/# rmmod sc_liam_dri
[ 3134.948927] --- driver exit ---
[ 3134.948976] ----- driver remove -----
root@OpenWrt:/# 
root@OpenWrt:/# rmmod sc_liam_dev
[ 3256.197876] --- device exit ---
root@OpenWrt:/# 

你可能感兴趣的:(#,Linux,linux,platfrom)