本文转载自:http://blog.csdn.net/angle_birds/article/details/8443695

platform_set_drvdata(struct platform_device *pdev, void *data)

platform_get_drvdata(const struct platform_device *pdev):
驱动中常用到platform_set_drvdata 和 platform_get_drvdata这两个函数,用于保存局部变量:
include/linux/platform_device.h中:
static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
        return dev_get_drvdata(&pdev->dev);
}
static inline void platform_set_drvdata(struct platform_device *pdev, void *data)
{
        dev_set_drvdata(&pdev->dev, data);
}
 
static inline void
dev_set_drvdata (struct device *dev, void *data)
{
    dev->driver_data = data;
}
就是吧data赋值给dev->driver_data,pdev是平台总线设备,对于整个驱动是可见的,所以可以通过platform_get_drvdata来获取data。
 
marvell sd驱动eg:
chip是在probe函数中定义的局部变量,如果想在其他地方使用它怎么办呢? 这就需要把它保存起来。内核提供了这个方法,使用函数platform_set_drvdata()可以将chip保存成平台总线设备的私有
数据。以后再要使用它时只需调用platform_get_drvdata()就可以了。
static int sdhci_mv_probe(struct platform_device *pdev)
{
 struct sdhci_mv_chip *chip;
 struct sdhci_mv_slot *slot;
 chip = kzalloc(sizeof(struct sdhci_mv_chip), GFP_KERNEL);
 if (!chip) {
  ret = -ENOMEM;
  goto err;
 }
 chip->fixes = (sdhci_mv_get_interface(pdev) == INTERFACE_SDIO0)? &sdhci0_fixes : &sdhci1_fixes;
 if (chip->fixes)
     chip->quirks = chip->fixes->quirks;
 platform_set_drvdata(pdev, chip);
}
chip是局部变量,在驱动其他函数使用时,eg:
static int __devexit sdhci_mv_remove(struct platform_device *pdev)
{
 int i;
 struct sdhci_mv_chip *chip;
 chip = platform_get_drvdata(pdev);
 if (chip) {
  for (i = 0;i < chip->num_slots; i++)
   sdhci_mv_remove_slot(chip->slots[i]);
  platform_set_drvdata(pdev, NULL);
  kfree(chip);
 }
 return 0;
}
 
container_of(ptr, type, member)
问题:如何通过结构中的某个变量获取结构本身的指针???
container_of(ptr, type, member)宏的作用是 传入结构体类型type的域member的地址ptr,返回该结构体变量的首地址。
member是结构体类型type的成员,ptr是成员member的实例,返回ptr的入口地址;即通过结构体中一个成员的地址来得到此成员所在结构体的地址。
关于container_of见kernel.h中:
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr:     the pointer to the member.
* @type:     the type of the container struct this is embedded in.
* @member:     the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({             /
         const typeof( ((type *)0)->member ) *__mptr = (ptr);     /
         (type *)( (char *)__mptr - offsetof(type,member) );})
container_of在Linux Kernel中的应用非常广泛,它用于获得某结构中某成员的入口地址.
 
 
/* sprd keypad backlight */
struct sprd_lcd_led {
struct platform_device *pdev;
struct mutex mutex;
struct work_structwork;
spinlock_t value_lock;
enum led_brightness value;
struct led_classdev cdev;
int enabled;
int suspend;
struct early_suspend sprd_early_suspend_desc;
};
static void led_work(structwork_struct*work)
{                                       // 传入的参数是结构体类型sprd_lcd_led 的成员work的实例的地址
structsprd_lcd_led*led =container_of(work, struct sprd_lcd_led, work);
unsigned long flags;
mutex_lock(&led->mutex);
spin_lock_irqsave(&led->value_lock, flags);
if (led->value == LED_OFF || led->suspend) {
spin_unlock_irqrestore(&led->value_lock, flags);
sprd_led_disable(led);
goto out;
}
spin_unlock_irqrestore(&led->value_lock, flags);
sprd_led_enable(led);
out:
mutex_unlock(&led->mutex);
}
static void sprd_lcd_led_shutdown(structplatform_device*pdev) 
{                                          //传入的参数为platform_device 类型,所以使用platform_get_drvdata()来获取platform_device->device->driver_data

struct sprd_lcd_led*led =platform_get_drvdata(pdev);
mutex_lock(&led->mutex);
led->value = LED_OFF;
led->enabled = 1;
sprd_led_disable(led);
mutex_unlock(&led->mutex);
}

