Re: [RFC] GPIO API changes

Johan Hedberg

Hi Tomasz,

On Thu, Mar 03, 2016, Tomasz Bursztyka wrote:
1) Let's add a user data pointer parameter to the callback:

typedef void (*gpio_callback_t)(struct device *port,
uint32_t pin,
void *user_data);

gpio_set_callback() would then require a void *user_data parameter as

2) The callback would not be only a function, but a structure in order
to be able to manage a simple linked-list of callbacks.

Johan had a good input on that one, as he and bt team have done that
in the BT stack. Instead of a function pointer you would pass a
pointer of:

struct gpio_callback {
void (*func)(struct device *port, uint32_t pin, void *user_data);
void *user_data;

struct gpio_callback *_next;

This avoid to manage any memory slots in the driver. All would be
statically allowed. Also, being a generic list, the code could be
centralized in a private header in drivers/gpio thus we would not have
to re-implement such management in every driver.
A perhaps slightly more compact solution (and a pattern I see a log e.g.
in Linux) is to take advantage of CONTAINER_OF. You'd first drop
user_data from the gpio_callback and pass the original struct to the

struct gpio_callback {
void (*func)(struct device *port, struct gpio_callback *cb, uint32_t pin);
struct gpio_callback *_next;

Then users of the API could just use this struct directly, or if they
need "user data" they can define their own structs that embed the gpio

struct my_struct {
struct gpio_callback cb;

void my_func(struct device *port, struct gpio_callback *cb, uint32_t pins)
struct my_struct *data = CONTAINER_OF(cb, struct my_struct, cb);

struct my_struct s;

GPIO_INIT_CB(&s.cb, my_func);

gpio_set_callback(port, &s.cb);


Join to automatically receive all group messages.