summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2022-07-20 07:50:41 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-08-09 09:39:13 +0200
commit291dd36e4adec5ad2d873123c1eca2b990d67b7b (patch)
tree9209d21402eb9b33dba60c1d28b0b1994fabbd01 /common
parent2fc6302090cd77c368cf784adf91dc2beb71764c (diff)
downloadbarebox-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.c101
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;