Linux version: 4.14

Code link: Linux source code (v4.14) - Bootlin


1 函数原型

(1) platform_get_drvdata  [ include/linux/platform_device.h: 211 ]

static inline void *platform_get_drvdata(const struct platform_device *pdev)
{return dev_get_drvdata(&pdev->dev);
}

其中 dev_get_drvdata  [ include/linux/device.h: 1024 ]

static inline void *dev_get_drvdata(const struct device *dev)
{return dev->driver_data;
}

(2)platform_set_drvdata  [ include/linux/platform_device.h: 216 ]

static inline void platform_set_drvdata(struct platform_device *pdev,void *data)
{dev_set_drvdata(&pdev->dev, data);
}

其中 dev_set_drvdata  [ include/linux/device.h: 1029 ]

static inline void dev_set_drvdata(struct device *dev, void *data)
{dev->driver_data = data;
}

2 涉及的变量类型

(1)platform_device  [ include/linux/platform_device.h: 23 ]

platform_device 是 platform设备结构体,主要关注里面 struct device dev;

struct platform_device {const char   *name;int       id;bool     id_auto;struct device   dev;u32     num_resources;struct resource   *resource;const struct platform_device_id   *id_entry;char *driver_override; /* Driver name to force a match *//* MFD cell pointer */struct mfd_cell *mfd_cell;/* arch specific additions */struct pdev_archdata    archdata;
};

(2)device  [ include/linux/device.h: 888 ]

device 是一个通用的设备结构体,里面放的是每个设备都会有的通用数据。我们主要关注 void *platform_data; 这个变量。

struct device {struct device     *parent;struct device_private   *p;struct kobject kobj;const char       *init_name; /* initial name of the device */const struct device_type *type;struct mutex     mutex;  /* mutex to synchronize calls to* its driver.*/struct bus_type  *bus;       /* type of bus device is on */struct device_driver *driver; /* which driver has allocated thisdevice */void     *platform_data; /* Platform specific data, devicecore doesn't touch it */void      *driver_data;   /* Driver data, set and get withdev_set/get_drvdata */struct dev_links_info links;struct dev_pm_info    power;struct dev_pm_domain  *pm_domain;#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAINstruct irq_domain    *msi_domain;
#endif
#ifdef CONFIG_PINCTRLstruct dev_pin_info    *pins;
#endif
#ifdef CONFIG_GENERIC_MSI_IRQstruct list_head   msi_list;
#endif#ifdef CONFIG_NUMAint     numa_node;  /* NUMA node this device is close to */
#endifconst struct dma_map_ops *dma_ops;u64     *dma_mask;  /* dma mask (if dma'able device) */u64     coherent_dma_mask;/* Like dma_mask, but foralloc_coherent mappings asnot all hardware supports64 bit addresses for consistentallocations such descriptors. */unsigned long  dma_pfn_offset;struct device_dma_parameters *dma_parms;struct list_head dma_pools;  /* dma pools (if dma'ble) */struct dma_coherent_mem    *dma_mem; /* internal for coherent memoverride */
#ifdef CONFIG_DMA_CMAstruct cma *cma_area;      /* contiguous memory area for dmaallocations */
#endif/* arch specific additions */struct dev_archdata  archdata;struct device_node *of_node; /* associated device tree node */struct fwnode_handle *fwnode; /* firmware device node */dev_t            devt;   /* dev_t, creates the sysfs "dev" */u32           id; /* device instance */spinlock_t     devres_lock;struct list_head    devres_head;struct klist_node   knode_class;struct class        *class;const struct attribute_group **groups;   /* optional groups */void   (*release)(struct device *dev);struct iommu_group   *iommu_group;struct iommu_fwspec    *iommu_fwspec;bool          offline_disabled:1;bool         offline:1;bool          of_node_reused:1;
};

(3)void *platform_data

platform_data 用来存放平台相关的初始化数据。使用 void * 可以让数据类型存在多种可能,即满足不同设备驱动的数据都能通过指针传参。其实这里是用来存放 platform_device 数据结构的,通过 platform_driver 和 platform_device 的名字进行匹配后,platform_driver 部分就可以使用platform_device 传过来的数据了。

小结:platform_get_drvdata 即为通过传入 struct platform_device 结构体类型的指针,得到设备传给驱动的数据。而 platform_set_drvdata 则将 platform_data 指向传入的数据。

3 应用例程

例如,对于DM9000网卡,为platform_data定义一个dm9000_plat_data结构体,定义完后,可以将MAC地址、总线宽度、板上有无EEPROM信息等放入platform_data中。

