From 6ea63215862dd8092f8eee0accae5a9c0ec1a615 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 3 Jun 2020 18:30:32 +0000 Subject: [PATCH] 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 --- boards/posix/native_posix/native_posix.dts | 1 + boards/x86/qemu_x86/qemu_x86.dts | 1 + drivers/flash/flash_gecko.c | 14 +++++++++++ drivers/flash/flash_sam.c | 13 +++++++++++ drivers/flash/flash_sam0.c | 13 +++++++++++ drivers/flash/flash_simulator.c | 23 +++++++++++++++---- drivers/flash/flash_stm32.c | 14 +++++++++++ drivers/flash/nrf_qspi_nor.c | 13 +++++++++++ drivers/flash/soc_flash_mcux.c | 17 ++++++++++++-- drivers/flash/soc_flash_nios2_qspi.c | 13 +++++++++++ drivers/flash/soc_flash_nrf.c | 13 +++++++++++ drivers/flash/soc_flash_rv32m1.c | 13 +++++++++++ drivers/flash/spi_flash_at45.c | 13 +++++++++++ drivers/flash/spi_flash_w25qxxdv.c | 13 +++++++++++ drivers/flash/spi_nor.c | 13 +++++++++++ .../flash_controller/zephyr,sim-flash.yaml | 6 +++++ tests/drivers/flash_simulator/src/main.c | 15 +++++++++++- 17 files changed, 201 insertions(+), 7 deletions(-) diff --git a/boards/posix/native_posix/native_posix.dts b/boards/posix/native_posix/native_posix.dts index 17a8cc62333..35cb1649c94 100644 --- a/boards/posix/native_posix/native_posix.dts +++ b/boards/posix/native_posix/native_posix.dts @@ -30,6 +30,7 @@ #address-cells = <1>; #size-cells = <1>; + erase-value = <0xff>; label = "flash_ctrl"; diff --git a/boards/x86/qemu_x86/qemu_x86.dts b/boards/x86/qemu_x86/qemu_x86.dts index 7a998d1c993..19332989980 100644 --- a/boards/x86/qemu_x86/qemu_x86.dts +++ b/boards/x86/qemu_x86/qemu_x86.dts @@ -54,6 +54,7 @@ #address-cells = <1>; #size-cells = <1>; + erase-value = <0xff>; flash_sim0: flash_sim@0 { compatible = "soc-nv-flash"; diff --git a/drivers/flash/flash_gecko.c b/drivers/flash/flash_gecko.c index 9fb7a2f4e4c..57abd4ea610 100644 --- a/drivers/flash/flash_gecko.c +++ b/drivers/flash/flash_gecko.c @@ -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 diff --git a/drivers/flash/flash_sam.c b/drivers/flash/flash_sam.c index c2f923edfd7..0e88216f859 100644 --- a/drivers/flash/flash_sam.c +++ b/drivers/flash/flash_sam.c @@ -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 diff --git a/drivers/flash/flash_sam0.c b/drivers/flash/flash_sam0.c index b611b64d38c..24289bcf5f3 100644 --- a/drivers/flash/flash_sam0.c +++ b/drivers/flash/flash_sam0.c @@ -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 diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 263dd5de127..511db4661db 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -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; } diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index 483ce52fe65..50b066326d6 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -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 diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index dc85538edd7..88a8cc6e81c 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -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 diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 369b122751a..30dfff5f680 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -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 diff --git a/drivers/flash/soc_flash_nios2_qspi.c b/drivers/flash/soc_flash_nios2_qspi.c index c44222e62ba..8beb36ea0eb 100644 --- a/drivers/flash/soc_flash_nios2_qspi.c +++ b/drivers/flash/soc_flash_nios2_qspi.c @@ -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, diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index 2cedcd0c40f..857865ea617 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -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 diff --git a/drivers/flash/soc_flash_rv32m1.c b/drivers/flash/soc_flash_rv32m1.c index cad81bc4f6a..56b1617bc43 100644 --- a/drivers/flash/soc_flash_rv32m1.c +++ b/drivers/flash/soc_flash_rv32m1.c @@ -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 diff --git a/drivers/flash/spi_flash_at45.c b/drivers/flash/spi_flash_at45.c index cbac3689348..4e7d644b8d0 100644 --- a/drivers/flash/spi_flash_at45.c +++ b/drivers/flash/spi_flash_at45.c @@ -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 diff --git a/drivers/flash/spi_flash_w25qxxdv.c b/drivers/flash/spi_flash_w25qxxdv.c index 8e6c228e1c7..8bdd6f40b3b 100644 --- a/drivers/flash/spi_flash_w25qxxdv.c +++ b/drivers/flash/spi_flash_w25qxxdv.c @@ -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 diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 75e4e8f6490..b92f6672c8f 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -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 diff --git a/dts/bindings/flash_controller/zephyr,sim-flash.yaml b/dts/bindings/flash_controller/zephyr,sim-flash.yaml index e0a292c30e2..8050254339a 100644 --- a/dts/bindings/flash_controller/zephyr,sim-flash.yaml +++ b/dts/bindings/flash_controller/zephyr,sim-flash.yaml @@ -9,3 +9,9 @@ include: base.yaml properties: label: required: true + +properties: + erase-value: + type: int + description: Value of erased flash cell + required: false diff --git a/tests/drivers/flash_simulator/src/main.c b/tests/drivers/flash_simulator/src/main.c index c8ac362c5a3..c3cb8b893d1 100644 --- a/tests/drivers/flash_simulator/src/main.c +++ b/tests/drivers/flash_simulator/src/main.c @@ -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); }