当前位置:   article > 正文

嵌入式软件开发之------浅析linux驱动模型(五)I2C驱动_i2c_generic_chip_drv 挂死

i2c_generic_chip_drv 挂死

Linux代码版本:linux3.0
开发板环境: tiny4412
导读:i2c控制器作为platform_device挂接在platform总线上,在《嵌入式软件开发之------浅谈linux驱动模型(四)device和driver》以i2c控制器为例,分析了

s3c_device_i2c1和s3c24xx_i2c_driver的注册过程,总结下来就是下图:

每个i2c控制器都是一个i2c 总线,i2c控制器即挂接在platform总线上,也为i2c提供总线。platform总线有platform_device和platform_driver,相应的i2c总线也有对应的device和driver,只不过是i2c_client和i2c_driver.

一、i2c_adapter的注册及 i2c_client 的实例化

下面看i2c_client,有没有觉得和platform_device很像?都是封装了devcie后添加了部分各自特点的成员:

  1. struct i2c_client {
  2. unsigned short flags; /* div., see below */
  3. unsigned short addr; /* chip address - NOTE: 7bit */
  4. /* addresses are stored in the */
  5. /* _LOWER_ 7 bits */
  6. char name[I2C_NAME_SIZE];
  7. struct i2c_adapter *adapter; /* the adapter we sit on */
  8. struct i2c_driver *driver; /* and our access routines */
  9. struct device dev; /* the device structure */
  10. int irq; /* irq issued by device */
  11. struct list_head detected;
  12. };

unsigned short flags;

标志,用 I2C_CLIENT_TEN 表示 10 bit 地址,用 I2C_CLIENT_PEC 表示SMBus的错误数据检测

unsigned short addr;

器件的地址

char name[I2C_NAME_SIZE];

设备的名字,在 new_device 属性文件中,低7位代表地址

struct i2c_adapter *adapter; /* the adapter we sit on */
虽然是挂接在I2C总线上的,client->dev.bus = &i2c_bus_type,可是 总要 指向所在的i2c控制器吗

 

struct i2c_driver *driver; /* and our access routines */

 

对应的驱动

struct device dev; /* the device structure */

封装的device结构体

int irq; /* irq issued by device */

用来表示此设备产生的IRQ

struct list_head detected;

用于插入 i2c_driver.clients 的节点,在遍历 i2c_drive r探测到实际挂接在 i2c_adapter 但又未注册

的 i2c 设备时,实例化成 i2c_client 后以此成员插入 i2c_driver.clients。

看到i2c_client就不得不看i2c设备的注册,这个时候可能有人会说,大概和platform设备注册差不多吧,确实 差不多,可还是有点区别下面就以mma7660为例,

  1. static struct i2c_board_info i2c_devs3[] __initdata = {
  2. {
  3. I2C_BOARD_INFO("mma7660", 0x4c),
  4. .platform_data = &mma7660_pdata,
  5. },
  6. };

展开

  1. static struct i2c_board_info i2c_devs3[] __initdata = {
  2. {
  3. .type = "mma7660",
  4. .addr = 0x4c
  5. .platform_data = &mma7660_pdata,
  6. },
  7. };

有没有发现什么不对?不是说i2c设备的结构体说 i2c_client ?咋变成了 i2c_board_info ?platform_device就是对应的啊。这里面肯定有蹊跷,i2c_board_info 最后肯定还得转成成 i2c_client,是的,这既是i2c设备的实例化,从定义的 i2c_board_info 组装成 i2c_client,这个过程将在代码中分析。接下来看一下 platform_device通过 platform_device_register来注册 ,那么 i2c_board_info 设备是通过i2c_register_board_info。

先看下 i2c_board_info 结构体

  1. struct i2c_board_info {
  2. char type[I2C_NAME_SIZE];
  3. unsigned short flags;
  4. unsigned short addr;
  5. void *platform_data;
  6. struct dev_archdata *archdata;
  7. struct device_node *of_node;
  8. int irq;
  9. };

再看一个结构体,下面会用到

  1. struct i2c_devinfo {
  2. struct list_head list;
  3. int busnum;
  4. struct i2c_board_info board_info;
  5. };

下面再看 i2c_register_board_info 实例

  1. i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
  2. {
  3. int status;
  4. down_write(&__i2c_board_lock);
  5. /* dynamic bus numbers will be assigned after the last static one */
  6. /*__i2c_first_dynamic_bus_num总是要比最大的bus号大1,后面会用到*/
  7. if (busnum >= __i2c_first_dynamic_bus_num)
  8. __i2c_first_dynamic_bus_num = busnum + 1;
  9. for (status = 0; len; len--, info++) {
  10. struct i2c_devinfo *devinfo;
  11. devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
  12. if (!devinfo) {
  13. pr_debug("i2c-core: can't register boardinfo!\n");
  14. status = -ENOMEM;
  15. break;
  16. }
  17. /*将i2c_board_info的信息赋值给 devinfo ,然后将devinfo插入 __i2c_board_list ,所有的i2c设备都会插入
  18. __i2c_board_list,所以一定要记住__i2c_board_list,
  19. devinfo->busnum = 3
  20. devinfo->board_info = &i2c_devs3 */
  21. devinfo->busnum = busnum;
  22. devinfo->board_info = *info;
  23. list_add_tail(&devinfo->list, &__i2c_board_list);
  24. }
  25. up_write(&__i2c_board_lock);
  26. return status;
  27. }

上面的知识将在下面的代码中用到,下面接着 分析 s3c24xx_i2c_probe,由于是在分析驱动框架,不是分析BSP,

硬件设备千变万化,看芯片手册写或者调试驱动是一个驱动工程师的基本功,所以对于硬件相关的设置将省略。

