/* * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com * * SPDX-License-Identifier: BSD-3-Clause */ /* * Device Power Management * * This module handles the main device power management operations including * device enable/disable, state management, retention control, and suspend handling. */ #include #include #include #include /** * device_enable() - Enable a device. * @dev: The device to enable. * * Performs the steps necessary to enable a device. */ static void device_enable(struct ti_device *dev) { const struct ti_dev_data *data; uint16_t i; assert(dev != NULL); data = ti_get_dev_data(dev); for (i = 0U; i < data->n_clocks; i++) { ti_device_clk_enable(dev, i); } ti_soc_device_enable(dev); } /** * ti_device_disable() - Disables a device. * @device: The device to modify. * @domain_reset: True if the device is being disabled due to a domain reset. * * Performs the steps necessary to disable a device. */ void ti_device_disable(struct ti_device *dev, bool domain_reset) { const struct ti_dev_data *data; int32_t i; assert(dev != NULL); data = ti_get_dev_data(dev); ti_soc_device_disable(dev, domain_reset); for (i = (int32_t) data->n_clocks - 1; i >= 0; i--) { ti_device_clk_disable(dev, (uint16_t) i); } } /** * ti_device_clear_flags() - Clear device initialization flags. * @dev: The device to modify. */ void ti_device_clear_flags(struct ti_device *dev) { assert(dev != NULL); ti_soc_device_clear_flags(dev); } /** * ti_device_set_state() - Set device enabled state. * @device_ptr: The device to modify. * @host_idx: Index of the host making the request. * @enable: True to enable the device, false to disable. */ void ti_device_set_state(struct ti_device *device_ptr, uint8_t host_idx, bool enable) { bool was_enabled; bool is_enabled; assert(device_ptr != NULL); assert((TI_DEV_FLAG_ENABLED(host_idx) & TI_DEV_FLAG_ENABLED_MASK) != 0UL); was_enabled = (device_ptr->flags & TI_DEV_FLAG_ENABLED_MASK) != 0UL; if (enable) { device_ptr->flags |= (uint32_t)TI_DEV_FLAG_ENABLED(host_idx); } else { device_ptr->flags &= ~(uint32_t)TI_DEV_FLAG_ENABLED(host_idx); } /* * As soon as any host gets or puts a device, we drop the power * on enabled flag. */ if (host_idx != TI_DEV_POWER_ON_ENABLED_HOST_IDX) { device_ptr->flags &= ~(uint32_t)TI_DEV_FLAG_POWER_ON_ENABLED; } is_enabled = (device_ptr->flags & TI_DEV_FLAG_ENABLED_MASK) != 0UL; if (was_enabled != is_enabled) { if (is_enabled) { device_enable(device_ptr); } else { ti_device_disable(device_ptr, false); } } } /** * ti_device_set_retention() - Enable or disable device retention. * @device_ptr: The device to modify. * @retention: True to enable retention, false to disable. */ void ti_device_set_retention(struct ti_device *device_ptr, bool retention) { bool is_retention; assert(device_ptr != NULL); is_retention = ((device_ptr->flags & TI_DEV_FLAG_RETENTION) != 0U); if (retention == is_retention) { return; } if (retention) { device_ptr->flags |= (uint32_t)TI_DEV_FLAG_RETENTION; ti_soc_device_ret_enable(device_ptr); } else { device_ptr->flags &= ~(uint32_t)TI_DEV_FLAG_RETENTION; ti_soc_device_ret_disable(device_ptr); } }