diff --git a/dts/bindings/retention/zephyr,retention.yaml b/dts/bindings/retention/zephyr,retention.yaml index 27fa1511c85596a..83b47d9125eb0cb 100644 --- a/dts/bindings/retention/zephyr,retention.yaml +++ b/dts/bindings/retention/zephyr,retention.yaml @@ -64,3 +64,9 @@ properties: 16-bit CRC, 4 for 32-bit CRC). Default is to not use a checksum. type: int default: 0 + + no-mutex: + description: | + If specified, will disable mutex protection, should only be enabled if + this is a requirement for a particular retention area. + type: boolean diff --git a/subsys/retention/Kconfig b/subsys/retention/Kconfig index 1081e236f02b489..9ba7af025bd2e27 100644 --- a/subsys/retention/Kconfig +++ b/subsys/retention/Kconfig @@ -20,13 +20,22 @@ config RETENTION_INIT_PRIORITY priorities for retained memory drivers. config RETENTION_MUTEXES - bool "Retention mutex support" + bool default y depends on MULTITHREADING + depends on !RETENTION_MUTEX_FORCE_DISABLE + +config RETENTION_MUTEX_FORCE_DISABLE + bool "Disable retention mutex support" + depends on MULTITHREADING help - Use mutexes to prevent issues with concurrent retention device - access. Should only be disabled whereby retained memory access is - required in an ISR or for special use cases. + Disable use of mutexes which prevent issues with concurrent retention + device access. This option should should only be enabled when + retention device access is required in an ISR or for special use + cases. + + Note that this can also be enforced on a per-partition basis by + setting the ``no-mutex;`` device tree property instead. config RETENTION_BUFFER_SIZE int "Retention stack buffer sizes" diff --git a/subsys/retention/retention.c b/subsys/retention/retention.c index db5b8d45b695f74..dd19b64960e6d43 100644 --- a/subsys/retention/retention.c +++ b/subsys/retention/retention.c @@ -41,6 +41,9 @@ struct retention_config { size_t offset; size_t size; size_t reserved_size; +#ifdef CONFIG_RETENTION_MUTEXES + bool mutex; +#endif uint8_t checksum_size; uint8_t prefix_len; uint8_t prefix[]; @@ -50,8 +53,11 @@ static inline void retention_lock_take(const struct device *dev) { #ifdef CONFIG_RETENTION_MUTEXES struct retention_data *data = dev->data; + const struct retention_config *config = dev->config; - k_mutex_lock(&data->lock, K_FOREVER); + if (config->mutex) { + k_mutex_lock(&data->lock, K_FOREVER); + } #else ARG_UNUSED(dev); #endif @@ -61,8 +67,11 @@ static inline void retention_lock_release(const struct device *dev) { #ifdef CONFIG_RETENTION_MUTEXES struct retention_data *data = dev->data; + const struct retention_config *config = dev->config; - k_mutex_unlock(&data->lock); + if (config->mutex) { + k_mutex_unlock(&data->lock); + } #else ARG_UNUSED(dev); #endif @@ -376,6 +385,13 @@ static const struct retention_api retention_api = { .clear = retention_clear, }; +#ifdef CONFIG_RETENTION_MUTEXES +#define RETENTION_MUTEX(inst) \ + .mutex = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, no_mutex), (false), (true)) +#else +#define RETENTION_MUTEX(inst) +#endif + #define RETENTION_DEVICE(inst) \ static struct retention_data \ retention_data_##inst = { \ @@ -393,6 +409,7 @@ static const struct retention_api retention_api = { .prefix_len = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, prefix), \ (DT_INST_PROP_LEN(inst, prefix)), (0)), \ .prefix = DT_INST_PROP_OR(inst, prefix, {0}), \ + RETENTION_MUTEX(inst) \ }; \ DEVICE_DT_INST_DEFINE(inst, \ &retention_init, \