下面接着分析经过platform总线匹配后调用的 s3c24xx_i2c_probe

 
  1. static int s3c24xx_i2c_probe(&s3c_device_i2c3)
  2. {
  3. struct s3c24xx_i2c *i2c;
  4. struct s3c2410_platform_i2c *pdata;
  5. struct resource *res;
  6. int ret;
  7. ......
  8. /*赋值 i2c->adap.name = "s3c2410-i2c",后面会用到*/
  9. strlcpy(i2c->adap.name, "s3c2410-i2c", sizeof(i2c->adap.name));
  10. /*i2c->adap进行复制,又看到了 THIS_MODULE 只有当此驱动编译成module的时候指向此模块
  11. ,如果没有编译成module则为NULL,绝大多数owner都是 THIS_MODULE */
  12. i2c->adap.owner = THIS_MODULE;
  13. /*i2c->adap.algo,对应实际硬件的通信方法,控制硬件产生读写时序的函数,adapter是对硬件控制器的抽象,
  14. 实际产生硬件通信时序的s3c24xx_i2c_algorithm*/
  15. i2c->adap.algo = &s3c24xx_i2c_algorithm;
  16. /*通信失败重新尝试的次数*/
  17. i2c->adap.retries = 2;
  18. /*此adapter支持的硬件类型,公共也就是三种 I2C_CLASS_HWMON、I2C_CLASS_SPD 和 I2C_CLASS_DDC
  19. 相应的,i2c_client或者i2c_driver肯定也会有相应的class来和 i2c->adap.class 匹配 */
  20. i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
  21. ......
  22. /* setup info block for the i2c core */
  23. i2c->adap.algo_data = i2c;
  24. /*i2c->adap.dev.parent 指向 s3c_device_i2c1 ,
  25. 意味着i2c->adap对应的目录会在/sys/devices/platform/s3c2440-i2c.3下*/
  26. i2c->adap.dev.parent = &pdev->dev;
  27. ......
  28. /* Note, previous versions of the driver used i2c_add_adapter()
  29. * to add the bus at any number. We now pass the bus number via
  30. * the platform data, so if unset it will now default to always
  31. * being bus 0.
  32. */
  33. /*此adapter所对应的i2c总线号,这里是通过 paltform_device的私有结构体传递,实际还有另一个代表
  34. /sys/devices/platform/s3c2440-i2c.3
  35. i2c总线号的,还记得 s3c_device_i2c3.id = 3吗*/
  36. i2c->adap.nr = pdata->bus_num;
  37. /*注册adapter*/
  38. ret = i2c_add_numbered_adapter(&i2c->adap);
  39. {
  40. int id;
  41. int status;
  42. if (adap->nr & ~MAX_ID_MASK)
  43. return -EINVAL;
  44. /*下面涉及idr机制,简单的说idr机制就是将一个整数id和特定指针映射起来,然后可以通过id号
  45. 找到对应的指针*/
  46. retry:
  47. /*为idr分配内存,通过idr获取id之前需要先分配内存*/
  48. if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
  49. return -ENOMEM;
  50. mutex_lock(&core_lock);
  51. /* "above" here means "above or equal to", sigh;
  52. * we need the "equal to" result to force the result
  53. */
  54. /*分配id号并和adap指针关联,对于i2c adapter分配的id就是bus号,所以下面会有
  55. id和adap->nr的判断*/
  56. status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id);
  57. if (status == 0 && id != adap->nr) {
  58. status = -EBUSY;
  59. idr_remove(&i2c_adapter_idr, id);
  60. }
  61. mutex_unlock(&core_lock);
  62. if (status == -EAGAIN)
  63. goto retry;
  64. if (status == 0)
  65. /*开始注册adapter*/
  66. status = i2c_register_adapter(adap);
  67. {
  68. int res = 0;
  69. /* Can't register until after driver model init */
  70. /*i2c被初始化过才能注册adapter,显然注册 i2c_bus_type 就已经初始化过*/
  71. if (unlikely(WARN_ON(!i2c_bus_type.p))) {
  72. res = -EAGAIN;
  73. goto out_list;
  74. }
  75. /* Sanity checks */
  76. /*前面已经初始化 adap->name[0] = "s3c2410-i2c" */
  77. if (unlikely(adap->name[0] == '\0')) {
  78. pr_err("i2c-core: Attempt to register an adapter with "
  79. "no name!\n");
  80. return -EINVAL;
  81. }
  82. /*上面已经初始化过 i2c->adap.algo = &s3c24xx_i2c_algorithm */
  83. if (unlikely(!adap->algo)) {
  84. pr_err("i2c-core: Attempt to register adapter '%s' with "
  85. "no algo!\n", adap->name);
  86. return -EINVAL;
  87. }
  88. rt_mutex_init(&adap->bus_lock);
  89. mutex_init(&adap->userspace_clients_lock);
  90. INIT_LIST_HEAD(&adap->userspace_clients);
  91. /* Set default timeout to 1 second if not already set */
  92. /*上面没有初始化超时时间,所以默认设置为1s*/
  93. if (adap->timeout == 0)
  94. adap->timeout = HZ;
  95. /*赋值 i2c->adap->dev->kobj->name = "i2c-3",意味着将来创建目录的名字为 i2c-3 */
  96. dev_set_name(&adap->dev, "i2c-%d", adap->nr);
  97. /*adapter也是一个device,类型为 i2c_adapter_type ,所以指向i2c_bus_type,其本身提供具体的i2c总线*/
  98. adap->dev.bus = &i2c_bus_type;
  99. adap->dev.type = &i2c_adapter_type;
  100. /*下面即使device的注册过程*/
  101. res = device_register(&adap->dev);
  102. {
  103. device_initialize(dev);
  104. {
  105. /*adapter也是一个device,所以其 kobject 属于 devices_kset,类型为 device_ktype*/
  106. dev->kobj.kset = devices_kset;
  107. kobject_init(&dev->kobj, &device_ktype);
  108. INIT_LIST_HEAD(&dev->dma_pools);
  109. mutex_init(&dev->mutex);
  110. lockdep_set_novalidate_class(&dev->mutex);
  111. spin_lock_init(&dev->devres_lock);
  112. INIT_LIST_HEAD(&dev->devres_head);
  113. device_pm_init(dev);
  114. set_dev_node(dev, -1);
  115. }
  116. return device_add(dev);
  117. {
  118. struct device *parent = NULL;
  119. struct class_interface *class_intf;
  120. int error = -EINVAL;
  121. dev = get_device(dev);
  122. if (!dev)
  123. goto done;
  124. if (!dev->p) {
  125. error = device_private_init(dev);
  126. {
  127. dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
  128. if (!dev->p)
  129. return -ENOMEM;
  130. dev->p->device = dev;
  131. klist_init(&dev->p->klist_children, klist_children_get,
  132. klist_children_put);
  133. return 0;
  134. }
  135. if (error)
  136. goto done;
  137. }
  138. /*
  139. * for statically allocated devices, which should all be converted
  140. * some day, we need to initialize the name. We prevent reading back
  141. * the name, and force the use of dev_name()
  142. */
  143. /* i2c->adap->dev->init_name未被赋值,也就是为NULL*/
  144. if (dev->init_name) {
  145. dev_set_name(dev, "%s", dev->init_name);
  146. dev->init_name = NULL;
  147. }
  148. /* i2c->adap->dev->kobj->name = "i2c-3" ,所以此条件不会被满足 */
  149. if (!dev_name(dev)) {
  150. error = -EINVAL;
  151. goto name_error;
  152. }
  153. pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
  154. /*前面初始化 i2c->adap.dev.parent = &pdev->dev */
  155. parent = get_device(dev->parent);
  156. /*device层面的parent已经建立,setup_parent要建立kobject 层面 的parent关系*/
  157. setup_parent(dev, parent);
  158. /* use parent numa_node */
  159. /*NUMA架构一般应用于大型多CPU的设备,嵌入式单个多核CPU使用SMP架构*/
  160. if (parent)
  161. set_dev_node(dev, dev_to_node(parent));
  162. /* first, register with generic layer. */
  163. /* we require the name to be set before, and pass NULL */
  164. /*又看见kobject_add,在sys/devices/platform/s3c2440-i2c.3创建i2c-3目录*/
  165. error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
  166. if (error)
  167. goto Error;
  168. /* notify platform of device entry */
  169. /*暂时不知道具体用途,代码中极少给platform_notify赋值*/
  170. if (platform_notify)
  171. platform_notify(dev);
  172. /*在sys/devices/platform/s3c2440-i2c.1/i2c-3创建uevent文件*/
  173. error = device_create_file(dev, &uevent_attr);
  174. if (error)
  175. goto attrError;
  176. /*此时 i2c->adap->dev 还没有设备号,所以执行不到,等到 device_creat 的时候再详细分析*/
  177. if (MAJOR(dev->devt)) {
  178. error = device_create_file(dev, &devt_attr);
  179. if (error)
  180. goto ueventattrError;
  181. error = device_create_sys_dev_entry(dev);
  182. if (error)
  183. goto devtattrError;
  184. devtmpfs_create_node(dev);
  185. }
  186. error = device_add_class_symlinks(dev);
  187. {
  188. int error;
  189. /*i2c->adap->dev->class未赋值,也就是为NULL,在此返回*/
  190. if (!dev->class)
  191. return 0;
  192. error = sysfs_create_link(&dev->kobj,
  193. &dev->class->p->subsys.kobj,
  194. "subsystem");
  195. if (error)
  196. goto out;
  197. if (dev->parent && device_is_not_partition(dev)) {
  198. error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
  199. "device");
  200. if (error)
  201. goto out_subsys;
  202. }
  203. #ifdef CONFIG_BLOCK
  204. /* /sys/block has directories and does not need symlinks */
  205. if (sysfs_deprecated && dev->class == &block_class)
  206. return 0;
  207. #endif
  208. /* link in the class directory pointing to the device */
  209. error = sysfs_create_link(&dev->class->p->subsys.kobj,
  210. &dev->kobj, dev_name(dev));
  211. if (error)
  212. goto out_device;
  213. return 0;
  214. out_device:
  215. sysfs_remove_link(&dev->kobj, "device");
  216. out_subsys:
  217. sysfs_remove_link(&dev->kobj, "subsystem");
  218. out:
  219. return error;
  220. }
  221. if (error)
  222. goto SymlinkError;
  223. /*为 i2c->adap 创建属性文件*/
  224. error = device_add_attrs(dev);
  225. {
  226. struct class *class = dev->class;
  227. const struct device_type *type = dev->type;
  228. int error;
  229. /*i2c->adap->dev->class未赋值,也就是为NULL,在此返回*/
  230. if (class) {
  231. error = device_add_attributes(dev, class->dev_attrs);
  232. {
  233. int error = 0;
  234. int i;
  235. if (attrs) {
  236. for (i = 0; attr_name(attrs[i]); i++) {
  237. error = device_create_file(dev, &attrs[i]);
  238. if (error)
  239. break;
  240. }
  241. if (error)
  242. while (--i >= 0)
  243. device_remove_file(dev, &attrs[i]);
  244. }
  245. return error;
  246. }
  247. if (error)
  248. return error;
  249. error = device_add_bin_attributes(dev, class->dev_bin_attrs);
  250. if (error)
  251. goto err_remove_class_attrs;
  252. }
  253. /*前面赋值 i2c->adap->dev->type = &i2c_adapter_type,其中
  254. i2c_adapter_type->groups = i2c_adapter_attr_groups,
  255. i2c_adapter_attr_groups = &i2c_adapter_attr_group,
  256. i2c_adapter_attr_group->attr = i2c_adapter_attrs,
  257. i2c_adapter_attrs[] = {
  258. &dev_attr_name.attr,
  259. &dev_attr_new_device.attr,
  260. &dev_attr_delete_device.attr,
  261. NULL
  262. };
  263. 所以最终将在/sys/devices/platform/s3c2440-i2c.3/i2c-3下创建 name、new_device和delete_device的属性文件*/
  264. if (type) {
  265. error = device_add_groups(dev, type->groups);
  266. {
  267. int error = 0;
  268. int i;
  269. if (groups) {
  270. for (i = 0; groups[i]; i++) {
  271. error = sysfs_create_group(&dev->kobj, groups[i]);
  272. if (error) {
  273. while (--i >= 0)
  274. sysfs_remove_group(&dev->kobj,
  275. groups[i]);
  276. break;
  277. }
  278. }
  279. }
  280. return error;
  281. }
  282. if (error)
  283. goto err_remove_class_bin_attrs;
  284. }
  285. /*i2c->adap->dev->groups也是未初始化的*/
  286. error = device_add_groups(dev, dev->groups);
  287. if (error)
  288. goto err_remove_type_groups;
  289. return 0;
  290. err_remove_type_groups:
  291. if (type)
  292. device_remove_groups(dev, type->groups);
  293. err_remove_class_bin_attrs:
  294. if (class)
  295. device_remove_bin_attributes(dev, class->dev_bin_attrs);
  296. err_remove_class_attrs:
  297. if (class)
  298. device_remove_attributes(dev, class->dev_attrs);
  299. return error;
  300. }
  301. if (error)
  302. goto AttrsError;
  303. /*i2c->adap 添加到 i2c_bus_type*/
  304. error = bus_add_device(dev);
  305. {
  306. struct bus_type *bus = bus_get(dev->bus);
  307. int error = 0;
  308. if (bus) {
  309. pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
  310. error = device_add_attrs(bus, dev);
  311. {
  312. int error = 0;
  313. int i;
  314. /*由于i2c_bus_type->dev_attrs = NULL,
  315. 所以不会创建任何属性文件*/
  316. if (!bus->dev_attrs)
  317. return 0;
  318. for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
  319. error = device_create_file(dev, &bus->dev_attrs[i]);
  320. if (error) {
  321. while (--i >= 0)
  322. device_remove_file(dev, &bus->dev_attrs[i]);
  323. break;
  324. }
  325. }
  326. return error;
  327. }
  328. if (error)
  329. goto out_put;
  330. /*在注册i2c_bus_type的时候
  331. priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);
  332. 下面就是要在/sys/bus/i2c/devices创建指向 /sys/devices/platform/s3c2440-i2c.3/i2c-3
  333. 的链接,名字也为i2c-3*/
  334. error = sysfs_create_link(&bus->p->devices_kset->kobj,
  335. &dev->kobj, dev_name(dev));
  336. if (error)
  337. goto out_id;
  338. /*在/sys/devices/platform/s3c2440-i2c.3/i2c-3创建指向/sys/bus/i2c/的链接,
  339. 名字为subsystem*/
  340. error = sysfs_create_link(&dev->kobj,
  341. &dev->bus->p->subsys.kobj, "subsystem");
  342. if (error)
  343. goto out_subsys;
  344. /*将 i2c->adap 加入到i2c_bus_type->p->klist_devices链表中*/
  345. klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
  346. }
  347. return 0;
  348. out_subsys:
  349. sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
  350. out_id:
  351. device_remove_attrs(bus, dev);
  352. out_put:
  353. bus_put(dev->bus);
  354. return error;
  355. }
  356. if (error)
  357. goto BusError;
  358. /*电源管理相关,后面分析的电源管理机制的时候再详细分析*/
  359. error = dpm_sysfs_add(dev);
  360. if (error)
  361. goto DPMError;
  362. device_pm_add(dev);
  363. /* Notify clients of device addition. This call must come
  364. * after dpm_sysf_add() and before kobject_uevent().
  365. */
  366. if (dev->bus)
  367. blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  368. BUS_NOTIFY_ADD_DEVICE, dev);
  369. kobject_uevent(&dev->kobj, KOBJ_ADD);
  370. bus_probe_device(dev);
  371. {
  372. struct bus_type *bus = dev->bus;
  373. int ret;
  374. /* i2c_bus_type 注册的时候初始化 i2c_bus_type->p->drivers_autoprobe = 1
  375. /sys/bus/i2c 下的drivers_autoprobe,drivers_autoprobe被置1
  376. 则自动进行驱动匹配*/
  377. if (bus && bus->p->drivers_autoprobe) {
  378. ret = device_attach(dev);
  379. {
  380. int ret = 0;
  381. device_lock(dev);
  382. /*现在只注册 i2c->adap , i2c->adap ->dev->driver = NULL*/
  383. if (dev->driver) {
  384. if (klist_node_attached(&dev->p->knode_driver)) {
  385. ret = 1;
  386. goto out_unlock;
  387. }
  388. ret = device_bind_driver(dev);
  389. {
  390. int ret;
  391. ret = driver_sysfs_add(dev);
  392. if (!ret)
  393. driver_bound(dev);
  394. return ret;
  395. }
  396. if (ret == 0)
  397. ret = 1;
  398. else {
  399. dev->driver = NULL;
  400. ret = 0;
  401. }
  402. }
  403. else {
  404. pm_runtime_get_noresume(dev);
  405. /*通过 __device_attach 函数逐个匹配 i2c_bus_type->p->klist_drivers成员
  406. i2c->adap 只是作为一个device注册,没有所谓的驱动,类似 platform_bus 一样,*/
  407. ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
  408. pm_runtime_put_sync(dev);
  409. }
  410. out_unlock:
  411. device_unlock(dev);
  412. return ret;
  413. }
  414. WARN_ON(ret < 0);
  415. }
  416. }
  417. /*将 i2c->adap 加入 s3c_device_i2c3 的子设备链表*/
  418. if (parent)
  419. klist_add_tail(&dev->p->knode_parent,
  420. &parent->p->klist_children);
  421. /*将 i2c->adap 加入到class的设备链表中,目前 i2c->adap->dev->class = NULL */
  422. if (dev->class) {
  423. mutex_lock(&dev->class->p->class_mutex);
  424. /* tie the class to the device */
  425. klist_add_tail(&dev->knode_class,
  426. &dev->class->p->klist_devices);
  427. /* notify any interfaces that the device is here */
  428. /*暂时还没弄清class_interface的具体用途*/
  429. list_for_each_entry(class_intf,
  430. &dev->class->p->class_interfaces, node)
  431. if (class_intf->add_dev)
  432. class_intf->add_dev(dev, class_intf);
  433. mutex_unlock(&dev->class->p->class_mutex);
  434. }
  435. done:
  436. put_device(dev);
  437. return error;
  438. DPMError:
  439. bus_remove_device(dev);
  440. BusError:
  441. device_remove_attrs(dev);
  442. AttrsError:
  443. device_remove_class_symlinks(dev);
  444. SymlinkError:
  445. if (MAJOR(dev->devt))
  446. devtmpfs_delete_node(dev);
  447. if (MAJOR(dev->devt))
  448. device_remove_sys_dev_entry(dev);
  449. devtattrError:
  450. if (MAJOR(dev->devt))
  451. device_remove_file(dev, &devt_attr);
  452. ueventattrError:
  453. device_remove_file(dev, &uevent_attr);
  454. attrError:
  455. kobject_uevent(&dev->kobj, KOBJ_REMOVE);
  456. kobject_del(&dev->kobj);
  457. Error:
  458. cleanup_device_parent(dev);
  459. if (parent)
  460. put_device(parent);
  461. name_error:
  462. kfree(dev->p);
  463. dev->p = NULL;
  464. goto done;
  465. }
  466. }
  467. if (res)
  468. goto out_list;
  469. dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
  470. #ifdef CONFIG_I2C_COMPAT
  471. /* i2c_adapter_compat_class = class_compat_register("i2c-adapter");
  472. 在 sys/calss/i2c-adapter 目录下创建链接*/
  473. res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,adap->dev.parent);
  474. {
  475. int error;
  476. /* 在 sys/calss/i2c-adapter 目录下创建链接 指向 sys/devices/platform/s3c2440-i2c.3/i2c-3 的链接,名字仍为 i2c-3 */
  477. error = sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev));
  478. {
  479. return sysfs_do_create_link(kobj, target, name, 1);
  480. }
  481. if (error)
  482. return error;
  483. /*
  484. * Optionally add a "device" link (typically to the parent), as a
  485. * class device would have one and we want to provide as much
  486. * backwards compatibility as possible.
  487. */
  488. if (device_link) {
  489. /*在 sys/devices/platform/s3c2440-i2c.3/i2c-3 目录下创建指向 sys/devices/platform/s3c2440-i2c.3 ,名字为device */
  490. error = sysfs_create_link(&dev->kobj, &device_link->kobj,
  491. "device");
  492. if (error)
  493. sysfs_remove_link(cls->kobj, dev_name(dev));
  494. }
  495. return error;
  496. }
  497. if (res)
  498. dev_warn(&adap->dev,
  499. "Failed to create compatibility class link\n");
  500. #endif
  501. /* create pre-declared device nodes */
  502. /* 重点来了, i2c_client 的实例化,由 i2c_board_info 生成 i2c_client */
  503. if (adap->nr < __i2c_first_dynamic_bus_num)
  504. i2c_scan_static_board_info(adap);
  505. {
  506. struct i2c_devinfo *devinfo;
  507. down_read(&__i2c_board_lock);
  508. /*还记得前面 i2c_register_board_info 把所有的 i2c_board_info 都注册到 __i2c_board_list ,
  509. 下面就是遍历 __i2c_board_list ,查找 属于 i2c->adap 的设备 */
  510. list_for_each_entry(devinfo, &__i2c_board_list, list) {
  511. if (devinfo->busnum == adapter->nr
  512. && !i2c_new_device(adapter,&devinfo->board_info))
  513. {
  514. /*每查到一个 属于 i2c->adap 的设备 ,声明一个 i2c_client ,这里就以前面注册的 i2c_devs3 为例*/
  515. struct i2c_client *client;
  516. int status;
  517. client = kzalloc(sizeof *client, GFP_KERNEL);
  518. if (!client)
  519. return NULL;
  520. /*初始化该 i2c_client 所属的 adap */
  521. client->adapter = adap;
  522. /* client->dev.platform_data = i2c_devs3->platform_data = &mma7660_pdata*/
  523. client->dev.platform_data = info->platform_data;
  524. if (info->archdata)
  525. client->dev.archdata = *info->archdata;
  526. /*i2c_devs3->flags 未初始化,也就是为 0 */
  527. client->flags = info->flags;
  528. /*client->addr = 0x4c*/
  529. client->addr = info->addr;
  530. client->irq = info->irq;
  531. /* client->name = "mma7660" */
  532. strlcpy(client->name, info->type, sizeof(client->name));
  533. /* Check for address validity */
  534. /*检查 client->addr 的合法性 */
  535. status = i2c_check_client_addr_validity(client);
  536. if (status) {
  537. dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",
  538. client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);
  539. goto out_err_silent;
  540. }
  541. /* Check for address business */
  542. /*检查 i2c->adap 是否注册过 相同 address 的 i2c 期间,一个 i2c 总线上的器件address 必须唯一*/
  543. status = i2c_check_addr_busy(adap, client->addr);
  544. {
  545. struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
  546. {
  547. /*前面初始化 i2c->adap->dev->parent = s3c_device_i2c3->dev,所以 parent = NULL */
  548. struct device *parent = adapter->dev.parent;
  549. if (parent != NULL && parent->type == &i2c_adapter_type)
  550. return to_i2c_adapter(parent);
  551. else
  552. return NULL;
  553. }
  554. int result = 0;
  555. /* parent = NULL */
  556. if (parent)
  557. result = i2c_check_mux_parents(parent, addr);
  558. {
  559. struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
  560. int result;
  561. result = device_for_each_child(&adapter->dev, &addr,
  562. __i2c_check_addr_busy);
  563. if (!result && parent)
  564. result = i2c_check_mux_parents(parent, addr);
  565. return result;
  566. }
  567. if (!result)
  568. result = device_for_each_child(&adapter->dev, &addr,i2c_check_mux_children);
  569. {
  570. struct klist_iter i;
  571. struct device *child;
  572. int error = 0;
  573. if (!parent->p)
  574. return 0;
  575. klist_iter_init(&parent->p->klist_children, &i);
  576. while ((child = next_device(&i)) && !error)
  577. error = fn(child, data); //fn = i2c_check_mux_children
  578. {
  579. int result;
  580. if (dev->type == &i2c_adapter_type)
  581. result = device_for_each_child(dev, addrp,
  582. i2c_check_mux_children);
  583. else
  584. /*此地址已经被注册过,则返回 -EBUSY */
  585. result = __i2c_check_addr_busy(dev, addrp);
  586. {
  587. struct i2c_client *client = i2c_verify_client(dev);
  588. int addr = *(int *)addrp;
  589. if (client && client->addr == addr)
  590. return -EBUSY;
  591. return 0;
  592. }
  593. return result;
  594. }
  595. klist_iter_exit(&i);
  596. return error;
  597. }
  598. return result;
  599. }
  600. if (status)
  601. goto out_err;
  602. client->dev.parent = &client->adapter->dev;
  603. client->dev.bus = &i2c_bus_type;
  604. client->dev.type = &i2c_client_type;
  605. client->dev.of_node = info->of_node;
  606. /* client->dev->kobj = "3-004c" */
  607. dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
  608. client->addr);
  609. /*将 client 注册到 /sys/devices/platform/s3c2440-i2c.3/i2c-3 目录下,并创建 3-004c 目录,同事创建
  610. uevent、name和 new_device 属性文件和一些链接文件等等 */
  611. status = device_register(&client->dev);
  612. if (status)
  613. goto out_err;
  614. dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
  615. client->name, dev_name(&client->dev));
  616. return client;
  617. out_err:
  618. dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
  619. "(%d)\n", client->name, client->addr, status);
  620. out_err_silent:
  621. kfree(client);
  622. return NULL;
  623. }
  624. dev_err(&adapter->dev,
  625. "Can't create device at 0x%02x\n",
  626. devinfo->board_info.addr);
  627. }
  628. up_read(&__i2c_board_lock);
  629. }
  630. /* Notify drivers */
  631. mutex_lock(&core_lock);
  632. /*遍历已经注册 i2c_driver 和 i2c->adap ,然后探测 i2c->adap 上i2c_driver支持的地址,
  633. 如果已经注册则跳过,未注册但有该 i2c 设备,则进行实例化*/
  634. bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
  635. {
  636. struct klist_iter i;
  637. struct device_driver *drv;
  638. int error = 0;
  639. if (!bus)
  640. return -EINVAL;
  641. /*遍历 i2c_bus_type->p->klist_drivers ,然后调用 __process_new_adapter*/
  642. klist_iter_init_node(&bus->p->klist_drivers, &i,
  643. start ? &start->p->knode_bus : NULL);
  644. while ((drv = next_driver(&i)) && !error)
  645. error = fn(drv, data); //fn = __process_new_adapter
  646. {
  647. return i2c_do_add_adapter(to_i2c_driver(d), data);
  648. {
  649. /* Detect supported devices on that bus, and instantiate them */
  650. i2c_detect(adap, driver);
  651. { /* driver 所支持i2c设备的 address 列表*/
  652. const unsigned short *address_list;
  653. /* 声明一个临时的 i2c_client */
  654. struct i2c_client *temp_client;
  655. int i, err = 0;
  656. int adap_id = i2c_adapter_id(adapter);
  657. /*如果 */
  658. address_list = driver->address_list;
  659. if (!driver->detect || !address_list)
  660. return 0;
  661. /* Stop here if the classes do not match */
  662. if (!(adapter->class & driver->class))
  663. return 0;
  664. /* Set up a temporary client to help detect callback */
  665. temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
  666. if (!temp_client)
  667. return -ENOMEM;
  668. temp_client->adapter = adapter;
  669. for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
  670. dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
  671. "addr 0x%02x\n", adap_id, address_list[i]);
  672. temp_client->addr = address_list[i];
  673. err = i2c_detect_address(temp_client, driver);
  674. {
  675. struct i2c_board_info info;
  676. struct i2c_adapter *adapter = temp_client->adapter;
  677. int addr = temp_client->addr;
  678. int err;
  679. /* Make sure the address is valid */
  680. err = i2c_check_addr_validity(addr);
  681. {
  682. /*
  683. * Reserved addresses per I2C specification:
  684. * 0x00 General call address / START byte
  685. * 0x01 CBUS address
  686. * 0x02 Reserved for different bus format
  687. * 0x03 Reserved for future purposes
  688. * 0x04-0x07 Hs-mode master code
  689. * 0x78-0x7b 10-bit slave addressing
  690. * 0x7c-0x7f Reserved for future purposes
  691. */
  692. if (addr < 0x08 || addr > 0x77)
  693. return -EINVAL;
  694. return 0;
  695. }
  696. if (err) {
  697. dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n",
  698. addr);
  699. return err;
  700. }
  701. /* Skip if already in use */
  702. if (i2c_check_addr_busy(adapter, addr))
  703. {
  704. /*前面初始化 i2c->adap->dev->parent = s3c_device_i2c3->dev,所以 parent = NULL */
  705. struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
  706. int result = 0;
  707. if (parent)
  708. result = i2c_check_mux_parents(parent, addr);
  709. if (!result)
  710. result = device_for_each_child(&adapter->dev, &addr,i2c_check_mux_children);
  711. {
  712. struct klist_iter i;
  713. struct device *child;
  714. int error = 0;
  715. if (!parent->p)
  716. return 0;
  717. /*遍历 查询 i2c->adap 下的设备,也就是 i2c _client */
  718. klist_iter_init(&parent, &i);
  719. while ((child = next_device(&i)) && !error)
  720. error = fn(child, data); //fn = i2c_check_mux_children
  721. {
  722. int result;
  723. if (dev->type == &i2c_adapter_type)
  724. result = device_for_each_child(dev, addrp,i2c_check_mux_children);
  725. else
  726. result = __i2c_check_addr_busy(dev, addrp);
  727. {
  728. struct i2c_client *client = i2c_verify_client(dev);
  729. int addr = *(int *)addrp;
  730. if (client && client->addr == addr)
  731. return -EBUSY;
  732. return 0;
  733. }
  734. return result;
  735. }
  736. klist_iter_exit(&i);
  737. return error;
  738. }
  739. return result;
  740. }
  741. return 0;
  742. /* Make sure there is something at this address */
  743. if (!i2c_default_probe(adapter, addr))
  744. {
  745. int err;
  746. union i2c_smbus_data dummy;
  747. #ifdef CONFIG_X86
  748. if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON)
  749. && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA))
  750. err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
  751. I2C_SMBUS_BYTE_DATA, &dummy);
  752. else
  753. #endif
  754. if (!((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50)
  755. && i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
  756. err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
  757. I2C_SMBUS_QUICK, NULL);
  758. else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE))
  759. err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
  760. I2C_SMBUS_BYTE, &dummy);
  761. else {
  762. dev_warn(&adap->dev, "No suitable probing method supported\n");
  763. err = -EOPNOTSUPP;
  764. }
  765. return err >= 0;
  766. }
  767. return 0;
  768. /* Finally call the custom detection function */
  769. memset(&info, 0, sizeof(struct i2c_board_info));
  770. info.addr = addr;
  771. err = driver->detect(temp_client, &info);
  772. if (err) {
  773. /* -ENODEV is returned if the detection fails. We catch it
  774. here as this isn't an error. */
  775. return err == -ENODEV ? 0 : err;
  776. }
  777. /* Consistency check */
  778. if (info.type[0] == '\0') {
  779. dev_err(&adapter->dev, "%s detection function provided "
  780. "no name for 0x%x\n", driver->driver.name,
  781. addr);
  782. } else {
  783. struct i2c_client *client;
  784. /* Detection succeeded, instantiate the device */
  785. dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
  786. info.type, info.addr);
  787. /*驱动探测到 adapter 上有该驱动支持的设备但又未 注册 ,则给其实例化*/
  788. client = i2c_new_device(adapter, &info);
  789. if (client)
  790. list_add_tail(&client->detected, &driver->clients);
  791. else
  792. dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
  793. info.type, info.addr);
  794. }
  795. return 0;
  796. }
  797. if (unlikely(err))
  798. break;
  799. }
  800. kfree(temp_client);
  801. return err;
  802. }
  803. /* Let legacy drivers scan this bus for matching devices */
  804. if (driver->attach_adapter) {
  805. dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
  806. driver->driver.name);
  807. dev_warn(&adap->dev, "Please use another way to instantiate "
  808. "your i2c_client\n");
  809. /* We ignore the return code; if it fails, too bad */
  810. driver->attach_adapter(adap);
  811. }
  812. return 0;
  813. }
  814. }
  815. klist_iter_exit(&i);
  816. return error;
  817. }
  818. mutex_unlock(&core_lock);
  819. return 0;
  820. out_list:
  821. mutex_lock(&core_lock);
  822. idr_remove(&i2c_adapter_idr, adap->nr);
  823. mutex_unlock(&core_lock);
  824. return res;
  825. }
  826. return status;
  827. }
  828. if (ret < 0) {
  829. dev_err(&pdev->dev, "failed to add bus to i2c core\n");
  830. goto err_cpufreq;
  831. }
  832. platform_set_drvdata(pdev, i2c);
  833. dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
  834. clk_disable(i2c->clk);
  835. return 0;
  836. err_cpufreq:
  837. s3c24xx_i2c_deregister_cpufreq(i2c);
  838. err_irq:
  839. free_irq(i2c->irq, i2c);
  840. err_iomap:
  841. iounmap(i2c->regs);
  842. err_ioarea:
  843. release_resource(i2c->ioarea);
  844. kfree(i2c->ioarea);
  845. err_clk:
  846. clk_disable(i2c->clk);
  847. clk_put(i2c->clk);
  848. err_noclk:
  849. kfree(i2c);
  850. return ret;
  851. }

