[PATCH] gpio: Get rid of gpio_hog_probe_all()

Marek Vasut marex at denx.de
Thu Sep 22 16:28:59 CEST 2022


On 9/22/22 15:59, Quentin Schulz wrote:
> Hi Marek,

Hi,

[...]

>> diff --git a/doc/README.gpio b/doc/README.gpio
>> index 548ff37b8cc..d253f654fad 100644
>> --- a/doc/README.gpio
>> +++ b/doc/README.gpio
>> @@ -2,10 +2,8 @@
>>   GPIO hog (CONFIG_GPIO_HOG)
>>   --------
>> -All the GPIO hog are initialized in gpio_hog_probe_all() function 
>> called in
>> -board_r.c just before board_late_init() but you can also acces 
>> directly to
>> -the gpio with gpio_hog_lookup_name().
>> -
>> +All the GPIO hog are initialized using DM_FLAG_PROBE_AFTER_BIND DM flag
>> +after bind().
>>   Example, for the device tree:
>> diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
>> index 0ed32b72170..32df0448a7b 100644
>> --- a/drivers/gpio/gpio-uclass.c
>> +++ b/drivers/gpio/gpio-uclass.c
>> @@ -315,34 +315,11 @@ static int gpio_hog_probe(struct udevice *dev)
>>       return 0;
>>   }
>> -int gpio_hog_probe_all(void)
>> -{
>> -    struct udevice *dev;
>> -    int ret;
>> -    int retval = 0;
>> -
>> -    for (uclass_first_device(UCLASS_NOP, &dev);
>> -         dev;
>> -         uclass_find_next_device(&dev)) {
>> -        if (dev->driver == DM_DRIVER_GET(gpio_hog)) {
>> -            ret = device_probe(dev);
>> -            if (ret) {
>> -                printf("Failed to probe device %s err: %d\n",
>> -                       dev->name, ret);
>> -                retval = ret;
>> -            }
>> -        }
>> -    }
>> -
>> -    return retval;
>> -}
>> -
>>   int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
>>   {
>>       struct udevice *dev;
>>       *desc = NULL;
>> -    gpio_hog_probe_all();
>>       if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
>>           struct gpio_hog_priv *priv = dev_get_priv(dev);
>> @@ -1503,6 +1480,8 @@ static int gpio_post_bind(struct udevice *dev)
>>                                    &child);
>>                   if (ret)
>>                       return ret;
>> +
>> +                dev_or_flags(child, DM_FLAG_PROBE_AFTER_BIND);
> 
> I replaced this line with:
> 
> +                               /*
> +                                * Make sure gpio-hogs are probed after 
> bind
> +                                * since hogs can be essential to the 
> hardware
> +                                * system.
> +                                */
> +                               dev_or_flags(child, 
> DM_FLAG_PROBE_AFTER_BIND);
> +
> +                               /*
> +                                * Since gpio-hog is a U_BOOT_DRIVER and 
> not
> +                                * a U_BOOT_CLASS, the DM core does not 
> bind
> +                                * it and therefore it's up to this 
> driver to
> +                                * set the DM_FLAG_PRE_RELOC appropriately.
> +                                */
> +                               if (ofnode_pre_reloc(node))
> +                                       dev_or_flags(child, 
> DM_FLAG_PRE_RELOC);

This second part should be handled by the DM, or you need dm-pre-reloc 
in your GPIO controller in DT. This would fail e.g. in case your GPIO 
controller has higher depth of hog subnodes, like:

gpio-controller {
   something {
     gpio-hog {
       u-boot,dm-pre-reloc;
     };
   };
};

Should really be:

gpio-controller {
   u-boot,dm-pre-reloc;
   something {
     u-boot,dm-pre-reloc;
     gpio-hog {
       u-boot,dm-pre-reloc;
     };
   };
};

At some point, I had the idea to instead of littering the DT with 
u-boot,dm-pre-reloc , we could use phandles instead and do something like:

/ {
  config {
   u-boot,dm-pre-reloc = <&node1 &node2 ... &gpio_hog ...>;
  };
}
...
gpio-controller {
   something {
     gpio_hog: gpio-hog {
     };
   };
};


More information about the U-Boot mailing list