device: Refactor device structures

When the device driver model got introduced, there were no concept of
SYS_INIT() which can be seen as software service. These were introduced
afterwards and reusing the device infrastructure for simplicity.
However, it meant to allocate a bit too much for something that only
required an initialization function to be called at right time.

Thus refactoring the devices structures relevantly:
- introducing struct init_entry which is a generic init end-point
- struct deviceconfig is removed and struct device owns everything now.
- SYS_INIT() generates only a struct init_entry via calling
  INIT_ENTRY_DEFINE()
- DEVICE_AND_API_INIT() generates a struct device and calls
  INIT_ENTRY_DEFINE()
- init objects sections are in ROM
- device objects sections are in RAM (but will end up in ROM once they
  will be 'constified')

It also generate a tiny memory gain on both ROM and RAM, which is nice.

Perhaps kernel/device.c could be renamed to something more relevant.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2020-03-09 11:02:20 +01:00 committed by Carles Cufí
commit 8d7bb8ffd8
11 changed files with 304 additions and 250 deletions

View file

@ -10,18 +10,18 @@
#include <string.h>
#include <device.h>
extern struct device __device_init_start[];
extern struct device __device_start[];
extern struct device __device_PRE_KERNEL_1_start[];
extern struct device __device_PRE_KERNEL_2_start[];
extern struct device __device_POST_KERNEL_start[];
extern struct device __device_APPLICATION_start[];
extern struct device __device_init_end[];
extern struct device __device_end[];
#ifdef CONFIG_SMP
extern struct device __device_SMP_start[];
#endif
static struct device *config_levels[] = {
static struct device *levels[] = {
__device_PRE_KERNEL_1_start,
__device_PRE_KERNEL_2_start,
__device_POST_KERNEL_start,
@ -30,20 +30,20 @@ static struct device *config_levels[] = {
__device_SMP_start,
#endif
/* End marker */
__device_init_end,
__device_end,
};
static bool device_get_config_level(const struct shell *shell, int level)
{
struct device *info;
struct device *dev;
bool devices = false;
for (info = config_levels[level]; info < config_levels[level+1];
info++) {
if (info->driver_api != NULL) {
for (dev = levels[level]; dev < levels[level+1]; dev++) {
if (dev->driver_api != NULL) {
devices = true;
shell_fprintf(shell, SHELL_NORMAL, "- %s\n",
info->config->name);
dev->config->name);
}
}
return devices;
@ -86,27 +86,30 @@ static int cmd_device_levels(const struct shell *shell,
static int cmd_device_list(const struct shell *shell,
size_t argc, char **argv)
{
struct device *info;
struct device *dev;
ARG_UNUSED(argc);
ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL, "devices:\n");
for (info = __device_init_start; info != __device_init_end; info++) {
if (info->driver_api != NULL) {
shell_fprintf(shell, SHELL_NORMAL, "- %s",
info->config->name);
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
u32_t state = DEVICE_PM_ACTIVE_STATE;
int err;
err = device_get_power_state(info, &state);
if (!err) {
shell_fprintf(shell, SHELL_NORMAL, " (%s)",
device_pm_state_str(state));
}
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
shell_fprintf(shell, SHELL_NORMAL, "\n");
for (dev = __device_start; dev != __device_end; dev++) {
if (dev->driver_api == NULL) {
continue;
}
shell_fprintf(shell, SHELL_NORMAL, "- %s", dev->config->name);
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
u32_t state = DEVICE_PM_ACTIVE_STATE;
int err;
err = device_get_power_state(dev, &state);
if (!err) {
shell_fprintf(shell, SHELL_NORMAL, " (%s)",
device_pm_state_str(state));
}
#endif /* CONFIG_DEVICE_POWER_MANAGEMENT */
shell_fprintf(shell, SHELL_NORMAL, "\n");
}
return 0;