上面的主要工作,就是初始化 i2c_adapter 的硬件,并且注册 i2c_adapter ,注册后将会 遍历 __i2c_board_list 查找挂接在此  i2c_adapter 的 i2c_board_info ,然后实例化 成  i2c_client ,然后 遍历 已经注册的 i2c_driver ,查找此 i2c_adapter  是否有 已经注册的 i2c_driver 支持的 但又未 注册的 i2c 器件,查到后实例化成 i2c_client 并注册。

整个过程下来,仍然会生成一些 属性文件 和一些链接文件,下面关注 new_device 和 delete_device 两个属性文件。

static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);

展开

  1. struct device_attribute dev_attr_new_device = {
  2. .attr = {
  3. .name = "new_device",
  4. .mode = S_IWUSR
  5. },
  6. .show = NULL,
  7. .store = i2c_sysfs_new_device,
  8. }

看store函数

  1. static ssize_t i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,const char *buf, size_t count)
  2. {
  3. struct i2c_adapter *adap = to_i2c_adapter(dev);
  4. struct i2c_board_info info;
  5. struct i2c_client *client;
  6. char *blank, end;
  7. int res;
  8. memset(&info, 0, sizeof(struct i2c_board_info));
  9. blank = strchr(buf, ' ');
  10. if (!blank) {
  11. dev_err(dev, "%s: Missing parameters\n", "new_device");
  12. return -EINVAL;
  13. }
  14. if (blank - buf > I2C_NAME_SIZE - 1) {
  15. dev_err(dev, "%s: Invalid device name\n", "new_device");
  16. return -EINVAL;
  17. }
  18. memcpy(info.type, buf, blank - buf);
  19. /* Parse remaining parameters, reject extra parameters */
  20. res = sscanf(++blank, "%hi%c", &info.addr, &end);
  21. if (res < 1) {
  22. dev_err(dev, "%s: Can't parse I2C address\n", "new_device");
  23. return -EINVAL;
  24. }
  25. if (res > 1 && end != '\n') {
  26. dev_err(dev, "%s: Extra parameters\n", "new_device");
  27. return -EINVAL;
  28. }
  29. client = i2c_new_device(adap, &info);
  30. if (!client)
  31. return -EINVAL;
  32. /* Keep track of the added device */
  33. mutex_lock(&adap->userspace_clients_lock);
  34. list_add_tail(&client->detected, &adap->userspace_clients);
  35. mutex_unlock(&adap->userspace_clients_lock);
  36. dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
  37. info.type, info.addr);
  38. return count;
  39. }

