设备树 — platform_device和platform_driver如何让匹配

设备树学习(九、platform_device和platform_driver如何让匹配)   关于这个问题,我之前在分析2.6内核的时候是已经分析过的。 https://blog.youkuaiyun.com/qq_16777851/article/details/81350037   同时在总线驱动模型章节也是从基础知识学习,到最终实现过一个简单的bus的,想要深入学习,最好看下面这个专栏。(基于4.x内核) https://blog.youkuaiyun.com/qq_16777851/colu... 阅读详情

4.x的内核都是已经支持设备树的,所以platform bus也是做了一些调整。

  主要是在匹配函数里面的支持设备树。

1

2

3

4

5

6

7

8

struct bus_type platform_bus_type = {

    .name       = "platform",

    .dev_groups = platform_dev_groups,

    .match      = platform_match,

    .uevent     = platform_uevent,

    .dma_configure  = platform_dma_configure,

    .pm     = &platform_dev_pm_ops,

};

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

/**

 * platform_match - bind platform device to platform driver.

 * @dev: device.

 * @drv: driver.

 *

 * Platform device IDs are assumed to be encoded like this:

 * "<name><instance>", where <name> is a short description of the type of

 * device, like "pci" or "floppy", and <instance> is the enumerated

 * instance of the device, like '0' or '42'.  Driver IDs are simply

 * "<name>".  So, extract the <name> from the platform_device structure,

 * and compare it against the name of the driver. Return whether they match

 * or not.

 */

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);

  

    /* When driver_override is set, only bind to the matching driver */

    /* 针对特殊情况,dev中的driver_override被设置,则只匹配和driver_override名字相同的驱动程序 */

    if (pdev->driver_override)

        return !strcmp(pdev->driver_override, drv->name);

  

    /* Attempt an OF style match first,设备树方式匹配 */

    if (of_driver_match_device(dev, drv))

        return 1;

  

    /* Then try ACPI style match */

    /* 高级配置和电源管理之类的匹配,这里不是我们这次的重点 */

    if (acpi_driver_match_device(dev, drv))

        return 1;

  

    /* Then try to match against the id table */

    /* 有驱动中有id_table,则dev中的名字和任何一个id_table里面的值匹配就认为匹配 */

    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);

}

  这里可以看到匹配的优先级如下:

  1. 设备里的driver_override被设置,优先级最高。
  2. 驱动里的of_match_table,和平台设备的compatible比较。
  3. 高级配置和电源管理之类的匹配。
  4. platform_driver里的id_table里的所有名字和设备名字匹配。
  5. 最后再是设备名字和驱动名字比较。

  当然除了第一个之外,其它的只要没匹配到,后面的几个匹配还会继续执行的。

设备树匹配方式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

/**

 * of_driver_match_device - Tell if a driver's of_match_table matches a device.

 * @drv: the device_driver structure to test

 * @dev: the device structure to match against

 */

static inline int of_driver_match_device(struct device *dev,

                     const struct device_driver *drv)

{

    return of_match_device(drv->of_match_table, dev) != NULL;

}

  

  

/**

 * of_match_device - Tell if a struct device matches an of_device_id list

 * @ids: array of of device match structures to search in

 * @dev: the of device structure to match against

 *

 * Used by a driver to check whether an platform_device present in the

 * system is in its list of supported devices.

 */

const struct of_device_id *of_match_device(const struct of_device_id *matches,

                       const struct device *dev)

{

    if ((!matches) || (!dev->of_node))

        return NULL;

    return of_match_node(matches, dev->of_node);

}

  

  

  

/**

 * of_match_node - Tell if a device_node has a matching of_match structure

 *  @matches:   array of of device match structures to search in

 *  @node:      the of device structure to match against

 *

 *  Low level utility function used by device matching.

 */

const struct of_device_id *of_match_node(const struct of_device_id *matches,

                     const struct device_node *node)

