Skip to content

Commit

Permalink
drivers/gpio: specify whether driver is ISR-safe
Browse files Browse the repository at this point in the history
At least one GPIO driver (SX1509B) is outside the SOC and requires I2C
transactions for its basic operations.  That fact could not be detected
from a generic GPIO driver reference, potentially causing problems if
a pin was written or reconfigured from within an ISR.

Add a flag to the driver API that specifies that ISR operations are
unsafe, and set the flag in the SX1509B driver API structure.  Add API
that allows querying the state of this flag, to be used in concert with
k_is_in_isr().

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
  • Loading branch information
pabigot committed Jul 28, 2019
1 parent bcd6018 commit 423cdb5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/gpio/gpio_sx1509b.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ static const struct gpio_driver_api gpio_sx1509b_drv_api_funcs = {
.config = gpio_sx1509b_config,
.write = gpio_sx1509b_write,
.read = gpio_sx1509b_read,
.not_isr_safe = true,
};

DEVICE_AND_API_INIT(gpio_sx1509b, CONFIG_GPIO_SX1509B_DEV_NAME,
Expand Down
20 changes: 20 additions & 0 deletions include/drivers/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ struct gpio_driver_api {
gpio_enable_callback_t enable_callback;
gpio_disable_callback_t disable_callback;
gpio_api_get_pending_int get_pending_int;
bool not_isr_safe;
};

__syscall int gpio_config(struct device *port, int access_op, u32_t pin,
Expand Down Expand Up @@ -435,6 +436,25 @@ static inline int z_impl_gpio_get_pending_int(struct device *dev)
return api->get_pending_int(dev);
}

/**
* @brief Function to check safety of operations from interrupts
*
* Some GPIO implementations may have operations that interact with
* peripherals outside the SOC, and so cannot be called from interrupt
* context. This method can be used to determine whether the GPIO
* being used has such limitations.
*
* @return 1 if operations on this GPIO can be safely invoked from an
* interrupt; 0 if they cannot.
*/
static inline int gpio_is_isr_safe(struct device *dev)
{
const struct gpio_driver_api *api =
(const struct gpio_driver_api *)dev->driver_api;

return !api->not_isr_safe;
}

struct gpio_pin_config {
char *gpio_controller;
u32_t gpio_pin;
Expand Down

0 comments on commit 423cdb5

Please sign in to comment.