new_device 文件就是为用户空间提供 一种添加 i2c 设备的接口,在不管 系统没有注册 此设备的时候 ,可以尝试通过 new_device 写入 i2c 期间的名字 添加该设备。

static DEVICE_ATTR(delete_device, S_IWUSR, NULL, i2c_sysfs_delete_device);

展开

  1. struct device_attribute dev_attr_delete_device = {
  2. .attr = {
  3. .name = "delete_device",
  4. .mode = S_IWUSR
  5. },
  6. .show = NULL,
  7. .store = i2c_sysfs_delete_device,
  8. }

查看 store 函数

  1. static ssize_t i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,const char *buf, size_t count)
  2. {
  3. struct i2c_adapter *adap = to_i2c_adapter(dev);
  4. struct i2c_client *client, *next;
  5. unsigned short addr;
  6. char end;
  7. int res;
  8. /* Parse parameters, reject extra parameters */
  9. res = sscanf(buf, "%hi%c", &addr, &end);
  10. if (res < 1) {
  11. dev_err(dev, "%s: Can't parse I2C address\n", "delete_device");
  12. return -EINVAL;
  13. }
  14. if (res > 1 && end != '\n') {
  15. dev_err(dev, "%s: Extra parameters\n", "delete_device");
  16. return -EINVAL;
  17. }
  18. /* Make sure the device was added through sysfs */
  19. res = -ENOENT;
  20. mutex_lock(&adap->userspace_clients_lock);
  21. list_for_each_entry_safe(client, next, &adap->userspace_clients,
  22. detected) {
  23. if (client->addr == addr) {
  24. dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
  25. "delete_device", client->name, client->addr);
  26. list_del(&client->detected);
  27. i2c_unregister_device(client);
  28. res = count;
  29. break;
  30. }
  31. }
  32. mutex_unlock(&adap->userspace_clients_lock);
  33. if (res < 0)
  34. dev_err(dev, "%s: Can't find device in list\n",
  35. "delete_device");
  36. return res;
  37. }