{

    const struct of_device_id *match;

    unsigned long flags;

  

    raw_spin_lock_irqsave(&devtree_lock, flags);

    match = __of_match_node(matches, node);

    raw_spin_unlock_irqrestore(&devtree_lock, flags);

    return match;

}

  

static

const struct of_device_id *__of_match_node(const struct of_device_id *matches,

                       const struct device_node *node)

{

    const struct of_device_id *best_match = NULL;

    int score, best_score = 0;

  

    if (!matches)

        return NULL;

  

    //根据匹配的分数,选择最高分的是最佳匹配

    for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {

        score = __of_device_is_compatible(node, matches->compatible,

                          matches->type, matches->name);

        if (score > best_score) {

            best_match = matches;

            best_score = score;

        }

    }

  

    return best_match;

}

  

  

  

/**

 * __of_device_is_compatible() - Check if the node matches given constraints

 * @device: pointer to node

 * @compat: required compatible string, NULL or "" for any match

 * @type: required device_type value, NULL or "" for any match

 * @name: required node name, NULL or "" for any match

 *

 * Checks if the given @compat, @type and @name strings match the

 * properties of the given @device. A constraints can be skipped by

 * passing NULL or an empty string as the constraint.

 *

 * Returns 0 for no match, and a positive integer on match. The return

 * value is a relative score with larger values indicating better

 * matches. The score is weighted for the most specific compatible value

 * to get the highest score. Matching type is next, followed by matching

 * name. Practically speaking, this results in the following priority

 * order for matches:

 *

 * 1. specific compatible && type && name

 * 2. specific compatible && type

 * 3. specific compatible && name

 * 4. specific compatible

 * 5. general compatible && type && name

 * 6. general compatible && type

 * 7. general compatible && name

 * 8. general compatible

 * 9. type && name

 * 10. type

 * 11. name

 */

static int __of_device_is_compatible(const struct device_node *device,

                     const char *compat, const char *type, const char *name)

{

    struct property *prop;

    const char *cp;

    int index = 0, score = 0;

  

    /* Compatible match has highest priority */

    /* compatible 匹配有限即最高,匹配到了,则给的分数相对较高 */

    if (compat && compat[0]) {

        prop = __of_find_property(device, "compatible", NULL);

        for (cp = of_prop_next_string(prop, NULL); cp;

             cp = of_prop_next_string(prop, cp), index++) {

            if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {

                score = INT_MAX/2 - (index << 2);

                break;

            }

        }

        if (!score)

            return 0;

    }

  

    /* Matching type is better than matching name,类型匹配会加2分 */

    if (type && type[0]) {

        if (!device->type || of_node_cmp(type, device->type))

            return 0;

        score += 2;

    }

  

    /* Matching name is a bit better than not,最后在确认名字匹配加1分 */

    if (name && name[0]) {

        if (!device->name || of_node_cmp(name, device->name))

            return 0;

        score++;

    }

  

    return score;

}

  看这句 prop = __of_find_property(device, "compatible", NULL);
  可以发先追溯到底,是利用"compatible"来匹配的,即设备树加载之后,内核会自动把设备树节点转换成 platform_device这种格式,同时把名字放到of_node这个地方。

  id_tabel是根据id_table表中的每一个和设备名字进行匹配,这样一个驱动可以支持多个名称的设备。

1

2

3

4

5

6

7

8

9

10

11

12

13

static const struct platform_device_id *platform_match_id(

            const struct platform_device_id *id,

            struct platform_device *pdev)

{

    while (id->name[0]) {

        if (strcmp(pdev->name, id->name) == 0) {

            pdev->id_entry = id;

            return id;

        }

        id++;

    }

    return NULL;

}

  

举例:

  1.ti的omap8250驱动可以支持好多个型号的芯片,其它芯片只要这个的驱动基础上做很小的改动就可通用。

  其中的改动点,使用of_device_id 的date表示的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

