diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 04b9de8038b..2fc90a24ab1 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -19,6 +19,10 @@ struct flash_priv { flash_config_t config; + /* + * HACK: flash write protection is managed in software. + */ + struct k_sem write_lock; }; /* @@ -37,12 +41,18 @@ static int flash_mcux_erase(struct device *dev, off_t offset, size_t len) status_t rc; int key; + if (k_sem_take(&priv->write_lock, K_NO_WAIT)) { + return -EACCES; + } + addr = offset + priv->config.PFlashBlockBase; key = irq_lock(); rc = FLASH_Erase(&priv->config, addr, len, kFLASH_ApiEraseKey); irq_unlock(key); + k_sem_give(&priv->write_lock); + return (rc == kStatus_Success) ? 0 : -EINVAL; } @@ -72,18 +82,33 @@ static int flash_mcux_write(struct device *dev, off_t offset, status_t rc; int key; + if (k_sem_take(&priv->write_lock, K_NO_WAIT)) { + return -EACCES; + } + addr = offset + priv->config.PFlashBlockBase; key = irq_lock(); rc = FLASH_Program(&priv->config, addr, (u32_t *) data, len); irq_unlock(key); + k_sem_give(&priv->write_lock); + return (rc == kStatus_Success) ? 0 : -EINVAL; } static int flash_mcux_write_protection(struct device *dev, bool enable) { - return -EIO; + struct flash_priv *priv = dev->driver_data; + int rc = 0; + + if (enable) { + rc = k_sem_take(&priv->write_lock, K_FOREVER); + } else { + k_sem_give(&priv->write_lock); + } + + return rc; } #if defined(CONFIG_FLASH_PAGE_LAYOUT) @@ -119,6 +144,8 @@ static int flash_mcux_init(struct device *dev) struct flash_priv *priv = dev->driver_data; status_t rc; + k_sem_init(&priv->write_lock, 0, 1); + rc = FLASH_Init(&priv->config); return (rc == kStatus_Success) ? 0 : -EIO;