platform_set_drvdata的源码分析

使用函数platform_set_drvdata()可以将radio保存成平台总线设备的私有数据。以后再要使用它时只需调用platform_get_drvdata()就可以了


struct marimba_fm_platform_data *tavarua_pdata;
	struct tavarua_device *radio;
	int retval;
	int i;
	FMDBG("%s: probe called\n", __func__);
	/* private data allocation */
	radio = kzalloc(sizeof(struct tavarua_device), GFP_KERNEL);
	if (!radio) {
		retval = -ENOMEM;
	goto err_initial;
	}


	radio->marimba = platform_get_drvdata(pdev);
	tavarua_pdata = pdev->dev.platform_data;
	radio->pdata = tavarua_pdata;
	radio->dev = &pdev->dev;
	platform_set_drvdata(pdev, radio);

	/* video device allocation */
	radio->videodev = video_device_alloc();
	if (!radio->videodev)
		goto err_radio;


	/* initial configuration */
	memcpy(radio->videodev, &tavarua_viddev_template,
	  sizeof(tavarua_viddev_template));


	/*allocate internal buffers for decoded rds and event buffer*/
	for (i = 0; i < TAVARUA_BUF_MAX; i++) {
		int kfifo_alloc_rc=0;
		spin_lock_init(&radio->buf_lock[i]);


		if (i == TAVARUA_BUF_RAW_RDS)
			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
				rds_buf*3, GFP_KERNEL);
		else if (i == TAVARUA_BUF_RT_RDS)
			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
				STD_BUF_SIZE * 2, GFP_KERNEL);
		else
			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
				STD_BUF_SIZE, GFP_KERNEL);


		if (kfifo_alloc_rc!=0) {
			printk(KERN_ERR "%s: failed allocating buffers %d\n",
				__func__, kfifo_alloc_rc);
			goto err_bufs;
		}
	}
	/* initializing the device count  */
	atomic_set(&radio->users, 1);
	radio->xfr_in_progress = 0;
	radio->xfr_bytes_left = 0;
static inline void platform_set_drvdata(struct platform_device *pdev, void *data)
{
	dev_set_drvdata(&pdev->dev, data);
}
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;
}
EXPORT_SYMBOL(dev_set_drvdata);


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 */
	struct list_head	deferred_probe;
	void		*platform_data;	/* Platform specific data, device
					   core doesn't touch it */
	struct dev_pm_info	power;
	struct dev_power_domain	*pwr_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" */

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










原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124149.html