static struct dm9000_plat_data dm9000_platdata = {.flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
};static struct platform_device dm9000_device = {.name = "dm9000",.id = 0,.num_resources = ARRAY_SIZE(dm9000_resource),.resource = dm9000_resource,.dev = {.platform_data = &dm9000_platdata, // 自定义设备数据}
};

在DM9000网卡驱动的probe()中,可这样拿到platform_data:

struct dm9000_plat_data *pdata = platform_get_drvdata(pdev);

4 参考

深度讲解Linux设备驱动的软件架构 - 知乎 (zhihu.com)

Platform 设备驱动:platform_get_drvdata 与 platform_set_drvdata相关推荐

  1. platform 设备驱动实验

    目录 Linux 驱动的分离与分层 驱动的分隔与分离 驱动的分层 platform 平台驱动模型简介 platform 总线 platform 驱动 platform 设备 硬件原理图分析 试验程序编 ...

  2. Linux 设备驱动开发 —— platform 设备驱动

    一.platform总线.设备与驱动         在Linux 2.6 的设备驱动模型中,关心总线.设备和驱动3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反 ...

  3. Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用

    关与设备树的概念,我们在Exynos4412 内核移植(六)-- 设备树解析 里面已经学习过,下面看一下设备树在设备驱动开发中起到的作用 Device Tree是一种描述硬件的数据结构,设备树源(De ...

  4. Linux驱动之platform设备驱动

    当我们在一块开发板上写好了驱动,但换一块不同芯片的开发板,我们就需要重新写一个驱动.其中主要是硬件连接也就是接口发生了改变,而软件框架几乎不用通用的.所以为了更加方便地移植,能够仅修改很小的内容就达到 ...

  5. Linux驱动-platform设备驱动

    #1 platform设备驱动模型数据结构 一般总线驱动设备数据结构 驱动 总线 设备 device_driver bus_type device 一般总线驱动设备数据结构 驱动 总线 设备 plat ...

  6. Linux platform 设备驱动实验-基于正点原子IMX6ULL开发板

    我们以前的设备驱动都非常的简单,都是对IO进行最简单的读写操作.像I2C. SPI.LCD 这些复杂外设的驱动就不能这么去写了,Linux 系统要考虑到驱动的可重用性,因此提出了驱动的分离与分层这样的 ...

  7. linux设备驱动归纳总结(九):1.platform设备驱动

    http://blog.chinaunix.net/uid-25014876-id-111745.html 这一节可以理解是第八章的延伸,从这节开始介绍platform设备驱动. 一.什么是paltf ...

  8. Linux 设备驱动开发 —— platform设备驱动应用实例解析

    前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 -- platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...

  9. platform设备驱动全透析(转自宋宝华老师)

    platform设备驱动全透析(转自宋宝华老师) 2013-04-12 09:58 384人阅读 评论(0) 收藏 举报 分类: linux kernel(22) 1.1 platform总线.设备与 ...

  10. STM32MP157驱动开发——platform设备驱动(中)

    STM32MP157驱动开发--platform设备驱动(中) 0.前言 一.platform设备模块--设备信息解析 二.platform驱动模块--加载设备 三.测试App 四.编译及运行 相关文 ...

最新文章

  1. python有相关的证书可以考吗-学python需要考证吗?考证有什么好处?
  2. Machine Learning week 6 quiz: programming assignment-Regularized Linear Regression and Bias/Variance
  3. [转载].怎样在有限状态机中延时
  4. MySQL数据库安装Version5.5
  5. Linux常用命令备忘(启动管理、文件或目录管理、系统管理)
  6. eks volumn s3_和平精英:SMG战队无缘总决赛,S3前提退场原因一览
  7. ibatis Clob对象处理
  8. 前端必须要有的学习能力
  9. 人脸识别-YOLOv5模型目标检测
  10. 大数据的4v特征及思考_大数据智能下数据脱敏的思考
  11. Python Pandas常用数据结构Series和DataFrame快速上手
  12. 魔方游戏程序设计制作(C语言)
  13. 在Vue项目中使用LayUI教程且解决laydate无效的问题
  14. 万豪酒店集团5亿客户记录泄露
  15. Python学习基础方便查询
  16. SQL语句LIKE CONCAT模糊查询
  17. Java--敲重点!JDK1.8 HashMap特性及底层数组+单链表+红黑树知识(建议收藏)
  18. EXCEL中对一列数据每隔n行提取数据出来
  19. 电子面单接口申请对接(返回电子面单模板)
  20. 计算机组成原理中op,计算机组成原理课程习题答案秦磊华

热门文章

  1. 南方电网计算机招聘笔试,南方电网招聘笔试题(附答案).PDF
  2. CAD图层亮度的设置
  3. wireshark无法测同一个局域网固定ip的数据_局域网安全攻防
  4. 前端学习案例16-js中的HMR
  5. 如何定义一个具有返回值的函数
  6. jsonp跨域原理及使用
  7. Python 之 如何一行输入多个整数
  8. Python+opencv 人脸识别
  9. Java利器之UML类图详解
  10. android手机华为p10,华为P10的手机系统是什么