drivers/gpio: stm32: Add port clock handling function

As a preparation for GPIO ports clocks power management,
add a dedicated central function fog GPIO ports clock toggling.

This function is made accessible to other users (pinmux).

Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
Erwan Gouriou 2021-02-17 10:36:02 +01:00 committed by Kumar Gala
commit 6b2ccbb721
2 changed files with 52 additions and 20 deletions

View file

@ -221,6 +221,49 @@ int gpio_stm32_configure(uint32_t *base_addr, int pin, int conf, int altf)
return 0;
}
/**
* @brief GPIO port clock handling
*/
int gpio_stm32_clock_request(const struct device *dev, bool on)
{
const struct gpio_stm32_config *cfg = dev->config;
int ret = 0;
__ASSERT_NO_MSG(dev != NULL);
/* enable clock for subsystem */
const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
if (on) {
ret = clock_control_on(clk,
(clock_control_subsys_t *)&cfg->pclken);
} else {
ret = clock_control_off(clk,
(clock_control_subsys_t *)&cfg->pclken);
}
if (ret != 0) {
return ret;
}
#if defined(PWR_CR2_IOSV) && DT_NODE_HAS_STATUS(DT_NODELABEL(gpiog), okay)
z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
if (cfg->port == STM32_PORTG) {
/* Port G[15:2] requires external power supply */
/* Cf: L4/L5 RM, Chapter "Independent I/O supply rail" */
if (on) {
LL_PWR_EnableVddIO2();
} else {
LL_PWR_DisableVddIO2();
}
}
z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
#endif
return ret;
}
static inline uint32_t gpio_stm32_pin_to_exti_line(int pin)
{
#if defined(CONFIG_SOC_SERIES_STM32L0X) || \
@ -525,30 +568,11 @@ static const struct gpio_driver_api gpio_stm32_driver = {
*/
static int gpio_stm32_init(const struct device *device)
{
const struct gpio_stm32_config *cfg = device->config;
struct gpio_stm32_data *data = device->data;
data->dev = device;
/* enable clock for subsystem */
const struct device *clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
if (clock_control_on(clk,
(clock_control_subsys_t *)&cfg->pclken) != 0) {
return -EIO;
}
#if defined(PWR_CR2_IOSV) && DT_NODE_HAS_STATUS(DT_NODELABEL(gpiog), okay)
if (cfg->port == STM32_PORTG) {
/* Port G[15:2] requires external power supply */
/* Cf: L4/L5 RM, Chapter "Independent I/O supply rail" */
z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
LL_PWR_EnableVddIO2();
z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
}
#endif /* PWR_CR2_IOSV */
return 0;
return gpio_stm32_clock_request(device, true);
}
#define GPIO_DEVICE_INIT(__node, __suffix, __base_addr, __port, __cenr, __bus) \