]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-imx/cmd_bmode.c
Merge git://www.denx.de/git/u-boot-marvell
[people/ms/u-boot.git] / arch / arm / mach-imx / cmd_bmode.c
1 /*
2 * Copyright (C) 2012 Boundary Devices Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6 #include <common.h>
7 #include <linux/errno.h>
8 #include <asm/io.h>
9 #include <asm/mach-imx/boot_mode.h>
10 #include <malloc.h>
11 #include <command.h>
12
13 static const struct boot_mode *modes[2];
14
15 static const struct boot_mode *search_modes(char *arg)
16 {
17 int i;
18
19 for (i = 0; i < ARRAY_SIZE(modes); i++) {
20 const struct boot_mode *p = modes[i];
21 if (p) {
22 while (p->name) {
23 if (!strcmp(p->name, arg))
24 return p;
25 p++;
26 }
27 }
28 }
29 return NULL;
30 }
31
32 static int create_usage(char *dest)
33 {
34 int i;
35 int size = 0;
36
37 for (i = 0; i < ARRAY_SIZE(modes); i++) {
38 const struct boot_mode *p = modes[i];
39 if (p) {
40 while (p->name) {
41 int len = strlen(p->name);
42 if (dest) {
43 memcpy(dest, p->name, len);
44 dest += len;
45 *dest++ = '|';
46 }
47 size += len + 1;
48 p++;
49 }
50 }
51 }
52 if (dest)
53 memcpy(dest - 1, " [noreset]", 11); /* include trailing 0 */
54 size += 10;
55 return size;
56 }
57
58 static int do_boot_mode(cmd_tbl_t *cmdtp, int flag, int argc,
59 char * const argv[])
60 {
61 const struct boot_mode *p;
62 int reset_requested = 1;
63
64 if (argc < 2)
65 return CMD_RET_USAGE;
66 p = search_modes(argv[1]);
67 if (!p)
68 return CMD_RET_USAGE;
69 if (argc == 3) {
70 if (strcmp(argv[2], "noreset"))
71 return CMD_RET_USAGE;
72 reset_requested = 0;
73 }
74
75 boot_mode_apply(p->cfg_val);
76 if (reset_requested && p->cfg_val)
77 do_reset(NULL, 0, 0, NULL);
78 return 0;
79 }
80
81 U_BOOT_CMD(
82 bmode, 3, 0, do_boot_mode,
83 NULL,
84 "");
85
86 void add_board_boot_modes(const struct boot_mode *p)
87 {
88 int size;
89 char *dest;
90
91 cmd_tbl_t *entry = ll_entry_get(cmd_tbl_t, bmode, cmd);
92
93 if (entry->usage) {
94 free(entry->usage);
95 entry->usage = NULL;
96 }
97
98 modes[0] = p;
99 modes[1] = soc_boot_modes;
100 size = create_usage(NULL);
101 dest = malloc(size);
102 if (dest) {
103 create_usage(dest);
104 entry->usage = dest;
105 }
106 }