diff --git a/include/zephyr/device.h b/include/zephyr/device.h index d2f2244cc0b8f0c..72944b2fe38aaf7 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -934,9 +934,24 @@ __syscall int device_init(const struct device *dev); .state = (state_), \ .data = (data_), \ IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \ - IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) /**/ \ + Z_DEVICE_INIT_PM_BASE(pm_) \ } +/* + * Anonymous unions require C11. Some pre-C11 gcc versions have early + * support for anonymous unions but they require these braces when + * combined with C99 designated initializers. These braces are + * compatible with any C version but not with C++20. For more obscure + * C/C++ compatibility details see commit c15f029a7108 and PR #69411. + */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100 +# define Z_DEVICE_INIT_PM_BASE(pm_) \ + IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),})) +#else +# define Z_DEVICE_INIT_PM_BASE(pm_) \ + IF_ENABLED(CONFIG_PM_DEVICE, (.pm_base = (pm_),)) +#endif + /** * @brief Device section name (used for sorting purposes). * @@ -1008,23 +1023,33 @@ __syscall int device_init(const struct device *dev); Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \ .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ (init_fn_)}, \ - { \ - COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ - &DEVICE_NAME_GET(dev_id), \ - }, \ + Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id), \ } +// TODO: TEST BOTH new DEFER and old non defer. Requires some zephyr,deferred-init devtree #define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_) \ static const Z_DECL_ALIGN(struct init_entry) __used __noasan \ __attribute__((__section__(".z_deferred_init"))) \ Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \ .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ (init_fn_)}, \ - { \ - COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ - &DEVICE_NAME_GET(dev_id), \ - }, \ + Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id), \ } +/* + * Anonymous unions require C11. Some pre-C11 gcc versions have early + * support for anonymous unions but they require these braces when + * combined with C99 designated initializers. These braces are + * compatible with any C version but not with C++20. For more obscure + * C/C++ compatibility details see commit c15f029a7108 and PR #69411. + */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100 +# define Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id) { Z_DEV_ENTRY_DEV(node_id, dev_id) } +#else +# define Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id) Z_DEV_ENTRY_DEV(node_id, dev_id) +#endif + +#define Z_DEV_ENTRY_DEV(node_id, dev_id) \ + COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = &DEVICE_NAME_GET(dev_id) /** * @brief Define a @ref device and all other required objects.