diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2022-07-20 07:50:41 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-08-09 09:39:13 +0200 |
commit | 291dd36e4adec5ad2d873123c1eca2b990d67b7b (patch) | |
tree | 9209d21402eb9b33dba60c1d28b0b1994fabbd01 /common | |
parent | 2fc6302090cd77c368cf784adf91dc2beb71764c (diff) | |
download | barebox-291dd36e4adec5ad2d873123c1eca2b990d67b7b.tar.gz barebox-291dd36e4adec5ad2d873123c1eca2b990d67b7b.tar.xz |
bootsource: allow DT aliases and bootrom numbering to differ
So far, we had no explicit mapping table between bootsource_instance
and device id numbering in barebox and mostly depended on DT aliases
reflecting the numbering of the bootrom. Add a new bootsource_set()
that optionally consults a mapping table in the DT to arrive at the
correct numbers.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.barebox.org/20220720055042.3510276-3-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r-- | common/bootsource.c | 101 |
1 files changed, 75 insertions, 26 deletions
diff --git a/common/bootsource.c b/common/bootsource.c index c37da38f7f..70bac945de 100644 --- a/common/bootsource.c +++ b/common/bootsource.c @@ -33,6 +33,34 @@ static enum bootsource bootsource = BOOTSOURCE_UNKNOWN; static int bootsource_instance = BOOTSOURCE_INSTANCE_UNKNOWN; const char *bootsource_alias_name = NULL; +const char *bootsource_get_alias_stem(enum bootsource src) +{ + switch (src) { + /* + * For I2C and SPI EEPROMs we set the stem to be 'i2c' + * and 'spi' correspondingly. The resulting alias will + * be pointing at the controller said EEPROM is + * attached to. + * + * NOTE: This code assumes single bootable EEPROM per + * controller + */ + case BOOTSOURCE_I2C_EEPROM: + return bootsource_str[BOOTSOURCE_I2C]; + case BOOTSOURCE_SPI_EEPROM: + case BOOTSOURCE_SPI_NOR: + return bootsource_str[BOOTSOURCE_SPI]; + case BOOTSOURCE_SERIAL: /* FALLTHROUGH */ + case BOOTSOURCE_I2C: /* FALLTHROUGH */ + case BOOTSOURCE_MMC: /* FALLTHROUGH */ + case BOOTSOURCE_SPI: /* FALLTHROUGH */ + case BOOTSOURCE_CAN: + return bootsource_str[src]; + default: + return NULL; + } +} + /** * bootsource_get_alias_name() - Get the name of the bootsource alias * @@ -58,33 +86,9 @@ char *bootsource_get_alias_name(void) if (bootsource_alias_name) return strdup(bootsource_alias_name); - switch (bootsource) { - /* - * For I2C and SPI EEPROMs we set the stem to be 'i2c' - * and 'spi' correspondingly. The resulting alias will - * be pointing at the controller said EEPROM is - * attached to. - * - * NOTE: This code assumes single bootable EEPROM per - * controller - */ - case BOOTSOURCE_I2C_EEPROM: - stem = bootsource_str[BOOTSOURCE_I2C]; - break; - case BOOTSOURCE_SPI_EEPROM: - case BOOTSOURCE_SPI_NOR: - stem = bootsource_str[BOOTSOURCE_SPI]; - break; - case BOOTSOURCE_SERIAL: /* FALLTHROUGH */ - case BOOTSOURCE_I2C: /* FALLTHROUGH */ - case BOOTSOURCE_MMC: /* FALLTHROUGH */ - case BOOTSOURCE_SPI: /* FALLTHROUGH */ - case BOOTSOURCE_CAN: - stem = bootsource_str[bootsource]; - break; - default: + stem = bootsource_get_alias_stem(bootsource); + if (!stem) return NULL; - } /* * We expect SoC specific bootsource detection code to properly @@ -123,6 +127,51 @@ void bootsource_set_raw_instance(int instance) pr_setenv("bootsource_instance", "%d", instance); } +int bootsource_of_alias_xlate(enum bootsource src, int instance) +{ + char alias[sizeof("barebox,bootsource-harddisk4294967295")]; + const char *bootsource_stem; + struct device_node *np; + int alias_id; + + if (!IS_ENABLED(CONFIG_OFDEVICE)) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + if (src == BOOTSOURCE_UNKNOWN || + instance == BOOTSOURCE_INSTANCE_UNKNOWN) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + bootsource_stem = bootsource_get_alias_stem(src); + if (!bootsource_stem) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + scnprintf(alias, sizeof(alias), "barebox,bootsource-%s%u", + bootsource_stem, instance); + + np = of_find_node_by_alias(NULL, alias); + if (!np) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + alias_id = of_alias_get_id(np, bootsource_stem); + if (alias_id < 0) + return BOOTSOURCE_INSTANCE_UNKNOWN; + + return alias_id; +} + +int bootsource_set(enum bootsource src, int instance) +{ + int alias_id; + + alias_id = bootsource_of_alias_xlate(src, instance); + if (alias_id == BOOTSOURCE_INSTANCE_UNKNOWN) + alias_id = instance; + + bootsource_set_raw(src, alias_id); + + return alias_id; +} + enum bootsource bootsource_get(void) { return bootsource; |