二、i2c_driver的注册

    上面的代码已经 实例化 i2c_client 并且注册,下面就该注册相应的 i2c_driver ,然后通过 i2c_bus_type 的 match 调用 到

i2c_driver->probe 即 mma7660_probe 。

  1. struct i2c_driver {
  2. unsigned int class;
  3. /* Notifies the driver that a new bus has appeared or is about to be
  4. * removed. You should avoid using this, it will be removed in a
  5. * near future.
  6. */
  7. int (*attach_adapter)(struct i2c_adapter *) __deprecated;
  8. int (*detach_adapter)(struct i2c_adapter *) __deprecated;
  9. /* Standard driver model interfaces */
  10. int (*probe)(struct i2c_client *, const struct i2c_device_id *);
  11. int (*remove)(struct i2c_client *);
  12. /* driver model interfaces that don't relate to enumeration */
  13. void (*shutdown)(struct i2c_client *);
  14. int (*suspend)(struct i2c_client *, pm_message_t mesg);
  15. int (*resume)(struct i2c_client *);
  16. /* Alert callback, for example for the SMBus alert protocol.
  17. * The format and meaning of the data value depends on the protocol.
  18. * For the SMBus alert protocol, there is a single bit of data passed
  19. * as the alert response's low bit ("event flag").
  20. */
  21. void (*alert)(struct i2c_client *, unsigned int data);
  22. /* a ioctl like command that can be used to perform specific functions
  23. * with the device.
  24. */
  25. int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
  26. struct device_driver driver;
  27. const struct i2c_device_id *id_table;
  28. /* Device detection callback for automatic device creation */
  29. int (*detect)(struct i2c_client *, struct i2c_board_info *);
  30. const unsigned short *address_list;
  31. struct list_head clients;
  32. };

 

