barebox has extensive support for manipulating the device tree it passes to Linux, which can be useful during bringup.
Let's collect some of this functionality into a safemode command in an attempt to gather that knowledge at one place. Signed-off-by: Ahmad Fatoum <[email protected]> --- commands/Kconfig | 7 +++ commands/Makefile | 1 + commands/safemode.c | 109 +++++++++++++++++++++++++++++++++++++++++ drivers/mci/mci-core.c | 6 +-- include/mci.h | 5 ++ 5 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 commands/safemode.c diff --git a/commands/Kconfig b/commands/Kconfig index 6bfc1499afdb..af3b65f35547 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -226,6 +226,13 @@ config CMD_MEMINFO system bytes = 282616 in use bytes = 274752 +config CMD_SAFEMODE + tristate + prompt "safemode" + select CMD_OF_PROPERTY + help + Apply safe-mode defaults for next kernel boot. + config CMD_CHECKLEAK tristate prompt "checkleak" diff --git a/commands/Makefile b/commands/Makefile index e7d65163ad80..657fb426ba3e 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_CMD_MW) += mw.o obj-$(CONFIG_CMD_MEMCMP) += memcmp.o obj-$(CONFIG_CMD_MEMCPY) += memcpy.o obj-$(CONFIG_CMD_MEMSET) += memset.o +obj-$(CONFIG_CMD_SAFEMODE) += safemode.o obj-$(CONFIG_CMD_EDIT) += edit.o obj-$(CONFIG_CMD_ETHLOG) += ethlog.o obj-$(CONFIG_CMD_EXEC) += exec.o diff --git a/commands/safemode.c b/commands/safemode.c new file mode 100644 index 000000000000..9016869bc56e --- /dev/null +++ b/commands/safemode.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <command.h> +#include <getopt.h> +#include <mci.h> +#include <xfuncs.h> +#include <stdio.h> +#include <environment.h> + +#define SAFEMODE_MMC BIT(0) +#define SAFEMODE_CONSOLE BIT(1) +#define SAFEMODE_BOOT BIT(2) + +#define run_command_fmt(args...) ({ \ + char *__buf = xasprintf(args); \ + if (verbose) \ + printf("%s\n", __buf); \ + int __ret = run_command(__buf); \ + free(__buf); \ + __ret; \ +}) + +static void safemode_mmc(int verbose) +{ + struct mci *mci; + + for_each_mci(mci) { + const char *dev = dev_name(&mci->dev); + + run_command_fmt("%s.broken_cd=1", dev); + run_command_fmt("of_property -fs %s max-frequency '<52000000>'", dev); + run_command_fmt("of_property -fs %s pinctrl-names default", dev); + } +} + +static void safemode_console(int verbose) +{ + run_command_fmt("global.bootm.earlycon=1"); +} + +static void safemode_boot(int verbose) +{ + if (IS_ENABLED(CONFIG_WATCHDOG)) + run_command_fmt("global.boot.watchdog_timeout=0"); + + if (IS_ENABLED(CONFIG_BOOTCHOOSER) && + getenv_nonempty("global.bootchooser.targets")) + run_command_fmt("bootchooser -a default -p defaut"); + + if (IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL)) + run_command_fmt("global.linux.efi.handover=1"); +} + +static int do_safemode(int argc, char *argv[]) +{ + unsigned safemode = 0; + int opt, verbose = 0; + + while((opt = getopt(argc, argv, "mcbv")) > 0) { + switch(opt) { + case 'm': + safemode |= SAFEMODE_MMC; + break; + case 'c': + safemode |= SAFEMODE_CONSOLE; + break; + case 'b': + safemode |= SAFEMODE_BOOT; + break; + case 'v': + verbose++; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + if (argc != optind) + return COMMAND_ERROR_USAGE; + + if (!safemode) + safemode = ~0; + + if (safemode & SAFEMODE_MMC) + safemode_mmc(verbose); + if (safemode & SAFEMODE_CONSOLE) + safemode_console(verbose); + if (safemode & SAFEMODE_BOOT) + safemode_boot(verbose); + + return 0; +} + +BAREBOX_CMD_HELP_START(safemode) +BAREBOX_CMD_HELP_TEXT("Apply safe-mode defaults for next kernel boot.") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-m", "safe mmc settings") +BAREBOX_CMD_HELP_OPT ("-c", "safe console settings") +BAREBOX_CMD_HELP_OPT ("-b", "safe boot defaults") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(safemode) + .cmd = do_safemode, + BAREBOX_CMD_DESC("enable safe mode") + BAREBOX_CMD_OPTS("[-mcb]") + BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP) + BAREBOX_CMD_HELP(cmd_safemode_help) +BAREBOX_CMD_END diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 57825bc849a1..ef676deb7c7f 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -40,11 +40,7 @@ static inline u32 unstuff_bits(const u32 *resp, int start, int size) return __res & __mask; } -static DEFINE_DEV_CLASS(mmc_class, "mmc"); - -#define for_each_mci(mci) \ - class_for_each_container_of_device(&mmc_class, mci, dev) - +DEFINE_DEV_CLASS(mmc_class, "mmc"); /** * @file diff --git a/include/mci.h b/include/mci.h index 3db33f914236..3f2b63598568 100644 --- a/include/mci.h +++ b/include/mci.h @@ -798,4 +798,9 @@ static inline bool mmc_card_hs200(struct mci *mci) return mci->host->ios.timing == MMC_TIMING_MMC_HS200; } +extern struct class mmc_class; + +#define for_each_mci(mci) \ + class_for_each_container_of_device(&mmc_class, mci, dev) + #endif /* _MCI_H_ */ -- 2.47.3
