Q1:GPIO的probe为什么没有被调用 ?
背景:dts已经配置,UCLASS_DRIVER->UCLASS_GPIO 已经实现
.post_probe = 已添加
原因:uboot的驱动probe不像kernel的platform driver - device,驱动加载的过程中会被自动调用,uboot需要调用GPIO相关的接口才会主动probe,比如:gpio_direction_output,gpio_set_value等标准接口
Q2:为什么定义了U_BOOT_DRIVER.ops,以下通用接口确没有调用到 ?
260struct dm_gpio_ops {
261 int (*request)(struct udevice *dev, unsigned offset, const char *label);
262 int (*rfree)(struct udevice *dev, unsigned int offset);
263 int (*direction_input)(struct udevice *dev, unsigned offset);
264 int (*direction_output)(struct udevice *dev, unsigned offset,
265 int value);
266 int (*get_value)(struct udevice *dev, unsigned offset);
267 int (*set_value)(struct udevice *dev, unsigned offset, int value);
268 /**
269 * get_function() Get the GPIO function
270 *
271 * @dev: Device to check
272 * @offset: GPIO offset within that device
273 * @return current function - GPIOF_...
274 */
275 int (*get_function)(struct udevice *dev, unsigned offset);
----------------------------------
}
整理下gpio_direction_output的调用流程,其他接口也可以
534int gpio_direction_output(unsigned gpio, int value)
535{
536 struct gpio_desc desc;
537 int ret;
538
539 ret = gpio_to_device(gpio, &desc);
540 if (ret)
541 return ret;
542 ret = check_reserved(&desc, "dir_output");
543 if (ret)
544 return ret;
545
546 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
547 desc.offset, value);
548}
------------------gpio_to_device-------------------------
42/**
43 * gpio_to_device() - Convert global GPIO number to device, number
44 *
45 * Convert the GPIO number to an entry in the list of GPIOs
46 * or GPIO blocks registered with the GPIO controller. Returns
47 * entry on success, NULL on error.
48 *
49 * @gpio: The numeric representation of the GPIO
50 * @desc: Returns description (desc->flags will always be 0)
51 * @return 0 if found, -ENOENT if not found
52 */
53static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
54{
55 struct gpio_dev_priv *uc_priv;
56 struct udevice *dev;
57 int ret;
58
59 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
60 dev;
61 ret = uclass_next_device(&dev)) {
62 uc_priv = dev_get_uclass_priv(dev);
63 if (gpio >= uc_priv->gpio_base &&
64 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
65 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
66 return 0;
67 }
68 }
69
70 /* No such GPIO */
71 return ret ? ret : -ENOENT;
72}
Note: gpio_to_device的作用是把GPIO Num找到对应的设备(dts可以配置多个gpio device)
我的问题卡在if (gpio >= uc_priv->gpio_base && gpio < uc_priv->gpio_base + uc_priv->gpio_count) 这个判断;
比如:gpio number = 225, uc_priv->gpio_base = 0(大部分从0开始),这里的uc_priv->gpio_count比较关键了,我的dts没有配置gpio_count,此处gpio_count == 0;导致没有找到对应的gpio device
Q3. gpio@4000000: dir_output: error: gpio 205 not reserved ?
482static int check_reserved(const struct gpio_desc *desc, const char *func)
483{
484 struct gpio_dev_priv *uc_priv;
485
486 if (!dm_gpio_is_valid(desc))
487 return -ENOENT;
488
489 uc_priv = dev_get_uclass_priv(desc->dev);
490 /*
491 if (!uc_priv->name[desc->offset]) {
492 printf("%s: %s: error: gpio %s%d not reserved\n",
493 desc->dev->name, func,
494 uc_priv->bank_name ? uc_priv->bank_name : "",
495 desc->offset);
496 return -EBUSY;
497 }
498 */
499 return 0;
500}
出错在此处,我这里没有配置每个gpio的name,所以把if (!uc_priv->name[desc->offset]) { }判断注释掉了