diff --git a/drivers/flash/flash_mcux_flexspi_nor.c b/drivers/flash/flash_mcux_flexspi_nor.c index 9ff6c538fc7..d264d71c1d4 100644 --- a/drivers/flash/flash_mcux_flexspi_nor.c +++ b/drivers/flash/flash_mcux_flexspi_nor.c @@ -55,13 +55,17 @@ enum { }; struct flash_flexspi_nor_config { - const struct device *controller; flexspi_port_t port; flexspi_device_config_t config; struct flash_pages_layout layout; struct flash_parameters flash_parameters; }; +/* Device variables used in critical sections should be in this structure */ +struct flash_flexspi_nor_data { + const struct device *controller; +}; + static const uint32_t flash_flexspi_nor_lut[][4] = { [READ_ID] = { FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, SPI_NOR_CMD_RDID, @@ -148,6 +152,7 @@ static int flash_flexspi_nor_get_vendor_id(const struct device *dev, uint8_t *vendor_id) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; uint32_t buffer = 0; int ret; @@ -163,7 +168,7 @@ static int flash_flexspi_nor_get_vendor_id(const struct device *dev, LOG_DBG("Reading id"); - ret = memc_flexspi_transfer(config->controller, &transfer); + ret = memc_flexspi_transfer(data->controller, &transfer); *vendor_id = buffer; return ret; @@ -173,6 +178,7 @@ static int flash_flexspi_nor_read_status(const struct device *dev, uint32_t *status) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; flexspi_transfer_t transfer = { .deviceAddress = 0, @@ -186,13 +192,14 @@ static int flash_flexspi_nor_read_status(const struct device *dev, LOG_DBG("Reading status register"); - return memc_flexspi_transfer(config->controller, &transfer); + return memc_flexspi_transfer(data->controller, &transfer); } static int flash_flexspi_nor_write_status(const struct device *dev, uint32_t *status) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; flexspi_transfer_t transfer = { .deviceAddress = 0, @@ -206,12 +213,13 @@ static int flash_flexspi_nor_write_status(const struct device *dev, LOG_DBG("Writing status register"); - return memc_flexspi_transfer(config->controller, &transfer); + return memc_flexspi_transfer(data->controller, &transfer); } static int flash_flexspi_nor_write_enable(const struct device *dev) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; flexspi_transfer_t transfer = { .deviceAddress = 0, @@ -225,13 +233,14 @@ static int flash_flexspi_nor_write_enable(const struct device *dev) LOG_DBG("Enabling write"); - return memc_flexspi_transfer(config->controller, &transfer); + return memc_flexspi_transfer(data->controller, &transfer); } static int flash_flexspi_nor_erase_sector(const struct device *dev, off_t offset) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; flexspi_transfer_t transfer = { .deviceAddress = offset, @@ -245,12 +254,13 @@ static int flash_flexspi_nor_erase_sector(const struct device *dev, LOG_DBG("Erasing sector at 0x%08zx", (ssize_t) offset); - return memc_flexspi_transfer(config->controller, &transfer); + return memc_flexspi_transfer(data->controller, &transfer); } static int flash_flexspi_nor_erase_chip(const struct device *dev) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; flexspi_transfer_t transfer = { .deviceAddress = 0, @@ -264,13 +274,14 @@ static int flash_flexspi_nor_erase_chip(const struct device *dev) LOG_DBG("Erasing chip"); - return memc_flexspi_transfer(config->controller, &transfer); + return memc_flexspi_transfer(data->controller, &transfer); } static int flash_flexspi_nor_page_program(const struct device *dev, off_t offset, const void *buffer, size_t len) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; flexspi_transfer_t transfer = { .deviceAddress = offset, @@ -284,7 +295,7 @@ static int flash_flexspi_nor_page_program(const struct device *dev, LOG_DBG("Page programming %d bytes to 0x%08zx", len, (ssize_t) offset); - return memc_flexspi_transfer(config->controller, &transfer); + return memc_flexspi_transfer(data->controller, &transfer); } static int flash_flexspi_nor_wait_bus_busy(const struct device *dev) @@ -306,12 +317,12 @@ static int flash_flexspi_nor_wait_bus_busy(const struct device *dev) static int flash_flexspi_nor_enable_quad_mode(const struct device *dev) { - const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; uint32_t status = 0x40; flash_flexspi_nor_write_status(dev, &status); flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(config->controller); + memc_flexspi_reset(data->controller); return 0; } @@ -320,7 +331,8 @@ static int flash_flexspi_nor_read(const struct device *dev, off_t offset, void *buffer, size_t len) { const struct flash_flexspi_nor_config *config = dev->config; - uint8_t *src = memc_flexspi_get_ahb_address(config->controller, + struct flash_flexspi_nor_data *data = dev->data; + uint8_t *src = memc_flexspi_get_ahb_address(data->controller, config->port, offset); @@ -333,16 +345,22 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, const void *buffer, size_t len) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; size_t size = len; uint8_t *src = (uint8_t *) buffer; int i; unsigned int key = 0; - uint8_t *dst = memc_flexspi_get_ahb_address(config->controller, + uint8_t *dst = memc_flexspi_get_ahb_address(data->controller, config->port, offset); - if (memc_flexspi_is_running_xip(config->controller)) { + if (memc_flexspi_is_running_xip(data->controller)) { + /* + * ==== ENTER CRITICAL SECTION ==== + * No flash access should be performed in critical section. All + * code and data accessed must reside in ram. + */ key = irq_lock(); } @@ -362,13 +380,14 @@ static int flash_flexspi_nor_write(const struct device *dev, off_t offset, flash_flexspi_nor_page_program(dev, offset, src, i); #endif flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(config->controller); + memc_flexspi_reset(data->controller); src += i; offset += i; len -= i; } - if (memc_flexspi_is_running_xip(config->controller)) { + if (memc_flexspi_is_running_xip(data->controller)) { + /* ==== EXIT CRITICAL SECTION ==== */ irq_unlock(key); } @@ -383,11 +402,12 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, size_t size) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; int num_sectors = size / SPI_NOR_SECTOR_SIZE; int i; unsigned int key = 0; - uint8_t *dst = memc_flexspi_get_ahb_address(config->controller, + uint8_t *dst = memc_flexspi_get_ahb_address(data->controller, config->port, offset); @@ -401,7 +421,12 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, return -EINVAL; } - if (memc_flexspi_is_running_xip(config->controller)) { + if (memc_flexspi_is_running_xip(data->controller)) { + /* + * ==== ENTER CRITICAL SECTION ==== + * No flash access should be performed in critical section. All + * code and data accessed must reside in ram. + */ key = irq_lock(); } @@ -409,18 +434,19 @@ static int flash_flexspi_nor_erase(const struct device *dev, off_t offset, flash_flexspi_nor_write_enable(dev); flash_flexspi_nor_erase_chip(dev); flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(config->controller); + memc_flexspi_reset(data->controller); } else { for (i = 0; i < num_sectors; i++) { flash_flexspi_nor_write_enable(dev); flash_flexspi_nor_erase_sector(dev, offset); flash_flexspi_nor_wait_bus_busy(dev); - memc_flexspi_reset(config->controller); + memc_flexspi_reset(data->controller); offset += SPI_NOR_SECTOR_SIZE; } } - if (memc_flexspi_is_running_xip(config->controller)) { + if (memc_flexspi_is_running_xip(data->controller)) { + /* ==== EXIT CRITICAL SECTION ==== */ irq_unlock(key); } @@ -453,28 +479,29 @@ static void flash_flexspi_nor_pages_layout(const struct device *dev, static int flash_flexspi_nor_init(const struct device *dev) { const struct flash_flexspi_nor_config *config = dev->config; + struct flash_flexspi_nor_data *data = dev->data; uint8_t vendor_id; - if (!device_is_ready(config->controller)) { + if (!device_is_ready(data->controller)) { LOG_ERR("Controller device is not ready"); return -ENODEV; } - if (!memc_flexspi_is_running_xip(config->controller) && - memc_flexspi_set_device_config(config->controller, &config->config, + if (!memc_flexspi_is_running_xip(data->controller) && + memc_flexspi_set_device_config(data->controller, &config->config, config->port)) { LOG_ERR("Could not set device configuration"); return -EINVAL; } - if (memc_flexspi_update_lut(config->controller, 0, + if (memc_flexspi_update_lut(data->controller, 0, (const uint32_t *) flash_flexspi_nor_lut, sizeof(flash_flexspi_nor_lut) / 4)) { LOG_ERR("Could not update lut"); return -EINVAL; } - memc_flexspi_reset(config->controller); + memc_flexspi_reset(data->controller); if (flash_flexspi_nor_get_vendor_id(dev, &vendor_id)) { LOG_ERR("Could not read vendor id"); @@ -535,7 +562,6 @@ static const struct flash_driver_api flash_flexspi_nor_api = { #define FLASH_FLEXSPI_NOR(n) \ static const struct flash_flexspi_nor_config \ flash_flexspi_nor_config_##n = { \ - .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ .port = DT_INST_REG_ADDR(n), \ .config = FLASH_FLEXSPI_DEVICE_CONFIG(n), \ .layout = { \ @@ -547,12 +573,16 @@ static const struct flash_driver_api flash_flexspi_nor_api = { .write_block_size = NOR_WRITE_SIZE, \ .erase_value = NOR_ERASE_VALUE, \ }, \ + }; \ + static struct flash_flexspi_nor_data \ + flash_flexspi_nor_data_##n = { \ + .controller = DEVICE_DT_GET(DT_INST_BUS(n)), \ }; \ \ DEVICE_DT_INST_DEFINE(n, \ flash_flexspi_nor_init, \ NULL, \ - NULL, \ + &flash_flexspi_nor_data_##n, \ &flash_flexspi_nor_config_##n, \ POST_KERNEL, \ CONFIG_FLASH_INIT_PRIORITY, \