diff --git a/samples/subsys/greybus/net/src/main.c b/samples/subsys/greybus/net/src/main.c index f28cf33..a5edc8d 100644 --- a/samples/subsys/greybus/net/src/main.c +++ b/samples/subsys/greybus/net/src/main.c @@ -7,13 +7,6 @@ #include #include -struct device; -extern int greybus_service_init(struct device *bus); - void main(void) { - int r = greybus_service_init(NULL); - if (r < 0) { - printf("gb_service_deferred_init() failed: %d\n", r); - } } diff --git a/samples/subsys/greybus/uart/src/main.c b/samples/subsys/greybus/uart/src/main.c index f2b1995..a5edc8d 100644 --- a/samples/subsys/greybus/uart/src/main.c +++ b/samples/subsys/greybus/uart/src/main.c @@ -7,13 +7,6 @@ #include #include -struct device; -extern int greybus_service_init(struct device *bus); - void main(void) { - int r = greybus_service_init(NULL); - if (r < 0) { - printf("gb_service_deferred_init() failed: %d\n", r); - } } diff --git a/subsys/greybus/CMakeLists.txt b/subsys/greybus/CMakeLists.txt index 22d029e..16ef15a 100644 --- a/subsys/greybus/CMakeLists.txt +++ b/subsys/greybus/CMakeLists.txt @@ -13,7 +13,6 @@ zephyr_library_sources( platform/manifest.c platform/platform.c - platform/deferred-init.c platform/service.c diff --git a/subsys/greybus/Kconfig b/subsys/greybus/Kconfig index 8f4cbb1..84bedef 100644 --- a/subsys/greybus/Kconfig +++ b/subsys/greybus/Kconfig @@ -161,6 +161,41 @@ config GREYBUS_VIBRATOR help Select this for Greybus Vibrator support. +config GREYBUS_SERVICE_INIT_PRIORITY + int "default Greybus Service Init Priority" + default 85 + range 0 99 + help + Greybus service init priority to ensure device initialization order. + +config GREYBUS_STRING_INIT_PRIORITY + int "default Greybus String Init Priority" + default 86 + range 0 99 + help + Greybus string init priority to ensure device initialization order. + +config GREYBUS_INTERFACE_INIT_PRIORITY + int "default Greybus Interface Init Priority" + default 87 + range 0 99 + help + Greybus interface init priority to ensure device initialization order. + +config GREYBUS_BUNDLE_INIT_PRIORITY + int "default Greybus Bundle Init Priority" + default 88 + range 0 99 + help + Greybus bundle init priority to ensure device initialization order. + +config GREYBUS_CPORT_INIT_PRIORITY + int "default Greybus Cport Init Priority" + default 89 + range 0 99 + help + Greybus cport init priority to ensure device initialization order. + module = GREYBUS module-str = gb source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/greybus/platform/bundle.c b/subsys/greybus/platform/bundle.c index bd890ec..33bedaa 100644 --- a/subsys/greybus/platform/bundle.c +++ b/subsys/greybus/platform/bundle.c @@ -32,11 +32,6 @@ static int greybus_bundle_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_bundle_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_bundle_init); -} - #define DEFINE_GREYBUS_BUNDLE(_num) \ \ static const struct greybus_bundle_config \ @@ -48,10 +43,10 @@ static int defer_greybus_bundle_init(const struct device *dev) { }; \ \ DEVICE_DT_INST_DEFINE(_num, \ - defer_greybus_bundle_init, \ + greybus_bundle_init, \ NULL, NULL, \ &greybus_bundle_config_##_num, \ POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + CONFIG_GREYBUS_BUNDLE_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_BUNDLE); diff --git a/subsys/greybus/platform/bus.c b/subsys/greybus/platform/bus.c index c1dc957..3b35097 100644 --- a/subsys/greybus/platform/bus.c +++ b/subsys/greybus/platform/bus.c @@ -38,7 +38,7 @@ static int greybus_init(const struct device *bus) { DEVICE_DT_INST_DEFINE(_num, \ greybus_init, NULL, NULL, \ &greybus_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + CONFIG_GREYBUS_SERVICE_INIT_PRIORITY, \ NULL); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS); diff --git a/subsys/greybus/platform/control.c b/subsys/greybus/platform/control.c index ab7d8ed..606f8e6 100644 --- a/subsys/greybus/platform/control.c +++ b/subsys/greybus/platform/control.c @@ -32,11 +32,6 @@ static int greybus_control_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_control_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_control_init); -} - #define DEFINE_GREYBUS_CONTROL(_num) \ \ BUILD_ASSERT(DT_PROP(DT_PARENT(DT_DRV_INST(_num)), bundle_class) \ @@ -54,9 +49,9 @@ static int defer_greybus_control_init(const struct device *dev) { }; \ \ DEVICE_DT_INST_DEFINE(_num, \ - defer_greybus_control_init, \ + greybus_control_init, \ NULL, NULL, \ &greybus_control_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + CONFIG_GREYBUS_CPORT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_CONTROL); diff --git a/subsys/greybus/platform/deferred-init.c b/subsys/greybus/platform/deferred-init.c deleted file mode 100644 index 8aa75d7..0000000 --- a/subsys/greybus/platform/deferred-init.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include - -/* - * FIXME: currently, Zephyr does not guarantee that parent DeviceTree nodes are - * initialized before child DeviceTree nodes. This has the unfortunate side - * effect of pushing-off device initialization to the application. - * It's possible that Zephyr may initialize things in the correct order if - * phandles are used instead, but that isn't clear at this point. - * - * E: greybus bundle: failed to get driver_api for device 'GREYBUS_0' - * E: greybus bundle: failed to get driver_api for device 'GREYBUS_0' - * I: probed greybus: 0 major: 0 minor: 1 - * I: probed cport 0: class: 0 protocol: 0 - * I: probed cport 0: class: 10 protocol: 2 - * E: failed to get driver_api for device 'GREYBUS_0' - * E: greybus string: driver_api was NULL - * E: greybus string: driver_api was NULL - * E: Cannot create zeth (-1) - * *** Booting Zephyr OS build zephyr-v2.3.0-733-g5217cd775382 *** - * I: Initializing network - * I: IPv4 address: 192.0.2.1 - * I: test_main(): ahoy! - * I: IPv6 address: fe80::5eff:fe00:533b - * I: IPv6 address: fe80::5eff:fe00:533b - * ^C - * - * pabigot is working on a PR to address this, which reorders custom - * elf-sections at link-time in order to create the proper order. - * - * See https://github.com/zephyrproject-rtos/zephyr/pull/26616 for details. - */ - -struct definit { - struct device *dev; - int (*init)(struct device *); -}; -static size_t definits_size; -static struct definit *definits; - -int gb_service_defer_init(struct device *dev, int (*init)(struct device *)) { - size_t n = definits_size; - struct definit *tmp; - - tmp = realloc(definits, (n + 1) * sizeof(*tmp)); - if (NULL == tmp) { - return -ENOMEM; - } - - definits = tmp; - definits[n].dev = dev; - definits[n].init = init; - - definits_size++; - - return 0; -} - -int gb_service_deferred_init(void) { - int r = 0; - int rr = 0; - struct device *dev; - int (*init)(struct device *); - - for(size_t i = 0; i < definits_size; ++i) { - - dev = definits[i].dev; - init = definits[i].init; - - r = init(dev); - if (r < 0) { - if (0 == rr) { - rr = r; - } - } - } - - if (NULL != definits) { - free(definits); - definits = NULL; - definits_size = 0; - } - - return rr; -} - diff --git a/subsys/greybus/platform/gpio.c b/subsys/greybus/platform/gpio.c index e0e67ef..d5e34d1 100644 --- a/subsys/greybus/platform/gpio.c +++ b/subsys/greybus/platform/gpio.c @@ -124,11 +124,6 @@ static int greybus_gpio_control_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_gpio_control_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_gpio_control_init); -} - #define DEFINE_GREYBUS_GPIO_CONTROL(_num) \ \ BUILD_ASSERT(DT_PROP(DT_PARENT(DT_DRV_INST(_num)), bundle_class) \ @@ -152,9 +147,9 @@ static int defer_greybus_gpio_control_init(const struct device *dev) { greybus_gpio_control_data_##_num; \ \ DEVICE_DT_INST_DEFINE(_num, \ - defer_greybus_gpio_control_init, NULL, \ + greybus_gpio_control_init, NULL, \ &greybus_gpio_control_data_##_num, \ &greybus_gpio_control_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + CONFIG_GREYBUS_CPORT_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_GPIO_CONTROL); diff --git a/subsys/greybus/platform/i2c.c b/subsys/greybus/platform/i2c.c index 75518c9..ddba83d 100644 --- a/subsys/greybus/platform/i2c.c +++ b/subsys/greybus/platform/i2c.c @@ -61,11 +61,6 @@ static int greybus_i2c_control_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_i2c_control_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_i2c_control_init); -} - #define DEFINE_GREYBUS_I2C_CONTROL(_num) \ \ BUILD_ASSERT(DT_PROP(DT_PARENT(DT_DRV_INST(_num)), bundle_class) \ @@ -89,9 +84,9 @@ static int defer_greybus_i2c_control_init(const struct device *dev) { greybus_i2c_control_data_##_num; \ \ DEVICE_INIT(i2c_i2c_control_##_num, "GBI2C_" #_num, \ - defer_greybus_i2c_control_init, \ + greybus_i2c_control_init, \ &greybus_i2c_control_data_##_num, \ &greybus_i2c_control_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE); + CONFIG_GREYBUS_CPORT_INIT_PRIORITY); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_I2C_CONTROL); diff --git a/subsys/greybus/platform/interface.c b/subsys/greybus/platform/interface.c index 31f37d3..a5ac29c 100644 --- a/subsys/greybus/platform/interface.c +++ b/subsys/greybus/platform/interface.c @@ -33,12 +33,6 @@ static int greybus_interface_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_interface_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_interface_init); -} - - #define DEFINE_GREYBUS_INTERFACE(_num) \ \ static const struct greybus_interface_config \ @@ -55,9 +49,9 @@ static int defer_greybus_interface_init(const struct device *dev) { }; \ \ DEVICE_DT_INST_DEFINE(_num, \ - defer_greybus_interface_init, \ + greybus_interface_init, \ NULL, NULL, \ &greybus_interface_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + CONFIG_GREYBUS_INTERFACE_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_INTERFACE); diff --git a/subsys/greybus/platform/service.c b/subsys/greybus/platform/service.c index f2c425c..971d3ce 100644 --- a/subsys/greybus/platform/service.c +++ b/subsys/greybus/platform/service.c @@ -40,23 +40,23 @@ gb_transport_get_backend(void) return xport; } -int greybus_service_init(const struct device *bus) +static int greybus_service_init(const struct device *bus) { - int r; + int r; uint8_t *mnfb; size_t mnfb_size; - unsigned int *cports = NULL; + unsigned int *cports = NULL; - LOG_DBG("Greybus initializing.."); - - r = gb_service_deferred_init(); - if (r < 0) { - LOG_ERR("gb_service_deferred_init() failed: %d", r); - goto out; + if (xport != NULL) { + LOG_ERR("service already initialized"); + return -EALREADY; } + LOG_DBG("Greybus initializing.."); + bus = device_get_binding(GREYBUS_BUS_NAME); if (NULL == bus) { + r = -ENODEV; LOG_ERR("failed to get " GREYBUS_BUS_NAME " device"); goto out; } @@ -114,4 +114,4 @@ int greybus_service_init(const struct device *bus) return r; } -//SYS_INIT(greybus_service_init, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY); +SYS_INIT(greybus_service_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/subsys/greybus/platform/spi.c b/subsys/greybus/platform/spi.c index b682c00..98bbc35 100644 --- a/subsys/greybus/platform/spi.c +++ b/subsys/greybus/platform/spi.c @@ -156,11 +156,6 @@ static int greybus_spi_control_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_spi_control_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_spi_control_init); -} - static int gb_plat_api_controller_config_response(const struct device *dev, struct gb_spi_master_config_response *rsp) { if (dev == NULL || NULL == rsp) { @@ -323,10 +318,10 @@ static const struct gb_platform_spi_api gb_platform_spi_api = { greybus_spi_control_data_##_num; \ \ DEVICE_DT_INST_DEFINE(_num, \ - defer_greybus_spi_control_init, \ + greybus_spi_control_init, \ NULL, &greybus_spi_control_data_##_num, \ &greybus_spi_control_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + CONFIG_GREYBUS_CPORT_INIT_PRIORITY, \ &gb_platform_spi_api); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_SPI_CONTROL); diff --git a/subsys/greybus/platform/string.c b/subsys/greybus/platform/string.c index 3b314b7..0d60491 100644 --- a/subsys/greybus/platform/string.c +++ b/subsys/greybus/platform/string.c @@ -29,11 +29,6 @@ static int greybus_string_init(const struct device *dev) { return 0; } -extern int gb_service_defer_init(const struct device *, int (*init)(const struct device *)); -static int defer_greybus_string_init(const struct device *dev) { - return gb_service_defer_init(dev, &greybus_string_init); -} - #define DEFINE_GREYBUS_STRING(_num) \ \ static const struct greybus_string_config \ @@ -45,8 +40,8 @@ static int defer_greybus_string_init(const struct device *dev) { }; \ \ DEVICE_DT_INST_DEFINE(_num, \ - defer_greybus_string_init, NULL, NULL, \ + greybus_string_init, NULL, NULL, \ &greybus_string_config_##_num, POST_KERNEL, \ - CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + CONFIG_GREYBUS_STRING_INIT_PRIORITY, NULL); DT_INST_FOREACH_STATUS_OKAY(DEFINE_GREYBUS_STRING); diff --git a/tests/subsys/greybus/gpio/src/gpio.c b/tests/subsys/greybus/gpio/src/gpio.c index 39f5a71..e914bf0 100644 --- a/tests/subsys/greybus/gpio/src/gpio.c +++ b/tests/subsys/greybus/gpio/src/gpio.c @@ -85,9 +85,6 @@ void test_greybus_setup(void) { *port = htons(PORT); - extern int greybus_service_init(const struct device *); - greybus_service_init(NULL); - gpio_dev = (struct device *)device_get_binding(GPIO_DEV_NAME); zassert_not_equal(gpio_dev, NULL, "failed to get device binding for " GPIO_DEV_NAME);