上一章介绍了pinctrl系统管理所有的物理pin脚,gpio也是pin脚的一种,所以需要某个gpio的时候就需要通过pinctrl把某个pin脚设置为gpio功能就即可;在pinctrl系统提供了操作pin脚的统一API接口,同时也可以用gpio的API来操作,在request gpio表明该pin没有被挪为他用之后,就可以设置该GPIO的输入输出,驱动能力,或者debounce功能等;
(一) GPIO 初始化
pinctrl有讲到一个pinctrl可以管理着个gpio range链表,每个node管理着一定范围内的gpio,可以叫作gpio bank,我们把它实例话成一个设备,用gpio_chip来表示,下面为各个结构关系图:
通过gpiochip_add()将gpio chip添加到gpio子系统中:
299 int gpiochip_add(struct gpio_chip *chip)
300 {
301 unsigned long flags;
302 int status = 0;
303 unsigned id;
304 int base = chip->base; //这个chip处理的第一个gpio number;
305 struct gpio_desc *descs;
306
307 descs = kcalloc(chip->ngpio, sizeof(descs[0]), GFP_KERNEL);
308 if (!descs)
309 return -ENOMEM;
310
311 spin_lock_irqsave(&gpio_lock, flags);
312
313 if (base < 0) {
//如果没有指定base,那么需要基于该chip的gpio数量在系统支持的gpio范围里找一段区间给该chip;
//一般平台默认为512个gpio,通过扫描gpio_chips全局chip链表,分配一段free的gpio空间;
314 base = gpiochip_find_base(chip->ngpio); //ngpio为该chip处理的gpio个数;
315 if (base < 0) {
316 status = base;
317 spin_unlock_irqrestore(&gpio_lock, flags);
318 goto err_free_descs;
319 }
320 chip->base = base;
321 }
322 //到这里的时候,说明一切正常,把它加入到全局的gpiochip链表中去,注意,加入的时候会基于base排序;
323 status = gpiochip_add_to_list(chip);
324 if (status) {
325 spin_unlock_irqrestore(&gpio_lock, flags);
326 goto err_free_descs;
327 }
328 //如果加入成功,最后一步就是初始化该chip对应的那些gpio了;
329 for (id = 0; id < chip->ngpio; id++) {
330 struct gpio_desc *desc = &descs[id]; //每个gpio分配一个gpio_desc来描述;
331
332 desc->chip = chip;
333 //默认指定为输入为好,考虑到大多数情况下推挽式输出,防止漏电;
340 desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0;
341 }
342
343 chip->desc = descs;
344
345 spin_unlock_irqrestore(&gpio_lock, flags);
346
347 #ifdef CONFIG_PINCTRL
348 INIT_LIST_HEAD(&chip->pin_ranges);
349 #endif
350
351 if (!chip->owner && chip->dev && chip->dev->driver)
352 chip->owner = chip->dev->driver->owner;
353
354 status = gpiochip_set_desc_names(chip);
355 if (status)
356 goto err_remove_from_list;
357
358 status = of_gpiochip_add(chip); // 初始化设备树相关的信息;
359 if (status)
360 goto err_remove_chip;
361 //添加chip到ACPI(Advanced Configuration & Power Interface.)
362 acpi_gpiochip_add(chip);
363
364 status = gpiochip_sysfs_register(chip);// 将该gpiochip导出到sys,用于调试和应用层直接操作;
372 return 0;
373
391 }
392 EXPORT_SYMBOL_GPL(gpiochip_add);
422 int of_gpiochip_add(struct gpio_chip