unsigned int class;

此driver支持的i2c设备种类,用来和i2c_adapter中的class做对比,共三种类型I2C_CLASS_HWMON、I2C_CLASS_SPD 和 I2C_CLASS_DDC 

int (*attach_adapter)(struct i2c_adapter *) __deprecated;

i2c 总线增加设备时的回调函数,已经弃用

int (*detach_adapter)(struct i2c_adapter *) __deprecated;

i2c 总线移除设备时的回调函数,已经弃用

 

int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
void (*shutdown)(struct i2c_client *);
int (*suspend)(struct i2c_client *, pm_message_t mesg);
int (*resume)(struct i2c_client *);
void (*alert)(struct i2c_client *, unsigned int data);
int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
struct device_driver driver;

 

const struct i2c_device_id *id_table;

此driver兼容的设备列表,i2c_device_match 时会调用

int (*detect)(struct i2c_client *, struct i2c_board_info *);

发现设备时的回调函数,在代码中发现 未注册 设备时会调用

const unsigned short *address_list;

此驱动支持的地址列表,注册 i2c_adapter 或 i2c_driver 时会调用此 列表判断

 i2c_adapter 是否挂有此驱动兼容的设备

struct list_head clients;

遍历驱动发现的i2c设备将挂入此链表中,和i2c_client的detected对应

上面以 mma7660 为例实例化的 i2c_client,下面还以 mma7660 为例分析 i2c_driver 的注册

i2c_mma7660_driver的定义

  1. static struct i2c_driver i2c_mma7660_driver = {
  2. .driver = {
  3. .name = MMA7660_NAME,
  4. },
  5. .probe = mma7660_probe,
  6. .remove = __devexit_p(mma7660_remove),
  7. .suspend = mma7660_suspend,
  8. .resume = mma7660_resume,
  9. .id_table = mma7660_ids,
  10. };

其中的 id_table 为

  1. static const struct i2c_device_id mma7660_ids[] = {
  2. { "mma7660", 0 },
  3. { },
  4. };

