驱动开发笔记——platform_set_drvdata分析

函数static inline void platform_set_drvdata(struct platform_device *pdev, void *data)目的存储用户在probe()中主动申请的内存区域的指针以防止丢失,static inline void *platform_get_drvdata(const struct platform_device *pdev)则是将其取出。

函数platform_set_drvdata()和platform_get_drvdata(),定义于..\include\linux\platform_device.h:

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


分析发现,函数platform_set_drvdata()调用了函数dev_set_drvdata(),函数dev_set_drvdata()定义于..\include\linux\Dd.h:

int dev_set_drvdata(struct device *dev, void *data)
{
	int error;
	
	if (!dev->p) {
		error = device_private_init(dev);
		if (error)
			return error;
	}
	dev->p->driver_data = data;
	return 0;
}

将data指向的内存地址赋予了dev->p->driver_data,分析platform_device结构体
platform_device 结构体定义于..\include\linux\platform_device.h:

struct platform_device {
	const char	* name;
	int		id;
	struct device	dev;
	u32		num_resources;
	struct resource	* resource;
	
	const struct platform_device_id	*id_entry;
	
	/* MFD cell pointer */
	struct mfd_cell *mfd_cell;
	
	/* arch specific additions */
	struct pdev_archdata	archdata;
};

device 结构体定义于..\include\linux\Device.h:

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 this
					   device */
	void		*platform_data;	/* Platform specific data, device
					   core doesn't touch it */
	struct dev_pm_info	power;
	struct dev_pm_domain	*pm_domain;
	
#ifdef CONFIG_NUMA
	int		numa_node;	/* NUMA node this device is close to */
#endif
	u64		*dma_mask;	/* dma mask (if dma'able device) */
	u64		coherent_dma_mask;/* Like dma_mask, but for
					     alloc_coherent mappings as
					     not all hardware supports
					     64 bit addresses for consistent
					     allocations such descriptors. */
	
	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 mem
					     override */
	/* arch specific additions */
	struct dev_archdata	archdata;
	
	struct device_node	*of_node; /* associated device tree 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);
};

device_private结构体定义于..\drivers\base\Base.h:

struct device_private {
	struct klist klist_children;
	struct klist_node knode_parent;
	struct klist_node knode_driver;
	struct klist_node knode_bus;
	struct list_head deferred_probe;
	void *driver_data;
	struct device *device;
};


你可能感兴趣的:(Linux-驱动)