/*

 * Struct used for matching a device

 */

struct of_device_id {

    char    name[32];

    char    type[32];

    char    compatible[128];

    const void *data;

};

  

  

  

static const u8 omap4_habit = UART_ERRATA_CLOCK_DISABLE;

static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;

static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;

  

  

static const struct of_device_id omap8250_dt_ids[] = {

    { .compatible = "ti,am654-uart" },

    { .compatible = "ti,omap2-uart" },

    { .compatible = "ti,omap3-uart" },

    { .compatible = "ti,omap4-uart", .data = &omap4_habit, },

    { .compatible = "ti,am3352-uart", .data = &am3352_habit, },

    { .compatible = "ti,am4372-uart", .data = &am3352_habit, },

    { .compatible = "ti,dra742-uart", .data = &dra742_habit, },

    {},

};

  

  

static struct platform_driver omap8250_platform_driver = {

    .driver = {

        .name       = "omap8250",

        .pm     = &omap8250_dev_pm_ops,

        .of_match_table = omap8250_dt_ids,

    },

    .probe          = omap8250_probe,

    .remove         = omap8250_remove,

};

  

2.ad5380有好多中类型,芯片使用完全兼容。可能就是版本差异。驱动可以完全兼容。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

static const struct spi_device_id ad5380_spi_ids[] = {

    { "ad5380-3", ID_AD5380_3 },

    { "ad5380-5", ID_AD5380_5 },

    { "ad5381-3", ID_AD5381_3 },

    { "ad5381-5", ID_AD5381_5 },

    { "ad5382-3", ID_AD5382_3 },

    { "ad5382-5", ID_AD5382_5 },

    { "ad5383-3", ID_AD5383_3 },

    { "ad5383-5", ID_AD5383_5 },

    { "ad5384-3", ID_AD5380_3 },

    { "ad5384-5", ID_AD5380_5 },

    { "ad5390-3", ID_AD5390_3 },

    { "ad5390-5", ID_AD5390_5 },

    { "ad5391-3", ID_AD5391_3 },

    { "ad5391-5", ID_AD5391_5 },

    { "ad5392-3", ID_AD5392_3 },

    { "ad5392-5", ID_AD5392_5 },

    { }

};

MODULE_DEVICE_TABLE(spi, ad5380_spi_ids);

  

static struct spi_driver ad5380_spi_driver = {

    .driver = {

           .name = "ad5380",

    },

    .probe = ad5380_spi_probe,

    .remove = ad5380_spi_remove,

    .id_table = ad5380_spi_ids,

};

  最后总结一下有了设备树前后,设备驱动怎么写

  有了设备树这样在dts中编写

1

2

3

4

samsung-beep{

         compatible = "samsung,beep";

         reg = <0x114000a0 0x4 0x139D0000 0x14>;

};

  a -- samsung-beep 为节点名,符合咱们前面提到的节点命名规范;

      我们通过名字可以知道,该节点描述的设备是beep, 设备名是samsung-beep;

  b -- compatible = "samsung,beep"; compatible 属性, 即一个字符串;

      前面提到,所有新的compatible值都应使用制造商的前缀,这里是samsung

  c -- reg = <0x114000a0 0x4 0x139D0000 0x14>;

       reg属性来将地址信息编码进设备树,表示该设备的地址范围;这里是我们用到的寄存器及偏移量;
 

之前在mach-xxx.c中编写

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

static struct  resource beep_resource[] =

{

    [0] = {

        .start = 0x114000a0,

        .end = 0x114000a0+0x4,

        .flags = IORESOURCE_MEM,

    },

    [1] = {

        .start = 0x139D0000,

        .end = 0x139D0000+0x14,

        .flags = IORESOURCE_MEM,

    },

};

static struct platform_device hello_device=

{

    .name = "beep",

    .id = -1,

    .dev.release = hello_release,

    .num_resources = ARRAY_SIZE(beep_resource ),

