init.h: use a counter when naming system devices

Avoids a build error if two or more system devices are declared
in the same C file that use the same init function.
Use _CONCAT() for token concatenation to ensure the names are
properly generated, needed if any of the components are themselves
macros that need to be expanded.

Change-Id: I559bd987617d8cf3bd8c9ee0c985d670b4f59a64
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-09-22 11:14:59 -07:00
commit a5b2682ce8
2 changed files with 20 additions and 16 deletions

View file

@ -108,15 +108,15 @@ extern "C" {
#define DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \ #define DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \
level, prio, api) \ level, prio, api) \
\ \
static struct device_config __config_##dev_name __used \ static struct device_config _CONCAT(__config_, dev_name) __used \
__attribute__((__section__(".devconfig.init"))) = { \ __attribute__((__section__(".devconfig.init"))) = { \
.name = drv_name, .init = (init_fn), \ .name = drv_name, .init = (init_fn), \
.config_info = (cfg_info) \ .config_info = (cfg_info) \
}; \ }; \
\ \
static struct device (__device_##dev_name) __used \ static struct device _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \ __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
.config = &(__config_##dev_name), \ .config = &_CONCAT(__config_, dev_name), \
.driver_api = api, \ .driver_api = api, \
.driver_data = data \ .driver_data = data \
} }
@ -162,16 +162,16 @@ extern "C" {
#define DEVICE_AND_API_INIT_PM(dev_name, drv_name, init_fn, device_pm_ops, \ #define DEVICE_AND_API_INIT_PM(dev_name, drv_name, init_fn, device_pm_ops, \
data, cfg_info, level, prio, api) \ data, cfg_info, level, prio, api) \
\ \
static struct device_config __config_##dev_name __used \ static struct device_config _CONCAT(__config_, dev_name) __used \
__attribute__((__section__(".devconfig.init"))) = { \ __attribute__((__section__(".devconfig.init"))) = { \
.name = drv_name, .init = (init_fn), \ .name = drv_name, .init = (init_fn), \
.dev_pm_ops = (device_pm_ops), \ .dev_pm_ops = (device_pm_ops), \
.config_info = (cfg_info) \ .config_info = (cfg_info) \
}; \ }; \
\ \
static struct device (__device_##dev_name) __used \ static struct device _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \ __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
.config = &(__config_##dev_name), \ .config = &_CONCAT(__config_, dev_name), \
.driver_api = api, \ .driver_api = api, \
.driver_data = data \ .driver_data = data \
} }
@ -191,7 +191,7 @@ extern struct device_pm_ops device_pm_ops_nop;
#define DEVICE_DEFINE(dev_name, drv_name, init_fn, control_fn, \ #define DEVICE_DEFINE(dev_name, drv_name, init_fn, control_fn, \
data, cfg_info, level, prio, api) \ data, cfg_info, level, prio, api) \
\ \
static struct device_config __config_##dev_name __used \ static struct device_config _CONCAT(__config_, dev_name) __used \
__attribute__((__section__(".devconfig.init"))) = { \ __attribute__((__section__(".devconfig.init"))) = { \
.name = drv_name, .init = (init_fn), \ .name = drv_name, .init = (init_fn), \
.device_control = (control_fn), \ .device_control = (control_fn), \
@ -199,9 +199,9 @@ extern struct device_pm_ops device_pm_ops_nop;
.config_info = (cfg_info) \ .config_info = (cfg_info) \
}; \ }; \
\ \
static struct device (__device_##dev_name) __used \ static struct device _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \ __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
.config = &(__config_##dev_name), \ .config = &_CONCAT(__config_, dev_name), \
.driver_api = api, \ .driver_api = api, \
.driver_data = data \ .driver_data = data \
} }
@ -306,7 +306,7 @@ struct device_pm_ops {
* @param _resume name of the resume function * @param _resume name of the resume function
*/ */
#define DEFINE_DEVICE_PM_OPS(_name, _suspend, _resume) \ #define DEFINE_DEVICE_PM_OPS(_name, _suspend, _resume) \
static struct device_pm_ops _name##_dev_pm_ops = { \ static struct device_pm_ops _CONCAT(_name, _dev_pm_ops) = { \
.suspend = _suspend, \ .suspend = _suspend, \
.resume = _resume, \ .resume = _resume, \
} }
@ -320,8 +320,7 @@ struct device_pm_ops {
* *
* @param _name name of the device * @param _name name of the device
*/ */
#define DEVICE_PM_OPS_GET(_name) \ #define DEVICE_PM_OPS_GET(_name) &_CONCAT(_name, _dev_pm_ops)
(&_name##_dev_pm_ops)
/** /**
* @} * @}

View file

@ -38,6 +38,11 @@ extern "C" {
#define _SYS_INIT_LEVEL_MICROKERNEL 3 #define _SYS_INIT_LEVEL_MICROKERNEL 3
#define _SYS_INIT_LEVEL_APPLICATION 4 #define _SYS_INIT_LEVEL_APPLICATION 4
/* Counter use to avoid issues if two or more system devices are declared
* in the same C file with the same init function
*/
#define _SYS_NAME(init_fn) _CONCAT(_CONCAT(sys_init_, init_fn), __COUNTER__)
/** /**
* @def SYS_INIT * @def SYS_INIT
* *
@ -53,7 +58,7 @@ extern "C" {
* DEVICE_INIT for details. * DEVICE_INIT for details.
*/ */
#define SYS_INIT(init_fn, level, prio) \ #define SYS_INIT(init_fn, level, prio) \
DEVICE_INIT(sys_init_##init_fn, "", init_fn, NULL, NULL, level, prio) DEVICE_INIT(_SYS_NAME(init_fn), "", init_fn, NULL, NULL, level, prio)
/** /**
* @def SYS_INIT_PM * @def SYS_INIT_PM
@ -68,15 +73,15 @@ extern "C" {
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT #ifdef CONFIG_DEVICE_POWER_MANAGEMENT
#define SYS_INIT_PM(drv_name, init_fn, device_pm_ops, level, prio) \ #define SYS_INIT_PM(drv_name, init_fn, device_pm_ops, level, prio) \
DEVICE_INIT_PM(sys_init_##init_fn, drv_name, init_fn, device_pm_ops, \ DEVICE_INIT_PM(_SYS_NAME(init_fn), drv_name, init_fn, device_pm_ops, \
NULL, NULL, level, prio) NULL, NULL, level, prio)
#else #else
#define SYS_INIT_PM(drv_name, init_fn, device_pm_ops, level, prio) \ #define SYS_INIT_PM(drv_name, init_fn, device_pm_ops, level, prio) \
DEVICE_INIT(sys_init_##init_fn, "", init_fn, NULL, NULL, level, prio) DEVICE_INIT(_SYS_NAME(init_fn), "", init_fn, NULL, NULL, level, prio)
#endif #endif
#define SYS_DEVICE_DEFINE(drv_name, init_fn, control_fn, level, prio) \ #define SYS_DEVICE_DEFINE(drv_name, init_fn, control_fn, level, prio) \
DEVICE_DEFINE(sys_init_##init_fn, drv_name, init_fn, control_fn, \ DEVICE_DEFINE(_SYS_NAME(init_fn), drv_name, init_fn, control_fn, \
NULL, NULL, level, prio, NULL) NULL, NULL, level, prio, NULL)
#ifdef __cplusplus #ifdef __cplusplus