From 56bf3c704cd8f25eed42fa6e5d38b9a67691af58 Mon Sep 17 00:00:00 2001 From: Abderrahmane JARMOUNI Date: Mon, 27 Oct 2025 14:38:52 +0100 Subject: [PATCH 01/13] UPSTREAM: include: drivers: fix Doxygen \retval command usage commit 3d78a7665040c378a1cefadcc1235d7f3d6e8856 upstream. Fix how Doxygen special commands \retval & \return are used in doc text. \retval: Starts a description for a function's return value with name , which needs to be attached and to not be a word that is part of the sentence, and each return val should have its own \retval. Otherwise \retval is replaced with \return. Signed-off-by: Abderrahmane JARMOUNI --- include/zephyr/drivers/adc.h | 2 +- include/zephyr/drivers/can.h | 8 ++++---- include/zephyr/drivers/cellular.h | 12 +++++------ include/zephyr/drivers/charger.h | 4 ++-- include/zephyr/drivers/clock_control.h | 4 ++-- include/zephyr/drivers/counter.h | 6 +++--- include/zephyr/drivers/dai.h | 6 +++--- include/zephyr/drivers/display.h | 20 +++++++++--------- include/zephyr/drivers/dma.h | 28 +++++++++++++------------- include/zephyr/drivers/entropy.h | 2 +- include/zephyr/drivers/espi_emul.h | 2 +- include/zephyr/drivers/flash.h | 6 +++--- include/zephyr/drivers/fpga.h | 8 ++++---- include/zephyr/drivers/gpio.h | 2 +- include/zephyr/drivers/hwinfo.h | 20 +++++++++--------- include/zephyr/drivers/hwspinlock.h | 2 +- include/zephyr/drivers/i2c.h | 2 +- include/zephyr/drivers/i2s.h | 2 +- include/zephyr/drivers/i3c.h | 2 +- include/zephyr/drivers/led_strip.h | 2 +- include/zephyr/drivers/peci.h | 8 ++++---- include/zephyr/drivers/pm_cpu_ops.h | 6 +++--- include/zephyr/drivers/ps2.h | 10 ++++----- include/zephyr/drivers/retained_mem.h | 8 ++++---- include/zephyr/drivers/sdhc.h | 20 +++++++++--------- include/zephyr/drivers/spi.h | 4 ++-- include/zephyr/drivers/tee.h | 2 +- include/zephyr/drivers/video.h | 4 ++-- 28 files changed, 101 insertions(+), 101 deletions(-) diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index 8334f504ba14..c49a9f7d5ba8 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -1309,7 +1309,7 @@ static inline int adc_sequence_init_dt(const struct adc_dt_spec *spec, * * @param spec ADC specification from devicetree * - * @retval true if the ADC device is ready for use and false otherwise. + * @return true if the ADC device is ready for use and false otherwise. */ static inline bool adc_is_ready_dt(const struct adc_dt_spec *spec) { diff --git a/include/zephyr/drivers/can.h b/include/zephyr/drivers/can.h index 4cfa440b705b..de60bae43303 100644 --- a/include/zephyr/drivers/can.h +++ b/include/zephyr/drivers/can.h @@ -1002,7 +1002,7 @@ static inline const struct can_timing *z_impl_can_get_timing_data_max(const stru * @param sample_pnt Sample point for the data phase in permille of the entire bit * time or 0 for automatic sample point location. * - * @retval 0 or positive sample point error on success. + * @return 0 or positive sample point error on success. * @retval -EINVAL if the requested bitrate or sample point is out of range. * @retval -ENOTSUP if the requested bitrate is not supported. * @retval -EIO if @a can_get_core_clock() is not available. @@ -1387,7 +1387,7 @@ static inline void z_impl_can_remove_rx_filter(const struct device *dev, int fil * @param ide Get the maximum standard (11-bit) CAN ID filters if false, or extended (29-bit) CAN ID * filters if true. * - * @retval Positive number of maximum concurrent filters. + * @retval >=0 number of maximum concurrent filters. * @retval -EIO General input/output error. * @retval -ENOSYS If this function is not implemented by the driver. */ @@ -1684,7 +1684,7 @@ static inline uint32_t z_impl_can_stats_get_rx_overruns(const struct device *dev * * @param dlc Data Length Code (DLC). * - * @retval Number of bytes. + * @return Number of bytes. */ static inline uint8_t can_dlc_to_bytes(uint8_t dlc) { @@ -1699,7 +1699,7 @@ static inline uint8_t can_dlc_to_bytes(uint8_t dlc) * * @param num_bytes Number of bytes. * - * @retval Data Length Code (DLC). + * @return Data Length Code (DLC). */ static inline uint8_t can_bytes_to_dlc(uint8_t num_bytes) { diff --git a/include/zephyr/drivers/cellular.h b/include/zephyr/drivers/cellular.h index ba78207a340c..2df3af846167 100644 --- a/include/zephyr/drivers/cellular.h +++ b/include/zephyr/drivers/cellular.h @@ -237,7 +237,7 @@ __subsystem struct cellular_driver_api { * @retval 0 if successful. * @retval -EINVAL if any provided cellular network configuration is invalid or unsupported. * @retval -ENOTSUP if API is not supported by cellular network device. - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_configure_networks(const struct device *dev, const struct cellular_network *networks, uint8_t size) @@ -260,7 +260,7 @@ static inline int cellular_configure_networks(const struct device *dev, * * @retval 0 if successful. * @retval -ENOTSUP if API is not supported by cellular network device. - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_get_supported_networks(const struct device *dev, const struct cellular_network **networks, @@ -285,7 +285,7 @@ static inline int cellular_get_supported_networks(const struct device *dev, * @retval 0 if successful. * @retval -ENOTSUP if API is not supported by cellular network device. * @retval -ENODATA if device is not in a state where signal can be polled - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_get_signal(const struct device *dev, const enum cellular_signal_type type, int16_t *value) @@ -310,7 +310,7 @@ static inline int cellular_get_signal(const struct device *dev, * @retval 0 if successful. * @retval -ENOTSUP if API is not supported by cellular network device. * @retval -ENODATA if modem does not provide info requested - * @retval Negative errno-code from chat module otherwise. + * @retval <0 Negative errno-code from chat module otherwise. */ static inline int cellular_get_modem_info(const struct device *dev, const enum cellular_modem_info_type type, char *info, @@ -335,7 +335,7 @@ static inline int cellular_get_modem_info(const struct device *dev, * @retval 0 if successful. * @retval -ENOSYS if API is not supported by cellular network device. * @retval -ENODATA if modem does not provide info requested - * @retval Negative errno-code from chat module otherwise. + * @retval <0 Negative errno-code from chat module otherwise. */ static inline int cellular_get_registration_status(const struct device *dev, enum cellular_access_technology tech, @@ -364,7 +364,7 @@ static inline int cellular_get_registration_status(const struct device *dev, * @retval -EINVAL if APN string invalid or too long. * @retval -EALREADY if APN identical to current one, nothing to do * @retval -EBUSY if modem is already dialled, APN cannot be changed - * @retval Negative errno-code otherwise. + * @retval <0 Negative errno-code otherwise. */ static inline int cellular_set_apn(const struct device *dev, const char *apn) { diff --git a/include/zephyr/drivers/charger.h b/include/zephyr/drivers/charger.h index 27e4602560e2..a49a7a61b5d0 100644 --- a/include/zephyr/drivers/charger.h +++ b/include/zephyr/drivers/charger.h @@ -376,7 +376,7 @@ __subsystem struct charger_driver_api { * @param val Pointer to charger_propval union * * @retval 0 if successful - * @retval < 0 if getting property failed + * @retval <0 if getting property failed */ __syscall int charger_get_prop(const struct device *dev, const charger_prop_t prop, union charger_propval *val); @@ -397,7 +397,7 @@ static inline int z_impl_charger_get_prop(const struct device *dev, const charge * @param val Pointer to charger_propval union * * @retval 0 if successful - * @retval < 0 if setting property failed + * @retval <0 if setting property failed */ __syscall int charger_set_prop(const struct device *dev, const charger_prop_t prop, const union charger_propval *val); diff --git a/include/zephyr/drivers/clock_control.h b/include/zephyr/drivers/clock_control.h index d09daf963860..1ef3cd01f88b 100644 --- a/include/zephyr/drivers/clock_control.h +++ b/include/zephyr/drivers/clock_control.h @@ -174,7 +174,7 @@ static inline int clock_control_off(const struct device *dev, * @retval -EALREADY if clock was already started and is starting or running. * @retval -ENOTSUP If the requested mode of operation is not supported. * @retval -ENOSYS if the interface is not implemented. - * @retval other negative errno on vendor specific error. + * @retval <0 other negative errno on vendor specific error. */ static inline int clock_control_async_on(const struct device *dev, clock_control_subsys_t sys, @@ -252,7 +252,7 @@ static inline int clock_control_get_rate(const struct device *dev, * @retval -EALREADY if clock was already in the given rate. * @retval -ENOTSUP If the requested mode of operation is not supported. * @retval -ENOSYS if the interface is not implemented. - * @retval other negative errno on vendor specific error. + * @retval <0 other negative errno on vendor specific error. */ static inline int clock_control_set_rate(const struct device *dev, clock_control_subsys_t sys, diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index ca3a35183f41..cc0bf024980e 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -377,7 +377,7 @@ static inline uint32_t z_impl_counter_get_max_top_value(const struct device *dev * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int counter_start(const struct device *dev); @@ -414,7 +414,7 @@ static inline int z_impl_counter_stop(const struct device *dev) * @param ticks Pointer to where to store the current counter value * * @retval 0 If successful. - * @retval Negative error code on failure getting the counter value + * @retval <0 Negative error code on failure getting the counter value */ __syscall int counter_get_value(const struct device *dev, uint32_t *ticks); @@ -433,7 +433,7 @@ static inline int z_impl_counter_get_value(const struct device *dev, * @param ticks Pointer to where to store the current counter value * * @retval 0 If successful. - * @retval Negative error code on failure getting the counter value + * @retval <0 Negative error code on failure getting the counter value */ __syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks); diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index f80ce20811d3..1adce5eceb1f 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -410,7 +410,7 @@ static inline int dai_config_set(const struct device *dev, * @param dev Pointer to the device structure for the driver instance * @param cfg Pointer to the config structure to be filled by the instance * @param dir Stream direction: RX or TX as defined by DAI_DIR_* - * @retval 0 if success, negative if invalid parameters or DAI un-configured + * @return 0 if success, negative if invalid parameters or DAI un-configured */ static inline int dai_config_get(const struct device *dev, struct dai_config *cfg, @@ -428,7 +428,7 @@ static inline int dai_config_get(const struct device *dev, * @param dir Stream direction: RX or TX as defined by DAI_DIR_* * @param stream_id Stream id: some drivers may have stream specific * properties, this id specifies the stream. - * @retval Pointer to the structure containing properties, + * @return Pointer to the structure containing properties, * or NULL if error or no properties */ static inline const struct dai_properties *dai_get_properties(const struct device *dev, @@ -565,7 +565,7 @@ static inline int dai_ts_get(const struct device *dev, struct dai_ts_cfg *cfg, * * @retval 0 If successful. * @retval -ENOSYS If the configuration update operation is not implemented. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dai_config_update(const struct device *dev, const void *bespoke_cfg, diff --git a/include/zephyr/drivers/display.h b/include/zephyr/drivers/display.h index 08d55557ae97..39911d08baad 100644 --- a/include/zephyr/drivers/display.h +++ b/include/zephyr/drivers/display.h @@ -275,7 +275,7 @@ __subsystem struct display_driver_api { * @param desc Pointer to a structure describing the buffer layout * @param buf Pointer to buffer array * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ static inline int display_write(const struct device *dev, const uint16_t x, const uint16_t y, @@ -297,7 +297,7 @@ static inline int display_write(const struct device *dev, const uint16_t x, * @param desc Pointer to a structure describing the buffer layout * @param buf Pointer to buffer array * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_read(const struct device *dev, const uint16_t x, @@ -320,7 +320,7 @@ static inline int display_read(const struct device *dev, const uint16_t x, * * @param dev Pointer to device structure * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_clear(const struct device *dev) @@ -340,7 +340,7 @@ static inline int display_clear(const struct device *dev) * * @param dev Pointer to device structure * - * @retval Pointer to frame buffer or NULL if direct framebuffer access + * @return Pointer to frame buffer or NULL if direct framebuffer access * is not supported * */ @@ -372,7 +372,7 @@ static inline void *display_get_framebuffer(const struct device *dev) * * @param dev Pointer to device structure * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_blanking_on(const struct device *dev) @@ -396,7 +396,7 @@ static inline int display_blanking_on(const struct device *dev) * * @param dev Pointer to device structure * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_blanking_off(const struct device *dev) @@ -420,7 +420,7 @@ static inline int display_blanking_off(const struct device *dev) * @param dev Pointer to device structure * @param brightness Brightness in steps of 1/256 * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_set_brightness(const struct device *dev, @@ -445,7 +445,7 @@ static inline int display_set_brightness(const struct device *dev, * @param dev Pointer to device structure * @param contrast Contrast in steps of 1/256 * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_set_contrast(const struct device *dev, uint8_t contrast) @@ -482,7 +482,7 @@ static inline void display_get_capabilities(const struct device *dev, * @param dev Pointer to device structure * @param pixel_format Pixel format to be used by display * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int @@ -505,7 +505,7 @@ display_set_pixel_format(const struct device *dev, * @param dev Pointer to device structure * @param orientation Orientation to be used by display * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. * @retval -ENOSYS if not implemented. */ static inline int display_set_orientation(const struct device *dev, diff --git a/include/zephyr/drivers/dma.h b/include/zephyr/drivers/dma.h index 7a0954e248a2..51ace1bec8e8 100644 --- a/include/zephyr/drivers/dma.h +++ b/include/zephyr/drivers/dma.h @@ -346,7 +346,7 @@ typedef int (*dma_api_get_attribute)(const struct device *dev, uint32_t type, ui * @param channel the channel id to use * @param filter_param filter function parameter, can be NULL * - * @retval True on filter matched otherwise return False. + * @return True on filter matched otherwise return False. */ typedef bool (*dma_api_chan_filter)(const struct device *dev, int channel, void *filter_param); @@ -390,7 +390,7 @@ __subsystem struct dma_driver_api { * selected channel * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dma_config(const struct device *dev, uint32_t channel, struct dma_config *config) @@ -412,7 +412,7 @@ static inline int dma_config(const struct device *dev, uint32_t channel, * @param size size of DMA transfer * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ #ifdef CONFIG_DMA_64BIT static inline int dma_reload(const struct device *dev, uint32_t channel, @@ -449,7 +449,7 @@ static inline int dma_reload(const struct device *dev, uint32_t channel, * be processed * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dma_start(const struct device *dev, uint32_t channel) { @@ -475,7 +475,7 @@ static inline int dma_start(const struct device *dev, uint32_t channel) * being processed * * @retval 0 if successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ static inline int dma_stop(const struct device *dev, uint32_t channel) { @@ -551,8 +551,8 @@ static inline int dma_resume(const struct device *dev, uint32_t channel) * @param dev Pointer to the device structure for the driver instance. * @param filter_param filter function parameter * - * @retval dma channel if successful. - * @retval Negative errno code if failure. + * @return dma channel if successful. + * @retval <0 Negative errno code if failure. */ static inline int dma_request_channel(const struct device *dev, void *filter_param) { @@ -624,7 +624,7 @@ static inline void dma_release_channel(const struct device *dev, uint32_t channe * @param channel channel number * @param filter_param filter attribute * - * @retval Negative errno code if not support + * @retval <0 Negative errno code if not support * */ static inline int dma_chan_filter(const struct device *dev, int channel, void *filter_param) @@ -652,8 +652,8 @@ static inline int dma_chan_filter(const struct device *dev, int channel, void *f * being processed * @param stat a non-NULL dma_status object for storing DMA status * - * @retval non-negative if successful. - * @retval Negative errno code if failure. + * @retval >=0 non-negative if successful. + * @retval <0 Negative errno code if failure. */ static inline int dma_get_status(const struct device *dev, uint32_t channel, struct dma_status *stat) @@ -682,8 +682,8 @@ static inline int dma_get_status(const struct device *dev, uint32_t channel, * @param type Numeric identification of the attribute * @param value A non-NULL pointer to the variable where the read value is to be placed * - * @retval non-negative if successful. - * @retval Negative errno code if failure. + * @retval >=0 non-negative if successful. + * @retval <0 Negative errno code if failure. */ static inline int dma_get_attribute(const struct device *dev, uint32_t type, uint32_t *value) { @@ -707,7 +707,7 @@ static inline int dma_get_attribute(const struct device *dev, uint32_t type, uin * * @param size: width of bus (in bytes) * - * @retval common DMA index to be placed into registers. + * @return common DMA index to be placed into registers. */ static inline uint32_t dma_width_index(uint32_t size) { @@ -736,7 +736,7 @@ static inline uint32_t dma_width_index(uint32_t size) * * @param burst: number of bytes to be sent in a single burst * - * @retval common DMA index to be placed into registers. + * @return common DMA index to be placed into registers. */ static inline uint32_t dma_burst_index(uint32_t burst) { diff --git a/include/zephyr/drivers/entropy.h b/include/zephyr/drivers/entropy.h index 185b0d8f019f..5fd24f2833fa 100644 --- a/include/zephyr/drivers/entropy.h +++ b/include/zephyr/drivers/entropy.h @@ -103,7 +103,7 @@ static inline int z_impl_entropy_get_entropy(const struct device *dev, * @param buffer Buffer to fill with entropy. * @param length Buffer length. * @param flags Flags to modify the behavior of the call. - * @retval number of bytes filled with entropy or -error. + * @return number of bytes filled with entropy or -error. */ static inline int entropy_get_entropy_isr(const struct device *dev, uint8_t *buffer, diff --git a/include/zephyr/drivers/espi_emul.h b/include/zephyr/drivers/espi_emul.h index 1b572cef7112..7e8ed4e23b62 100644 --- a/include/zephyr/drivers/espi_emul.h +++ b/include/zephyr/drivers/espi_emul.h @@ -69,7 +69,7 @@ typedef int (*emul_espi_api_get_vw)(const struct emul *target, enum espi_vwire_s * * @param target The device Emulator instance * - * @retval The address of the memory. + * @return The address of the memory. */ typedef uintptr_t (*emul_espi_api_get_acpi_shm)(const struct emul *target); #endif diff --git a/include/zephyr/drivers/flash.h b/include/zephyr/drivers/flash.h index d8f39c4278be..91a8d199231b 100644 --- a/include/zephyr/drivers/flash.h +++ b/include/zephyr/drivers/flash.h @@ -525,7 +525,7 @@ void flash_page_foreach(const struct device *dev, flash_page_cb cb, * * @retval 0 on success * @retval -ENOTSUP if the flash driver does not support SFDP access - * @retval negative values for other errors. + * @retval <0 negative values for other errors. */ __syscall int flash_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len); @@ -553,7 +553,7 @@ static inline int z_impl_flash_sfdp_read(const struct device *dev, * * @retval 0 on successful store of 3-byte JEDEC id * @retval -ENOTSUP if flash driver doesn't support this function - * @retval negative values for other errors + * @retval <0 negative values for other errors */ __syscall int flash_read_jedec_id(const struct device *dev, uint8_t *id); @@ -637,7 +637,7 @@ static inline const struct flash_parameters *z_impl_flash_get_parameters(const s * @retval 0 on success. * @retval -ENOTSUP if given device doesn't support extended operation. * @retval -ENOSYS if support for extended operations is not enabled in Kconfig - * @retval negative value on extended operation errors. + * @retval <0 negative value on extended operation errors. */ __syscall int flash_ex_op(const struct device *dev, uint16_t code, const uintptr_t in, void *out); diff --git a/include/zephyr/drivers/fpga.h b/include/zephyr/drivers/fpga.h index 5c175f31c706..f8198706a77a 100644 --- a/include/zephyr/drivers/fpga.h +++ b/include/zephyr/drivers/fpga.h @@ -89,7 +89,7 @@ static inline enum FPGA_status fpga_get_status(const struct device *dev) * @param dev FPGA device structure. * * @retval 0 if successful. - * @retval Failed Otherwise. + * @return Failed Otherwise. */ static inline int fpga_reset(const struct device *dev) { @@ -111,7 +111,7 @@ static inline int fpga_reset(const struct device *dev) * @param img_size Bitstream size in bytes. * * @retval 0 if successful. - * @retval Failed Otherwise. + * @return Failed Otherwise. */ static inline int fpga_load(const struct device *dev, uint32_t *image_ptr, uint32_t img_size) @@ -132,7 +132,7 @@ static inline int fpga_load(const struct device *dev, uint32_t *image_ptr, * @param dev FPGA device structure. * * @retval 0 if successful. - * @retval negative errno code on failure. + * @retval <0 negative errno code on failure. */ static inline int fpga_on(const struct device *dev) { @@ -173,7 +173,7 @@ static inline const char *fpga_get_info(const struct device *dev) * @param dev FPGA device structure. * * @retval 0 if successful. - * @retval negative errno code on failure. + * @retval <0 negative errno code on failure. */ static inline int fpga_off(const struct device *dev) { diff --git a/include/zephyr/drivers/gpio.h b/include/zephyr/drivers/gpio.h index 33962528136f..ff65b4e7713e 100644 --- a/include/zephyr/drivers/gpio.h +++ b/include/zephyr/drivers/gpio.h @@ -1892,7 +1892,7 @@ static inline int gpio_remove_callback_dt(const struct gpio_dt_spec *spec, * * @param dev Pointer to the device structure for the driver instance. * - * @retval status != 0 if at least one gpio interrupt is pending. + * @return status != 0 if at least one gpio interrupt is pending. * @retval 0 if no gpio interrupt is pending. * @retval -ENOSYS If driver does not implement the operation */ diff --git a/include/zephyr/drivers/hwinfo.h b/include/zephyr/drivers/hwinfo.h index 55bd5f0a7d92..b777b3ae40c1 100644 --- a/include/zephyr/drivers/hwinfo.h +++ b/include/zephyr/drivers/hwinfo.h @@ -91,9 +91,9 @@ extern "C" { * @param buffer Buffer to write the ID to. * @param length Max length of the buffer. * - * @retval size of the device ID copied. + * @return size of the device ID copied. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall ssize_t hwinfo_get_device_id(uint8_t *buffer, size_t length); @@ -107,9 +107,9 @@ ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length); * * @param buffer Buffer of 8 bytes to write the ID to. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_get_device_eui64(uint8_t *buffer); @@ -131,9 +131,9 @@ int z_impl_hwinfo_get_device_eui64(uint8_t *buffer); * Successive calls to this routine will return the same value, unless * `hwinfo_clear_reset_cause` has been called. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_get_reset_cause(uint32_t *cause); @@ -144,9 +144,9 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause); * * Clears reset cause flags. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_clear_reset_cause(void); @@ -159,9 +159,9 @@ int z_impl_hwinfo_clear_reset_cause(void); * * Retrieves all `reset_cause` flags that are supported by this device. * - * @retval zero if successful. + * @retval 0 if successful. * @retval -ENOSYS if there is no implementation for the particular device. - * @retval any negative value on driver specific errors. + * @retval <0 any negative value on driver specific errors. */ __syscall int hwinfo_get_supported_reset_cause(uint32_t *supported); diff --git a/include/zephyr/drivers/hwspinlock.h b/include/zephyr/drivers/hwspinlock.h index 25d9d4a2d246..4d40fb8ae6fe 100644 --- a/include/zephyr/drivers/hwspinlock.h +++ b/include/zephyr/drivers/hwspinlock.h @@ -337,7 +337,7 @@ static inline void hw_spin_unlock(const struct device *dev, hwspinlock_ctx_t *ct * * @param dev HW spinlock device instance. * - * @retval HW spinlock max ID. + * @return HW spinlock max ID. */ static inline uint32_t hw_spinlock_get_max_id(const struct device *dev) { diff --git a/include/zephyr/drivers/i2c.h b/include/zephyr/drivers/i2c.h index 28fb25e08cb1..6a9c6ff3c7bd 100644 --- a/include/zephyr/drivers/i2c.h +++ b/include/zephyr/drivers/i2c.h @@ -982,7 +982,7 @@ static inline int i2c_transfer_cb_dt(const struct i2c_dt_spec *spec, * @param userdata Userdata passed to callback. * * @retval 0 if successful - * @retval negative on error. + * @retval <0 negative on error. */ static inline int i2c_write_read_cb(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr, const void *write_buf, diff --git a/include/zephyr/drivers/i2s.h b/include/zephyr/drivers/i2s.h index 406789c365da..ddecf758ebd7 100644 --- a/include/zephyr/drivers/i2s.h +++ b/include/zephyr/drivers/i2s.h @@ -373,7 +373,7 @@ static inline int z_impl_i2s_configure(const struct device *dev, * * @param dev Pointer to the device structure for the driver instance * @param dir Stream direction: RX or TX as defined by I2S_DIR_* - * @retval Pointer to the structure containing configuration parameters, + * @return Pointer to the structure containing configuration parameters, * or NULL if un-configured */ static inline const struct i2s_config *i2s_config_get(const struct device *dev, diff --git a/include/zephyr/drivers/i3c.h b/include/zephyr/drivers/i3c.h index 72a061528fad..4b39ef05efb0 100644 --- a/include/zephyr/drivers/i3c.h +++ b/include/zephyr/drivers/i3c.h @@ -2596,7 +2596,7 @@ void i3c_sec_handoffed(struct k_work *work); * * This allocates memory from a mem slab for a i3c_device_desc * - * @retval Pointer to allocated i3c_device_desc + * @return Pointer to allocated i3c_device_desc * @retval NULL if no mem slabs available */ struct i3c_device_desc *i3c_device_desc_alloc(void); diff --git a/include/zephyr/drivers/led_strip.h b/include/zephyr/drivers/led_strip.h index 3932a6737b33..4f5e50030f0c 100644 --- a/include/zephyr/drivers/led_strip.h +++ b/include/zephyr/drivers/led_strip.h @@ -159,7 +159,7 @@ static inline int led_strip_update_channels(const struct device *dev, * * @param dev LED strip device. * - * @retval Length of LED strip device. + * @return Length of LED strip device. */ static inline size_t led_strip_length(const struct device *dev) { diff --git a/include/zephyr/drivers/peci.h b/include/zephyr/drivers/peci.h index c7a9a28f8ec6..58e21cf32210 100644 --- a/include/zephyr/drivers/peci.h +++ b/include/zephyr/drivers/peci.h @@ -271,7 +271,7 @@ __subsystem struct peci_driver_api { * @param bitrate the selected bitrate expressed in Kbps. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_config(const struct device *dev, uint32_t bitrate); @@ -290,7 +290,7 @@ static inline int z_impl_peci_config(const struct device *dev, * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_enable(const struct device *dev); @@ -308,7 +308,7 @@ static inline int z_impl_peci_enable(const struct device *dev) * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_disable(const struct device *dev); @@ -327,7 +327,7 @@ static inline int z_impl_peci_disable(const struct device *dev) * @param msg Structure representing a PECI transaction. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int peci_transfer(const struct device *dev, struct peci_msg *msg); diff --git a/include/zephyr/drivers/pm_cpu_ops.h b/include/zephyr/drivers/pm_cpu_ops.h index ac69ac52e640..677154ab0363 100644 --- a/include/zephyr/drivers/pm_cpu_ops.h +++ b/include/zephyr/drivers/pm_cpu_ops.h @@ -35,7 +35,7 @@ extern "C" { * This call is intended for use in hotplug. A core that is powered down by * cpu_off can only be powered up again in response to a cpu_on * - * @retval The call does not return when successful + * @return The call does not return when successful * @retval -ENOTSUP If the operation is not supported */ int pm_cpu_off(void); @@ -50,7 +50,7 @@ int pm_cpu_off(void); * @param cpuid CPU id to power on * @param entry_point Address at which the core must commence execution * - * @retval 0 on success, a negative errno otherwise + * @return 0 on success, a negative errno otherwise * @retval -ENOTSUP If the operation is not supported */ int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point); @@ -62,7 +62,7 @@ int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point); * * @param reset system reset type, cold or warm. * - * @retval 0 on success, a negative errno otherwise + * @return 0 on success, a negative errno otherwise */ int pm_system_reset(unsigned char reset); diff --git a/include/zephyr/drivers/ps2.h b/include/zephyr/drivers/ps2.h index cd71aa3e49fc..691d68cf5371 100644 --- a/include/zephyr/drivers/ps2.h +++ b/include/zephyr/drivers/ps2.h @@ -74,7 +74,7 @@ __subsystem struct ps2_driver_api { * command or when a mouse/keyboard send data to the client application. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_config(const struct device *dev, ps2_callback_t callback_isr); @@ -95,7 +95,7 @@ static inline int z_impl_ps2_config(const struct device *dev, * @param value Data for the PS2 device. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_write(const struct device *dev, uint8_t value); @@ -113,7 +113,7 @@ static inline int z_impl_ps2_write(const struct device *dev, uint8_t value) * @param value Pointer used for reading the PS/2 device. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_read(const struct device *dev, uint8_t *value); @@ -130,7 +130,7 @@ static inline int z_impl_ps2_read(const struct device *dev, uint8_t *value) * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_enable_callback(const struct device *dev); @@ -151,7 +151,7 @@ static inline int z_impl_ps2_enable_callback(const struct device *dev) * @param dev Pointer to the device structure for the driver instance. * * @retval 0 If successful. - * @retval Negative errno code if failure. + * @retval <0 Negative errno code if failure. */ __syscall int ps2_disable_callback(const struct device *dev); diff --git a/include/zephyr/drivers/retained_mem.h b/include/zephyr/drivers/retained_mem.h index d265341e9fe4..45650baf89fc 100644 --- a/include/zephyr/drivers/retained_mem.h +++ b/include/zephyr/drivers/retained_mem.h @@ -90,7 +90,7 @@ __subsystem struct retained_mem_driver_api { * * @param dev Retained memory device to use. * - * @retval Positive value indicating size in bytes on success, else negative errno + * @return Positive value indicating size in bytes on success, else negative errno * code. */ __syscall ssize_t retained_mem_size(const struct device *dev); @@ -110,7 +110,7 @@ static inline ssize_t z_impl_retained_mem_size(const struct device *dev) * @param buffer Buffer to store read data in. * @param size Size of data to read. * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ __syscall int retained_mem_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size); @@ -144,7 +144,7 @@ static inline int z_impl_retained_mem_read(const struct device *dev, off_t offse * @param buffer Data to write. * @param size Size of data to be written. * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ __syscall int retained_mem_write(const struct device *dev, off_t offset, const uint8_t *buffer, size_t size); @@ -174,7 +174,7 @@ static inline int z_impl_retained_mem_write(const struct device *dev, off_t offs * * @param dev Retained memory device to use. * - * @retval 0 on success else negative errno code. + * @return 0 on success else negative errno code. */ __syscall int retained_mem_clear(const struct device *dev); diff --git a/include/zephyr/drivers/sdhc.h b/include/zephyr/drivers/sdhc.h index 159a312de9aa..37d9b977b9c1 100644 --- a/include/zephyr/drivers/sdhc.h +++ b/include/zephyr/drivers/sdhc.h @@ -285,8 +285,8 @@ __subsystem struct sdhc_driver_api { * * @param dev: SD host controller device * @retval 0 reset succeeded - * @retval -ETIMEDOUT: controller reset timed out - * @retval -EIO: reset failed + * @retval -ETIMEDOUT controller reset timed out + * @retval -EIO reset failed */ __syscall int sdhc_hw_reset(const struct device *dev); @@ -313,7 +313,7 @@ static inline int z_impl_sdhc_hw_reset(const struct device *dev) * @retval 0 command was sent successfully * @retval -ETIMEDOUT command timed out while sending * @retval -ENOTSUP host controller does not support command - * @retval -EIO: I/O error + * @retval -EIO I/O error */ __syscall int sdhc_request(const struct device *dev, struct sdhc_command *cmd, struct sdhc_data *data); @@ -389,9 +389,9 @@ static inline int z_impl_sdhc_card_present(const struct device *dev) * allows an application to request the SD host controller to tune the card. * @param dev: SDHC device * @retval 0 tuning succeeded, card is ready for commands - * @retval -ETIMEDOUT: tuning failed after timeout - * @retval -ENOTSUP: controller does not support tuning - * @retval -EIO: I/O error while tuning + * @retval -ETIMEDOUT tuning failed after timeout + * @retval -ENOTSUP controller does not support tuning + * @retval -EIO I/O error while tuning */ __syscall int sdhc_execute_tuning(const struct device *dev); @@ -468,8 +468,8 @@ static inline int z_impl_sdhc_get_host_props(const struct device *dev, * indicating which interrupts should produce a callback * @param user_data: parameter that will be passed to callback function * @retval 0 interrupts were enabled, and callback was installed - * @retval -ENOTSUP: controller does not support this function - * @retval -EIO: I/O error + * @retval -ENOTSUP controller does not support this function + * @retval -EIO I/O error */ __syscall int sdhc_enable_interrupt(const struct device *dev, sdhc_interrupt_cb_t callback, @@ -497,8 +497,8 @@ static inline int z_impl_sdhc_enable_interrupt(const struct device *dev, * @param sources: bitmask of @ref sdhc_interrupt_source values * indicating which interrupts should be disabled. * @retval 0 interrupts were disabled - * @retval -ENOTSUP: controller does not support this function - * @retval -EIO: I/O error + * @retval -ENOTSUP controller does not support this function + * @retval -EIO I/O error */ __syscall int sdhc_disable_interrupt(const struct device *dev, int sources); diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index 3d129780b2d0..6e1759b6db90 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -149,7 +149,7 @@ extern "C" { * @brief Get SPI word size in bits from a @ref spi_operation_t * * @param operation A @ref spi_operation_t from which to get the configured word size. - * @retval The size (in bits) of a spi word for the operation. + * @return The size (in bits) of a spi word for the operation. */ #define SPI_WORD_SIZE_GET(operation) \ (((operation) & SPI_WORD_SIZE_MASK) >> SPI_WORD_SIZE_SHIFT) @@ -158,7 +158,7 @@ extern "C" { * @brief Get a bitmask to set the word size in a @ref spi_operation_t * * @param word_size The size of a SPI data frame in bits. - * @retval A bitmask to apply to a @ref spi_operation_t + * @return A bitmask to apply to a @ref spi_operation_t */ #define SPI_WORD_SET(word_size) \ ((word_size) << SPI_WORD_SIZE_SHIFT) diff --git a/include/zephyr/drivers/tee.h b/include/zephyr/drivers/tee.h index 11ae15bab05a..04d46cebc869 100644 --- a/include/zephyr/drivers/tee.h +++ b/include/zephyr/drivers/tee.h @@ -640,7 +640,7 @@ static inline int z_impl_tee_suppl_recv(const struct device *dev, uint32_t *func * @param param List of the params for send/receive * * @retval -ENOSYS If callback was not implemented - * @retval Return value for sent request + * @return Return value for sent request * * @retval 0 On success, negative on error */ diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index ded70a80ff89..cf66a674c15a 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -870,7 +870,7 @@ static inline int video_get_selection(const struct device *dev, struct video_sel * @param align Alignment of the requested memory, must be a power of two. * @param timeout Timeout duration or K_NO_WAIT * - * @retval pointer to allocated video buffer + * @return pointer to allocated video buffer */ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout); @@ -880,7 +880,7 @@ struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_tim * @param size Size of the video buffer (in bytes). * @param timeout Timeout duration or K_NO_WAIT * - * @retval pointer to allocated video buffer + * @return pointer to allocated video buffer */ struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout); From 4765decab896b478bdd0e88f5a247bdbbeeae67a Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Wed, 5 Nov 2025 06:13:20 -0500 Subject: [PATCH 02/13] UPSTREAM: drivers: promote APIs from unstable to stable commit 4704c6d24d95c38968e079b0532a0de48ada736c upstream. Quite a few well established APIs are stuck in unstable status, move them to stable. Signed-off-by: Anas Nashif --- include/zephyr/drivers/counter.h | 2 +- include/zephyr/drivers/dac.h | 2 +- include/zephyr/drivers/mipi_dbi.h | 2 +- include/zephyr/drivers/mipi_dsi.h | 2 +- include/zephyr/drivers/retained_mem.h | 2 +- include/zephyr/drivers/uart.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index cc0bf024980e..cad0909ef078 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -18,7 +18,7 @@ * @brief Interfaces for counters. * @defgroup counter_interface Counter * @since 1.14 - * @version 0.8.0 + * @version 1.0.0 * @ingroup io_interfaces * @{ */ diff --git a/include/zephyr/drivers/dac.h b/include/zephyr/drivers/dac.h index d603f8701cef..1a2365fc2bf3 100644 --- a/include/zephyr/drivers/dac.h +++ b/include/zephyr/drivers/dac.h @@ -23,7 +23,7 @@ extern "C" { * @brief Interfaces for Digital-to-Analog Converters. * @defgroup dac_interface DAC * @since 2.3 - * @version 0.8.0 + * @version 1.0.0 * @ingroup io_interfaces * @{ */ diff --git a/include/zephyr/drivers/mipi_dbi.h b/include/zephyr/drivers/mipi_dbi.h index 85ed9e58475f..b47c9b1749ae 100644 --- a/include/zephyr/drivers/mipi_dbi.h +++ b/include/zephyr/drivers/mipi_dbi.h @@ -26,7 +26,7 @@ * @brief Interfaces for MIPI-DBI (Display Bus Interface). * @defgroup mipi_dbi_interface MIPI-DBI * @since 3.6 - * @version 0.8.0 + * @version 1.0.0 * @ingroup display_interface * @{ */ diff --git a/include/zephyr/drivers/mipi_dsi.h b/include/zephyr/drivers/mipi_dsi.h index 3e26436317a3..c726b0942b90 100644 --- a/include/zephyr/drivers/mipi_dsi.h +++ b/include/zephyr/drivers/mipi_dsi.h @@ -17,7 +17,7 @@ * @brief Interfaces for MIPI-DSI (Display Serial Interface). * @defgroup mipi_dsi_interface MIPI-DSI * @since 3.1 - * @version 0.8.0 + * @version 1.0.0 * @ingroup display_interface * @{ */ diff --git a/include/zephyr/drivers/retained_mem.h b/include/zephyr/drivers/retained_mem.h index 45650baf89fc..fe2deca73040 100644 --- a/include/zephyr/drivers/retained_mem.h +++ b/include/zephyr/drivers/retained_mem.h @@ -32,7 +32,7 @@ BUILD_ASSERT(!(sizeof(off_t) > sizeof(size_t)), * @brief Interfaces for retained memory. * @defgroup retained_mem_interface Retained memory * @since 3.4 - * @version 0.8.0 + * @version 1.0.0 * @ingroup io_interfaces * @{ */ diff --git a/include/zephyr/drivers/uart.h b/include/zephyr/drivers/uart.h index b4edee131099..1009a9d1d12a 100644 --- a/include/zephyr/drivers/uart.h +++ b/include/zephyr/drivers/uart.h @@ -147,7 +147,7 @@ typedef void (*uart_irq_callback_user_data_t)(const struct device *dev, * * @defgroup uart_async Async UART API * @since 1.14 - * @version 0.8.0 + * @version 1.0.0 * @{ */ From 8bb2aa47ccdfff9de250d30f8564692b40c900b4 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Thu, 14 Aug 2025 16:40:18 -0700 Subject: [PATCH 03/13] UPSTREAM: drivers: counter: introduce counter set value api commit 34befefd939f669039c2e6dce266fc01e0a3ae56 upstream. Introduce a counter set value api to set the ticks for 32b and 64b. Signed-off-by: Ryan McClelland --- include/zephyr/drivers/counter.h | 52 ++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index cad0909ef078..871bc33cbaa3 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -217,6 +217,10 @@ typedef int (*counter_api_get_value)(const struct device *dev, typedef int (*counter_api_get_value_64)(const struct device *dev, uint64_t *ticks); typedef int (*counter_api_reset)(const struct device *dev); +typedef int (*counter_api_set_value)(const struct device *dev, + uint32_t ticks); +typedef int (*counter_api_set_value_64)(const struct device *dev, + uint64_t ticks); typedef int (*counter_api_set_alarm)(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg); @@ -239,6 +243,8 @@ __subsystem struct counter_driver_api { counter_api_get_value get_value; counter_api_get_value_64 get_value_64; counter_api_reset reset; + counter_api_set_value set_value; + counter_api_set_value_64 set_value_64; counter_api_set_alarm set_alarm; counter_api_cancel_alarm cancel_alarm; counter_api_set_top_value set_top_value; @@ -471,6 +477,52 @@ static inline int z_impl_counter_reset(const struct device *dev) return api->reset(dev); } +/** + * @brief Set current counter value. + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Tick value to set + * + * @retval 0 If successful. + * @retval Negative error code on failure setting the counter value + */ +__syscall int counter_set_value(const struct device *dev, uint32_t ticks); + +static inline int z_impl_counter_set_value(const struct device *dev, + uint32_t ticks) +{ + const struct counter_driver_api *api = + (struct counter_driver_api *)dev->api; + + if (!api->set_value) { + return -ENOSYS; + } + + return api->set_value(dev, ticks); +} + +/** + * @brief Set current counter 64-bit value. + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Tick value to set + * + * @retval 0 If successful. + * @retval Negative error code on failure setting the counter value + */ +__syscall int counter_set_value_64(const struct device *dev, uint64_t ticks); + +static inline int z_impl_counter_set_value_64(const struct device *dev, + uint64_t ticks) +{ + const struct counter_driver_api *api = + (struct counter_driver_api *)dev->api; + + if (!api->set_value_64) { + return -ENOSYS; + } + + return api->set_value_64(dev, ticks); +} + /** * @brief Set a single shot alarm on a channel. * From 054560a4c5e8ee8c351d265e3f5d643d61228215 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Thu, 20 Nov 2025 19:10:53 -0800 Subject: [PATCH 04/13] UPSTREAM: drivers: counter: add ns to ticks helper commit 849ba3a33f33fb5ceea71f2abb7a751c9b6be909 upstream. There is already a helper for converting ticks to ns. Add one that does the opposite. Signed-off-by: Ryan McClelland --- include/zephyr/drivers/counter.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index 871bc33cbaa3..603ada6fcd6f 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -344,6 +344,23 @@ static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, return ((uint64_t)ticks * USEC_PER_SEC) / z_impl_counter_get_frequency(dev); } +/** + * @brief Function to convert nanoseconds to ticks. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ns Nanoseconds. + * + * @return Converted ticks. Ticks will be saturated if exceed 32 bits. + */ +__syscall uint32_t counter_ns_to_ticks(const struct device *dev, uint64_t ns); + +static inline uint32_t z_impl_counter_ns_to_ticks(const struct device *dev, uint64_t ns) +{ + uint64_t ticks = (ns * get_frequency(dev)) / NSEC_PER_SEC; + + return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; +} + /** * @brief Function to convert ticks to nanoseconds. * From af499d5e2a3b30f65fb396e33856b3f8d721b94a Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sat, 26 Apr 2025 00:24:04 -0500 Subject: [PATCH 05/13] UPSTREAM: drivers: counter: add kconfig for enabling... commit fd72085d9bc16225f15ee6ffaf2296ec9478f68b upstream Some counters, such as those that use fractional adders, tick at resolutions greater than 4294967295Hz. This changes the freq in the common info to a uint64_t. This adds a KConfig that can be selected by a driver. This also has the counter ticks to sec (and vice versa) helper functions call the get frequency for 64 bits if the kconfig is selected. Signed-off-by: Ryan McClelland --- drivers/counter/Kconfig | 7 +++ include/zephyr/drivers/counter.h | 93 ++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 5f1b8d29ac6f..d32a97ffefac 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -22,6 +22,13 @@ config COUNTER_SHELL help Enable Shell Commands for Counter and Timer +config COUNTER_64BITS_FREQ + bool + help + Select this option if the counter driver should use 64-bits for frequency. + This is typically set by drivers that have frequencies greater than + 4,294,967,295 Hz. + module = COUNTER module-str = counter source "subsys/logging/Kconfig.template.log_config" diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index 603ada6fcd6f..8ab877274a10 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -190,14 +190,18 @@ struct counter_top_cfg { /** @brief Structure with generic counter features. */ struct counter_config_info { - /** - * Maximal (default) top value on which counter is reset (cleared or reloaded). - */ - uint32_t max_top_value; /** * Frequency of the source clock if synchronous events are counted. */ +#ifdef CONFIG_COUNTER_64BITS_FREQ + uint64_t freq; +#else uint32_t freq; +#endif + /** + * Maximal (default) top value on which counter is reset (cleared or reloaded). + */ + uint32_t max_top_value; /** * Flags (see @ref COUNTER_FLAGS). */ @@ -236,6 +240,7 @@ typedef int (*counter_api_set_guard_period)(const struct device *dev, uint32_t ticks, uint32_t flags); typedef uint32_t (*counter_api_get_freq)(const struct device *dev); +typedef uint64_t (*counter_api_get_freq_64)(const struct device *dev); __subsystem struct counter_driver_api { counter_api_start start; @@ -253,6 +258,9 @@ __subsystem struct counter_driver_api { counter_api_get_guard_period get_guard_period; counter_api_set_guard_period set_guard_period; counter_api_get_freq get_freq; +#ifdef CONFIG_COUNTER_64BITS_FREQ + counter_api_get_freq_64 get_freq_64; +#endif /* CONFIG_COUNTER_64BITS_FREQ */ }; /** @@ -290,16 +298,43 @@ static inline uint8_t z_impl_counter_get_num_of_channels(const struct device *de return config->channels; } +__syscall uint32_t counter_get_frequency(const struct device *dev); + +#ifdef CONFIG_COUNTER_64BITS_FREQ /** * @brief Function to get counter frequency. * * @param[in] dev Pointer to the device structure for the driver instance. * * @return Frequency of the counter in Hz, or zero if the counter does - * not have a fixed frequency. + * not have a fixed frequency, or UINT32_MAX if the counter frequency + * is higher or equal to UINT32_MAX, in which case it is recommended to + * use counter_get_frequency_64(). */ -__syscall uint32_t counter_get_frequency(const struct device *dev); +static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) +{ + const struct counter_config_info *config = + (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = + (struct counter_driver_api *)dev->api; + if (api->get_freq) { + return api->get_freq(dev); + } else { + return config->freq > UINT32_MAX ? UINT32_MAX : (uint32_t)config->freq; + } +} + +#else + +/** + * @brief Function to get counter frequency. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Frequency of the counter in Hz, or zero if the counter does + * not have a fixed frequency. + */ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) { const struct counter_config_info *config = @@ -309,6 +344,44 @@ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) return api->get_freq ? api->get_freq(dev) : config->freq; } +#endif + +/** + * @brief Function to get counter frequency in 64bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Frequency of the counter in Hz, or zero if the counter does + * not have a fixed frequency. + */ +__syscall uint64_t counter_get_frequency_64(const struct device *dev); + +static inline uint64_t z_impl_counter_get_frequency_64(const struct device *dev) +{ +#ifdef CONFIG_COUNTER_64BITS_FREQ + const struct counter_config_info *config = + (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = + (struct counter_driver_api *)dev->api; + + if (api->get_freq_64) { + return api->get_freq_64(dev); + } else if (api->get_freq) { + return (uint64_t)api->get_freq(dev); + } else { + return config->freq; + } +#else + ARG_UNUSED(dev); + return -ENOTSUP; +#endif +} + +#ifdef CONFIG_COUNTER_64BITS_FREQ +#define z_counter_get_frequency z_impl_counter_get_frequency_64 +#else +#define z_counter_get_frequency z_impl_counter_get_frequency +#endif /** * @brief Function to convert microseconds to ticks. @@ -323,7 +396,7 @@ __syscall uint32_t counter_us_to_ticks(const struct device *dev, uint64_t us); static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, uint64_t us) { - uint64_t ticks = (us * z_impl_counter_get_frequency(dev)) / USEC_PER_SEC; + uint64_t ticks = (us * z_counter_get_frequency(dev)) / USEC_PER_SEC; return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; } @@ -341,7 +414,7 @@ __syscall uint64_t counter_ticks_to_us(const struct device *dev, uint32_t ticks) static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, uint32_t ticks) { - return ((uint64_t)ticks * USEC_PER_SEC) / z_impl_counter_get_frequency(dev); + return ((uint64_t)ticks * USEC_PER_SEC) / z_counter_get_frequency(dev); } /** @@ -356,7 +429,7 @@ __syscall uint32_t counter_ns_to_ticks(const struct device *dev, uint64_t ns); static inline uint32_t z_impl_counter_ns_to_ticks(const struct device *dev, uint64_t ns) { - uint64_t ticks = (ns * get_frequency(dev)) / NSEC_PER_SEC; + uint64_t ticks = (ns * z_counter_get_frequency(dev)) / NSEC_PER_SEC; return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; } @@ -374,7 +447,7 @@ __syscall uint64_t counter_ticks_to_ns(const struct device *dev, uint32_t ticks) static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, uint32_t ticks) { - return ((uint64_t)ticks * NSEC_PER_SEC) / z_impl_counter_get_frequency(dev); + return ((uint64_t)ticks * NSEC_PER_SEC) / z_counter_get_frequency(dev); } /** From bea262141d236be7f8b60cdd7453b251fe55095a Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Thu, 20 Nov 2025 20:20:48 -0800 Subject: [PATCH 06/13] UPSTREAM: drivers: counter: run clang-format on counter.h commit ac8f2200ae6005459abe3ed8b1595f3297324caf upstream. Run clang-format on counter.h Signed-off-by: Ryan McClelland --- include/zephyr/drivers/counter.h | 156 +++++++++++-------------------- 1 file changed, 53 insertions(+), 103 deletions(-) diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index 8ab877274a10..c660225a0e39 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -93,7 +93,7 @@ extern "C" { * * Alarm callback must be called from the same context as if it was set on time. */ -#define COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE BIT(1) +#define COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE BIT(1) /**@} */ @@ -120,8 +120,7 @@ extern "C" { * @param ticks Counter value that triggered the alarm. * @param user_data User data. */ -typedef void (*counter_alarm_callback_t)(const struct device *dev, - uint8_t chan_id, uint32_t ticks, +typedef void (*counter_alarm_callback_t)(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *user_data); /** @brief Alarm callback structure. @@ -163,8 +162,7 @@ struct counter_alarm_cfg { * @param dev Pointer to the device structure for the driver instance. * @param user_data User data provided in @ref counter_set_top_value. */ -typedef void (*counter_top_callback_t)(const struct device *dev, - void *user_data); +typedef void (*counter_top_callback_t)(const struct device *dev, void *user_data); /** @brief Top value configuration structure. */ @@ -216,29 +214,21 @@ struct counter_config_info { typedef int (*counter_api_start)(const struct device *dev); typedef int (*counter_api_stop)(const struct device *dev); -typedef int (*counter_api_get_value)(const struct device *dev, - uint32_t *ticks); -typedef int (*counter_api_get_value_64)(const struct device *dev, - uint64_t *ticks); +typedef int (*counter_api_get_value)(const struct device *dev, uint32_t *ticks); +typedef int (*counter_api_get_value_64)(const struct device *dev, uint64_t *ticks); typedef int (*counter_api_reset)(const struct device *dev); -typedef int (*counter_api_set_value)(const struct device *dev, - uint32_t ticks); -typedef int (*counter_api_set_value_64)(const struct device *dev, - uint64_t ticks); -typedef int (*counter_api_set_alarm)(const struct device *dev, - uint8_t chan_id, +typedef int (*counter_api_set_value)(const struct device *dev, uint32_t ticks); +typedef int (*counter_api_set_value_64)(const struct device *dev, uint64_t ticks); +typedef int (*counter_api_set_alarm)(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg); -typedef int (*counter_api_cancel_alarm)(const struct device *dev, - uint8_t chan_id); +typedef int (*counter_api_cancel_alarm)(const struct device *dev, uint8_t chan_id); typedef int (*counter_api_set_top_value)(const struct device *dev, const struct counter_top_cfg *cfg); typedef uint32_t (*counter_api_get_pending_int)(const struct device *dev); typedef uint32_t (*counter_api_get_top_value)(const struct device *dev); -typedef uint32_t (*counter_api_get_guard_period)(const struct device *dev, - uint32_t flags); -typedef int (*counter_api_set_guard_period)(const struct device *dev, - uint32_t ticks, - uint32_t flags); +typedef uint32_t (*counter_api_get_guard_period)(const struct device *dev, uint32_t flags); +typedef int (*counter_api_set_guard_period)(const struct device *dev, uint32_t ticks, + uint32_t flags); typedef uint32_t (*counter_api_get_freq)(const struct device *dev); typedef uint64_t (*counter_api_get_freq_64)(const struct device *dev); @@ -275,8 +265,7 @@ __syscall bool counter_is_counting_up(const struct device *dev); static inline bool z_impl_counter_is_counting_up(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; return config->flags & COUNTER_CONFIG_INFO_COUNT_UP; } @@ -292,8 +281,7 @@ __syscall uint8_t counter_get_num_of_channels(const struct device *dev); static inline uint8_t z_impl_counter_get_num_of_channels(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; return config->channels; } @@ -313,10 +301,8 @@ __syscall uint32_t counter_get_frequency(const struct device *dev); */ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (api->get_freq) { return api->get_freq(dev); @@ -337,10 +323,8 @@ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) */ static inline uint32_t z_impl_counter_get_frequency(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_freq ? api->get_freq(dev) : config->freq; } @@ -359,10 +343,8 @@ __syscall uint64_t counter_get_frequency_64(const struct device *dev); static inline uint64_t z_impl_counter_get_frequency_64(const struct device *dev) { #ifdef CONFIG_COUNTER_64BITS_FREQ - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (api->get_freq_64) { return api->get_freq_64(dev); @@ -393,8 +375,7 @@ static inline uint64_t z_impl_counter_get_frequency_64(const struct device *dev) */ __syscall uint32_t counter_us_to_ticks(const struct device *dev, uint64_t us); -static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, - uint64_t us) +static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, uint64_t us) { uint64_t ticks = (us * z_counter_get_frequency(dev)) / USEC_PER_SEC; @@ -411,8 +392,7 @@ static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, */ __syscall uint64_t counter_ticks_to_us(const struct device *dev, uint32_t ticks); -static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, - uint32_t ticks) +static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, uint32_t ticks) { return ((uint64_t)ticks * USEC_PER_SEC) / z_counter_get_frequency(dev); } @@ -444,8 +424,7 @@ static inline uint32_t z_impl_counter_ns_to_ticks(const struct device *dev, uint */ __syscall uint64_t counter_ticks_to_ns(const struct device *dev, uint32_t ticks); -static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, - uint32_t ticks) +static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, uint32_t ticks) { return ((uint64_t)ticks * NSEC_PER_SEC) / z_counter_get_frequency(dev); } @@ -461,8 +440,7 @@ __syscall uint32_t counter_get_max_top_value(const struct device *dev); static inline uint32_t z_impl_counter_get_max_top_value(const struct device *dev) { - const struct counter_config_info *config = - (const struct counter_config_info *)dev->config; + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; return config->max_top_value; } @@ -479,8 +457,7 @@ __syscall int counter_start(const struct device *dev); static inline int z_impl_counter_start(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->start(dev); } @@ -498,8 +475,7 @@ __syscall int counter_stop(const struct device *dev); static inline int z_impl_counter_stop(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->stop(dev); } @@ -514,11 +490,9 @@ static inline int z_impl_counter_stop(const struct device *dev) */ __syscall int counter_get_value(const struct device *dev, uint32_t *ticks); -static inline int z_impl_counter_get_value(const struct device *dev, - uint32_t *ticks) +static inline int z_impl_counter_get_value(const struct device *dev, uint32_t *ticks) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_value(dev, ticks); } @@ -533,11 +507,9 @@ static inline int z_impl_counter_get_value(const struct device *dev, */ __syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks); -static inline int z_impl_counter_get_value_64(const struct device *dev, - uint64_t *ticks) +static inline int z_impl_counter_get_value_64(const struct device *dev, uint64_t *ticks) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (!api->get_value_64) { return -ENOSYS; @@ -557,8 +529,7 @@ __syscall int counter_reset(const struct device *dev); static inline int z_impl_counter_reset(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (!api->reset) { return -ENOSYS; @@ -577,11 +548,9 @@ static inline int z_impl_counter_reset(const struct device *dev) */ __syscall int counter_set_value(const struct device *dev, uint32_t ticks); -static inline int z_impl_counter_set_value(const struct device *dev, - uint32_t ticks) +static inline int z_impl_counter_set_value(const struct device *dev, uint32_t ticks) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (!api->set_value) { return -ENOSYS; @@ -600,11 +569,9 @@ static inline int z_impl_counter_set_value(const struct device *dev, */ __syscall int counter_set_value_64(const struct device *dev, uint64_t ticks); -static inline int z_impl_counter_set_value_64(const struct device *dev, - uint64_t ticks) +static inline int z_impl_counter_set_value_64(const struct device *dev, uint64_t ticks) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (!api->set_value_64) { return -ENOSYS; @@ -633,16 +600,13 @@ static inline int z_impl_counter_set_value_64(const struct device *dev, * @retval -ETIME if absolute alarm was set too late. * @retval -EBUSY if alarm is already active. */ -__syscall int counter_set_channel_alarm(const struct device *dev, - uint8_t chan_id, +__syscall int counter_set_channel_alarm(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg); -static inline int z_impl_counter_set_channel_alarm(const struct device *dev, - uint8_t chan_id, +static inline int z_impl_counter_set_channel_alarm(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (chan_id >= counter_get_num_of_channels(dev)) { return -ENOTSUP; @@ -663,14 +627,11 @@ static inline int z_impl_counter_set_channel_alarm(const struct device *dev, * @retval -ENOTSUP if request is not supported or the counter was not started * yet. */ -__syscall int counter_cancel_channel_alarm(const struct device *dev, - uint8_t chan_id); +__syscall int counter_cancel_channel_alarm(const struct device *dev, uint8_t chan_id); -static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, - uint8_t chan_id) +static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, uint8_t chan_id) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (chan_id >= counter_get_num_of_channels(dev)) { return -ENOTSUP; @@ -703,15 +664,12 @@ static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, * @retval -ETIME if @ref COUNTER_TOP_CFG_DONT_RESET was set and new top value * is smaller than current counter value (counter counting up). */ -__syscall int counter_set_top_value(const struct device *dev, - const struct counter_top_cfg *cfg); +__syscall int counter_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg); static inline int z_impl_counter_set_top_value(const struct device *dev, - const struct counter_top_cfg - *cfg) + const struct counter_top_cfg *cfg) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (cfg->ticks > counter_get_max_top_value(dev)) { return -EINVAL; @@ -737,8 +695,7 @@ __syscall int counter_get_pending_int(const struct device *dev); static inline int z_impl_counter_get_pending_int(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_pending_int(dev); } @@ -754,8 +711,7 @@ __syscall uint32_t counter_get_top_value(const struct device *dev); static inline uint32_t z_impl_counter_get_top_value(const struct device *dev) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return api->get_top_value(dev); } @@ -812,15 +768,12 @@ static inline uint32_t z_impl_counter_get_top_value(const struct device *dev) * @retval -ENOSYS if function or flags are not supported. * @retval -EINVAL if ticks value is invalid. */ -__syscall int counter_set_guard_period(const struct device *dev, - uint32_t ticks, - uint32_t flags); +__syscall int counter_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags); -static inline int z_impl_counter_set_guard_period(const struct device *dev, - uint32_t ticks, uint32_t flags) +static inline int z_impl_counter_set_guard_period(const struct device *dev, uint32_t ticks, + uint32_t flags) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; if (!api->set_guard_period) { return -ENOSYS; @@ -840,14 +793,11 @@ static inline int z_impl_counter_set_guard_period(const struct device *dev, * @return Guard period given in counter ticks or 0 if function or flags are * not supported. */ -__syscall uint32_t counter_get_guard_period(const struct device *dev, - uint32_t flags); +__syscall uint32_t counter_get_guard_period(const struct device *dev, uint32_t flags); -static inline uint32_t z_impl_counter_get_guard_period(const struct device *dev, - uint32_t flags) +static inline uint32_t z_impl_counter_get_guard_period(const struct device *dev, uint32_t flags) { - const struct counter_driver_api *api = - (struct counter_driver_api *)dev->api; + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; return (api->get_guard_period) ? api->get_guard_period(dev, flags) : 0; } From 3320810f72de5ecb3dd4e9c4f52c27951b942fa0 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Sun, 9 Nov 2025 11:33:43 -0800 Subject: [PATCH 07/13] UPSTREAM: drivers: counter: add 64bit apis commit 779383e769071367e447425e994c7811900fe5ed upstream. Add apis for 64 bits. Signed-off-by: Ryan McClelland --- drivers/counter/Kconfig | 7 + drivers/counter/Kconfig.ace | 2 + drivers/counter/Kconfig.cc23x0_rtc | 1 + drivers/counter/Kconfig.esp32_tmr | 1 + drivers/counter/Kconfig.stm32_rtc | 1 + drivers/counter/counter_esp32_tmr.c | 122 +++++-- drivers/counter/counter_handlers.c | 2 + drivers/sensor/sensor_clock_external.c | 5 +- include/zephyr/drivers/counter.h | 436 ++++++++++++++++++++++--- 9 files changed, 508 insertions(+), 69 deletions(-) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index d32a97ffefac..66a0017285a7 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -29,6 +29,13 @@ config COUNTER_64BITS_FREQ This is typically set by drivers that have frequencies greater than 4,294,967,295 Hz. +config COUNTER_64BITS_TICKS + bool + help + Select this option if the counter driver should use 64-bits for ticks. + This is typically set by drivers that require extended + tick ranges beyond the 32-bit limit. + module = COUNTER module-str = counter source "subsys/logging/Kconfig.template.log_config" diff --git a/drivers/counter/Kconfig.ace b/drivers/counter/Kconfig.ace index a7c5d611a92c..d3f24cb24e74 100644 --- a/drivers/counter/Kconfig.ace +++ b/drivers/counter/Kconfig.ace @@ -5,6 +5,7 @@ config ACE_V1X_ART_COUNTER bool "DSP ART Wall Clock for ACE V1X" depends on DT_HAS_INTEL_ACE_ART_COUNTER_ENABLED + select COUNTER_64BITS_TICKS default y help DSP ART Wall Clock used by ACE V1X. @@ -12,6 +13,7 @@ config ACE_V1X_ART_COUNTER config ACE_V1X_RTC_COUNTER bool "DSP RTC Wall Clock for ACE V1X" depends on DT_HAS_INTEL_ACE_RTC_COUNTER_ENABLED + select COUNTER_64BITS_TICKS default y help DSP RTC Wall Clock used by ACE V1X. diff --git a/drivers/counter/Kconfig.cc23x0_rtc b/drivers/counter/Kconfig.cc23x0_rtc index ce4e9ad6b2c1..0f04e9fb29c1 100644 --- a/drivers/counter/Kconfig.cc23x0_rtc +++ b/drivers/counter/Kconfig.cc23x0_rtc @@ -6,5 +6,6 @@ config COUNTER_CC23X0_RTC default y depends on DT_HAS_TI_CC23X0_RTC_ENABLED depends on CC23X0_SYSTIM_TIMER + select COUNTER_64BITS_TICKS help Enable counter driver based on RTC timer for cc23x0 diff --git a/drivers/counter/Kconfig.esp32_tmr b/drivers/counter/Kconfig.esp32_tmr index 099c1d820640..86d39871fc25 100644 --- a/drivers/counter/Kconfig.esp32_tmr +++ b/drivers/counter/Kconfig.esp32_tmr @@ -7,6 +7,7 @@ config COUNTER_TMR_ESP32 bool "ESP32 Counter Driver based on GP-Timers" default y depends on DT_HAS_ESPRESSIF_ESP32_COUNTER_ENABLED + select COUNTER_64BITS_TICKS help Enables the Counter driver API based on Espressif's General Purpose Timers for ESP32 series devices. diff --git a/drivers/counter/Kconfig.stm32_rtc b/drivers/counter/Kconfig.stm32_rtc index 4273d1c49313..83ba82b57f80 100644 --- a/drivers/counter/Kconfig.stm32_rtc +++ b/drivers/counter/Kconfig.stm32_rtc @@ -23,6 +23,7 @@ config COUNTER_RTC_STM32_SAVE_VALUE_BETWEEN_RESETS config COUNTER_RTC_STM32_SUBSECONDS bool "Use the subseconds as a basic tick." depends on !SOC_SERIES_STM32F1X + select COUNTER_64BITS_TICKS help Use the subseconds as the basic time tick. It increases resolution of the counter. The frequency of the time is RTC Source Clock divided diff --git a/drivers/counter/counter_esp32_tmr.c b/drivers/counter/counter_esp32_tmr.c index 995b5101c2b1..49ab808526da 100644 --- a/drivers/counter/counter_esp32_tmr.c +++ b/drivers/counter/counter_esp32_tmr.c @@ -26,10 +26,10 @@ typedef bool (*timer_isr_t)(void *); struct counter_esp32_top_data { counter_top_callback_t callback; - uint32_t ticks; + uint64_t ticks; void *user_data; bool auto_reload; - uint32_t guard_period; + uint64_t guard_period; }; struct counter_esp32_config { @@ -45,9 +45,10 @@ struct counter_esp32_config { }; struct counter_esp32_data { - struct counter_alarm_cfg alarm_cfg; + struct counter_alarm_cfg_64 alarm_cfg; + counter_alarm_callback_t alarm_callback_32; struct counter_esp32_top_data top_data; - uint32_t ticks; + uint64_t ticks; uint32_t clock_src_hz; timer_hal_context_t hal_ctx; }; @@ -140,18 +141,18 @@ static int counter_esp32_get_value_64(const struct device *dev, uint64_t *ticks) return 0; } -static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, - const struct counter_alarm_cfg *alarm_cfg) +static int counter_esp32_set_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg) { ARG_UNUSED(chan_id); struct counter_esp32_data *data = dev->data; bool absolute = alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE; - uint32_t ticks = alarm_cfg->ticks; - uint32_t top = data->top_data.ticks; - uint32_t max_rel_val = data->top_data.ticks; + uint64_t ticks = alarm_cfg->ticks; + uint64_t top = data->top_data.ticks; + uint64_t max_rel_val = data->top_data.ticks; uint64_t now; uint64_t target; - uint32_t diff; + uint64_t diff; int err = 0; bool irq_on_late = 0; @@ -177,7 +178,7 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, timer_ll_set_alarm_value(data->hal_ctx.dev, data->hal_ctx.timer_id, target); - diff = (alarm_cfg->ticks - (uint32_t)now); + diff = (alarm_cfg->ticks - now); if (diff > max_rel_val) { if (absolute) { err = -ETIME; @@ -216,21 +217,22 @@ static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id) return 0; } -static int counter_esp32_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) +static int counter_esp32_set_top_value_64(const struct device *dev, + const struct counter_top_cfg_64 *cfg) { const struct counter_esp32_config *config = dev->config; struct counter_esp32_data *data = dev->data; - uint32_t now; + uint64_t now; if (data->alarm_cfg.callback) { return -EBUSY; } - if (cfg->ticks > config->counter_info.max_top_value) { + if (cfg->ticks > config->counter_info.max_top_value_64) { return -ENOTSUP; } - counter_esp32_get_value(dev, &now); + counter_esp32_get_value_64(dev, &now); if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) { timer_hal_set_counter_value(&data->hal_ctx, 0); @@ -267,7 +269,7 @@ static uint32_t counter_esp32_get_pending_int(const struct device *dev) return timer_ll_get_intr_status(data->hal_ctx.dev); } -static uint32_t counter_esp32_get_top_value(const struct device *dev) +static uint64_t counter_esp32_get_top_value_64(const struct device *dev) { struct counter_esp32_data *data = dev->data; @@ -291,7 +293,7 @@ static int counter_esp32_reset(const struct device *dev) return 0; } -static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_t flags) +static uint64_t counter_esp32_get_guard_period_64(const struct device *dev, uint32_t flags) { struct counter_esp32_data *data = dev->data; @@ -300,7 +302,8 @@ static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_ return data->top_data.guard_period; } -static int counter_esp32_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags) +static int counter_esp32_set_guard_period_64(const struct device *dev, uint64_t ticks, + uint32_t flags) { struct counter_esp32_data *data = dev->data; @@ -314,6 +317,76 @@ static int counter_esp32_set_guard_period(const struct device *dev, uint32_t tic return 0; } +static int counter_esp32_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg) +{ + struct counter_top_cfg_64 alarm_cfg_64 = { + .callback = cfg->callback, + .ticks = (uint64_t)cfg->ticks, + .user_data = cfg->user_data, + .flags = cfg->flags, + }; + + return counter_esp32_set_top_value_64(dev, &alarm_cfg_64); +} + +static void counter_esp32_callback_32_trampoline(const struct device *dev, + uint8_t chan_id, + uint64_t ticks, + void *user_data) +{ + struct counter_esp32_data *data = dev->data; + + /* Safely call the original 32-bit callback */ + data->alarm_callback_32(dev, chan_id, (uint32_t)ticks, user_data); +} + +static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + struct counter_esp32_data *data = dev->data; + struct counter_alarm_cfg_64 alarm_cfg_64 = { + .callback = counter_esp32_callback_32_trampoline, + .ticks = (uint64_t)alarm_cfg->ticks, + .user_data = alarm_cfg->user_data, + .flags = alarm_cfg->flags, + }; + + /* use trampoline function to handle the function pointer type difference */ + data->alarm_callback_32 = alarm_cfg->callback; + + return counter_esp32_set_alarm_64(dev, chan_id, &alarm_cfg_64); +} + +static uint32_t counter_esp32_get_top_value(const struct device *dev) +{ + struct counter_esp32_data *data = dev->data; + + return (uint32_t)data->top_data.ticks; +} + +static uint32_t counter_esp32_get_guard_period(const struct device *dev, uint32_t flags) +{ + struct counter_esp32_data *data = dev->data; + + ARG_UNUSED(flags); + + return (uint32_t)data->top_data.guard_period; +} + +static int counter_esp32_set_guard_period(const struct device *dev, uint32_t ticks, uint32_t flags) +{ + struct counter_esp32_data *data = dev->data; + + ARG_UNUSED(flags); + + if (ticks > data->top_data.ticks) { + return -EINVAL; + } + + data->top_data.guard_period = (uint64_t)ticks; + return 0; +} + static DEVICE_API(counter, counter_api) = { .start = counter_esp32_start, .stop = counter_esp32_stop, @@ -321,24 +394,29 @@ static DEVICE_API(counter, counter_api) = { .reset = counter_esp32_reset, .get_value_64 = counter_esp32_get_value_64, .set_alarm = counter_esp32_set_alarm, + .set_alarm_64 = counter_esp32_set_alarm_64, .cancel_alarm = counter_esp32_cancel_alarm, .set_top_value = counter_esp32_set_top_value, + .set_top_value_64 = counter_esp32_set_top_value_64, .get_pending_int = counter_esp32_get_pending_int, .get_top_value = counter_esp32_get_top_value, + .get_top_value_64 = counter_esp32_get_top_value_64, .get_freq = counter_esp32_get_freq, .get_guard_period = counter_esp32_get_guard_period, + .get_guard_period_64 = counter_esp32_get_guard_period_64, .set_guard_period = counter_esp32_set_guard_period, + .set_guard_period_64 = counter_esp32_set_guard_period_64, }; static void counter_esp32_isr(void *arg) { const struct device *dev = (const struct device *)arg; struct counter_esp32_data *data = dev->data; - counter_alarm_callback_t cb = data->alarm_cfg.callback; + counter_alarm_callback_64_t cb = data->alarm_cfg.callback; void *cb_data = data->alarm_cfg.user_data; - uint32_t now; + uint64_t now; - counter_esp32_get_value(dev, &now); + counter_esp32_get_value_64(dev, &now); if (cb) { timer_ll_enable_intr(data->hal_ctx.dev, @@ -374,7 +452,7 @@ static void counter_esp32_isr(void *arg) static struct counter_esp32_data counter_data_##idx; \ \ static const struct counter_esp32_config counter_config_##idx = { \ - .counter_info = {.max_top_value = UINT32_MAX, \ + .counter_info = {.max_top_value_64 = UINT64_MAX, \ .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ .channels = 1}, \ .config = \ diff --git a/drivers/counter/counter_handlers.c b/drivers/counter/counter_handlers.c index 697d8d41f963..263e764bb21d 100644 --- a/drivers/counter/counter_handlers.c +++ b/drivers/counter/counter_handlers.c @@ -73,6 +73,7 @@ static inline int z_vrfy_counter_get_value(const struct device *dev, } #include +#ifdef CONFIG_COUNTER_64BITS_TICKS static inline int z_vrfy_counter_get_value_64(const struct device *dev, uint64_t *ticks) { @@ -81,6 +82,7 @@ static inline int z_vrfy_counter_get_value_64(const struct device *dev, return z_impl_counter_get_value_64((const struct device *)dev, ticks); } #include +#endif /* CONFIG_COUNTER_64BITS_TICKS */ static inline int z_vrfy_counter_set_channel_alarm(const struct device *dev, uint8_t chan_id, diff --git a/drivers/sensor/sensor_clock_external.c b/drivers/sensor/sensor_clock_external.c index 5baf1ac15639..f86e9425572e 100644 --- a/drivers/sensor/sensor_clock_external.c +++ b/drivers/sensor/sensor_clock_external.c @@ -40,12 +40,15 @@ int sensor_clock_get_cycles(uint64_t *cycles) __ASSERT_NO_MSG(counter_is_counting_up(external_sensor_clock)); int rc; +#ifdef COUNTER_64BITS_TICKS const struct counter_driver_api *api = (const struct counter_driver_api *)external_sensor_clock->api; if (api->get_value_64) { rc = counter_get_value_64(external_sensor_clock, cycles); - } else { + } else +#endif /* COUNTER_64BITS_TICKS */ + { uint32_t result_32; rc = counter_get_value(external_sensor_clock, &result_32); diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index c660225a0e39..92695f5d77c7 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -199,7 +199,22 @@ struct counter_config_info { /** * Maximal (default) top value on which counter is reset (cleared or reloaded). */ +#ifdef CONFIG_COUNTER_64BITS_TICKS + union { + uint64_t max_top_value_64; + struct { +#ifdef CONFIG_BIG_ENDIAN + uint32_t reserved; + uint32_t max_top_value; +#else + uint32_t max_top_value; + uint32_t reserved; +#endif /* CONFIG_BIG_ENDIAN */ + }; + }; +#else uint32_t max_top_value; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ /** * Flags (see @ref COUNTER_FLAGS). */ @@ -212,13 +227,76 @@ struct counter_config_info { uint8_t channels; }; +/** @brief Alarm callback + * + * @param dev Pointer to the device structure for the driver instance. + * @param chan_id Channel ID. + * @param ticks Counter value that triggered the alarm. + * @param user_data User data. + */ +typedef void (*counter_alarm_callback_64_t)(const struct device *dev, uint8_t chan_id, + uint64_t ticks, void *user_data); + +/** @brief Alarm callback structure. + */ +struct counter_alarm_cfg_64 { + /** + * Number of ticks that triggers the alarm. + * + * It can be relative (to now) or an absolute value (see @ref + * COUNTER_ALARM_CFG_ABSOLUTE). Both, relative and absolute, alarm + * values can be any value between zero and the current top value (see + * @ref counter_get_top_value). When setting an absolute alarm value + * close to the current counter value there is a risk that the counter + * will have counted past the given absolute value before the driver + * manages to activate the alarm. Therefore a guard period can be + * defined that lets the driver decide unambiguously whether it is late + * or not (see @ref counter_set_guard_period). If the counter is clock + * driven then ticks can be converted to microseconds (see @ref + * counter_ticks_to_us). Alternatively, the counter implementation may + * count asynchronous events. + */ + uint64_t ticks; + /** + * Callback called on alarm (cannot be NULL). + */ + counter_alarm_callback_64_t callback; + /** + * User data returned in callback. + */ + void *user_data; + /** + * Alarm flags (see @ref COUNTER_ALARM_FLAGS). + */ + uint32_t flags; +}; + +/** @brief Top value configuration structure. + */ +struct counter_top_cfg_64 { + /** + * Top value. + */ + uint64_t ticks; + /** + * Callback function (can be NULL). + */ + counter_top_callback_t callback; + /** + * User data passed to callback function (not valid if callback is NULL). + */ + void *user_data; + /** + * Flags (see @ref COUNTER_TOP_FLAGS). + */ + uint32_t flags; +}; + typedef int (*counter_api_start)(const struct device *dev); typedef int (*counter_api_stop)(const struct device *dev); typedef int (*counter_api_get_value)(const struct device *dev, uint32_t *ticks); -typedef int (*counter_api_get_value_64)(const struct device *dev, uint64_t *ticks); typedef int (*counter_api_reset)(const struct device *dev); typedef int (*counter_api_set_value)(const struct device *dev, uint32_t ticks); -typedef int (*counter_api_set_value_64)(const struct device *dev, uint64_t ticks); typedef int (*counter_api_set_alarm)(const struct device *dev, uint8_t chan_id, const struct counter_alarm_cfg *alarm_cfg); typedef int (*counter_api_cancel_alarm)(const struct device *dev, uint8_t chan_id); @@ -232,14 +310,23 @@ typedef int (*counter_api_set_guard_period)(const struct device *dev, uint32_t t typedef uint32_t (*counter_api_get_freq)(const struct device *dev); typedef uint64_t (*counter_api_get_freq_64)(const struct device *dev); +typedef int (*counter_api_get_value_64)(const struct device *dev, uint64_t *ticks); +typedef int (*counter_api_set_value_64)(const struct device *dev, uint64_t ticks); +typedef int (*counter_api_set_alarm_64)(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg); +typedef uint64_t (*counter_api_get_guard_period_64)(const struct device *dev, uint32_t flags); +typedef int (*counter_api_set_guard_period_64)(const struct device *dev, uint64_t ticks, + uint32_t flags); +typedef uint64_t (*counter_api_get_top_value_64)(const struct device *dev); +typedef int (*counter_api_set_top_value_64)(const struct device *dev, + const struct counter_top_cfg_64 *cfg); + __subsystem struct counter_driver_api { counter_api_start start; counter_api_stop stop; counter_api_get_value get_value; - counter_api_get_value_64 get_value_64; counter_api_reset reset; counter_api_set_value set_value; - counter_api_set_value_64 set_value_64; counter_api_set_alarm set_alarm; counter_api_cancel_alarm cancel_alarm; counter_api_set_top_value set_top_value; @@ -251,6 +338,15 @@ __subsystem struct counter_driver_api { #ifdef CONFIG_COUNTER_64BITS_FREQ counter_api_get_freq_64 get_freq_64; #endif /* CONFIG_COUNTER_64BITS_FREQ */ +#ifdef CONFIG_COUNTER_64BITS_TICKS + counter_api_get_value_64 get_value_64; + counter_api_set_value_64 set_value_64; + counter_api_set_alarm_64 set_alarm_64; + counter_api_get_guard_period_64 get_guard_period_64; + counter_api_set_guard_period_64 set_guard_period_64; + counter_api_get_top_value_64 get_top_value_64; + counter_api_set_top_value_64 set_top_value_64; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ }; /** @@ -434,6 +530,10 @@ static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, uint * * @param[in] dev Pointer to the device structure for the driver instance. * + * @warning With `CONFIG_COUNTER_64BITS_TICKS` enabled this function returns only the lower + * 32 bits of the max top value. Use `counter_get_max_top_value_64()` to get + * the full 64 bit value if it is expected to exceed 32 bits. + * * @return Max top value. */ __syscall uint32_t counter_get_max_top_value(const struct device *dev); @@ -497,27 +597,6 @@ static inline int z_impl_counter_get_value(const struct device *dev, uint32_t *t return api->get_value(dev, ticks); } -/** - * @brief Get current counter 64-bit value. - * @param dev Pointer to the device structure for the driver instance. - * @param ticks Pointer to where to store the current counter value - * - * @retval 0 If successful. - * @retval <0 Negative error code on failure getting the counter value - */ -__syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks); - -static inline int z_impl_counter_get_value_64(const struct device *dev, uint64_t *ticks) -{ - const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; - - if (!api->get_value_64) { - return -ENOSYS; - } - - return api->get_value_64(dev, ticks); -} - /** * @brief Reset the counter to the initial value. * @param dev Pointer to the device structure for the driver instance. @@ -559,27 +638,6 @@ static inline int z_impl_counter_set_value(const struct device *dev, uint32_t ti return api->set_value(dev, ticks); } -/** - * @brief Set current counter 64-bit value. - * @param dev Pointer to the device structure for the driver instance. - * @param ticks Tick value to set - * - * @retval 0 If successful. - * @retval Negative error code on failure setting the counter value - */ -__syscall int counter_set_value_64(const struct device *dev, uint64_t ticks); - -static inline int z_impl_counter_set_value_64(const struct device *dev, uint64_t ticks) -{ - const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; - - if (!api->set_value_64) { - return -ENOSYS; - } - - return api->set_value_64(dev, ticks); -} - /** * @brief Set a single shot alarm on a channel. * @@ -653,6 +711,10 @@ static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev, * outside the new top value. In that case, error is returned and optionally * driver can reset the counter (see @ref COUNTER_TOP_CFG_RESET_WHEN_LATE). * + * @warning With `CONFIG_COUNTER_64BITS_TICKS` enabled this function sets the lower + * 32 bits of the max top value. Use `counter_set_top_value_64()` to get + * the full 64 bit value if it is expected to exceed 32 bits. + * * @param dev Pointer to the device structure for the driver instance. * @param cfg Configuration. Cannot be NULL. * @@ -802,6 +864,288 @@ static inline uint32_t z_impl_counter_get_guard_period(const struct device *dev, return (api->get_guard_period) ? api->get_guard_period(dev, flags) : 0; } +/** + * @brief Function to retrieve maximum top value that can be set for 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Max top value in 64 bits. + */ +__syscall uint64_t counter_get_max_top_value_64(const struct device *dev); + +static inline uint64_t z_impl_counter_get_max_top_value_64(const struct device *dev) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_config_info *config = (const struct counter_config_info *)dev->config; + + return config->max_top_value_64; +#else + ARG_UNUSED(dev); + return -ENOTSUP; +#endif +} + +/** + * @brief Set counter top value for 64 bits. + * + * Function sets top value and optionally resets the counter to 0 or top value + * depending on counter direction. On turnaround, counter can be reset and + * optional callback is periodically called. Top value can only be changed when + * there is no active channel alarm. + * + * @ref COUNTER_TOP_CFG_DONT_RESET prevents counter reset. When counter is + * running while top value is updated, it is possible that counter progresses + * outside the new top value. In that case, error is returned and optionally + * driver can reset the counter (see @ref COUNTER_TOP_CFG_RESET_WHEN_LATE). + * + * @param dev Pointer to the device structure for the driver instance. + * @param cfg Configuration. Cannot be NULL. + * + * @retval 0 If successful. + * @retval -ENOTSUP if request is not supported (e.g. top value cannot be + * changed or counter cannot/must be reset during top value + update). + * @retval -EBUSY if any alarm is active. + * @retval -ETIME if @ref COUNTER_TOP_CFG_DONT_RESET was set and new top value + * is smaller than current counter value (counter counting up). + */ +__syscall int counter_set_top_value_64(const struct device *dev, + const struct counter_top_cfg_64 *cfg); + +static inline int z_impl_counter_set_top_value_64(const struct device *dev, + const struct counter_top_cfg_64 *cfg) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (cfg->ticks > counter_get_max_top_value_64(dev)) { + return -EINVAL; + } + + return api->set_top_value_64(dev, cfg); +#else + ARG_UNUSED(dev); + ARG_UNUSED(cfg); + return -ENOTSUP; +#endif +} + +/** + * @brief Set a single shot alarm on a channel for 64 bits. + * + * After expiration alarm can be set again, disabling is not needed. When alarm + * expiration handler is called, channel is considered available and can be + * set again in that context. + * + * @note API is not thread safe. + * + * @param dev Pointer to the device structure for the driver instance. + * @param chan_id Channel ID. + * @param alarm_cfg Alarm configuration. + * + * @retval 0 If successful. + * @retval -ENOTSUP if request is not supported (device does not support + * interrupts or requested channel). + * @retval -EINVAL if alarm settings are invalid. + * @retval -ETIME if absolute alarm was set too late. + * @retval -EBUSY if alarm is already active. + */ +__syscall int counter_set_channel_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg); + +static inline int z_impl_counter_set_channel_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (chan_id >= counter_get_num_of_channels(dev)) { + return -ENOTSUP; + } + + return api->set_alarm_64(dev, chan_id, alarm_cfg); +#else + ARG_UNUSED(dev); + ARG_UNUSED(chan_id); + ARG_UNUSED(alarm_cfg); + return -ENOTSUP; +#endif +} + +/** + * @brief Function to retrieve current top value for 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * + * @return Top value in 64 bits. + */ +__syscall uint64_t counter_get_top_value_64(const struct device *dev); + +static inline uint64_t z_impl_counter_get_top_value_64(const struct device *dev) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + return api->get_top_value_64(dev); +#else + ARG_UNUSED(dev); + return 0; +#endif +} + +/** + * @brief Set guard period in counter ticks for 64 bits. + * + * When setting an absolute alarm value close to the current counter value there + * is a risk that the counter will have counted past the given absolute value + * before the driver manages to activate the alarm. If this would go unnoticed + * then the alarm would only expire after the timer has wrapped and reached the + * given absolute value again after a full timer period. This could take a long + * time in case of a 32 bit timer. Setting a sufficiently large guard period will + * help the driver detect unambiguously whether it is late or not. + * + * The guard period should be as many counter ticks as the driver will need at + * most to actually activate the alarm after the driver API has been called. If + * the driver finds that the counter has just passed beyond the given absolute + * tick value but is still close enough to fall within the guard period, it will + * assume that it is "late", i.e. that the intended expiry time has already passed. + * Depending on the @ref COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE flag the driver will + * either ignore the alarm or expire it immediately in such a case. + * + * If, however, the counter is past the given absolute tick value but outside + * the guard period, then the driver will assume that this is intentional and + * let the counter wrap around to/from zero before it expires. + * + * More precisely: + * + * - When counting upwards (see @ref COUNTER_CONFIG_INFO_COUNT_UP) the given + * absolute tick value must be above (now + guard_period) % top_value to be + * accepted by the driver. + * - When counting downwards, the given absolute tick value must be less than + * (now + top_value - guard_period) % top_value to be accepted. + * + * Examples: + * + * - counting upwards, now = 4950, top value = 5000, guard period = 100: + * absolute tick value >= (4950 + 100) % 5000 = 50 + * - counting downwards, now = 50, top value = 5000, guard period = 100: + * absolute tick value <= (50 + 5000 - * 100) % 5000 = 4950 + * + * If you need only short alarm periods, you can set the guard period very high + * (e.g. half of the counter top value) which will make it highly unlikely that + * the counter will ever unintentionally wrap. + * + * The guard period is set to 0 on initialization (no protection). + * + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Guard period in counter ticks of 64 bits. + * @param flags See @ref COUNTER_GUARD_PERIOD_FLAGS. + * + * @retval 0 if successful. + * @retval -ENOSYS if function or flags are not supported. + * @retval -EINVAL if ticks value is invalid. + */ +__syscall int counter_set_guard_period_64(const struct device *dev, uint64_t ticks, uint32_t flags); + +static inline int z_impl_counter_set_guard_period_64(const struct device *dev, uint64_t ticks, + uint32_t flags) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (!api->set_guard_period_64) { + return -ENOSYS; + } + + return api->set_guard_period_64(dev, ticks, flags); +#else + ARG_UNUSED(dev); + ARG_UNUSED(ticks); + ARG_UNUSED(flags); + return -ENOTSUP; +#endif +} + +/** + * @brief Return guard period for 64 bits. + * + * @see counter_set_guard_period_64. + * + * @param dev Pointer to the device structure for the driver instance. + * @param flags See @ref COUNTER_GUARD_PERIOD_FLAGS. + * + * @return Guard period given in counter ticks or 0 if function or flags are + * not supported. + */ +__syscall uint64_t counter_get_guard_period_64(const struct device *dev, uint32_t flags); + +static inline uint64_t z_impl_counter_get_guard_period_64(const struct device *dev, uint32_t flags) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + return (api->get_guard_period_64) ? api->get_guard_period_64(dev, flags) : 0; +#else + ARG_UNUSED(dev); + ARG_UNUSED(flags); + return -ENOTSUP; +#endif +} + +/** + * @brief Get current counter 64-bit value. + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Pointer to where to store the current counter value in 64 bits. + * + * @retval 0 If successful. + * @retval <0 Negative error code on failure getting the counter value + */ +__syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks); + +static inline int z_impl_counter_get_value_64(const struct device *dev, uint64_t *ticks) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (!api->get_value_64) { + return -ENOSYS; + } + + return api->get_value_64(dev, ticks); +#else + ARG_UNUSED(dev); + ARG_UNUSED(ticks); + return -ENOTSUP; +#endif +} + +/** + * @brief Set current counter 64-bit value. + * @param dev Pointer to the device structure for the driver instance. + * @param ticks Tick value to set in 64 bits + * + * @retval 0 If successful. + * @retval <0 Negative error code on failure setting the counter value + */ +__syscall int counter_set_value_64(const struct device *dev, uint64_t ticks); + +static inline int z_impl_counter_set_value_64(const struct device *dev, uint64_t ticks) +{ +#ifdef CONFIG_COUNTER_64BITS_TICKS + const struct counter_driver_api *api = (struct counter_driver_api *)dev->api; + + if (!api->set_value_64) { + return -ENOSYS; + } + + return api->set_value_64(dev, ticks); +#else + ARG_UNUSED(dev); + ARG_UNUSED(ticks); + return -ENOTSUP; +#endif +} + #ifdef __cplusplus } #endif From fb67a57602c5e1104842a0a260550a0937a1a605 Mon Sep 17 00:00:00 2001 From: Ryan McClelland Date: Thu, 20 Nov 2025 20:02:53 -0800 Subject: [PATCH 08/13] UPSTREAM: drivers: counter: add inline helpers for(n/u)sec to ticks in 64b commit c07454ff7ca27f74b1dcbc5a229af195bbff0a48 upstream. Add inline helpers to convert nanoseconds or microseconds to 64b ticks and vice versa. Signed-off-by: Ryan McClelland --- include/zephyr/drivers/counter.h | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/include/zephyr/drivers/counter.h b/include/zephyr/drivers/counter.h index 92695f5d77c7..bb6ae869141d 100644 --- a/include/zephyr/drivers/counter.h +++ b/include/zephyr/drivers/counter.h @@ -478,6 +478,21 @@ static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev, uint return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; } +/** + * @brief Function to convert microseconds to ticks with 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] us Microseconds. + * + * @return Converted ticks as a uint64_t + */ +__syscall uint64_t counter_us_to_ticks_64(const struct device *dev, uint64_t us); + +static inline uint64_t z_impl_counter_us_to_ticks_64(const struct device *dev, uint64_t us) +{ + return (us * z_counter_get_frequency(dev)) / USEC_PER_SEC; +} + /** * @brief Function to convert ticks to microseconds. * @@ -493,6 +508,21 @@ static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev, uint return ((uint64_t)ticks * USEC_PER_SEC) / z_counter_get_frequency(dev); } +/** + * @brief Function to convert ticks with 64 bits to microseconds. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ticks Ticks in 64 bits. + * + * @return Converted microseconds. + */ +__syscall uint64_t counter_ticks_to_us_64(const struct device *dev, uint64_t ticks); + +static inline uint64_t z_impl_counter_ticks_to_us_64(const struct device *dev, uint64_t ticks) +{ + return (ticks * USEC_PER_SEC) / z_counter_get_frequency(dev); +} + /** * @brief Function to convert nanoseconds to ticks. * @@ -510,6 +540,21 @@ static inline uint32_t z_impl_counter_ns_to_ticks(const struct device *dev, uint return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks; } +/** + * @brief Function to convert nanoseconds to ticks with 64 bits. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ns Nanoseconds. + * + * @return Converted ticks as a uint64_t. + */ +__syscall uint64_t counter_ns_to_ticks_64(const struct device *dev, uint64_t ns); + +static inline uint64_t z_impl_counter_ns_to_ticks_64(const struct device *dev, uint64_t ns) +{ + return (ns * z_counter_get_frequency(dev)) / NSEC_PER_SEC; +} + /** * @brief Function to convert ticks to nanoseconds. * @@ -525,6 +570,21 @@ static inline uint64_t z_impl_counter_ticks_to_ns(const struct device *dev, uint return ((uint64_t)ticks * NSEC_PER_SEC) / z_counter_get_frequency(dev); } +/** + * @brief Function to convert ticks with 64 bits to nanoseconds. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[in] ticks Ticks in 64 bits. + * + * @return Converted nanoseconds. + */ +__syscall uint64_t counter_ticks_to_ns_64(const struct device *dev, uint64_t ticks); + +static inline uint64_t z_impl_counter_ticks_to_ns_64(const struct device *dev, uint64_t ticks) +{ + return (ticks * NSEC_PER_SEC) / z_counter_get_frequency(dev); +} + /** * @brief Function to retrieve maximum top value that can be set. * From bd5e73d5a744fe7c692d92294fe22c4f804ff2ce Mon Sep 17 00:00:00 2001 From: Sunil Hegde Date: Fri, 13 Feb 2026 13:48:05 +0530 Subject: [PATCH 09/13] UPSTREAM-PEND: dts: bindings: counter: add TI RTC counter - This is the counter based rtc module used in k3 devices. PR: 104048 Signed-off-by: Sunil Hegde --- dts/bindings/counter/ti,k3-rtc-counter.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 dts/bindings/counter/ti,k3-rtc-counter.yaml diff --git a/dts/bindings/counter/ti,k3-rtc-counter.yaml b/dts/bindings/counter/ti,k3-rtc-counter.yaml new file mode 100644 index 000000000000..71134b70bf96 --- /dev/null +++ b/dts/bindings/counter/ti,k3-rtc-counter.yaml @@ -0,0 +1,19 @@ +# Copyright 2026 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Counter based Real Time Clock (RTC) available in the TI K3 generation of processors. + +compatible: "ti,k3-rtc-counter" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clock-frequency: + type: int + required: true From 316499ff90574ac1a51548b6715ab05fb65120f9 Mon Sep 17 00:00:00 2001 From: Sunil Hegde Date: Fri, 13 Feb 2026 13:52:29 +0530 Subject: [PATCH 10/13] UPSTREAM-PEND: drivers: counter: k3_rtc: Add TI RTC... This commit adds the counter RTC driver used in TI k3 devices. PR: 104048 Signed-off-by: Sunil Hegde --- drivers/counter/CMakeLists.txt | 1 + drivers/counter/Kconfig | 2 + drivers/counter/Kconfig.k3_rtc_counter | 9 + drivers/counter/counter_k3_rtc.c | 527 +++++++++++++++++++++++++ 4 files changed, 539 insertions(+) create mode 100644 drivers/counter/Kconfig.k3_rtc_counter create mode 100644 drivers/counter/counter_k3_rtc.c diff --git a/drivers/counter/CMakeLists.txt b/drivers/counter/CMakeLists.txt index d45a8d7cfa27..36892039fe2e 100644 --- a/drivers/counter/CMakeLists.txt +++ b/drivers/counter/CMakeLists.txt @@ -68,3 +68,4 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_WUT_MAX32 counter_max32_wu zephyr_library_sources_ifdef(CONFIG_COUNTER_CC23X0_RTC counter_cc23x0_rtc.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_CC23X0_LGPT counter_cc23x0_lgpt.c) zephyr_library_sources_ifdef(CONFIG_COUNTER_MSPM0_TIMER counter_mspm0_timer.c) +zephyr_library_sources_ifdef(CONFIG_COUNTER_TI_K3_RTC counter_k3_rtc.c) diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 66a0017285a7..8224c97aa81a 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -146,4 +146,6 @@ source "drivers/counter/Kconfig.cc23x0_lgpt" source "drivers/counter/Kconfig.mspm0" +source "drivers/counter/Kconfig.k3_rtc_counter" + endif # COUNTER diff --git a/drivers/counter/Kconfig.k3_rtc_counter b/drivers/counter/Kconfig.k3_rtc_counter new file mode 100644 index 000000000000..130bef27194c --- /dev/null +++ b/drivers/counter/Kconfig.k3_rtc_counter @@ -0,0 +1,9 @@ +# Copyright (c) 2026 Texas Instruments Inc. +# SPDX-License-Identifier: Apache-2.0 + +config COUNTER_TI_K3_RTC + bool "RTC Counter Driver for TI K3 SoCs" + default y + depends on DT_HAS_TI_K3_RTC_COUNTER_ENABLED + help + Enable the RTC driver for TI K3 SoCs. diff --git a/drivers/counter/counter_k3_rtc.c b/drivers/counter/counter_k3_rtc.c new file mode 100644 index 000000000000..d05ca1ab8d4e --- /dev/null +++ b/drivers/counter/counter_k3_rtc.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2026 Texas Instruments Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_k3_rtc_counter + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(counter_ti_k3_rtc, CONFIG_COUNTER_LOG_LEVEL); + +#define RTC_MAX_TOP_VALUE UINT32_MAX +#define RTC_MAX_TOP_VALUE_64 BIT_MASK(48) + +#define K3_RTC_KICK0_UNLOCK 0x83e70b13 +#define K3_RTC_KICK1_UNLOCK 0x95a4f1e0 + +#define RTC_CNT_FMODE_MASK BIT(25) +#define RTC_UNLOCK_MASK BIT(23) +#define RTC_O32K_OSC_MASK BIT(21) +#define RTC_SYNCPEND_STATUS_MASK BIT_MASK(2) + +#define RTC_IRQ_ALARM1_MASK BIT(0) +#define RTC_IRQ_ALARM2_MASK BIT(1) +#define RTC_IRQ_STATUS_MASK BIT_MASK(2) + +#define DEV_CFG(dev) ((const struct k3_rtc_counter_cfg *)(dev)->config) +#define DEV_DATA(dev) ((struct k3_rtc_counter_data *)(dev)->data) +#define DEV_REGS(dev) ((k3_rtc_regs_t *)DEVICE_MMIO_NAMED_GET(dev, reg_base)) + +typedef struct { + volatile uint32_t MOD_VER; /* Module ID and Version - 0h */ + volatile uint32_t SUB_S_CNT; /* SubSecondCount - 4h*/ + volatile uint32_t S_CNT_LSW; /* SecondCount_31_0 - 8h */ + volatile uint32_t S_CNT_MSW; /* SecondCount_47_32 - Ch */ + volatile uint32_t COMP; /* Compensation - 10h */ + uint8_t Resv_24[4]; + volatile uint32_t OFF_ON_S_CNT_LSW; /* OffOnSCnt_31_0 - 18h */ + volatile uint32_t OFF_ON_S_CNT_MSW; /* OffOnSCnt_47_32 - 1Ch */ + volatile uint32_t ON_OFF_S_CNT_LSW; /* OnOffSCnt_31_0 - 20h */ + volatile uint32_t ON_OFF_S_CNT_MSW; /* OnOffSCnt_47_32 - 24h */ + volatile uint32_t DEBOUNCE; /* Debounce - 28h */ + volatile uint32_t ANALOG; /* AnalogCfg - 2Ch */ + volatile uint32_t SCRATCH[8]; /* Scratch Storage X - 30h */ + volatile uint32_t GENRAL_CTL; /* GeneralControl - 50h */ + volatile uint32_t IRQSTATUS_RAW_SYS; /* Interrupt Raw Status Register - 54h */ + volatile uint32_t IRQSTATUS_SYS; /* Interrupt Status Register - 58h */ + volatile uint32_t IRQENABLE_SET_SYS; /* Interrupt Enable Set Register - 5Ch */ + volatile uint32_t IRQENABLE_CLR_SYS; /* Interrupt Enable Clear Register - 60h */ + uint8_t Resv_104[4]; /* SyncPending - 68h */ + volatile uint32_t SYNCPEND; + uint8_t Resv_112[4]; + volatile uint32_t KICK0; /* Kick0 - 70h */ + volatile uint32_t KICK1; /* Kick1 - 74h */ + uint8_t Resv_128[8]; +} k3_rtc_regs_t; + +struct k3_rtc_counter_cfg { + struct counter_config_info counter_info; + + DEVICE_MMIO_NAMED_ROM(reg_base); + + void (*irq_config_func)(void); + uint32_t osc_freq; +}; + +struct k3_rtc_counter_data { + DEVICE_MMIO_NAMED_RAM(reg_base); +#ifdef CONFIG_COUNTER_64BITS_TICKS + struct counter_alarm_cfg_64 alarm_cfg[2]; +#else + struct counter_alarm_cfg alarm_cfg[2]; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + uint32_t sync_timeout_us; +}; + +static int k3_rtc_fence(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + + /* Add slight delay in order to wait for register writes to sync */ + k_usleep(data->sync_timeout_us); + int timeout = WAIT_FOR((rtc_regs->SYNCPEND & RTC_SYNCPEND_STATUS_MASK) != 0, + data->sync_timeout_us, + k_busy_wait(1)); + + return timeout; +} + +static int k3_rtc_unlock_status(k3_rtc_regs_t *rtc_regs) +{ + return !!(rtc_regs->GENRAL_CTL & RTC_UNLOCK_MASK); +} + +static int k3_rtc_unlock(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + if (k3_rtc_unlock_status(rtc_regs) == 0) { + rtc_regs->KICK0 = K3_RTC_KICK0_UNLOCK; + rtc_regs->KICK1 = K3_RTC_KICK1_UNLOCK; + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after unlock"); + return ret; + } + + if (k3_rtc_unlock_status(rtc_regs) == 0) { + LOG_ERR("RTC unlock failed!"); + return -EIO; + } + } + + return 0; +} + +static int k3_counter_start(const struct device *dev) +{ + ARG_UNUSED(dev); + /* RTC counter runs after power-on reset */ + return 0; +} + +static int k3_counter_stop(const struct device *dev) +{ + ARG_UNUSED(dev); + /* RTC counter can only be reset, not stopped */ + return 0; +} + +static int k3_counter_get_value(const struct device *dev, uint32_t *ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + + if (ticks == NULL) { + return -EINVAL; + } + + *ticks = rtc_regs->S_CNT_LSW; + + return 0; +} + +static int k3_counter_set_value(const struct device *dev, uint32_t ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + rtc_regs->S_CNT_LSW = ticks; + rtc_regs->S_CNT_MSW = 0; + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after set_value"); + return ret; + } + + return 0; +} + +static int k3_counter_reset(const struct device *dev) +{ + int ret; + + ret = k3_counter_set_value(dev, 0); + if (ret != 0) { + LOG_ERR("Failed to sync after reset"); + return ret; + } + + return 0; +} + +static int k3_counter_set_alarm(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg *alarm_cfg) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + int ret, key; + + if (chan_id > 1) { + LOG_ERR("Invalid alarm channel"); + return -EINVAL; + } + + if (alarm_cfg == NULL) { + LOG_ERR("NULL alarm config"); + return -EINVAL; + } + + if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) != 0) { + data->alarm_cfg[chan_id].ticks = alarm_cfg->ticks; + } else { + uint32_t now; + + ret = k3_counter_get_value(dev, &now); + if (ret != 0) { + return ret; + } + data->alarm_cfg[chan_id].ticks = now + alarm_cfg->ticks; + } + + key = irq_lock(); + + if (chan_id == 0) { + rtc_regs->ON_OFF_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->ON_OFF_S_CNT_MSW = 0; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM1_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM1_MASK; + } else { + rtc_regs->OFF_ON_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->OFF_ON_S_CNT_MSW = 0; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM2_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM2_MASK; + } + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after alarm set: %d", ret); + irq_unlock(key); + return ret; + } + + data->alarm_cfg[chan_id].callback = alarm_cfg->callback; + data->alarm_cfg[chan_id].user_data = alarm_cfg->user_data; + + irq_unlock(key); + + return 0; +} + +static int k3_counter_cancel_alarm(const struct device *dev, uint8_t chan_id) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + int ret, key; + + if (chan_id > 1) { + LOG_ERR("Invalid alarm channel"); + return -EINVAL; + } + + key = irq_lock(); + if (chan_id == 0) { + rtc_regs->IRQENABLE_CLR_SYS = RTC_IRQ_ALARM1_MASK; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM1_MASK; + } else { + rtc_regs->IRQENABLE_CLR_SYS = RTC_IRQ_ALARM2_MASK; + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM2_MASK; + } + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after alarm cancel: %d", ret); + irq_unlock(key); + return ret; + } + + data->alarm_cfg[chan_id].callback = NULL; + data->alarm_cfg[chan_id].user_data = NULL; + data->alarm_cfg[chan_id].flags = 0; + + irq_unlock(key); + + return 0; +} + +static uint32_t k3_counter_get_pending_int(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + + return rtc_regs->IRQSTATUS_SYS & RTC_IRQ_STATUS_MASK; +} + +static uint32_t k3_counter_get_top_value(const struct device *dev) +{ + ARG_UNUSED(dev); + return RTC_MAX_TOP_VALUE; +} + +static uint32_t k3_counter_get_frequency(const struct device *dev) +{ + const struct k3_rtc_counter_cfg *config = DEV_CFG(dev); + + return config->counter_info.freq; +} + +#ifdef CONFIG_COUNTER_64BITS_TICKS +static int k3_counter_get_value_64(const struct device *dev, uint64_t *ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + + if (ticks == NULL) { + return -EINVAL; + } + + uint32_t seconds_low = rtc_regs->S_CNT_LSW; + uint32_t seconds_high = rtc_regs->S_CNT_MSW; + + *ticks = ((uint64_t)seconds_high << 32) | (uint64_t)seconds_low; + + return 0; +} + +static int k3_counter_set_value_64(const struct device *dev, uint64_t ticks) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + rtc_regs->S_CNT_LSW = ticks; + rtc_regs->S_CNT_MSW = (uint32_t)(ticks >> 32); + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after set_value"); + return ret; + } + + return 0; +} + +static uint64_t k3_counter_get_top_value_64(const struct device *dev) +{ + ARG_UNUSED(dev); + return RTC_MAX_TOP_VALUE_64; +} + +static int k3_counter_set_alarm_64(const struct device *dev, uint8_t chan_id, + const struct counter_alarm_cfg_64 *alarm_cfg) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + int ret, key; + + if (chan_id > 1) { + LOG_ERR("Invalid alarm channel"); + return -EINVAL; + } + + if (alarm_cfg == NULL) { + LOG_ERR("NULL alarm config"); + return -EINVAL; + } + + if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) != 0) { + data->alarm_cfg[chan_id].ticks = alarm_cfg->ticks; + } else { + uint64_t now; + + ret = k3_counter_get_value_64(dev, &now); + if (ret != 0) { + return ret; + } + data->alarm_cfg[chan_id].ticks = now + alarm_cfg->ticks; + } + + key = irq_lock(); + + if (chan_id == 0) { + rtc_regs->ON_OFF_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->ON_OFF_S_CNT_MSW = (uint32_t)(data->alarm_cfg[chan_id].ticks >> 32); + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM1_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM1_MASK; + } else { + rtc_regs->OFF_ON_S_CNT_LSW = (uint32_t)data->alarm_cfg[chan_id].ticks; + rtc_regs->OFF_ON_S_CNT_MSW = (uint32_t)(data->alarm_cfg[chan_id].ticks >> 32); + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_ALARM2_MASK; + rtc_regs->IRQENABLE_SET_SYS = RTC_IRQ_ALARM2_MASK; + } + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed to sync after alarm set: %d", ret); + irq_unlock(key); + return ret; + } + + data->alarm_cfg[chan_id].callback = alarm_cfg->callback; + data->alarm_cfg[chan_id].user_data = alarm_cfg->user_data; + data->alarm_cfg[chan_id].flags = alarm_cfg->flags; + + irq_unlock(key); + + return 0; +} +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + +static void k3_rtc_isr(const struct device *dev) +{ + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + uint32_t status; + int ret; +#ifdef CONFIG_COUNTER_64BITS_TICKS + uint64_t now; +#else + uint32_t now; +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + + status = rtc_regs->IRQSTATUS_SYS; + if (status == 0) { + return; + } + + rtc_regs->IRQSTATUS_SYS = status; + + if ((status & RTC_IRQ_ALARM1_MASK) != 0 && data->alarm_cfg[0].callback != NULL) { +#ifdef CONFIG_COUNTER_64BITS_TICKS + ret = k3_counter_get_value_64(dev, &now); +#else + ret = k3_counter_get_value(dev, &now); +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + if (ret != 0) { + LOG_ERR("Invalid ticks: %d", ret); + return; + } + data->alarm_cfg[0].callback(dev, 0, now, data->alarm_cfg[0].user_data); + } + + if ((status & RTC_IRQ_ALARM2_MASK) != 0 && data->alarm_cfg[1].callback != NULL) { +#ifdef CONFIG_COUNTER_64BITS_TICKS + k3_counter_get_value_64(dev, &now); +#else + k3_counter_get_value(dev, &now); +#endif /* CONFIG_COUNTER_64BITS_TICKS */ + data->alarm_cfg[1].callback(dev, 1, now, data->alarm_cfg[1].user_data); + } +} + +static int k3_counter_init(const struct device *dev) +{ + DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE); + const struct k3_rtc_counter_cfg *config = DEV_CFG(dev); + struct k3_rtc_counter_data *data = DEV_DATA(dev); + k3_rtc_regs_t *rtc_regs = DEV_REGS(dev); + int ret; + + ret = k3_rtc_unlock(dev); + if (ret != 0) { + LOG_ERR("Failed to unlock RTC"); + return ret; + } + + /* 4 clock cycles for sync */ + data->sync_timeout_us = (USEC_PER_SEC / config->osc_freq) * 4; + + /* Enable 32k oscillator dependency */ + rtc_regs->GENRAL_CTL |= RTC_O32K_OSC_MASK; + + /* Enable freeze mode for atomic 48-bit reads */ + rtc_regs->GENRAL_CTL |= RTC_CNT_FMODE_MASK; + + /* Clear and disable all interrupts */ + rtc_regs->IRQSTATUS_SYS = RTC_IRQ_STATUS_MASK; + rtc_regs->IRQENABLE_CLR_SYS = RTC_IRQ_STATUS_MASK; + + ret = k3_rtc_fence(dev); + if (ret != 0) { + LOG_ERR("Failed sync in init"); + return ret; + } + + config->irq_config_func(); + + return 0; +} + +static const struct counter_driver_api k3_counter_api = { + .start = k3_counter_start, + .stop = k3_counter_stop, + .get_value = k3_counter_get_value, + .reset = k3_counter_reset, + .set_value = k3_counter_set_value, + .set_alarm = k3_counter_set_alarm, + .cancel_alarm = k3_counter_cancel_alarm, + .get_pending_int = k3_counter_get_pending_int, + .get_top_value = k3_counter_get_top_value, + .get_freq = k3_counter_get_frequency, +#ifdef CONFIG_COUNTER_64BITS_TICKS + .get_value_64 = k3_counter_get_value_64, + .set_value_64 = k3_counter_set_value_64, + .set_alarm_64 = k3_counter_set_alarm_64, + .get_top_value_64 = k3_counter_get_top_value_64, +#endif /* CONFIG_COUNTER_64BITS_TICKS */ +}; + +#define TI_K3_COUNTER_INIT(i) \ + static void ti_k3_counter_irq_config_##i(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(i), \ + DT_INST_IRQ(i, priority), \ + k3_rtc_isr, \ + DEVICE_DT_INST_GET(i), 0); \ + irq_enable(DT_INST_IRQN(i)); \ + } \ + static struct k3_rtc_counter_data k3_counter_data_##i = {}; \ + static struct k3_rtc_counter_cfg k3_counter_cfg_##i = { \ + .counter_info = \ + { \ + .freq = 1, \ + COND_CODE_1(CONFIG_COUNTER_64BITS_TICKS, \ + (.max_top_value_64 = RTC_MAX_TOP_VALUE_64,), \ + (.max_top_value = RTC_MAX_TOP_VALUE,)) \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 2, \ + }, \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(i)), \ + .irq_config_func = ti_k3_counter_irq_config_##i, \ + .osc_freq = DT_INST_PROP(i, clock_frequency) \ + }; \ + DEVICE_DT_INST_DEFINE(i, \ + k3_counter_init, \ + NULL, \ + &k3_counter_data_##i, \ + &k3_counter_cfg_##i, \ + POST_KERNEL, \ + CONFIG_COUNTER_INIT_PRIORITY, \ + &k3_counter_api \ + ); + +DT_INST_FOREACH_STATUS_OKAY(TI_K3_COUNTER_INIT) From 84d8d0144ea0d3502f35a9827fb0cc57cdea9787 Mon Sep 17 00:00:00 2001 From: Sunil Hegde Date: Fri, 13 Feb 2026 13:39:33 +0530 Subject: [PATCH 11/13] UPSTREAM-PEND: dts: ti: Add RTC node and interrupts - Add RTC node in am62-main.dtsi which can also be used as a counter - Add child counter_rtc node which can be used as a virtual rtc. - Add interrupts in am62x_a53.dtsi PR: 104048 Signed-off-by: Sunil Hegde --- dts/arm64/ti/ti_am62x_a53.dtsi | 5 +++++ dts/vendor/ti/k3-am62-main.dtsi | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/dts/arm64/ti/ti_am62x_a53.dtsi b/dts/arm64/ti/ti_am62x_a53.dtsi index 2e20926e4746..4cf5a54df41e 100644 --- a/dts/arm64/ti/ti_am62x_a53.dtsi +++ b/dts/arm64/ti/ti_am62x_a53.dtsi @@ -154,3 +154,8 @@ interrupts = ; interrupt-parent = <&gic>; }; + +&main_rtc0 { + interrupts = ; + interrupt-parent = <&gic>; +}; diff --git a/dts/vendor/ti/k3-am62-main.dtsi b/dts/vendor/ti/k3-am62-main.dtsi index 17a4f32ff1c3..e2e86b578fc9 100644 --- a/dts/vendor/ti/k3-am62-main.dtsi +++ b/dts/vendor/ti/k3-am62-main.dtsi @@ -216,4 +216,17 @@ ti,itap-del-sel-sdr25 = <0x0>; status = "disabled"; }; + + main_rtc0: rtc@2b1f0000 { + compatible = "ti,k3-rtc-counter"; + reg = <0x2b1f0000 0x64>; + clock-frequency = <32768>; + status = "disabled"; + + counter_rtc0: counter_rtc { + compatible = "zephyr,rtc-counter"; + alarms-count = <2>; + status = "disabled"; + }; + }; }; From ded9f8d0f4dde962f4935ca3ac689d49f6ccc1fc Mon Sep 17 00:00:00 2001 From: Sunil Hegde Date: Fri, 13 Feb 2026 14:46:47 +0530 Subject: [PATCH 12/13] UPSTREAM-PEND: boards: ti: sk_am62: a53.dts: Enable RTC node Enable RTC node for a53 core. PR: 104048 Signed-off-by: Sunil Hegde --- boards/ti/sk_am62/sk_am62_am6254_a53.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/boards/ti/sk_am62/sk_am62_am6254_a53.dts b/boards/ti/sk_am62/sk_am62_am6254_a53.dts index f6baa119150f..fb3b26696671 100644 --- a/boards/ti/sk_am62/sk_am62_am6254_a53.dts +++ b/boards/ti/sk_am62/sk_am62_am6254_a53.dts @@ -19,6 +19,10 @@ zephyr,sram = &ddr0; }; + aliases { + rtc = &counter_rtc0; + }; + cpus { cpu@0 { status = "okay"; @@ -103,3 +107,11 @@ ti,fails-without-test-cd; status = "disabled"; }; + +&main_rtc0 { + status = "okay"; +}; + +&counter_rtc0 { + status = "okay"; +}; From 8658628379f5f6ae04a9f65ed399526aaf5f0398 Mon Sep 17 00:00:00 2001 From: Sunil Hegde Date: Wed, 18 Feb 2026 14:39:35 +0530 Subject: [PATCH 13/13] UPSTREAM_PEND: samples: drivers: rtc: boards: add config for... - Set RTC init priority to initialise zephyr,rtc-counter driver after counter driver is initialsed whose default priority is 60. PR: 104048 Signed-off-by: Sunil Hegde --- samples/drivers/rtc/boards/sk_am62_am6254_a53.conf | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 samples/drivers/rtc/boards/sk_am62_am6254_a53.conf diff --git a/samples/drivers/rtc/boards/sk_am62_am6254_a53.conf b/samples/drivers/rtc/boards/sk_am62_am6254_a53.conf new file mode 100644 index 000000000000..01028be7938c --- /dev/null +++ b/samples/drivers/rtc/boards/sk_am62_am6254_a53.conf @@ -0,0 +1,7 @@ +# +# Copyright 2026 Texas Instruments Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_RTC_INIT_PRIORITY=70