    .resource = beep_resource,

};

  

硬件驱动中platform机制及其设备树 这样就形成了驱动的分离,一边是SOC的硬件资源,另一边是用户设备,它们通过统一的接口来连接。驱动分离的思想带来了许多好处,linux长久的发展中,省去了很多冏余的代码,SOC厂家根据统一的接口提供SOC片上外设的驱动,设备厂家也根据结构统一的接口提供设备的驱动,用户需要选择好SOC和外设,就能径方便的关联到一起。这样的思想也延续到了单个SOC中,片上驱动和设备驱动通过总线协议来关联。当我们往内核中添加驱动时,总线就会查找对应的设备,添加设备时就去查找对应的驱动。 这就是linux 中的bus、driver、 阅读详情

相关推荐

告别手动拖拽!PyQt5/PyQt6 QTableView列宽自适应窗口的三种实战方案(附性能对比)

本文详细介绍了PyQt5/PyQt6中QTableView列宽自适应窗口的三种实战方案,包括Stretch模式、resizeEvent手动计算和ResizeToContents模式,并附有性能对比。帮助开发者解决窗口大小变化时列宽不变的常见问题,提升用户体验和开发效率。

weixin_42538752的博客 231

Linux设备模型、平台设备驱动、设备树(device tree)、GPIO子系统以及pinctrl子系统介绍

Linux设备模型、平台设备驱动、设备树(device tree)、GPIO子系统以及pinctrl子系统介绍 我们实现设备驱动开发的时候,需要提前了解一些基础知识,下面慢慢介绍。 主要参考资料:[野火i.MX Linux开发实战指南]

m0_51429770的博客 4127

【电子电力】IEEE33节点系统参数及拓扑图visio

IEEE33节点系统是一种广泛用于电力系统分析和研究的标准配电网络。该系统具有典型的辐射结构,适用于负载流分析、分布式发电优化及电力系统的可靠性评估。本报告主要基于IEEE33节点系统的拓扑图,讨论其在电子电力系统中的应用。通过MATLAB仿真分析了节点的电压分布、功率损耗等关键参数,并验证了系统的稳定性和有效性。

2401_84610415的博客 1万+

Linux I2C子系统【1】-I2C驱动分析-设备树创建platform_device

linux i2c子系统

m0_46535940的博客 4094

S32K344 Flash Driver实战:手把手教你实现任意字节写入与扇区解锁(含C40_Ip避坑指南)

本文深入解析S32K344微控制器的Flash驱动开发,重点解决C40_Ip驱动库的8字节对齐限制和扇区保护锁问题。通过实战案例和代码示例,详细介绍了如何实现任意字节写入、扇区解锁及性能优化策略,为Bootloader和OTA升级等应用提供可靠解决方案。

weixin_33713707的博客 430

Buck的振铃实验与分析

上上期我们提到了buck电路的开关的振铃波形,本质原因是LC的阻尼振荡。文章偏理论,那BUCK到底是怎么产生尖峰振荡呢? 要想把这个问题搞清楚,也很是不容易,所以文章有点长,请直接点赞转发加收藏。 问题 本期主要分析以下这两个问题: 1、死区时间是什么?这里有个小台阶是什么情况? 2、上下尖峰振荡是如何产生的?跟哪些因素有关? 理想的BUCK的SW波形 我们由浅入深,一步一步来,先看理想的开关SW波形—没有尖峰电压的波形。 为了能更好的看buck电路各个点的电压电流情况.

weixin_42005993的博客 3万+

Platform_device和platform_driver

