device: introduce struct device_ops
Instead of passing a single init function, create struct device_ops with the init function inside. This allows to easily extend device's capabilities in the future without too much breakage, e.g. to add a de-init call. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
f44a30109c
commit
766bfe7b2e
@ -451,6 +451,12 @@ typedef uint8_t device_flags_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Device operations */
|
||||
struct device_ops {
|
||||
/** Initialization function */
|
||||
int (*init)(const struct device *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Runtime device structure (in ROM) per driver instance
|
||||
*/
|
||||
@ -465,8 +471,8 @@ struct device {
|
||||
struct device_state *state;
|
||||
/** Address of the device instance private data */
|
||||
void *data;
|
||||
/** Initialization function (optional) */
|
||||
int (*init_fn)(const struct device *);
|
||||
/** Device operations */
|
||||
struct device_ops ops;
|
||||
/** Device flags */
|
||||
device_flags_t flags;
|
||||
#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
|
||||
@ -1090,7 +1096,7 @@ device_get_dt_nodelabels(const struct device *dev)
|
||||
.api = (api_), \
|
||||
.state = (state_), \
|
||||
.data = (data_), \
|
||||
.init_fn = (init_fn_), \
|
||||
.ops = { .init = (init_fn_) }, \
|
||||
.flags = (flags_), \
|
||||
IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
|
||||
IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) /**/ \
|
||||
|
||||
@ -306,8 +306,8 @@ static int do_device_init(const struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (dev->init_fn != NULL) {
|
||||
rc = dev->init_fn(dev);
|
||||
if (dev->ops.init != NULL) {
|
||||
rc = dev->ops.init(dev);
|
||||
/* Mark device initialized. If initialization
|
||||
* failed, record the error condition.
|
||||
*/
|
||||
|
||||
@ -86,16 +86,16 @@ ZTEST(devicetree_devices, test_init_get)
|
||||
DEVICE_DT_GET(TEST_NOLABEL), NULL);
|
||||
|
||||
/* Check init functions */
|
||||
zassert_equal(DEVICE_DT_GET(TEST_GPIO)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_I2C)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_DEVA)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_DEVB)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_GPIOX)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_DEVC)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_PARTITION)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_GPIO_INJECTED)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_GET(manual_dev)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_NOLABEL)->init_fn, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_GPIO)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_I2C)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_DEVA)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_DEVB)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_GPIOX)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_DEVC)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_PARTITION)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_GPIO_INJECTED)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_GET(manual_dev)->ops.init, dev_init);
|
||||
zassert_equal(DEVICE_DT_GET(TEST_NOLABEL)->ops.init, dev_init);
|
||||
}
|
||||
|
||||
ZTEST(devicetree_devices, test_init_order)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user