static int sprd_lcd_led_probe(structplatform_device*pdev)
{
struct sprd_lcd_led*led;//局部变量
int ret;
...............................................
led = kzalloc(sizeof(*led), GFP_KERNEL);
platform_set_drvdata(pdev, led);//局部变量保存到pdev->dev->driver_data      (platform_device->device->driver_data)
...............................................
}

platform_set_drvdata()/platform_get_drvdata()/container_of()【转】的更多相关文章

  1. platform_set_drvdata 和 platform_get_drvdata

    ndev是我们在probe函数中定义的局部变量,如果我想在其他地方使用它怎么办呢? 这就需要把它保存起来.内核提供了这个方法,使用函数platform_set_drvdata()可以将ndev保存成平 ...

  2. platform_set_drvdata和platform_get_drvdata用法【转】

    本文转载自:http://www.cnblogs.com/wangxianzhen/archive/2013/04/09/3009530.html 在用到Linux设备驱动的platform框架时,常 ...

  3. linux中offsetof与container_of宏定义

    linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER)    ((size_t) &((TYPE *)0)->M ...

  4. 刨一刨内核container_of()的设计精髓

    新年第一帖,总得拿出点干货才行,虽然这篇水分还是有点大,大家可以晒干了温水冲服.这段时间一直在整理内核学习的基础知识点,期间又碰到了container_of()这个宏,当然还包括一个叫做offseto ...

  5. (转)offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  6. linux内核宏container_of

    首先来个简单版本 /* given a pointer @ptr to the field @member embedded into type (usually * struct) @type, r ...

  7. linux tricks 之 container_of.

    转载:http://blog.chinaunix.net/uid-20608849-id-3027972.html 由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数 ...

  8. (十)Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  9. typeof、offsetof、container_of的解释

    链表是内核最经典的数据结构之一,说到链表就不得不提及内核最经典(没有之一)的宏container_of. container_of似乎就是为链表而生的,它的主要作用是根据一个结构体变量中的一个域成员变 ...

随机推荐

  1. Presto查询引擎简单分析

    Hive查询流程分析 各个组件的作用 UI(user interface)(用户接口):提交数据操作的窗口Driver(引擎):负责接收数据操作,实现了会话句柄,并提供基于JDBC / ODBC的ex ...

  2. HDU 4081 Qin Shi Huang's National Road System 最小生成树+倍增求LCA

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 Qin Shi Huang's National Road System Time Limit: ...

  3. 某考试 T3 bitboard

                    bitboardDiscription    天才发明家小K 制造了一块比特板.板子上有2^n个比特元,编号为0 ∼ 2^n−1.每个比特元

  4. SSM框架CRUD小案例

    1.数据库准备 部门tbl_dept 员工tbl_emp 建立员工和部门的外键 2.在IDEA创建SSM项目环境 2.1配置Web模块 最上面的图是错误示范,注意!!! 在Tomcat配置了项目路径, ...

  5. servlet跳转页面后图片不显示

    我是用图片的相对路径,原先直接打开jsp的话图片是可以正常显示的,通过servlet跳转之后图片就显示不出来了 后来发现是图片路径的问题, 我是将图片放在WebRoot里面自己创建的img中,原先图片 ...

  6. 获取path的几种方式:NSFileManager NSHomeDirectory NSBundle

    //---------------------------------------------------------------------------------NSFileManager *fi ...

  7. js转换金额为中文大写

    function changeMoneyToChinese(money){ var cnNums = new Array("零","壹","贰&quo ...

  8. 算法之美--3.2.2 MP算法

    这块硬骨头,放在这里半年的时间了,一直没有动,今天周末看看,书上把过程写的比较详细,自己基本也看懂了,但是对代码本身的编写还是比较生疏,要经常复习,估计才能看透,后面有看了kmp;这两者之间的关系也是 ...

  9. MySQL常用SQL整理

    MySQL常用SQL整理 一.DDL #创建数据库 CREATE DATABASE IF NOT EXISTS product DEFAULT CHARSET utf8 COLLATE utf8_ge ...

  10. C#串口通信发送数据

    1 发送数据 需要2个串口 http://www.openedv.com/thread-228847-1-1.html 下载源文件 File_Protocol_Test.rar