下面就看  i2c_mma7660_driver 的注册过程。

  1. static int __init init_mma7660(void)
  2. {
  3. int ret;
  4. ret = i2c_add_driver(&i2c_mma7660_driver);
  5. {
  6. return i2c_register_driver(THIS_MODULE, driver);
  7. {
  8. int res;
  9. /* Can't register until after driver model init */
  10. if (unlikely(WARN_ON(!i2c_bus_type.p)))
  11. return -EAGAIN;
  12. /* add the driver to the list of i2c drivers in the driver core */
  13. driver->driver.owner = owner;
  14. driver->driver.bus = &i2c_bus_type;
  15. /* When registration returns, the driver core
  16. * will have called probe() for all matching-but-unbound devices.
  17. */
  18. res = driver_register(&driver->driver);
  19. {
  20. int ret;
  21. struct device_driver *other;
  22. BUG_ON(!drv->bus->p);
  23. /* i2c_bus_type->probe = i2c_device_probe
  24. i2c_bus_type->remove = i2c_device_remove
  25. i2c_bus_type->shutdown = i2c_device_shutdown
  26. i2c_mma7660_driver->driver->probe = NULL
  27. i2c_mma7660_driver->driver->remove = NULL
  28. i2c_mma7660_driver->driver->shutdown = NULL*/
  29. if ((drv->bus->probe && drv->probe) ||
  30. (drv->bus->remove && drv->remove) ||
  31. (drv->bus->shutdown && drv->shutdown))
  32. printk(KERN_WARNING "Driver '%s' needs updating - please use "
  33. "bus_type methods\n", drv->name);
  34. /*通过name查找是否已经注册过此driver*/
  35. other = driver_find(drv->name, drv->bus);
  36. {
  37. struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
  38. struct driver_private *priv;
  39. if (k) {
  40. priv = to_driver(k);
  41. return priv->driver;
  42. }
  43. return NULL;
  44. }
  45. if (other) {
  46. put_driver(other);
  47. printk(KERN_ERR "Error: Driver '%s' is already registered, "
  48. "aborting...\n", drv->name);
  49. return -EBUSY;
  50. }
  51. ret = bus_add_driver(drv);
  52. {
  53. struct bus_type *bus;
  54. struct driver_private *priv;
  55. int error = 0;
  56. /*前面初始化 i2c_mma7660_driver->driver.bus = &i2c_bus_type*/
  57. bus = bus_get(drv->bus);
  58. if (!bus)
  59. return -EINVAL;
  60. pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
  61. /*为 i2c_mma7660_driver->driver申请私有结构体*/
  62. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  63. if (!priv) {
  64. error = -ENOMEM;
  65. goto out_put_bus;
  66. }
  67. klist_init(&priv->klist_devices, NULL, NULL);
  68. priv->driver = drv;
  69. drv->p = priv;
  70. /*i2c_mma7660_driver->driver->priv->kobj.kset = i2c_bus_type->p->drivers_kset
  71. 还记得sys/bus/i2c 下的drivers目录吗
  72. priv->drivers_kset = kset_create_and_add("drivers", NULL, &priv->subsys.kobj);*/
  73. priv->kobj.kset = bus->p->drivers_kset;
  74. /*在sys/bus/i2c/drivers目录下创建 mma7660 的目录*/
  75. error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
  76. "%s", drv->name);
  77. if (error)
  78. goto out_unregister;
  79. /*又见到了drivers_autoprobe,还记得/sys/bus/i2c 下的drivers_autoprobe文件吗
  80. i2c_type->p->drivers_autoprobe = 1,自动匹配device和driver*/
  81. if (drv->bus->p->drivers_autoprobe) {
  82. error = driver_attach(drv);
  83. {
  84. return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
  85. {
  86. struct klist_iter i;
  87. struct device *dev;
  88. int error = 0;
  89. if (!bus || !bus->p)
  90. return -EINVAL;
  91. /*device 注册的时候就是挂接到 i2c_bus_type->p->klist_devices
  92. 下面就是遍历 i2c_bus_type 的device 链表,然后通过__driver_attach和driver
  93. 做匹配*/
  94. klist_iter_init_node(&bus->p->klist_devices, &i,
  95. (start ? &start->p->knode_bus : NULL));
  96. while ((dev = next_device(&i)) && !error)
  97. error = fn(dev, data); //fn = __driver_attach
  98. {
  99. struct device_driver *drv = data;
  100. /*
  101. * Lock device and try to bind to it. We drop the error
  102. * here and always return 0, because we need to keep trying
  103. * to bind to devices and some drivers will return an error
  104. * simply if it didn't support the device.
  105. *
  106. * driver_probe_device() will spit a warning if there
  107. * is an error.
  108. */
  109. if (!driver_match_device(drv, dev))
  110. { /* drv->bus->match = i2c_device_match ,最终还是调用到 i2c 总线 的match函数
  111. 最终会匹配到 mma7660 的 i2c_client*/
  112. return drv->bus->match ? drv->bus->match(dev, drv) : 1;
  113. }
  114. return 0;
  115. /*dev = client->dev
  116. client->dev.parent = &client->adapter->dev */
  117. if (dev->parent) /* Needed for USB */
  118. device_lock(dev->parent);
  119. device_lock(dev);
  120. /*虽然device和driver都找到了,可还未将driver赋值给device呢*/
  121. if (!dev->driver)
  122. driver_probe_device(drv, dev);
  123. {
  124. int ret = 0;
  125. if (!device_is_registered(dev))
  126. return -ENODEV;
  127. pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
  128. drv->bus->name, __func__, dev_name(dev), drv->name);
  129. pm_runtime_get_noresume(dev);
  130. pm_runtime_barrier(dev);
  131. ret = really_probe(dev, drv);
  132. {
  133. int ret = 0;
  134. atomic_inc(&probe_count);
  135. pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
  136. drv->bus->name, __func__, drv->name, dev_name(dev));
  137. WARN_ON(!list_empty(&dev->devres_head));
  138. /*这里才将driver和device关联起来*/
  139. dev->driver = drv;
  140. if (driver_sysfs_add(dev)) {
  141. {
  142. int ret;
  143. if (dev->bus)
  144. blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  145. BUS_NOTIFY_BIND_DRIVER, dev);
  146. /*sys/bus/i2c/drivers/mma7660创建指向 3-004c 的链接,
  147. 名字仍然为 3-004c */
  148. ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj,
  149. kobject_name(&dev->kobj));
  150. if (ret == 0) {
  151. /*在 /sys/devices/platform/s3c2440-i2c.3/i2c-3/3-004c/ 下
  152. 创建指向 /sys/bus/i2c/drivers/mma7660 的链接,名字为driver*/
  153. ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj,
  154. "driver");
  155. if (ret)
  156. sysfs_remove_link(&dev->driver->p->kobj,
  157. kobject_name(&dev->kobj));
  158. }
  159. return ret;
  160. }
  161. printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
  162. __func__, dev_name(dev));
  163. goto probe_failed;
  164. }
  165. /*i2c_bus_type->probe = i2c_device_probe ,所以调用
  166. i2c_device_probe ,最终调用 mma7660_probe*/
  167. if (dev->bus->probe) {
  168. ret = dev->bus->probe(dev);
  169. if (ret)
  170. goto probe_failed;
  171. } else if (drv->probe) {
  172. ret = drv->probe(dev);
  173. if (ret)
  174. goto probe_failed;
  175. }
  176. driver_bound(dev);
  177. { /*前面 client->dev->p->knode_driver未初始化,也就是为NULL*/
  178. if (klist_node_attached(&dev->p->knode_driver)) {
  179. printk(KERN_WARNING "%s: device %s already bound\n",
  180. __func__, kobject_name(&dev->kobj));
  181. return;
  182. }
  183. pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
  184. __func__, dev->driver->name);
  185. /*将device挂接在driver的设备链表中*/
  186. klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
  187. if (dev->bus)
  188. blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
  189. BUS_NOTIFY_BOUND_DRIVER, dev);
  190. }
  191. ret = 1;
  192. pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
  193. drv->bus->name, __func__, dev_name(dev), drv->name);
  194. goto done;
  195. probe_failed:
  196. devres_release_all(dev);
  197. driver_sysfs_remove(dev);
  198. dev->driver = NULL;
  199. if (ret != -ENODEV && ret != -ENXIO) {
  200. /* driver matched but the probe failed */
  201. printk(KERN_WARNING
  202. "%s: probe of %s failed with error %d\n",
  203. drv->name, dev_name(dev), ret);
  204. }
  205. /*
  206. * Ignore errors returned by ->probe so that the next driver can try
  207. * its luck.
  208. */
  209. ret = 0;
  210. done:
  211. atomic_dec(&probe_count);
  212. wake_up(&probe_waitqueue);
  213. return ret;
  214. }
  215. pm_runtime_put_sync(dev);
  216. return ret;
  217. }
  218. device_unlock(dev);
  219. if (dev->parent)
  220. device_unlock(dev->parent);
  221. return 0;
  222. }
  223. klist_iter_exit(&i);
  224. return error;
  225. }
  226. }
  227. if (error)
  228. goto out_unregister;
  229. }
  230. /*将 i2c_mma7660_driver 挂接在 i2c_bus_type 的driver链表中*/
  231. klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
  232. module_add_driver(drv->owner, drv);
  233. /*在/sys/bus/i2c/drivers/mma7660 创建 uevent 文件*/
  234. error = driver_create_file(drv, &driver_attr_uevent);
  235. if (error) {
  236. printk(KERN_ERR "%s: uevent attr (%s) failed\n",
  237. __func__, drv->name);
  238. }
  239. /*为 i2c_mma7660_driver 创建默认的属性文件,可是i2c_bus_type->drv_attrs = NULL,所以此例中没有
  240. 没有创建任何文件*/
  241. error = driver_add_attrs(bus, drv);
  242. {
  243. int error = 0;
  244. int i;
  245. if (bus->drv_attrs) {
  246. for (i = 0; attr_name(bus->drv_attrs[i]); i++) {
  247. error = driver_create_file(drv, &bus->drv_attrs[i]);
  248. if (error)
  249. goto err;
  250. }
  251. }
  252. done:
  253. return error;
  254. err:
  255. while (--i >= 0)
  256. driver_remove_file(drv, &bus->drv_attrs[i]);
  257. goto done;
  258. }
  259. if (error) {
  260. /* How the hell do we get out of this pickle? Give up */
  261. printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
  262. __func__, drv->name);
  263. }
  264. /*i2c_mma7660_driver->drv->suppress_bind_attrs 未赋值,也就是为0*/
  265. if (!drv->suppress_bind_attrs) {
  266. error = add_bind_files(drv);
  267. {
  268. int ret;
  269. /*在/sys/bus/i2c/drivers/mma7660 目录下创建 ubind 文件*/
  270. ret = driver_create_file(drv, &driver_attr_unbind);
  271. if (ret == 0) {
  272. /*在/sys/bus/i2c/drivers/mma7660目录下创建 bind 文件*/
  273. ret = driver_create_file(drv, &driver_attr_bind);
  274. if (ret)
  275. driver_remove_file(drv, &driver_attr_unbind);
  276. }
  277. return ret;
  278. }
  279. if (error) {
  280. /* Ditto */
  281. printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
  282. __func__, drv->name);
  283. }
  284. }
  285. /*发送 KOBJ_ADD */
  286. kobject_uevent(&priv->kobj, KOBJ_ADD);
  287. return 0;
  288. out_unregister:
  289. kobject_put(&priv->kobj);
  290. kfree(drv->p);
  291. drv->p = NULL;
  292. out_put_bus:
  293. bus_put(bus);
  294. return error;
  295. }
  296. if (ret)
  297. return ret;
  298. ret = driver_add_groups(drv, drv->groups);
  299. if (ret)
  300. bus_remove_driver(drv);
  301. return ret;
  302. }
  303. if (res)
  304. return res;
  305. /* Drivers should switch to dev_pm_ops instead. */
  306. if (driver->suspend)
  307. pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
  308. driver->driver.name);
  309. if (driver->resume)
  310. pr_warn("i2c-core: driver [%s] using legacy resume method\n",
  311. driver->driver.name);
  312. pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
  313. INIT_LIST_HEAD(&driver->clients);
  314. /* Walk the adapters that are already present */
  315. i2c_for_each_dev(driver, __process_new_driver);
  316. {
  317. int res;
  318. mutex_lock(&core_lock);
  319. res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn);
  320. {
  321. struct klist_iter i;
  322. struct device *dev;
  323. int error = 0;
  324. if (!bus || !bus->p)
  325. return -EINVAL;
  326. klist_iter_init_node(&bus->p->klist_devices, &i,
  327. (start ? &start->p->knode_bus : NULL));
  328. while ((dev = next_device(&i)) && !error)
  329. error = fn(dev, data); //fn = __process_new_driver
  330. {
  331. if (dev->type != &i2c_adapter_type)
  332. return 0;
  333. return i2c_do_add_adapter(data, to_i2c_adapter(dev));
  334. {
  335. /* Detect supported devices on that bus, and instantiate them */
  336. i2c_detect(adap, driver);
  337. { /* driver 所支持i2c设备的 address 列表*/
  338. const unsigned short *address_list;
  339. /* 声明一个临时的 i2c_client */
  340. struct i2c_client *temp_client;
  341. int i, err = 0;
  342. int adap_id = i2c_adapter_id(adapter);
  343. /* i2c_mma7660_driver->address_list 未赋值,也就是为 NULL 函数在此返回*/
  344. address_list = driver->address_list;
  345. if (!driver->detect || !address_list)
  346. return 0;
  347. ......
  348. kfree(temp_client);
  349. return err;
  350. }
  351. /* Let legacy drivers scan this bus for matching devices */
  352. if (driver->attach_adapter) {
  353. dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
  354. driver->driver.name);
  355. dev_warn(&adap->dev, "Please use another way to instantiate "
  356. "your i2c_client\n");
  357. /* We ignore the return code; if it fails, too bad */
  358. driver->attach_adapter(adap);
  359. }
  360. return 0;
  361. }
  362. }
  363. klist_iter_exit(&i);
  364. return error;
  365. }
  366. mutex_unlock(&core_lock);
  367. return res;
  368. }
  369. return 0;
  370. }
  371. }
  372. printk(KERN_INFO "MMA7660 sensor driver registered.\n");
  373. return ret;
  374. }

