使用函数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);
}