Platform 设备驱动:platform
Platform 设备驱动:platform
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)
- Annotation(注解)是什么?
- iOS annotation
- vmware装的ubuntu的界面怎么全屏?
- 服务器iis短文件名漏洞,IIS短文件名漏洞分析及一个实例
- AndroidWidget——GridView 学习笔记
- LruCache源码浅析
- 哀悼日, 网页变灰的实现
- mmap()
- Android 6.0 Marshmallow介绍
- CA6140车床拨叉工艺及铣30X80面夹具设计
- (转)Visual SourceSafe (VSS的使用方法)使用方法
- VC知识大全
- 1024专场回顾
- html5 调用手机摄像头详解
- Https单向认证和双向认证 认识和区别
- LSSVM分类和回归
- Vue面试题分享之Vue双向绑定数据原理