从上面的代码中可以看出,其实和platform的那一套机制是一回事,驱动框架完成了大量的工作,然后实际驱动只需要注册device和driver,驱动框架就会调用到probe函数,开始真正的硬件初始化相关的工作。

三、i2c-dev

不是说 linux 秉承一切皆文件吗(网络设备除外),驱动不是应该完成open、close、read和write等函数吗?到目前为止不管platform还是i2c都没有这些信息。不要忘了,bus、device和driver驱动模型,只是驱动的一种框架,并没有完成任何实质性工作,真正的注册char、block还是网络设备都是开发者自己的事,驱动模型不是最终保证会调用到probe函数吗,对的,你可以在probe函数中完成实际的设备驱动注册,如 register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops),驱动模型只是套了个架子而已,实际驱动工作还得自己做。

对于实际的 i2c 器件,只是将 i2c 作为通信通道而已,再简单的说实际设备功能并不关心是通过spi还是 i2c 进行,比如驱动中的 read 函数,按顺序读写寄存器,并不关心 是 i2c还是spi甚至usb,只要进行数据传输达到目的就行。对于 i2c 器件一般会是input、rtc或者misc,文件系统的接口自然由 input、rtc或misc模型提供,当然你也可以专门为此期间写一个char类型的驱动,完成open、close、read和write等函数,但对于i2c部分,只是利用 i2c_client->adapter->i2c_algorithm->master_xfer和器件进行数据交互。

下面看一下i2c-dev,linux提供的 i2c-dev 并不是实际存在具体的一个i2c器件,而是代表一个i2c总线的设备,可以通过 i2c-dev 提供的 read、write和ioctl来访问总线上的 i2c 器件(根据指定的器件地址)。由于不同的 i2c 器件的 read 和 write 实现各不相同,所以linux提供的 i2c-dev 并不是很通用。

下面简单看一下i2c-dev的注册过程

  1. static const struct file_operations i2cdev_fops = {
  2. .owner = THIS_MODULE,
  3. .llseek = no_llseek,
  4. .read = i2cdev_read,
  5. .write = i2cdev_write,
  6. .unlocked_ioctl = i2cdev_ioctl,
  7. .open = i2cdev_open,
  8. .release = i2cdev_release,
  9. };
  1. static int __init i2c_dev_init(void)
  2. {
  3. int res;
  4. printk(KERN_INFO "i2c /dev entries driver\n");
  5.         /*注册为char型设备,主设备号为 I2C_MAJOR(123)(终于见到设备号了) */
  6. res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
  7. if (res)
  8. goto out;
  9. i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
  10. if (IS_ERR(i2c_dev_class)) {
  11. res = PTR_ERR(i2c_dev_class);
  12. goto out_unreg_chrdev;
  13. }
  14. /* Keep track of adapters which will be added or removed later */
  15. res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
  16. if (res)
  17. goto out_unreg_class;
  18. /* Bind to already existing adapters right away */
  19. i2c_for_each_dev(NULL, i2cdev_attach_adapter);
  20. return 0;
  21. out_unreg_class:
  22. class_destroy(i2c_dev_class);
  23. out_unreg_chrdev:
  24. unregister_chrdev(I2C_MAJOR, "i2c");
  25. out:
  26. printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
  27. return res;
  28. }

其中 i2cdev_attach_adapter中会创建设备文件,也就是在/dev/目录下创建 i2c- %d的文件,如 i2c-3 就代表第三个i2c 上的设备或者说i2c_adapter,可通过/dev/i2c-3 来访问该总线上设备(如open、close、read和write等)。

  1. static int i2cdev_attach_adapter(struct device *dev, void *dummy)
  2. {
  3. ......
  4. /* register this i2c device with the driver core */
  5. /*创建设备文件,这回 是带 设备号的,所以也会在 /sys/dev/目录下创建文件,如i2c-3*/
  6. i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
  7. MKDEV(I2C_MAJOR, adap->nr), NULL,
  8. "i2c-%d", adap->nr);
  9. ......
  10. return res;
  11. }

上面就是i2c驱动框架的大致内容了,整体来说还是比较复杂的,不过从代码一点一点分析,还是可以理解的,但是鉴于个人的水平有限,可能会出现理解错误的地方,欢迎交流。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/275182
推荐阅读
相关标签
  

闽ICP备14008679号