drivers: gpio: stm32: keep track of clock enabling per pin
The driver enables the clock of a gpio-port if any of the pins use the port. This is done by calling pm_device_runtime_get when a pin is used and pm_device_runtime_put when the pin is not used anymore. These calls needs to be balanced. But if a single pin was configured as GPIO_DISCONNECTED multiple times, every time pm_device_runtime_put was called. This caused the clock of the port to be stopped and therefore also other pins on the same port stopped working. This commit fixes this by keeping track of which pin on a port has requested the clock and only call pm_device_runtime_get or pm_device_runtime_put when the clock-request for the specific pin changes. Fixes #77698 Signed-off-by: Jeroen Broersen <jbroersen@interact.nl>
This commit is contained in:
parent
f61b8f9fd2
commit
cf837dd371
|
@ -469,6 +469,7 @@ static int gpio_stm32_config(const struct device *dev,
|
|||
{
|
||||
int err;
|
||||
uint32_t pincfg;
|
||||
struct gpio_stm32_data *data = dev->data;
|
||||
|
||||
/* figure out if we can map the requested GPIO
|
||||
* configuration
|
||||
|
@ -479,11 +480,13 @@ static int gpio_stm32_config(const struct device *dev,
|
|||
}
|
||||
|
||||
/* Enable device clock before configuration (requires bank writes) */
|
||||
if (((flags & GPIO_OUTPUT) != 0) || ((flags & GPIO_INPUT) != 0)) {
|
||||
if ((((flags & GPIO_OUTPUT) != 0) || ((flags & GPIO_INPUT) != 0)) &&
|
||||
!(data->pin_has_clock_enabled & BIT(pin))) {
|
||||
err = pm_device_runtime_get(dev);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
data->pin_has_clock_enabled |= BIT(pin);
|
||||
}
|
||||
|
||||
if ((flags & GPIO_OUTPUT) != 0) {
|
||||
|
@ -515,12 +518,14 @@ static int gpio_stm32_config(const struct device *dev,
|
|||
}
|
||||
#endif /* CONFIG_STM32_WKUP_PINS */
|
||||
|
||||
/* Release clock only if pin is disconnected */
|
||||
if (((flags & GPIO_OUTPUT) == 0) && ((flags & GPIO_INPUT) == 0)) {
|
||||
/* Decrement GPIO usage count only if pin is now disconnected after being connected */
|
||||
if (((flags & GPIO_OUTPUT) == 0) && ((flags & GPIO_INPUT) == 0) &&
|
||||
(data->pin_has_clock_enabled & BIT(pin))) {
|
||||
err = pm_device_runtime_put(dev);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
data->pin_has_clock_enabled &= ~BIT(pin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -259,6 +259,8 @@ struct gpio_stm32_data {
|
|||
const struct device *dev;
|
||||
/* user ISR cb */
|
||||
sys_slist_t cb;
|
||||
/* keep track of pins that are connected and need GPIO clock to be enabled */
|
||||
uint32_t pin_has_clock_enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue