Search code examples
linuxlinux-kernellinux-device-driverkernel-modulegpio

Should I use `gpio_free` before using `gpio_desc` which is returned by `gpio_to_desc`?


Update at 2020/10/31

Thanks for 0andriy asking the question on mailing list. And Alexandre Courbot aka Gunurou answered my question!

I have to thank 0andriy again! Your are the true hero behind this question.


Old Question:

This question seems like typo in documentation, but I want to double check.

My question is the last two paragraphs in the last section of GPIO Descriptor Consumer Interface.

the following two functions allow you to convert a GPIO descriptor into the GPIO integer namespace and vice-versa:

int desc_to_gpio(const struct gpio_desc *desc)
struct gpio_desc *gpio_to_desc(unsigned gpio)

The GPIO number returned by desc_to_gpio() can be safely used as long as the GPIO descriptor has not been freed. All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.

Freeing a GPIO obtained by one API with the other API is forbidden and an unchecked error.

My understanding for each sentence

The GPIO number returned by desc_to_gpio() can be safely used as long as the GPIO descriptor has not been freed.

Any GPIO pin could be use before gpiod_put() free the descriptor. Following is pseudo code for my understanding.

struct gpio_desc desc = gpiod_get(...);
gpio pin = desc_to_gpio(desc);

// operation here

gpiod_put(desc);

All the same, a GPIO number passed to gpio_to_desc() must have been properly acquired, and usage of the returned GPIO descriptor is only possible after the GPIO number has been released.

I'm confused with "All the same" and "usage of the returned GPIO descriptor is only possible after the GPIO number has been released".

If "All the same" applies, I presume gpio_desc could be used before gpio_free(). But "usage of the returned GPIO descriptor is only possible after the GPIO number has been released" makes me think I have to gpio_free() before using gpio_desc returned from gpio_to_desc().

To re-state my question, which of the following code snippet should be correct usage of gpio_to_desc()? I presume "usage of the returned GPIO descriptor" means the gpio_desc return from gpio_to_desc().

I thought second one should be incorrect, but I'd like to be confirmed with any documentation or example for it.

  1. Use gpio_desc before free.
    gpio pin = gpio_request( ... );
    struct gpio_desc desc = gpio_to_desc(pin);
    
    // gpiod operation here, before free
    
    gpio_free(gpio_desc)
  1. Using gpio_desc AFTER free.
    gpio pin = gpio_request( ... );
    struct gpio_desc desc = gpio_to_desc(pin);
    gpio_free(gpio_desc)
    
    // gpiod operation here, after free

In other words, should

"usage of the returned GPIO descriptor is only possible after the GPIO number has been released"

be changed to

"usage of the returned GPIO descriptor is only possible before the GPIO number has been released"?


Side question

According to this sentence.

Freeing a GPIO obtained by one API with the other API is forbidden and an unchecked error.

Should I NOT release the gpio_desc with gpiod_put() returned by gpio_to_desc()?


Keywords on Google.

  • gpio_to_desc() must gpio_free() first

    No offical articles mention about it.

  • gpio_to_desc() gpiod_put()

    I found header files. However it doesn't explain it.


Solution

  • The short answer to this question is don't ever call these functions. They have been obsolete since 2014 and there should be no reason for new code to use them. New code should only rely on the gpiod_*() family of functions, and never work with GPIO numbers.

    If you deal with old code, the safest thing to do is to convert it to use the gpiod interface first thing.

    Now if you absolutely need to work with these functions, my recollection is that the following usages are valid (copied from your question):

    struct gpio_desc desc = gpiod_get(...);
    gpio pin = desc_to_gpio(desc);
    
    // operation here
    
    gpiod_put(desc);
    
    gpio pin = gpio_request( ... );
    struct gpio_desc desc = gpio_to_desc(pin);
       
    // gpiod operation here, before free
      
    gpio_free(gpio_desc)
    

    That's because the gpio_*() family of functions are built on top of the gpiod interface, as you can see in drivers/gpio/gpiolib-legacy.c. So the descriptor corresponding to the GPIO number you requested will have been acquired by gpiod_request(), and thus is guaranteed to remain valid until gpio_free() (which really just calls gpiod_free() is invoked.

    As for your side question:

    Should I NOT release the gpio_desc with gpiod_put() returned by gpio_to_desc()?

    That's correct, you should never do that. At the moment the APIs are built in such a way that doing so might work, but there is no guarantee they will not diverge in the future. Also if you acquired a descriptor, there is no reason why you could not keep it around to free it using the correct API.

    But again, the best thing to do is assume that these functions do not exist, and use gpiod everywhere you can.