Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions doc/releases/release-notes-3.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ Stable API changes in this release
New APIs in this release
========================

* Introduced :c:func:`flash_ex_op` function. This allows to perform extra
operations on flash devices, defined by Zephyr Flash API or by vendor specific
header files. Support for extra operations is enabled by
:kconfig:option:`CONFIG_FLASH_EX_OP_ENABLED` which depends on
:kconfig:option:`CONFIG_FLASH_HAS_EX_OP` selected by driver.

Kernel
******

Expand Down Expand Up @@ -250,6 +256,14 @@ Drivers and Sensors

* Flash

* Introduced new flash API call :c:func:`flash_ex_op` which calls
:c:func:`ec_op` callback provided by a flash driver. This allows to perform
extra operations on flash devices, defined by Zephyr Flash API or by vendor
specific header files. :kconfig:option:`CONFIG_FLASH_HAS_EX_OP` should be
selected by the driver to indicate that extra operations are supported.
To enable extra operations user should select
:kconfig:option:`CONFIG_FLASH_EX_OP_ENABLED`.

* FPGA

* Fuel Gauge
Expand Down
14 changes: 14 additions & 0 deletions drivers/flash/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ config FLASH_HAS_DRIVER_ENABLED
help
This option is enabled when any flash driver is enabled.

config FLASH_HAS_EX_OP
bool
help
This option is selected by drivers that support flash extended
operations.

config FLASH_HAS_PAGE_LAYOUT
bool
help
Expand Down Expand Up @@ -78,6 +84,14 @@ config FLASH_PAGE_LAYOUT
help
Enables API for retrieving the layout of flash memory pages.

config FLASH_EX_OP_ENABLED
bool "API for extended flash operations"
depends on FLASH_HAS_EX_OP
default n
help
Enables flash extended operations API. It can be used to perform
non-standard operations e.g. manipulating flash protection.

config FLASH_INIT_PRIORITY
int "Flash init priority"
default KERNEL_INIT_PRIORITY_DEVICE
Expand Down
19 changes: 19 additions & 0 deletions drivers/flash/flash_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,22 @@ static inline int z_vrfy_flash_read_jedec_id(const struct device *dev,
#include <syscalls/flash_sfdp_jedec_id.c>

#endif /* CONFIG_FLASH_JESD216_API */

#ifdef CONFIG_FLASH_EX_OP_ENABLED

static inline int z_vrfy_flash_ex_op(const struct device *dev, uint16_t code,
const uintptr_t in, void *out)
{
Z_OOPS(Z_SYSCALL_DRIVER_FLASH(dev, ex_op));

/*
* If the code is a vendor code, then ex_op function have to perform
* verification. Zephyr codes should be verified here, but currently
* there are no Zephyr extended codes yet.
*/

return z_impl_flash_ex_op(dev, code, in, out);
}
#include <syscalls/flash_ex_op_mrsh.c>

#endif /* CONFIG_FLASH_EX_OP_ENABLED */
66 changes: 66 additions & 0 deletions include/zephyr/drivers/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ typedef void (*flash_api_pages_layout)(const struct device *dev,
typedef int (*flash_api_sfdp_read)(const struct device *dev, off_t offset,
void *data, size_t len);
typedef int (*flash_api_read_jedec_id)(const struct device *dev, uint8_t *id);
typedef int (*flash_api_ex_op)(const struct device *dev, uint16_t code,
const uintptr_t in, void *out);

__subsystem struct flash_driver_api {
flash_api_read read;
Expand All @@ -138,6 +140,9 @@ __subsystem struct flash_driver_api {
flash_api_sfdp_read sfdp_read;
flash_api_read_jedec_id read_jedec_id;
#endif /* CONFIG_FLASH_JESD216_API */
#if defined(CONFIG_FLASH_EX_OP_ENABLED)
flash_api_ex_op ex_op;
#endif /* CONFIG_FLASH_EX_OP_ENABLED */
};

/**
Expand Down Expand Up @@ -422,6 +427,67 @@ static inline const struct flash_parameters *z_impl_flash_get_parameters(const s
return api->get_parameters(dev);
}

/**
* @brief Execute flash extended operation on given device
*
* Besides of standard flash operations like write or erase, flash controllers
* also support additional features like write protection or readout
* protection. These features are not available in every flash controller,
* what's more controllers can implement it in a different way.
*
* It doesn't make sense to add a separate flash API function for every flash
* controller feature, because it could be unique (supported on small number of
* flash controllers) or the API won't be able to represent the same feature on
* every flash controller.
*
* @param dev Flash device
* @param code Operation which will be executed on the device.
* @param in Pointer to input data used by operation. If operation doesn't
* need any input data it could be NULL.
* @param out Pointer to operation output data. If operation doesn't produce
* any output it could be NULL.
*
* @retval 0 on success.
* @retval -ENOTSUP if given device doesn't support extended operation.
* @retval -ENOSYS if support for extended operations is not enabled in Kconfig
* @retval negative value on extended operation errors.
*/
__syscall int flash_ex_op(const struct device *dev, uint16_t code,
const uintptr_t in, void *out);

/*
* Extended operation interface provides flexible way for supporting flash
* controller features. Code space is divided equally into Zephyr codes
* (MSb == 0) and vendor codes (MSb == 1). This way we can easily add extended
* operations to the drivers without cluttering the API or problems with API
* incompatibility. Extended operation can be promoted from vendor codes to
* Zephyr codes if the feature is available in most flash controllers and
* can be represented in the same way.
*
* It's not forbidden to have operation in Zephyr codes and vendor codes for
* the same functionality. In this case, vendor operation could provide more
* specific access when abstraction in Zephyr counterpart is insufficient.
*/
#define FLASH_EX_OP_VENDOR_BASE 0x8000
#define FLASH_EX_OP_IS_VENDOR(c) ((c) & FLASH_EX_OP_VENDOR_BASE)

static inline int z_impl_flash_ex_op(const struct device *dev, uint16_t code,
const uintptr_t in, void *out)
{
#if defined(CONFIG_FLASH_EX_OP_ENABLED)
const struct flash_driver_api *api =
(const struct flash_driver_api *)dev->api;

if (api->ex_op == NULL) {
return -ENOTSUP;
}

return api->ex_op(dev, code, in, out);
#else
return -ENOSYS;
#endif /* CONFIG_FLASH_EX_OP_ENABLED */
}

#ifdef __cplusplus
}
#endif
Expand Down