drivers/flash: Add support for flash_get_parameters to drivers

With addition of flash_get_parameters API call, it is needed to provide
support for the API to flash drivers.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
Dominik Ermel 2020-06-03 18:30:32 +00:00 committed by Carles Cufí
commit 6ea6321586
17 changed files with 201 additions and 7 deletions

View file

@ -30,6 +30,7 @@
#address-cells = <1>;
#size-cells = <1>;
erase-value = <0xff>;
label = "flash_ctrl";

View file

@ -54,6 +54,7 @@
#address-cells = <1>;
#size-cells = <1>;
erase-value = <0xff>;
flash_sim0: flash_sim@0 {
compatible = "soc-nv-flash";

View file

@ -24,6 +24,11 @@ struct flash_gecko_data {
struct k_sem mutex;
};
static const struct flash_parameters flash_gecko_parameters = {
.erase_value = 0xff,
};
#define DEV_NAME(dev) ((dev)->name)
#define DEV_DATA(dev) \
((struct flash_gecko_data *const)(dev)->driver_data)
@ -178,6 +183,14 @@ void flash_gecko_page_layout(struct device *dev,
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static const struct flash_parameters *
flash_gecko_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_gecko_parameters;
}
static int flash_gecko_init(struct device *dev)
{
struct flash_gecko_data *const dev_data = DEV_DATA(dev);
@ -199,6 +212,7 @@ static const struct flash_driver_api flash_gecko_driver_api = {
.write = flash_gecko_write,
.erase = flash_gecko_erase,
.write_protection = flash_gecko_write_protection,
.get_parameters = flash_gecko_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = flash_gecko_page_layout,
#endif

View file

@ -46,6 +46,10 @@ struct flash_sam_dev_data {
struct k_sem sem;
};
static const struct flash_parameters flash_sam_parameters = {
.erase_value = 0xff,
};
#define DEV_CFG(dev) \
((const struct flash_sam_dev_cfg *const)(dev)->config_info)
@ -330,6 +334,14 @@ void flash_sam_page_layout(struct device *dev,
}
#endif
static const struct flash_parameters *
flash_sam_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_sam_parameters;
}
static int flash_sam_init(struct device *dev)
{
struct flash_sam_dev_data *const data = DEV_DATA(dev);
@ -344,6 +356,7 @@ static const struct flash_driver_api flash_sam_api = {
.erase = flash_sam_erase,
.write = flash_sam_write,
.read = flash_sam_read,
.get_parameters = flash_sim_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = flash_sam_page_layout,
#endif

View file

@ -61,6 +61,10 @@ static const struct flash_pages_layout flash_sam0_pages_layout = {
};
#endif
static const struct flash_parameters flash_sam0_parameters = {
.erase_value = 0xff,
};
static inline void flash_sam0_sem_take(struct device *dev)
{
struct flash_sam0_data *ctx = dev->driver_data;
@ -388,6 +392,14 @@ void flash_sam0_page_layout(struct device *dev,
}
#endif
static const struct flash_parameters *
flash_sam0_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_sam0_parameters;
}
static int flash_sam0_init(struct device *dev)
{
struct flash_sam0_data *ctx = dev->driver_data;
@ -414,6 +426,7 @@ static const struct flash_driver_api flash_sam0_api = {
.erase = flash_sam0_erase,
.write = flash_sam0_write,
.read = flash_sam0_read,
.get_parameters = flash_sam0_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = flash_sam0_page_layout,
#endif

View file

@ -42,6 +42,8 @@
#define FLASH_SIMULATOR_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE)
#define FLASH_SIMULATOR_DEV_NAME DT_INST_LABEL(0)
#define FLASH_SIMULATOR_ERASE_VALUE \
DT_PROP(DT_PARENT(SOC_NV_FLASH_NODE), erase_value)
#define FLASH_SIMULATOR_PAGE_COUNT (FLASH_SIMULATOR_FLASH_SIZE / \
FLASH_SIMULATOR_ERASE_UNIT)
@ -139,6 +141,10 @@ static bool write_protection;
static const struct flash_driver_api flash_sim_api;
static const struct flash_parameters flash_sim_parameters = {
.erase_value = FLASH_SIMULATOR_ERASE_VALUE
};
static int flash_range_is_valid(struct device *dev, off_t offset, size_t len)
{
ARG_UNUSED(dev);
@ -219,7 +225,7 @@ static int flash_sim_write(struct device *dev, const off_t offset,
uint8_t buf[FLASH_SIMULATOR_PROG_UNIT];
memset(buf, 0xFF, sizeof(buf));
memset(buf, FLASH_SIMULATOR_ERASE_VALUE, sizeof(buf));
if (memcmp(buf, FLASH(offset + i), sizeof(buf))) {
STATS_INC(flash_sim_stats, double_writes);
#if !CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES
@ -273,9 +279,9 @@ static void unit_erase(const uint32_t unit)
(unit * FLASH_SIMULATOR_ERASE_UNIT);
/* byte pattern to fill the flash with */
uint8_t byte_pattern = 0xFF;
uint8_t byte_pattern = FLASH_SIMULATOR_ERASE_VALUE;
/* erase the memory unit by pulling all bits to one */
/* erase the memory unit by setting it to erase value */
memset(FLASH(unit_addr), byte_pattern,
FLASH_SIMULATOR_ERASE_UNIT);
}
@ -343,12 +349,21 @@ static void flash_sim_page_layout(struct device *dev,
}
#endif
static const struct flash_parameters *
flash_sim_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_sim_parameters;
}
static const struct flash_driver_api flash_sim_api = {
.read = flash_sim_read,
.write = flash_sim_write,
.erase = flash_sim_erase,
.write_protection = flash_wp_set,
.write_block_size = FLASH_SIMULATOR_PROG_UNIT,
.get_parameters = flash_sim_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = flash_sim_page_layout,
#endif
@ -409,7 +424,7 @@ static int flash_mock_init(struct device *dev)
static int flash_mock_init(struct device *dev)
{
memset(mock_flash, 0xFF, ARRAY_SIZE(mock_flash));
memset(mock_flash, FLASH_SIMULATOR_ERASE_VALUE, ARRAY_SIZE(mock_flash));
return 0;
}

View file

@ -57,6 +57,11 @@ LOG_MODULE_REGISTER(flash_stm32, CONFIG_FLASH_LOG_LEVEL);
#define CFG_HW_FLASH_SEMID 2
static const struct flash_parameters flash_stm32_parameters = {
/* WARNING: This value may be not valid for L0/L1 chips */
.erase_value = 0xff,
};
#if defined(CONFIG_MULTITHREADING)
/*
* This is named flash_stm32_sem_take instead of flash_stm32_lock (and
@ -281,6 +286,14 @@ static int flash_stm32_write_protection(struct device *dev, bool enable)
return rc;
}
static const struct flash_parameters *
flash_stm32_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_stm32_parameters;
}
static struct flash_stm32_priv flash_data = {
.regs = (FLASH_TypeDef *) DT_INST_REG_ADDR(0),
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
@ -299,6 +312,7 @@ static const struct flash_driver_api flash_stm32_api = {
.erase = flash_stm32_erase,
.write = flash_stm32_write,
.read = flash_stm32_read,
.get_parameters = flash_stm32_get_parameters,
#ifdef CONFIG_FLASH_PAGE_LAYOUT
.page_layout = flash_stm32_page_layout,
#endif

View file

@ -33,6 +33,10 @@
LOG_MODULE_REGISTER(qspi_nor, CONFIG_FLASH_LOG_LEVEL);
static const struct flash_parameters qspi_flash_parameters = {
.erase_value = 0xff,
};
/**
* @brief QSPI buffer structure
* Structure used both for TX and RX purposes.
@ -757,6 +761,14 @@ static const struct flash_pages_layout dev_layout = {
};
#undef LAYOUT_PAGES_COUNT
static const struct flash_parameters *
qspi_flash_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &qspi_flash_parameters;
}
static void qspi_nor_pages_layout(struct device *dev,
const struct flash_pages_layout **layout,
size_t *layout_size)
@ -771,6 +783,7 @@ static const struct flash_driver_api qspi_nor_api = {
.write = qspi_nor_write,
.erase = qspi_nor_erase,
.write_protection = qspi_nor_write_protection_set,
.get_parameters = qspi_flash_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = qspi_nor_pages_layout,
#endif

View file

@ -43,6 +43,10 @@ struct flash_priv {
uint32_t pflash_block_base;
};
static const struct flash_parameters flash_mcux_parameters = {
.erase_value = 0xff,
};
/*
* Interrupt vectors could be executed from flash hence the need for locking.
* The underlying MCUX driver takes care of copying the functions to SRAM.
@ -137,14 +141,22 @@ static const struct flash_pages_layout dev_layout = {
};
static void flash_mcux_pages_layout(struct device *dev,
const struct flash_pages_layout **layout,
size_t *layout_size)
const struct flash_pages_layout **layout,
size_t *layout_size)
{
*layout = &dev_layout;
*layout_size = 1;
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static const struct flash_parameters *
flash_mcux_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_mcux_parameters;
}
static struct flash_priv flash_data;
static const struct flash_driver_api flash_mcux_api = {
@ -152,6 +164,7 @@ static const struct flash_driver_api flash_mcux_api = {
.erase = flash_mcux_erase,
.write = flash_mcux_write,
.read = flash_mcux_read,
.get_parameters = flash_mcux_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = flash_mcux_pages_layout,
#endif

View file

@ -61,6 +61,10 @@ struct flash_nios2_qspi_config {
struct k_sem sem_lock;
};
static const struct flash_parameters flash_nios2_qspi_parameters = {
.erase_value = 0xff,
};
static int flash_nios2_qspi_erase(struct device *dev, off_t offset, size_t len)
{
struct flash_nios2_qspi_config *flash_cfg = dev->driver_data;
@ -449,11 +453,20 @@ static int flash_nios2_qspi_write_protection(struct device *dev, bool enable)
return rc;
}
static const struct flash_parameters *
flash_nios2_qspi_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_nios2_qspi_parameters;
}
static const struct flash_driver_api flash_nios2_qspi_api = {
.write_protection = flash_nios2_qspi_write_protection,
.erase = flash_nios2_qspi_erase,
.write = flash_nios2_qspi_write,
.read = flash_nios2_qspi_read,
.get_parameters = flash_nios2_qspi_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = (flash_api_pages_layout)
flash_page_layout_not_implemented,

View file

@ -105,6 +105,10 @@ static int erase_op(void *context); /* instance of flash_op_handler_t */
static int erase_in_timeslice(uint32_t addr, uint32_t size);
#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
static const struct flash_parameters flash_nrf_parameters = {
.erase_value = 0xff,
};
#if defined(CONFIG_MULTITHREADING)
/* semaphore for locking flash resources (tickers) */
static struct k_sem sem_lock;
@ -278,11 +282,20 @@ static void flash_nrf_pages_layout(struct device *dev,
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static const struct flash_parameters *
flash_nrf_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_nrf_parameters;
}
static const struct flash_driver_api flash_nrf_api = {
.read = flash_nrf_read,
.write = flash_nrf_write,
.erase = flash_nrf_erase,
.write_protection = flash_nrf_write_protection,
.get_parameters = flash_nrf_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = flash_nrf_pages_layout,
#endif

View file

@ -28,6 +28,10 @@ struct flash_priv {
uint32_t pflash_block_base;
};
static const struct flash_parameters flash_mcux_parameters = {
.erase_value = 0xff,
};
/*
* Interrupt vectors could be executed from flash hence the need for locking.
* The underlying MCUX driver takes care of copying the functions to SRAM.
@ -131,6 +135,14 @@ static void flash_mcux_pages_layout(
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static const struct flash_parameters *
flash_mcux_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_mcux_parameters;
}
static struct flash_priv flash_data;
static const struct flash_driver_api flash_mcux_api = {
@ -138,6 +150,7 @@ static const struct flash_driver_api flash_mcux_api = {
.erase = flash_mcux_erase,
.write = flash_mcux_write,
.read = flash_mcux_read,
.get_parameters = flash_mcux_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = flash_mcux_pages_layout,
#endif

View file

@ -76,6 +76,10 @@ struct spi_flash_at45_config {
uint8_t jedec_id[3];
};
static const struct flash_parameters flash_at45_parameters = {
.erase_value = 0xff,
};
static struct spi_flash_at45_data *get_dev_data(struct device *dev)
{
return dev->driver_data;
@ -624,11 +628,20 @@ static int spi_flash_at45_pm_control(struct device *dev, uint32_t ctrl_command,
}
#endif /* IS_ENABLED(CONFIG_DEVICE_POWER_MANAGEMENT) */
static const struct flash_parameters *
flash_at45_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_at45_parameters;
}
static const struct flash_driver_api spi_flash_at45_api = {
.read = spi_flash_at45_read,
.write = spi_flash_at45_write,
.erase = spi_flash_at45_erase,
.write_protection = spi_flash_at45_write_protection,
.get_parameters = flash_at45_get_parameters,
#if IS_ENABLED(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = spi_flash_at45_pages_layout,
#endif

View file

@ -27,6 +27,10 @@
#define SYNC_UNLOCK()
#endif
static const struct flash_parameters flash_wb_parameters = {
.erase_value = 0xff,
};
static int spi_flash_wb_access(struct spi_flash_data *ctx,
uint8_t cmd, bool addressed, off_t offset,
void *data, size_t length, bool write)
@ -388,11 +392,20 @@ static void flash_wb_pages_layout(struct device *dev,
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static const struct flash_parameters *
flash_wb_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_wb_parameters;
}
static const struct flash_driver_api spi_flash_api = {
.read = spi_flash_wb_read,
.write = spi_flash_wb_write,
.erase = spi_flash_wb_erase,
.write_protection = spi_flash_wb_write_protection_set,
.get_parameters = flash_wb_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = flash_wb_pages_layout,
#endif

View file

@ -84,6 +84,10 @@ struct spi_nor_data {
struct k_sem sem;
};
static const struct flash_parameters flash_nor_parameters = {
.erase_value = 0xff,
};
/* Capture the time at which the device entered deep power-down. */
static inline void record_entered_dpd(const struct device *const dev)
{
@ -568,11 +572,20 @@ static void spi_nor_pages_layout(struct device *dev,
}
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
static const struct flash_parameters *
flash_nor_get_parameters(const struct device *dev)
{
ARG_UNUSED(dev);
return &flash_nor_parameters;
}
static const struct flash_driver_api spi_nor_api = {
.read = spi_nor_read,
.write = spi_nor_write,
.erase = spi_nor_erase,
.write_protection = spi_nor_write_protection_set,
.get_parameters = flash_nor_get_parameters,
#if defined(CONFIG_FLASH_PAGE_LAYOUT)
.page_layout = spi_nor_pages_layout,
#endif

View file

@ -9,3 +9,9 @@ include: base.yaml
properties:
label:
required: true
properties:
erase-value:
type: int
description: Value of erased flash cell
required: false

View file

@ -19,6 +19,9 @@
#define FLASH_SIMULATOR_PROG_UNIT DT_PROP(SOC_NV_FLASH_NODE, write_block_size)
#define FLASH_SIMULATOR_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE)
#define FLASH_SIMULATOR_ERASE_VALUE \
DT_PROP(DT_PARENT(SOC_NV_FLASH_NODE), erase_value)
/* Offset between pages */
#define TEST_SIM_FLASH_SIZE FLASH_SIMULATOR_FLASH_SIZE
@ -266,6 +269,15 @@ static void test_double_write(void)
zassert_equal(-EIO, rc, "Unexpected error code (%d)", rc);
}
static void test_get_erase_value(void)
{
const struct flash_parameters *fp = flash_get_parameters(flash_dev);
zassert_equal(fp->erase_value, FLASH_SIMULATOR_ERASE_VALUE,
"Expected erase value %x",
FLASH_SIMULATOR_ERASE_VALUE);
}
void test_main(void)
{
ztest_test_suite(flash_sim_api,
@ -275,7 +287,8 @@ void test_main(void)
ztest_unit_test(test_access),
ztest_unit_test(test_out_of_bounds),
ztest_unit_test(test_align),
ztest_unit_test(test_double_write));
ztest_unit_test(test_double_write),
ztest_unit_test(test_get_erase_value));
ztest_run_test_suite(flash_sim_api);
}