From 3e066bcaefb51adcf5c0594d42abe145f701dbeb Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Thu, 20 Dec 2018 16:12:51 +0800 Subject: reset: MedaiTek: add reset controller driver for MediaTek SoCs This patch adds reset controller driver for MediaTek SoCs. Signed-off-by: Ryder Lee Signed-off-by: Weijie Gao --- include/dt-bindings/reset/mtk-reset.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/dt-bindings/reset/mtk-reset.h (limited to 'include') diff --git a/include/dt-bindings/reset/mtk-reset.h b/include/dt-bindings/reset/mtk-reset.h new file mode 100644 index 00000000000..5f0a74f280c --- /dev/null +++ b/include/dt-bindings/reset/mtk-reset.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + */ + +#ifndef _DT_BINDINGS_MTK_RESET_H_ +#define _DT_BINDINGS_MTK_RESET_H_ + +/* ETHSYS */ +#define ETHSYS_PPE_RST 31 +#define ETHSYS_EPHY_RST 24 +#define ETHSYS_GMAC_RST 23 +#define ETHSYS_ESW_RST 16 +#define ETHSYS_FE_RST 6 +#define ETHSYS_MCM_RST 2 +#define ETHSYS_SYS_RST 0 + +#endif /* _DT_BINDINGS_MTK_RESET_H_ */ -- cgit v1.3.1 From 8505cdde8eb3afa8254e864f48574bc1d52c01f2 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Thu, 20 Dec 2018 16:12:56 +0800 Subject: arm: MediaTek: add ethernet support for MT7623 boards Enable ethernet related configs to mt7623n_bpir2_defconfig. Add default IP addresses. Enable noncached memory region required by ethernet driver. Signed-off-by: Mark Lee --- configs/mt7623n_bpir2_defconfig | 6 ++++++ include/configs/mt7623.h | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'include') diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig index ae4fb280dc4..53ac63e19c9 100644 --- a/configs/mt7623n_bpir2_defconfig +++ b/configs/mt7623n_bpir2_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2" +CONFIG_NET_RANDOM_ETHADDR=y CONFIG_REGMAP=y CONFIG_SYSCON=y # CONFIG_BLOCK_CACHE is not set @@ -37,6 +38,11 @@ CONFIG_DM_MMC=y # CONFIG_MMC_QUIRKS is not set CONFIG_MMC_HS400_SUPPORT=y CONFIG_MMC_MTK=y +CONFIG_DM_RESET=y +CONFIG_RESET_MEDIATEK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_MT7623=y diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h index ba763501cf2..5129c83da8f 100644 --- a/include/configs/mt7623.h +++ b/include/configs/mt7623.h @@ -24,6 +24,7 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN SZ_4M +#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M /* Environment */ #define CONFIG_ENV_SIZE SZ_4K @@ -53,4 +54,8 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ FDT_HIGH +/* Ethernet */ +#define CONFIG_IPADDR 192.168.1.1 +#define CONFIG_SERVERIP 192.168.1.2 + #endif -- cgit v1.3.1 From d7fe0ad2850a1bdba6d5582d8a6b871cd4ace8de Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Thu, 20 Dec 2018 16:12:57 +0800 Subject: arm: MediaTek: add ethernet support for MT7629 boards Enable ethernet related configs to mt7629_rfb_defconfig. Add default IP addresses. Enable noncached memory region required by ethernet driver. Signed-off-by: Mark Lee --- configs/mt7629_rfb_defconfig | 5 +++++ include/configs/mt7629.h | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'include') diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig index 1729d13c3d3..fdd5f575774 100644 --- a/configs/mt7629_rfb_defconfig +++ b/configs/mt7629_rfb_defconfig @@ -32,6 +32,7 @@ CONFIG_CMD_PING=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb" CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents" +CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_REGMAP=y CONFIG_SPL_REGMAP=y @@ -51,6 +52,10 @@ CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y +CONFIG_DM_RESET=y +CONFIG_RESET_MEDIATEK=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_MT7629=y diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h index a665a5eb7f2..9910d8c89a6 100644 --- a/include/configs/mt7629.h +++ b/include/configs/mt7629.h @@ -24,6 +24,7 @@ /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN SZ_4M +#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M /* Environment */ #define CONFIG_ENV_SIZE SZ_4K @@ -54,4 +55,8 @@ /* DRAM */ #define CONFIG_SYS_SDRAM_BASE 0x40000000 +/* Ethernet */ +#define CONFIG_IPADDR 192.168.1.1 +#define CONFIG_SERVERIP 192.168.1.2 + #endif -- cgit v1.3.1 From 5bb409c1ba4aea00b5dbd834f0e217a759c1041c Mon Sep 17 00:00:00 2001 From: Manivannan Sadhasivam Date: Thu, 27 Dec 2018 19:04:03 +0530 Subject: include: configs: Add gunzip size for HiKey board Default 8MB gunzip size is not enough to load the release kernel, hence fix 64MB size for uncompressing the kernel. Signed-off-by: Manivannan Sadhasivam Reviewed-by: Simon Glass Reviewed-by: Simon Glass --- include/configs/hikey.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/configs/hikey.h b/include/configs/hikey.h index 1376d6155de..572a52fad59 100644 --- a/include/configs/hikey.h +++ b/include/configs/hikey.h @@ -18,6 +18,8 @@ #define CONFIG_REMAKE_ELF +#define CONFIG_SYS_BOOTM_LEN SZ_64M + /* Physical Memory Map */ /* CONFIG_SYS_TEXT_BASE needs to align with where ATF loads bl33.bin */ -- cgit v1.3.1 From 2432dace1199618463b6dfbd8f30dd6d14c8037d Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 27 Dec 2018 17:03:27 +0100 Subject: omap3: igep00x0: Remove USB support due DM_USB deadline The USB support for this board was never really tested, in fact, the presence of these options are more a copy & paste error from the Beagleboard than a feature that really was used. As doesn't work, remove for now. If someone at some point want to add this support he'll need to migrate the board to use CONFIG_DM_USB instead. Signed-off-by: Enric Balletbo i Serra --- configs/igep00x0_defconfig | 5 ----- include/configs/omap3_igep00x0.h | 10 ---------- 2 files changed, 15 deletions(-) (limited to 'include') diff --git a/configs/igep00x0_defconfig b/configs/igep00x0_defconfig index 330350c32ac..ba32609eab2 100644 --- a/configs/igep00x0_defconfig +++ b/configs/igep00x0_defconfig @@ -42,11 +42,6 @@ CONFIG_SMC911X_32_BIT=y CONFIG_CONS_INDEX=3 CONFIG_SPI=y CONFIG_OMAP3_SPI=y -CONFIG_USB=y -CONFIG_USB_MUSB_UDC=y -CONFIG_USB_OMAP3=y -CONFIG_TWL4030_USB=y -CONFIG_USB_GADGET=y CONFIG_FAT_WRITE=y CONFIG_UBIFS_SILENCE_MSG=y CONFIG_BCH=y diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h index 775374cf288..521e1675e0e 100644 --- a/include/configs/omap3_igep00x0.h +++ b/include/configs/omap3_igep00x0.h @@ -32,16 +32,6 @@ #define GPIO_IGEP00X0_BOARD_DETECTION 28 #define GPIO_IGEP00X0_REVISION_DETECTION 129 -/* USB device configuration */ -#define CONFIG_USB_DEVICE 1 -#define CONFIG_USB_TTY 1 - -/* Change these to suit your needs */ -#define CONFIG_USBD_VENDORID 0x0451 -#define CONFIG_USBD_PRODUCTID 0x5678 -#define CONFIG_USBD_MANUFACTURER "Texas Instruments" -#define CONFIG_USBD_PRODUCT_NAME "IGEP" - #ifndef CONFIG_SPL_BUILD /* Environment */ -- cgit v1.3.1 From 6fb61445bb28a37397fdce5cb2d3f5ffd0e1a4e4 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 3 Dec 2018 22:54:19 +0100 Subject: common: command: Expose a generic helper to auto-complete sub commands Some commands have a table of sub-commands. With minor adjustments, complete_cmdv() is able to provide auto-completion for sub-commands (it's just about passing the table of commands instead of taking the global one). We rename this function into complete_subcmd() and implement complete_cmdv() as a wrapper around complete_subcmdv(). Signed-off-by: Boris Brezillon Reviewed-by: Tom Rini --- common/command.c | 20 ++++++++++++++++---- include/command.h | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/common/command.c b/common/command.c index 435824356b5..e13cb47ac18 100644 --- a/common/command.c +++ b/common/command.c @@ -161,11 +161,11 @@ int var_complete(int argc, char * const argv[], char last_char, int maxv, char * /*************************************************************************************/ -static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]) +int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc, + char * const argv[], char last_char, + int maxv, char *cmdv[]) { #ifdef CONFIG_CMDLINE - cmd_tbl_t *cmdtp = ll_entry_start(cmd_tbl_t, cmd); - const int count = ll_entry_count(cmd_tbl_t, cmd); const cmd_tbl_t *cmdend = cmdtp + count; const char *p; int len, clen; @@ -193,7 +193,7 @@ static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv /* more than one arg or one but the start of the next */ if (argc > 1 || last_char == '\0' || isblank(last_char)) { - cmdtp = find_cmd(argv[0]); + cmdtp = find_cmd_tbl(argv[0], cmdtp, count); if (cmdtp == NULL || cmdtp->complete == NULL) { cmdv[0] = NULL; return 0; @@ -238,6 +238,18 @@ static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv #endif } +static int complete_cmdv(int argc, char * const argv[], char last_char, + int maxv, char *cmdv[]) +{ +#ifdef CONFIG_CMDLINE + return complete_subcmdv(ll_entry_start(cmd_tbl_t, cmd), + ll_entry_count(cmd_tbl_t, cmd), argc, argv, + last_char, maxv, cmdv); +#else + return 0; +#endif +} + static int make_argv(char *s, int argvsz, char *argv[]) { int argc = 0; diff --git a/include/command.h b/include/command.h index 200c7a5e9f4..89efcecfa92 100644 --- a/include/command.h +++ b/include/command.h @@ -54,6 +54,9 @@ int _do_help (cmd_tbl_t *cmd_start, int cmd_items, cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); cmd_tbl_t *find_cmd(const char *cmd); cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len); +int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc, + char * const argv[], char last_char, int maxv, + char *cmdv[]); extern int cmd_usage(const cmd_tbl_t *cmdtp); -- cgit v1.3.1 From 80a48dd47e3bf3ede676fae5a630cb6c80de3e69 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 3 Dec 2018 22:54:20 +0100 Subject: common: command: Rework the 'cmd is repeatable' logic The repeatable property is currently attached to the main command and sub-commands have no way to change the repeatable value (the ->repeatable field in sub-command entries is ignored). Replace the ->repeatable field by an extended ->cmd() hook (called ->cmd_rep()) which takes a new int pointer to store the repeatable cap of the command being executed. With this trick, we can let sub-commands decide whether they are repeatable or not. We also patch mmc and dtimg who are testing the ->repeatable field directly (they now use cmd_is_repeatable() instead), and fix the help entry manually since it doesn't use the U_BOOT_CMD() macro. Signed-off-by: Boris Brezillon Reviewed-by: Tom Rini --- cmd/dtimg.c | 2 +- cmd/help.c | 2 +- cmd/mmc.c | 4 ++-- common/command.c | 36 ++++++++++++++++++++++++++++++++---- include/command.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 84 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/cmd/dtimg.c b/cmd/dtimg.c index 65c8d101b98..ae7d82f26dd 100644 --- a/cmd/dtimg.c +++ b/cmd/dtimg.c @@ -116,7 +116,7 @@ static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (!cp || argc > cp->maxargs) return CMD_RET_USAGE; - if (flag == CMD_FLAG_REPEAT && !cp->repeatable) + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) return CMD_RET_SUCCESS; return cp->cmd(cmdtp, flag, argc, argv); diff --git a/cmd/help.c b/cmd/help.c index 503fa632e74..fa2010c67eb 100644 --- a/cmd/help.c +++ b/cmd/help.c @@ -29,7 +29,7 @@ U_BOOT_CMD( /* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names */ ll_entry_declare(cmd_tbl_t, question_mark, cmd) = { - "?", CONFIG_SYS_MAXARGS, 1, do_help, + "?", CONFIG_SYS_MAXARGS, cmd_always_repeatable, do_help, "alias for 'help'", #ifdef CONFIG_SYS_LONGHELP "" diff --git a/cmd/mmc.c b/cmd/mmc.c index 9951315f911..8bc3648193c 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -256,7 +256,7 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag, if (cp == NULL || argc > cp->maxargs) return CMD_RET_USAGE; - if (flag == CMD_FLAG_REPEAT && !cp->repeatable) + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) return CMD_RET_SUCCESS; mmc = init_mmc_device(curr_device, false); @@ -916,7 +916,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (cp == NULL || argc > cp->maxargs) return CMD_RET_USAGE; - if (flag == CMD_FLAG_REPEAT && !cp->repeatable) + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp)) return CMD_RET_SUCCESS; if (curr_device < 0) { diff --git a/common/command.c b/common/command.c index e13cb47ac18..19f0534a76e 100644 --- a/common/command.c +++ b/common/command.c @@ -501,6 +501,30 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size) } #endif +int cmd_always_repeatable(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[], int *repeatable) +{ + *repeatable = 1; + + return cmdtp->cmd(cmdtp, flag, argc, argv); +} + +int cmd_never_repeatable(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[], int *repeatable) +{ + *repeatable = 0; + + return cmdtp->cmd(cmdtp, flag, argc, argv); +} + +int cmd_discard_repeatable(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int repeatable; + + return cmdtp->cmd_rep(cmdtp, flag, argc, argv, &repeatable); +} + /** * Call a command function. This should be the only route in U-Boot to call * a command, so that we can track whether we are waiting for input or @@ -510,13 +534,15 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size) * @param flag Some flags normally 0 (see CMD_FLAG_.. above) * @param argc Number of arguments (arg 0 must be the command text) * @param argv Arguments + * @param repeatable Can the command be repeated * @return 0 if command succeeded, else non-zero (CMD_RET_...) */ -static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], + int *repeatable) { int result; - result = (cmdtp->cmd)(cmdtp, flag, argc, argv); + result = cmdtp->cmd_rep(cmdtp, flag, argc, argv, repeatable); if (result) debug("Command failed, result=%d\n", result); return result; @@ -553,12 +579,14 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[], /* If OK so far, then do the command */ if (!rc) { + int newrep; + if (ticks) *ticks = get_timer(0); - rc = cmd_call(cmdtp, flag, argc, argv); + rc = cmd_call(cmdtp, flag, argc, argv, &newrep); if (ticks) *ticks = get_timer(*ticks); - *repeatable &= cmdtp->repeatable; + *repeatable &= newrep; } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp); diff --git a/include/command.h b/include/command.h index 89efcecfa92..bb93f022c51 100644 --- a/include/command.h +++ b/include/command.h @@ -29,7 +29,16 @@ struct cmd_tbl_s { char *name; /* Command Name */ int maxargs; /* maximum number of arguments */ - int repeatable; /* autorepeat allowed? */ + /* + * Same as ->cmd() except the command + * tells us if it can be repeated. + * Replaces the old ->repeatable field + * which was not able to make + * repeatable property different for + * the main command and sub-commands. + */ + int (*cmd_rep)(struct cmd_tbl_s *cmd, int flags, int argc, + char * const argv[], int *repeatable); /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); char *usage; /* Usage message (short) */ @@ -60,6 +69,19 @@ int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc, extern int cmd_usage(const cmd_tbl_t *cmdtp); +/* Dummy ->cmd and ->cmd_rep wrappers. */ +int cmd_always_repeatable(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[], int *repeatable); +int cmd_never_repeatable(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[], int *repeatable); +int cmd_discard_repeatable(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]); + +static inline bool cmd_is_repeatable(cmd_tbl_t *cmdtp) +{ + return cmdtp->cmd_rep == cmd_always_repeatable; +} + #ifdef CONFIG_AUTO_COMPLETE extern int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]); extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp); @@ -188,16 +210,28 @@ int board_run_command(const char *cmdline); #endif #ifdef CONFIG_CMDLINE +#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \ + _usage, _help, _comp) \ + { #_name, _maxargs, _cmd_rep, cmd_discard_repeatable, \ + _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) } + #define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ _usage, _help, _comp) \ - { #_name, _maxargs, _rep, _cmd, _usage, \ - _CMD_HELP(_help) _CMD_COMPLETE(_comp) } + { #_name, _maxargs, \ + _rep ? cmd_always_repeatable : cmd_never_repeatable, \ + _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) } #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \ ll_entry_declare(cmd_tbl_t, _name, cmd) = \ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ _usage, _help, _comp); +#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \ + _help, _comp) \ + ll_entry_declare(cmd_tbl_t, _name, cmd) = \ + U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \ + _usage, _help, _comp) + #else #define U_BOOT_SUBCMD_START(name) static cmd_tbl_t name[] = {}; #define U_BOOT_SUBCMD_END @@ -209,15 +243,25 @@ int board_run_command(const char *cmdline); _cmd(NULL, 0, 0, NULL); \ return 0; \ } + +#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \ + _usage, _help, _comp) \ + { #_name, _maxargs, 0 ? _cmd_rep : NULL, NULL, _usage, \ + _CMD_HELP(_help) _CMD_COMPLETE(_comp) } + #define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, \ _help, _comp) \ - { #_name, _maxargs, _rep, 0 ? _cmd : NULL, _usage, \ + { #_name, _maxargs, NULL, 0 ? _cmd : NULL, _usage, \ _CMD_HELP(_help) _CMD_COMPLETE(_comp) } #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \ _comp) \ _CMD_REMOVE(sub_ ## _name, _cmd) +#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \ + _help, _comp) \ + _CMD_REMOVE(sub_ ## _name, _cmd_rep) + #endif /* CONFIG_CMDLINE */ #define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \ -- cgit v1.3.1 From c0cf06e523cbe50dbf38d5c81d0595f5b8517f4a Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 3 Dec 2018 22:54:21 +0100 Subject: command: commands: Add macros to declare commands with subcmds Most cmd/xxx.c source files expose several commands through a single entry point. Some of them are doing the sub-command parsing manually in their do_() function, others are declaring a table of sub-commands and then use find_cmd_tbl() to delegate the request to the sub command handler. In either case, the amount of code to do that is not negligible and repetitive, not to mention that almost no commands are implementing the auto-completion hook, which means most u-boot commands lack auto-completion. Provide several macros to easily define commands exposing sub-commands. Signed-off-by: Boris Brezillon Reviewed-by: Tom Rini --- include/command.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'include') diff --git a/include/command.h b/include/command.h index bb93f022c51..461b17447c0 100644 --- a/include/command.h +++ b/include/command.h @@ -209,6 +209,70 @@ int board_run_command(const char *cmdline); # define _CMD_HELP(x) #endif +#ifdef CONFIG_NEEDS_MANUAL_RELOC +#define U_BOOT_SUBCMDS_RELOC(_cmdname) \ + static void _cmdname##_subcmds_reloc(void) \ + { \ + static int relocated; \ + \ + if (relocated) \ + return; \ + \ + fixup_cmdtable(_cmdname##_subcmds, \ + ARRAY_SIZE(_cmdname##_subcmds)); \ + relocated = 1; \ + } +#else +#define U_BOOT_SUBCMDS_RELOC(_cmdname) \ + static void _cmdname##_subcmds_reloc(void) { } +#endif + +#define U_BOOT_SUBCMDS_DO_CMD(_cmdname) \ + static int do_##_cmdname(cmd_tbl_t *cmdtp, int flag, int argc, \ + char * const argv[], int *repeatable) \ + { \ + cmd_tbl_t *subcmd; \ + \ + _cmdname##_subcmds_reloc(); \ + \ + /* We need at least the cmd and subcmd names. */ \ + if (argc < 2 || argc > CONFIG_SYS_MAXARGS) \ + return CMD_RET_USAGE; \ + \ + subcmd = find_cmd_tbl(argv[1], _cmdname##_subcmds, \ + ARRAY_SIZE(_cmdname##_subcmds)); \ + if (!subcmd || argc - 1 > subcmd->maxargs) \ + return CMD_RET_USAGE; \ + \ + if (flag == CMD_FLAG_REPEAT && \ + !cmd_is_repeatable(subcmd)) \ + return CMD_RET_SUCCESS; \ + \ + return subcmd->cmd_rep(subcmd, flag, argc - 1, \ + argv + 1, repeatable); \ + } + +#ifdef CONFIG_AUTO_COMPLETE +#define U_BOOT_SUBCMDS_COMPLETE(_cmdname) \ + static int complete_##_cmdname(int argc, char * const argv[], \ + char last_char, int maxv, \ + char *cmdv[]) \ + { \ + return complete_subcmdv(_cmdname##_subcmds, \ + ARRAY_SIZE(_cmdname##_subcmds), \ + argc - 1, argv + 1, last_char, \ + maxv, cmdv); \ + } +#else +#define U_BOOT_SUBCMDS_COMPLETE(_cmdname) +#endif + +#define U_BOOT_SUBCMDS(_cmdname, ...) \ + static cmd_tbl_t _cmdname##_subcmds[] = { __VA_ARGS__ }; \ + U_BOOT_SUBCMDS_RELOC(_cmdname) \ + U_BOOT_SUBCMDS_DO_CMD(_cmdname) \ + U_BOOT_SUBCMDS_COMPLETE(_cmdname) + #ifdef CONFIG_CMDLINE #define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \ _usage, _help, _comp) \ @@ -271,4 +335,18 @@ int board_run_command(const char *cmdline); U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \ _usage, _help, NULL) +#define U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd, \ + _comp) \ + U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd, \ + "", "", _comp) + +#define U_BOOT_SUBCMD_MKENT(_name, _maxargs, _rep, _do_cmd) \ + U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd, \ + NULL) + +#define U_BOOT_CMD_WITH_SUBCMDS(_name, _usage, _help, ...) \ + U_BOOT_SUBCMDS(_name, __VA_ARGS__) \ + U_BOOT_CMDREP_COMPLETE(_name, CONFIG_SYS_MAXARGS, do_##_name, \ + _usage, _help, complete_##_name) + #endif /* __COMMAND_H */ -- cgit v1.3.1 From 31a2cf1ca4968dcaf78aef222b6683fea4f2c72d Mon Sep 17 00:00:00 2001 From: Tien Fong Chee Date: Mon, 10 Dec 2018 21:29:44 +0800 Subject: misc: fs_loader: Switching private data allocation to DM auto allocation Switching private data manual allocation to driver model auto allocation so users no longer need to deallocate themself because this would be deallocated by driver model when the device is no longer required. Signed-off-by: Tien Fong Chee Reviewed-by: Simon Glass --- doc/driver-model/fs_firmware_loader.txt | 35 +++-------- drivers/misc/fs_loader.c | 108 +++++++++++++------------------- include/fs_loader.h | 32 ++-------- 3 files changed, 56 insertions(+), 119 deletions(-) (limited to 'include') diff --git a/doc/driver-model/fs_firmware_loader.txt b/doc/driver-model/fs_firmware_loader.txt index 290915a9598..b9aee848cc5 100644 --- a/doc/driver-model/fs_firmware_loader.txt +++ b/doc/driver-model/fs_firmware_loader.txt @@ -74,17 +74,16 @@ Firmware storage device described in device tree source File system firmware Loader API ------------------------------- -int request_firmware_into_buf(struct device_platdata *plat, +int request_firmware_into_buf(struct udevice *dev, const char *name, - void *buf, size_t size, u32 offset, - struct firmware **firmwarep) + void *buf, size_t size, u32 offset) -------------------------------------------------------------------- Load firmware into a previously allocated buffer Parameters: -1. struct device_platdata *plat - Platform data such as storage and partition firmware loading from +1. struct udevice *dev + An instance of a driver 2. const char *name name of firmware file @@ -98,36 +97,16 @@ Parameters: 5. u32 offset offset of a file for start reading into buffer -6. struct firmware **firmwarep - pointer to firmware image - return: size of total read -ve when error Description: - The firmware is loaded directly into the buffer pointed to by buf and - the @firmwarep data member is pointed at buf - -Note: Memory would be allocated for firmware image, hence user should - free() *firmwarep and *firmwarep->priv structs after usage of - request_firmware_into_buf(), otherwise it will always leak memory - while subsequent calls of request_firmware_into_buf() with the same - *firmwarep argument. Those arguments can be free through calling API - below release_firmware(); + The firmware is loaded directly into the buffer pointed to by buf Example of creating firmware loader instance and calling request_firmware_into_buf API: if (uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev)) { - request_firmware_into_buf(dev->plat, filename, buffer_location, - buffer_size, offset_ofreading, &fw); + request_firmware_into_buf(dev, filename, buffer_location, + buffer_size, offset_ofreading); } - -void release_firmware(struct firmware *firmware) ------------------------------------------------- -Release the resource associated with a firmware image - -Parameters: - -1. struct firmware *firmware - Firmware resource to release diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c index baa5f8302ae..57a14a3479a 100644 --- a/drivers/misc/fs_loader.c +++ b/drivers/misc/fs_loader.c @@ -16,9 +16,22 @@ DECLARE_GLOBAL_DATA_PTR; -struct firmware_priv { - const char *name; /* Filename */ - u32 offset; /* Offset of reading a file */ +/** + * struct firmware - A place for storing firmware and its attribute data. + * + * This holds information about a firmware and its content. + * + * @size: Size of a file + * @data: Buffer for file + * @priv: Firmware loader private fields + * @name: Filename + * @offset: Offset of reading a file + */ +struct firmware { + size_t size; + const u8 *data; + const char *name; + u32 offset; }; #ifdef CONFIG_CMD_UBIFS @@ -88,74 +101,42 @@ static int select_fs_dev(struct device_platdata *plat) /** * _request_firmware_prepare - Prepare firmware struct. * + * @dev: An instance of a driver. * @name: Name of firmware file. * @dbuf: Address of buffer to load firmware into. * @size: Size of buffer. * @offset: Offset of a file for start reading into buffer. - * @firmwarep: Pointer to pointer to firmware image. * * Return: Negative value if fail, 0 for successful. */ -static int _request_firmware_prepare(const char *name, void *dbuf, - size_t size, u32 offset, - struct firmware **firmwarep) +static int _request_firmware_prepare(struct udevice *dev, + const char *name, void *dbuf, + size_t size, u32 offset) { if (!name || name[0] == '\0') return -EINVAL; - /* No memory allocation is required if *firmwarep is allocated */ - if (!(*firmwarep)) { - (*firmwarep) = calloc(1, sizeof(struct firmware)); - if (!(*firmwarep)) - return -ENOMEM; + struct firmware *firmwarep = dev_get_priv(dev); - (*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv)); - if (!(*firmwarep)->priv) { - free(*firmwarep); - return -ENOMEM; - } - } else if (!(*firmwarep)->priv) { - (*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv)); - if (!(*firmwarep)->priv) { - free(*firmwarep); - return -ENOMEM; - } - } + if (!firmwarep) + return -ENOMEM; - ((struct firmware_priv *)((*firmwarep)->priv))->name = name; - ((struct firmware_priv *)((*firmwarep)->priv))->offset = offset; - (*firmwarep)->data = dbuf; - (*firmwarep)->size = size; + firmwarep->name = name; + firmwarep->offset = offset; + firmwarep->data = dbuf; + firmwarep->size = size; return 0; } -/** - * release_firmware - Release the resource associated with a firmware image - * @firmware: Firmware resource to release - */ -void release_firmware(struct firmware *firmware) -{ - if (firmware) { - if (firmware->priv) { - free(firmware->priv); - firmware->priv = NULL; - } - free(firmware); - } -} - /** * fw_get_filesystem_firmware - load firmware into an allocated buffer. - * @plat: Platform data such as storage and partition firmware loading from. - * @firmware: pointer to firmware image. + * @dev: An instance of a driver. * * Return: Size of total read, negative value when error. */ -static int fw_get_filesystem_firmware(struct device_platdata *plat, - struct firmware *firmware) +static int fw_get_filesystem_firmware(struct udevice *dev) { - struct firmware_priv *fw_priv = NULL; loff_t actread; char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume; int ret; @@ -178,20 +159,23 @@ static int fw_get_filesystem_firmware(struct device_platdata *plat, else ret = -ENODEV; } else { - ret = select_fs_dev(plat); + ret = select_fs_dev(dev->platdata); } if (ret) goto out; - fw_priv = firmware->priv; + struct firmware *firmwarep = dev_get_priv(dev); + + if (!firmwarep) + return -ENOMEM; - ret = fs_read(fw_priv->name, (ulong)map_to_sysmem(firmware->data), - fw_priv->offset, firmware->size, &actread); + ret = fs_read(firmwarep->name, (ulong)map_to_sysmem(firmwarep->data), + firmwarep->offset, firmwarep->size, &actread); if (ret) { debug("Error: %d Failed to read %s from flash %lld != %zu.\n", - ret, fw_priv->name, actread, firmware->size); + ret, firmwarep->name, actread, firmwarep->size); } else { ret = actread; } @@ -205,33 +189,30 @@ out: /** * request_firmware_into_buf - Load firmware into a previously allocated buffer. - * @plat: Platform data such as storage and partition firmware loading from. + * @dev: An instance of a driver. * @name: Name of firmware file. * @buf: Address of buffer to load firmware into. * @size: Size of buffer. * @offset: Offset of a file for start reading into buffer. - * @firmwarep: Pointer to firmware image. * - * The firmware is loaded directly into the buffer pointed to by @buf and - * the @firmwarep data member is pointed at @buf. + * The firmware is loaded directly into the buffer pointed to by @buf. * * Return: Size of total read, negative value when error. */ -int request_firmware_into_buf(struct device_platdata *plat, +int request_firmware_into_buf(struct udevice *dev, const char *name, - void *buf, size_t size, u32 offset, - struct firmware **firmwarep) + void *buf, size_t size, u32 offset) { int ret; - if (!plat) + if (!dev) return -EINVAL; - ret = _request_firmware_prepare(name, buf, size, offset, firmwarep); + ret = _request_firmware_prepare(dev, name, buf, size, offset); if (ret < 0) /* error */ return ret; - ret = fw_get_filesystem_firmware(plat, *firmwarep); + ret = fw_get_filesystem_firmware(dev); return ret; } @@ -286,6 +267,7 @@ U_BOOT_DRIVER(fs_loader) = { .probe = fs_loader_probe, .ofdata_to_platdata = fs_loader_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct device_platdata), + .priv_auto_alloc_size = sizeof(struct firmware), }; UCLASS_DRIVER(fs_loader) = { diff --git a/include/fs_loader.h b/include/fs_loader.h index 0be4f17e632..b728c06fcff 100644 --- a/include/fs_loader.h +++ b/include/fs_loader.h @@ -8,21 +8,6 @@ #include -/** - * struct firmware - A place for storing firmware and its attribute data. - * - * This holds information about a firmware and its content. - * - * @size: Size of a file - * @data: Buffer for file - * @priv: Firmware loader private fields - */ -struct firmware { - size_t size; - const u8 *data; - void *priv; -}; - /** * struct phandle_part - A place for storing phandle of node and its partition * @@ -52,28 +37,19 @@ struct device_platdata { char *ubivol; }; -/** - * release_firmware - Release the resource associated with a firmware image - * @firmware: Firmware resource to release - */ -void release_firmware(struct firmware *firmware); - /** * request_firmware_into_buf - Load firmware into a previously allocated buffer. - * @plat: Platform data such as storage and partition firmware loading from. + * @dev: An instance of a driver. * @name: Name of firmware file. * @buf: Address of buffer to load firmware into. * @size: Size of buffer. * @offset: Offset of a file for start reading into buffer. - * @firmwarep: Pointer to firmware image. * - * The firmware is loaded directly into the buffer pointed to by @buf and - * the @firmwarep data member is pointed at @buf. + * The firmware is loaded directly into the buffer pointed to by @buf. * * Return: Size of total read, negative value when error. */ -int request_firmware_into_buf(struct device_platdata *plat, +int request_firmware_into_buf(struct udevice *dev, const char *name, - void *buf, size_t size, u32 offset, - struct firmware **firmwarep); + void *buf, size_t size, u32 offset); #endif -- cgit v1.3.1 From 03dcf17dba3dbd6f1cfe9ecaa0665ea8c11e0ef2 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 5 Dec 2018 09:26:50 +0100 Subject: common: command: Add support for $ auto-completion Add the dollar_complete() function to auto-complete arguments starting with a '$' and use it in the cmd_auto_complete() path such that all args starting with a $ can be auto-completed based on the available env vars. Signed-off-by: Boris Brezillon [trini: Fix some linking problems] Signed-off-by: Tom Rini --- common/command.c | 32 ++++++++++++++++++++++++++------ env/common.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- include/common.h | 3 ++- lib/Makefile | 3 +-- 4 files changed, 77 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/common/command.c b/common/command.c index 19f0534a76e..e14d1fa1d6b 100644 --- a/common/command.c +++ b/common/command.c @@ -142,23 +142,38 @@ int cmd_usage(const cmd_tbl_t *cmdtp) } #ifdef CONFIG_AUTO_COMPLETE +static char env_complete_buf[512]; int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]) { - static char tmp_buf[512]; int space; space = last_char == '\0' || isblank(last_char); if (space && argc == 1) - return env_complete("", maxv, cmdv, sizeof(tmp_buf), tmp_buf); + return env_complete("", maxv, cmdv, sizeof(env_complete_buf), + env_complete_buf, false); if (!space && argc == 2) - return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf); + return env_complete(argv[1], maxv, cmdv, + sizeof(env_complete_buf), + env_complete_buf, false); return 0; } +static int dollar_complete(int argc, char * const argv[], char last_char, + int maxv, char *cmdv[]) +{ + /* Make sure the last argument starts with a $. */ + if (argc < 1 || argv[argc - 1][0] != '$' || + last_char == '\0' || isblank(last_char)) + return 0; + + return env_complete(argv[argc - 1], maxv, cmdv, sizeof(env_complete_buf), + env_complete_buf, true); +} + /*************************************************************************************/ int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc, @@ -357,9 +372,14 @@ int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp) /* separate into argv */ argc = make_argv(tmp_buf, sizeof(argv)/sizeof(argv[0]), argv); - /* do the completion and return the possible completions */ - i = complete_cmdv(argc, argv, last_char, - sizeof(cmdv) / sizeof(cmdv[0]), cmdv); + /* first try a $ completion */ + i = dollar_complete(argc, argv, last_char, + sizeof(cmdv) / sizeof(cmdv[0]), cmdv); + if (!i) { + /* do the completion and return the possible completions */ + i = complete_cmdv(argc, argv, last_char, + sizeof(cmdv) / sizeof(cmdv[0]), cmdv); + } /* no match; bell and out */ if (i == 0) { diff --git a/env/common.c b/env/common.c index 3317cef3552..d1a6a528601 100644 --- a/env/common.c +++ b/env/common.c @@ -240,32 +240,76 @@ void env_relocate(void) } } -#if defined(CONFIG_AUTO_COMPLETE) && !defined(CONFIG_SPL_BUILD) -int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf) +#ifdef CONFIG_AUTO_COMPLETE +int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf, + bool dollar_comp) { ENTRY *match; int found, idx; + if (dollar_comp) { + /* + * When doing $ completion, the first character should + * obviously be a '$'. + */ + if (var[0] != '$') + return 0; + + var++; + + /* + * The second one, if present, should be a '{', as some + * configuration of the u-boot shell expand ${var} but not + * $var. + */ + if (var[0] == '{') + var++; + else if (var[0] != '\0') + return 0; + } + idx = 0; found = 0; cmdv[0] = NULL; + while ((idx = hmatch_r(var, idx, &match, &env_htab))) { int vallen = strlen(match->key) + 1; - if (found >= maxv - 2 || bufsz < vallen) + if (found >= maxv - 2 || + bufsz < vallen + (dollar_comp ? 3 : 0)) break; cmdv[found++] = buf; + + /* Add the '${' prefix to each var when doing $ completion. */ + if (dollar_comp) { + strcpy(buf, "${"); + buf += 2; + bufsz -= 3; + } + memcpy(buf, match->key, vallen); buf += vallen; bufsz -= vallen; + + if (dollar_comp) { + /* + * This one is a bit odd: vallen already contains the + * '\0' character but we need to add the '}' suffix, + * hence the buf - 1 here. strcpy() will add the '\0' + * character just after '}'. buf is then incremented + * to account for the extra '}' we just added. + */ + strcpy(buf - 1, "}"); + buf++; + } } qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar); if (idx) - cmdv[found++] = "..."; + cmdv[found++] = dollar_comp ? "${...}" : "..."; cmdv[found] = NULL; return found; diff --git a/include/common.h b/include/common.h index 657cc404cfa..18948b6bc2d 100644 --- a/include/common.h +++ b/include/common.h @@ -248,7 +248,8 @@ static inline int env_set_addr(const char *varname, const void *addr) } #ifdef CONFIG_AUTO_COMPLETE -int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf); +int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf, + bool dollar_comp); #endif int get_env_id (void); diff --git a/lib/Makefile b/lib/Makefile index a6dd928a926..f06d6316d46 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -41,7 +41,6 @@ obj-y += ldiv.o obj-$(CONFIG_MD5) += md5.o obj-y += net_utils.o obj-$(CONFIG_PHYSMEM) += physmem.o -obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o obj-$(CONFIG_RBTREE) += rbtree.o @@ -67,7 +66,6 @@ obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o obj-$(CONFIG_LIBAVB) += libavb/ -obj-$(CONFIG_$(SPL_TPL_)SAVEENV) += qsort.o obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += libfdt/ ifneq ($(CONFIG_$(SPL_TPL_)BUILD)$(CONFIG_$(SPL_TPL_)OF_PLATDATA),yy) obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += fdtdec_common.o @@ -80,6 +78,7 @@ obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o endif obj-$(CONFIG_ADDR_MAP) += addr_map.o +obj-y += qsort.o obj-y += hashtable.o obj-y += errno.o obj-y += display_options.o -- cgit v1.3.1