天天看点

Linux驱动之platform_set_drvdata与platform_get_drvdata

作者:有AI野心的电工和码农

probe函数中定义的局部变量,如果我想在其他地方使用它怎么办呢?这就需要把它保存起来。

内核提供了这个方法,使用函数platform_set_drvdata()可以将ndev保存成平台总线设备的私有数据。以后再要使用它时只需调用platform_get_drvdata()就可以了。

#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))

/*   /drivers/base/dd.c  */

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;  
}           
/* /linux/device.h */

struct device {  
    struct device       *parent;  

    struct device_private   *p;  

    struct kobject kobj;  
    const char      *init_name; /* initial name of the device */  
    struct device_type  *type;  

    struct semaphore    sem;    /* semaphore 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;  

#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;  

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

继续阅读