drivers: flash: nrf_qspi_nor: support write of sub-word lengths

mcumgr and possibly mcuboot write single byte values to update the
state of objects.  Rather than fail to do the write of values too
short for this peripheral detect the situation and write from a stack
buffer that meets the length criteria.

Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-06-04 07:11:25 -05:00 committed by Carles Cufí
commit 16573923b3

View file

@ -549,6 +549,28 @@ static int qspi_nor_read(struct device *dev, off_t addr, void *dest,
return rc;
}
/* addr aligned, sptr not null, slen less than 4 */
static inline nrfx_err_t write_sub_word(struct device *dev, off_t addr,
const void *sptr, size_t slen)
{
uint8_t __aligned(4) buf[4];
nrfx_err_t res;
/* read out the whole word so that unchanged data can be
* written back
*/
res = nrfx_qspi_read(buf, sizeof(buf), addr);
qspi_wait_for_completion(dev, res);
if (res == NRFX_SUCCESS) {
memcpy(sptr, buf, slen);
res = nrfx_qspi_write(src, size, addr);
qspi_wait_for_completion(dev, res);
}
return res;
}
static int qspi_nor_write(struct device *dev, off_t addr, const void *src,
size_t size)
{
@ -556,8 +578,9 @@ static int qspi_nor_write(struct device *dev, off_t addr, const void *src,
return -EINVAL;
}
/* write size must be non-zero multiple of 4 bytes */
if (((size % 4U) != 0) || (size == 0)) {
/* write size must be non-zero, less than 4, or a multiple of 4 */
if ((size == 0)
|| ((size > 4) && ((size % 4U) != 0))) {
return -EINVAL;
}
/* address must be 4-byte aligned */
@ -581,11 +604,16 @@ static int qspi_nor_write(struct device *dev, off_t addr, const void *src,
return -EINVAL;
}
nrfx_err_t res = NRFX_SUCCESS;
qspi_lock(dev);
nrfx_err_t res = nrfx_qspi_write(src, size, addr);
qspi_wait_for_completion(dev, res);
if (size < 4U) {
res = write_sub_word(dev, addr, src, size);
} else {
res = nrfx_qspi_write(src, size, addr);
qspi_wait_for_completion(dev, res);
}
qspi_unlock(dev);