<br />通过Platform机制开发发底层驱动的大致流程为: 定义 platform_device---注册 platform_device ---定义 platform_driver-----注册 platform_driver。 <br />1. Platform_device 定义于 kernel/include/linux/platform_device.h中,<br />struct platform_device {<br /> const char * name;<br /> u32 id

嵌入精灵 3086

Sentinel2 哨兵2数据下载方法(USGS)-史上最全讲解

本文讲述了从USGS官网下载Sentinel2的方法。主要包括USGS官网的注册和下载流程,以及选定研究区中所出现的问题、解决办法。

xiatiandexia123的博客 6万+

linux开发之设备树七、设备树下platform_device和platform_driver匹配

device和driver会通过名字进行匹配,匹配成功以后,会执行driver中的probe函数,在这个probe函数中就可以实现去device中取出硬件信息的方法了。设备树替换掉了device部分,也就是设备树也会被转换为platform_device,然后就会通过名字匹配driver,匹配成功后就是调用driver中的probe函数了,然后就是获取硬件信息。

qq_40170041的博客 574

大聪明教你学Java | Seata 2.5 从下载到运行:全流程编译部署教程

Seata 2.5 版本带来了不少特性优化,但实际部署时却发现一个尴尬问题:全网找不到一篇完整覆盖「Git 源码下载→本地编译→环境配置→启动验证」的实操教程。作为一名踩遍无数坑才成功跑通的开发者,我深知这个过程的煎熬:Git 拉取源码后编译失败、依赖版本冲突、配置文件参数混乱、启动时端口占用或连接报错… 每一个坑都能耗费数小时排查。为了让后续开发者少走弯路,我将自己从0到1的完整实操经验整理成文,跟着步骤走即可成功运行 Seata 2.5.

不肯过江东丶 2071

【OS】AUTOSAR OS系统调用产生Trap的过程详解

AUTOSAR OS系统调用产生Trap的过程详解

qq_36056498的博客 2438

基于设备树动态创建的 platform_device和platform_driver 的平台总线(platform bus)匹配机制

对于设备树节点的标准属性,内核把属性放在struct resource和总线设备驱动框架下的platform_device一致,仍可通过platform_get_resource()获取。of_match_table指针指向驱动可支持的设备,将 const struct of_device_id *of_match_table;其中的 compatile="ohhh";其中:内核对device_node(设备树中的节点)→platform_device的处理只是针对满足条件的device_node。

weixin_60725397的博客 886

基于Simulink的永磁同步电机三闭环(位置/速度/电流)控制仿真

本文详细介绍了基于Simulink的永磁同步电机三闭环控制系统设计与实现方法。系统采用位置环、速度环、电流环的三层嵌套结构,通过坐标变换(Clark/Park)实现解耦控制,达到精密定位目的。文章包含完整的建模步骤:从主电路搭建、三环PID设计到坐标变换与SVPWM调制实现,并提供了核心控制算法的MATLAB代码。通过工业机械臂关节场景验证,系统在阶跃响应(稳态误差0.002°)、正弦跟踪(误差0.008°)和抗扰动性能(恢复时间0.05s)方面表现优异。最后还提出了前馈补偿、扰动观测器等优化方向。该方案适

xiaoheshang_123的博客 280

3.6内核对设备树的处理——platform_device跟platform_driver的匹配

platform_device跟platform_driver的匹配

一个嵌入式软件工程师的博客 1614

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

内核对设备树的处理__platform_device跟platform_driver的匹配

内核对设备树的处理__platform_device跟platform_driver的匹配

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 437

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

点亮MIPI屏;系统启动失败-无法启动根文件系统;启动设备树下 platform_device 和 platform_driver 匹配实验

改.dts” 是解决板级设备节点配置的正确方向,且能规避之前的.dtsi引用问题,但 “语法正确” 只是第一步。需同时满足 “属性合规、无资源冲突、编译配置正确、驱动匹配”,才能确保修改后编译生效。点亮mipi屏幕点亮MIPI屏幕打开设备树文件:打开这个/** 屏幕选择* ATK_LCD_TYPE_MIPI_720P: 正点原子5.5寸 720*1280 MIPI屏* ATK_LCD_TYPE_MIPI_1080P: 正点原子5.5寸 1080*1920 MIPI屏。

weixin_57340941的博客 770

Linux dts设备树和platform驱动详解

概念 小麦大叔 2019-05-06 22:56:31 12603 收藏 135 什么是设备树 dts(device tree)? 设备树(Device Tree)是描述计算机的特定硬件设备信息的数据结构,以便于操作系统的内核可以管理和使用这些硬件,包括CPU或CPU,内存,总线和其他一些外设。dtb文件会被保存到ROM中,最终通过bootbolader被加载到内核,这样内核就可以通过解析设备树来让驱动去控制实际的硬件了。 设备树是通过Open Firmware项目从基于SPARC的工作站和服务器派生而来的

qq_43491149的博客 1万+

驱动-设备树和驱动自动匹配

前面通过设设备树了解过设备树语法、中断、时钟、GPIO、pinctrl,设备树描述设备属性,同时部分硬件设备描述放在设备树里面。对于硬件外设等接口放到设备树中,在平台总线篇章 是需要驱动和设备匹配的。那么现在的问题就是如何在设备树中描述硬件信息,驱动起来后自动和设备树中的设备匹配起来,建立通信桥梁?这里我们终于从之前了解的设备树属性关联延伸到具体设备树到设备的实战了解了设备树到device及device和driver 匹配过程。

十年饮冰,难凉热血 1750

设备树如何转化为platform_device:内核匹配机制与驱动加载全解析

本文详细解析Linux内核中设备树(DTS)转换为platform_device的完整流程与匹配机制。重点阐述compatible属性的核心作用、四种设备驱动匹配策略的优先级与应用场景,并提供实际开发中的调试技巧与常见问题解决方案,帮助开发者深入理解设备树与驱动的协同工作方式。

t8u9v0的博客 710

设备树和Platform架构--6-platform_driver及match

1 概述 (1)Linux设备模型使用了三个数据结构分别来描述总线、设备和驱动。所有的设备和对应的驱动都必须挂载在某一个总线上,通过总线,可以绑定设备和驱动。这个属于分离的思想,将设备和驱动分开管理。 (2)Platform总线仅仅时诸多总线中的一种。platform总线的设计初衷:见《设备树和Platform架构--4--platform bus概述及其初始化》 (3)在设备树为引入到li...

huofengfeihu的博客 1090

platform总线、设备与驱动

Linux设备驱动开发详解:基于最新的Linux 4.0内核 (宋宝华)》一个现实的Linux设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB、PC、SPI等的设备而言,这自然不是问题,但是在嵌入式系统里面,在SoC系统中集成的独立外设控制器、挂接在SoC内存空间的外设等却不依附于此类总线。基于这一背景,相应的设备称为,而驱Linux发明了一种虚拟的总线,称为platform总线,而驱动成为。,而它们本身就是字符设备。

张哈哈的博客 1093

platform平台驱动模型简述(linux驱动开发篇)

此篇是驱动分离(总线、驱动和设备模型)的应用扩展,主要简述platform平台 1. platform总线 总线(IIC、SPI、USB等),platform应该叫做虚拟总线 /****************************** ***bus_type结构体表示总线******* ******************************/ struct bus_type { const char *name; /* 总线名字

栋哥修炼日记 3526

如何理解驱动程序、设备树、platform、device、driver之间的关系

理解驱动程序、设备树、platform、device、driver之间的关系,学习利用设备树来使用或者编写驱动程序

weixin_42408707的博客 6532

3.6platform_device和platform_driver如何让匹配

分析 主要是在匹配函数里面的支持设备树。 struct bus_type platform_bus_type = { .name = "platform", .dev_groups = platform_dev_groups, .match = platform_match, .uevent = platform_uevent, .dma_configure = ...

qq_34738528的博客 189
上一篇: 内核编译版本号带有+问题
下一篇: 设备树 — platform_device和platform_driver如何让匹配
mtOS1573
博客等级 码龄15年 305粉丝 188原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值