diff --git a/drivers/i2c/i2c_dw.c b/drivers/i2c/i2c_dw.c index 2791248cc89..224c7261ae7 100644 --- a/drivers/i2c/i2c_dw.c +++ b/drivers/i2c/i2c_dw.c @@ -425,15 +425,15 @@ static int i2c_dw_transfer(const struct device *dev, * While waiting at device_sync_sem, kernel can switch to idle * task which in turn can call pm_system_suspend() hook of Power * Management App (PMA). - * device_busy_set() call here, would indicate to PMA that it should not - * execute PM policies that would turn off this ip block, causing an + * pm_device_busy_set() call here, would indicate to PMA that it should + * not execute PM policies that would turn off this ip block, causing an * ongoing hw transaction to be left in an inconsistent state. * Note : This is just a sample to show a possible use of the API, it is * upto the driver expert to see, if he actually needs it here, or * somewhere else, or not needed as the driver's suspend()/resume() * can handle everything */ - device_busy_set(dev); + pm_device_busy_set(dev); /* Process all the messages */ while (msg_left > 0) { @@ -493,7 +493,7 @@ static int i2c_dw_transfer(const struct device *dev, msg_left--; } - device_busy_clear(dev); + pm_device_busy_clear(dev); dw->state = I2C_DW_STATE_READY; diff --git a/drivers/sensor/bmp388/bmp388.c b/drivers/sensor/bmp388/bmp388.c index 49fc504a34d..fcaf2375547 100644 --- a/drivers/sensor/bmp388/bmp388.c +++ b/drivers/sensor/bmp388/bmp388.c @@ -353,7 +353,7 @@ static int bmp388_sample_fetch(const struct device *dev, } #endif - device_busy_set(dev); + pm_device_busy_set(dev); /* Wait for status to indicate that data is ready. */ raw[0] = 0U; @@ -382,7 +382,7 @@ static int bmp388_sample_fetch(const struct device *dev, bmp388->sample.comp_temp = 0; error: - device_busy_clear(dev); + pm_device_busy_clear(dev); return ret; } diff --git a/drivers/serial/uart_cc13xx_cc26xx.c b/drivers/serial/uart_cc13xx_cc26xx.c index dc0549f5a65..fb6de8e863e 100644 --- a/drivers/serial/uart_cc13xx_cc26xx.c +++ b/drivers/serial/uart_cc13xx_cc26xx.c @@ -241,7 +241,7 @@ static void uart_cc13xx_cc26xx_irq_tx_enable(const struct device *dev) * to transmit using the uart, hence we should no longer go * into standby. * - * Instead of using device_busy_set(), which currently does + * Instead of using pm_device_busy_set(), which currently does * not impact the PM policy, we specifically disable the * standby mode instead, since it is the power state that * would interfere with a transfer. diff --git a/drivers/serial/uart_nrfx_uart.c b/drivers/serial/uart_nrfx_uart.c index 9ce7d6fe5f4..66e4601598c 100644 --- a/drivers/serial/uart_nrfx_uart.c +++ b/drivers/serial/uart_nrfx_uart.c @@ -833,7 +833,7 @@ static void uart_nrfx_irq_tx_enable(const struct device *dev) /* Indicate that this device started a transaction that should not be * interrupted by putting the SoC into the deep sleep mode. */ - device_busy_set(dev); + pm_device_busy_set(dev); /* Activate the transmitter. */ nrf_uart_task_trigger(uart0_addr, NRF_UART_TASK_STARTTX); @@ -956,7 +956,7 @@ static void uart_nrfx_isr(const struct device *dev) /* The transaction is over. It is okay to enter the deep sleep * mode if needed. */ - device_busy_clear(dev); + pm_device_busy_clear(dev); disable_tx_irq = false; diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 9dce6d9c137..c0d264d4c6e 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -344,8 +344,8 @@ static int transceive(const struct device *dev, spi_context_lock(&spi->ctx, asynchronous, signal, config); #ifdef CONFIG_PM_DEVICE - if (device_busy_check(dev) != (-EBUSY)) { - device_busy_set(dev); + if (pm_device_busy_check(dev) != (-EBUSY)) { + pm_device_busy_set(dev); } #endif /* CONFIG_PM_DEVICE */ @@ -434,7 +434,7 @@ static int transceive(const struct device *dev, out: spi_context_release(&spi->ctx, ret); - device_busy_clear(dev); + pm_device_busy_clear(dev); return ret; } diff --git a/include/device.h b/include/device.h index 6584c566aaa..6c69afdcbf2 100644 --- a/include/device.h +++ b/include/device.h @@ -612,52 +612,6 @@ static inline bool device_is_ready(const struct device *dev) return device_usable_check(dev) == 0; } -/** - * @brief Indicate that the device is in the middle of a transaction - * - * Called by a device driver to indicate that it is in the middle of a - * transaction. - * - * @param dev Pointer to device structure of the driver instance. - */ -void device_busy_set(const struct device *dev); - -/** - * @brief Indicate that the device has completed its transaction - * - * Called by a device driver to indicate the end of a transaction. - * - * @param dev Pointer to device structure of the driver instance. - */ -void device_busy_clear(const struct device *dev); - -#ifdef CONFIG_PM_DEVICE -/** - * @brief Check if any device is in the middle of a transaction - * - * Called by an application to see if any device is in the middle - * of a critical transaction that cannot be interrupted. - * - * @retval 0 if no device is busy - * @retval -EBUSY if any device is busy - */ -int device_any_busy_check(void); - -/** - * @brief Check if a specific device is in the middle of a transaction - * - * Called by an application to see if a particular device is in the - * middle of a critical transaction that cannot be interrupted. - * - * @param chk_dev Pointer to device structure of the specific device driver - * the caller is interested in. - * @retval 0 if the device is not busy - * @retval -EBUSY if the device is busy - */ -int device_busy_check(const struct device *chk_dev); - -#endif - /** * @} */ diff --git a/include/pm/device.h b/include/pm/device.h index 8b9160b6676..9c7467b0f59 100644 --- a/include/pm/device.h +++ b/include/pm/device.h @@ -133,6 +133,56 @@ int pm_device_state_set(const struct device *dev, int pm_device_state_get(const struct device *dev, enum pm_device_state *device_power_state); +#ifdef CONFIG_PM_DEVICE +/** + * @brief Indicate that the device is in the middle of a transaction + * + * Called by a device driver to indicate that it is in the middle of a + * transaction. + * + * @param dev Pointer to device structure of the driver instance. + */ +void pm_device_busy_set(const struct device *dev); + +/** + * @brief Indicate that the device has completed its transaction + * + * Called by a device driver to indicate the end of a transaction. + * + * @param dev Pointer to device structure of the driver instance. + */ +void pm_device_busy_clear(const struct device *dev); + +/** + * @brief Check if any device is in the middle of a transaction + * + * Called by an application to see if any device is in the middle + * of a critical transaction that cannot be interrupted. + * + * @retval 0 if no device is busy + * @retval -EBUSY if any device is busy + */ +int pm_device_any_busy_check(void); + +/** + * @brief Check if a specific device is in the middle of a transaction + * + * Called by an application to see if a particular device is in the + * middle of a critical transaction that cannot be interrupted. + * + * @param chk_dev Pointer to device structure of the specific device driver + * the caller is interested in. + * @retval 0 if the device is not busy + * @retval -EBUSY if the device is busy + */ +int pm_device_busy_check(const struct device *chk_dev); +#else +static inline void pm_device_busy_set(const struct device *dev) {} +static inline void pm_device_busy_clear(const struct device *dev) {} +static inline int pm_device_any_busy_check(void) { return -ENOSYS; } +static inline int pm_device_busy_check(const struct device *chk_dev) { return -ENOSYS; } +#endif + /** Alias for legacy use of device_pm_control_nop */ #define device_pm_control_nop __DEPRECATED_MACRO NULL diff --git a/kernel/device.c b/kernel/device.c index e88e15f64f0..d7a9e7ab0ee 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -195,50 +195,3 @@ int device_required_foreach(const struct device *dev, return handle_count; } - -#ifdef CONFIG_PM_DEVICE -int device_any_busy_check(void) -{ - const struct device *dev = __device_start; - - while (dev < __device_end) { - if (atomic_test_bit(&dev->pm->atomic_flags, - PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT)) { - return -EBUSY; - } - ++dev; - } - - return 0; -} - -int device_busy_check(const struct device *dev) -{ - if (atomic_test_bit(&dev->pm->atomic_flags, - PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT)) { - return -EBUSY; - } - return 0; -} - -#endif - -void device_busy_set(const struct device *dev) -{ -#ifdef CONFIG_PM_DEVICE - atomic_set_bit(&dev->pm->atomic_flags, - PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT); -#else - ARG_UNUSED(dev); -#endif -} - -void device_busy_clear(const struct device *dev) -{ -#ifdef CONFIG_PM_DEVICE - atomic_clear_bit(&dev->pm->atomic_flags, - PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT); -#else - ARG_UNUSED(dev); -#endif -} diff --git a/samples/boards/stm32/power_mgmt/blinky/src/main.c b/samples/boards/stm32/power_mgmt/blinky/src/main.c index a8bffd93009..30c73bfd7bd 100644 --- a/samples/boards/stm32/power_mgmt/blinky/src/main.c +++ b/samples/boards/stm32/power_mgmt/blinky/src/main.c @@ -24,7 +24,7 @@ void main(void) printk("Device ready\n"); /* Don't let the system power off / low power this device */ - device_busy_set(led.port); + pm_device_busy_set(led.port); while (true) { gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); diff --git a/subsys/pm/device.c b/subsys/pm/device.c index 96bc58da3ac..e34bf53ca15 100644 --- a/subsys/pm/device.c +++ b/subsys/pm/device.c @@ -10,7 +10,6 @@ #include #include -#if defined(CONFIG_PM) #define LOG_LEVEL CONFIG_PM_LOG_LEVEL /* From power module Kconfig */ #include LOG_MODULE_DECLARE(power); @@ -18,6 +17,7 @@ LOG_MODULE_DECLARE(power); extern const struct device __device_start[]; extern const struct device __device_end[]; +#if defined(CONFIG_PM) extern const struct device *__pm_device_slots_start[]; /* Number of devices successfully suspended. */ @@ -28,7 +28,7 @@ static bool should_suspend(const struct device *dev, enum pm_device_state state) int rc; enum pm_device_state current_state; - if (device_busy_check(dev) != 0) { + if (pm_device_busy_check(dev) != 0) { return false; } @@ -149,3 +149,39 @@ int pm_device_state_get(const struct device *dev, return dev->pm_control(dev, PM_DEVICE_STATE_GET, device_power_state); } + +int pm_device_any_busy_check(void) +{ + const struct device *dev = __device_start; + + while (dev < __device_end) { + if (atomic_test_bit(&dev->pm->atomic_flags, + PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT)) { + return -EBUSY; + } + ++dev; + } + + return 0; +} + +int pm_device_busy_check(const struct device *dev) +{ + if (atomic_test_bit(&dev->pm->atomic_flags, + PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT)) { + return -EBUSY; + } + return 0; +} + +void pm_device_busy_set(const struct device *dev) +{ + atomic_set_bit(&dev->pm->atomic_flags, + PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT); +} + +void pm_device_busy_clear(const struct device *dev) +{ + atomic_clear_bit(&dev->pm->atomic_flags, + PM_DEVICE_ATOMIC_FLAGS_BUSY_BIT); +} diff --git a/tests/kernel/device/src/main.c b/tests/kernel/device/src/main.c index 25513a5bf4c..22739531559 100644 --- a/tests/kernel/device/src/main.c +++ b/tests/kernel/device/src/main.c @@ -51,7 +51,7 @@ extern void test_mmio_device_map(void); * * @ingroup kernel_device_tests * - * @see device_get_binding(), device_busy_set(), device_busy_clear(), + * @see device_get_binding(), pm_device_busy_set(), pm_device_busy_clear(), * DEVICE_DEFINE() */ void test_dummy_device(void) @@ -66,8 +66,8 @@ void test_dummy_device(void) dev = device_get_binding(DUMMY_PORT_2); zassert_false((dev == NULL), NULL); - device_busy_set(dev); - device_busy_clear(dev); + pm_device_busy_set(dev); + pm_device_busy_clear(dev); /* device_get_binding() returns false for device object * with failed init. @@ -283,8 +283,8 @@ static void test_enable_and_disable_automatic_runtime_pm(void) * enabled. It also checks if the device is in the middle of a transaction, * sets/clears busy status and validates status again. * - * @see device_get_binding(), device_busy_set(), device_busy_clear(), - * device_busy_check(), device_any_busy_check(), + * @see device_get_binding(), pm_device_busy_set(), pm_device_busy_clear(), + * pm_device_busy_check(), pm_device_any_busy_check(), * pm_device_state_set() */ void test_dummy_device_pm(void) @@ -296,22 +296,22 @@ void test_dummy_device_pm(void) dev = device_get_binding(DUMMY_PORT_2); zassert_false((dev == NULL), NULL); - busy = device_any_busy_check(); + busy = pm_device_any_busy_check(); zassert_true((busy == 0), NULL); /* Set device state to BUSY*/ - device_busy_set(dev); + pm_device_busy_set(dev); - busy = device_any_busy_check(); + busy = pm_device_any_busy_check(); zassert_false((busy == 0), NULL); - busy = device_busy_check(dev); + busy = pm_device_busy_check(dev); zassert_false((busy == 0), NULL); /* Clear device BUSY state*/ - device_busy_clear(dev); + pm_device_busy_clear(dev); - busy = device_busy_check(dev); + busy = pm_device_busy_check(dev); zassert_true((busy == 0), NULL); test_build_suspend_device_list();