Skip to content

Commit

Permalink
drivers: retained_mem: Add generic retained register driver
Browse files Browse the repository at this point in the history
Devices like the ATSAM series chips have retained registers
which are used to store memory. The memory is accessed just
like RAM, but since they are registers, their size and
address is used directly.

This commit adds a near complete copy of the generic retained
ram driver and bindings file, adding the reg property to
the bindings file, and updating the init macro in the driver
to use the reg address and size.

Signed-off-by: Bjarki Arge Andreasen <[email protected]>
  • Loading branch information
bjarki-andreasen authored and fabiobaltieri committed Jan 2, 2024
1 parent 49f9d8e commit c6cb2d6
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/retained_mem/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ zephyr_library()
zephyr_library_sources_ifdef(CONFIG_USERSPACE retained_mem_handlers.c)
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_NRF_GPREGRET retained_mem_nrf_gpregret.c)
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_ZEPHYR_RAM retained_mem_zephyr_ram.c)
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_ZEPHYR_REG retained_mem_zephyr_reg.c)
7 changes: 7 additions & 0 deletions drivers/retained_mem/Kconfig.zephyr
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ config RETAINED_MEM_ZEPHYR_RAM
depends on DT_HAS_ZEPHYR_RETAINED_RAM_ENABLED
help
Enable driver for retained memory in RAM.

config RETAINED_MEM_ZEPHYR_REG
bool "Generic Zephyr register retained memory driver"
default y
depends on DT_HAS_ZEPHYR_RETAINED_REG_ENABLED
help
Enable driver for retained memory in retained registers.
135 changes: 135 additions & 0 deletions drivers/retained_mem/retained_mem_zephyr_reg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2023, Nordic Semiconductor ASA
* Copyright (c) 2023, Bjarki Arge Andreasen
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT zephyr_retained_reg

#include <string.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/retained_mem.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(retained_mem_zephyr_reg, CONFIG_RETAINED_MEM_LOG_LEVEL);

struct zephyr_retained_mem_reg_data {
#ifdef CONFIG_RETAINED_MEM_MUTEXES
struct k_mutex lock;
#endif
};

struct zephyr_retained_mem_reg_config {
uint8_t *address;
size_t size;
};

static inline void zephyr_retained_mem_reg_lock_take(const struct device *dev)
{
#ifdef CONFIG_RETAINED_MEM_MUTEXES
struct zephyr_retained_mem_reg_data *data = dev->data;

k_mutex_lock(&data->lock, K_FOREVER);
#else
ARG_UNUSED(dev);
#endif
}

static inline void zephyr_retained_mem_reg_lock_release(const struct device *dev)
{
#ifdef CONFIG_RETAINED_MEM_MUTEXES
struct zephyr_retained_mem_reg_data *data = dev->data;

k_mutex_unlock(&data->lock);
#else
ARG_UNUSED(dev);
#endif
}

static int zephyr_retained_mem_reg_init(const struct device *dev)
{
#ifdef CONFIG_RETAINED_MEM_MUTEXES
struct zephyr_retained_mem_reg_data *data = dev->data;

k_mutex_init(&data->lock);
#endif

return 0;
}

static ssize_t zephyr_retained_mem_reg_size(const struct device *dev)
{
const struct zephyr_retained_mem_reg_config *config = dev->config;

return (ssize_t)config->size;
}

static int zephyr_retained_mem_reg_read(const struct device *dev, off_t offset, uint8_t *buffer,
size_t size)
{
const struct zephyr_retained_mem_reg_config *config = dev->config;

zephyr_retained_mem_reg_lock_take(dev);

memcpy(buffer, (config->address + offset), size);

zephyr_retained_mem_reg_lock_release(dev);

return 0;
}

static int zephyr_retained_mem_reg_write(const struct device *dev, off_t offset,
const uint8_t *buffer, size_t size)
{
const struct zephyr_retained_mem_reg_config *config = dev->config;

zephyr_retained_mem_reg_lock_take(dev);

memcpy((config->address + offset), buffer, size);

zephyr_retained_mem_reg_lock_release(dev);

return 0;
}

static int zephyr_retained_mem_reg_clear(const struct device *dev)
{
const struct zephyr_retained_mem_reg_config *config = dev->config;

zephyr_retained_mem_reg_lock_take(dev);

memset(config->address, 0, config->size);

zephyr_retained_mem_reg_lock_release(dev);

return 0;
}

static const struct retained_mem_driver_api zephyr_retained_mem_reg_api = {
.size = zephyr_retained_mem_reg_size,
.read = zephyr_retained_mem_reg_read,
.write = zephyr_retained_mem_reg_write,
.clear = zephyr_retained_mem_reg_clear,
};

#define ZEPHYR_RETAINED_MEM_REG_DEVICE(inst) \
static struct zephyr_retained_mem_reg_data zephyr_retained_mem_reg_data_##inst; \
static const struct zephyr_retained_mem_reg_config \
zephyr_retained_mem_reg_config_##inst = { \
.address = (uint8_t *)DT_INST_REG_ADDR(inst), \
.size = DT_INST_REG_SIZE(inst), \
}; \
DEVICE_DT_INST_DEFINE(inst, \
&zephyr_retained_mem_reg_init, \
NULL, \
&zephyr_retained_mem_reg_data_##inst, \
&zephyr_retained_mem_reg_config_##inst, \
POST_KERNEL, \
CONFIG_RETAINED_MEM_INIT_PRIORITY, \
&zephyr_retained_mem_reg_api);

DT_INST_FOREACH_STATUS_OKAY(ZEPHYR_RETAINED_MEM_REG_DEVICE)
19 changes: 19 additions & 0 deletions dts/bindings/retained_mem/zephyr,retained-reg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# Copyright (c) 2023 Bjarki Arge Andreasen
# SPDX-License-Identifier: Apache-2.0

description: Retained register based retained memory area.

compatible: "zephyr,retained-reg"

include: base.yaml

properties:
"#address-cells":
const: 1

"#size-cells":
const: 1

reg:
required: true

0 comments on commit c6cb2d6

Please sign in to comment.