From 3bc0db11bace657112f475ed6c93f3afbb012fcd Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 14 Oct 2020 14:34:52 +0800 Subject: [PATCH] cmd: Add a 'misc' command to access miscellaneous devices Enable the command "misc" for accessing miscellaneous devices with a MISC uclass driver. The command provides listing all MISC devices as well as read and write functionalities via their drivers. Signed-off-by: Bin Meng --- cmd/Kconfig | 8 +++ cmd/Makefile | 1 + cmd/misc.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 cmd/misc.c diff --git a/cmd/Kconfig b/cmd/Kconfig index cc7e93190f..11f299da2b 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1025,6 +1025,14 @@ config CMD_LSBLK Print list of available block device drivers, and for each, the list of known block devices. +config CMD_MISC + bool "misc" + depends on MISC + help + Enable the command "misc" for accessing miscellaneous devices with + a MISC uclass driver. The command provides listing all MISC devices + as well as read and write functionalities via their drivers. + config CMD_MMC bool "mmc" help diff --git a/cmd/Makefile b/cmd/Makefile index c617474a63..da4e0600b2 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -94,6 +94,7 @@ obj-$(CONFIG_CMD_MEMORY) += mem.o obj-$(CONFIG_CMD_IO) += io.o obj-$(CONFIG_CMD_MFSL) += mfsl.o obj-$(CONFIG_CMD_MII) += mii.o +obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MDIO) += mdio.o obj-$(CONFIG_CMD_SLEEP) += sleep.o obj-$(CONFIG_CMD_MMC) += mmc.o diff --git a/cmd/misc.c b/cmd/misc.c new file mode 100644 index 0000000000..653deed7f5 --- /dev/null +++ b/cmd/misc.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020 Wind River Systems, Inc. + * + * Author: + * Bin Meng + * + * A command interface to access misc devices with MISC uclass driver APIs. + */ + +#include +#include +#include +#include +#include + +enum misc_op { + MISC_OP_READ, + MISC_OP_WRITE +}; + +static char *misc_op_str[] = { + "read", + "write" +}; + +static int do_misc_list(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + struct udevice *dev; + + printf("Device Index Driver\n"); + printf("-------------------------------------\n"); + for (uclass_first_device(UCLASS_MISC, &dev); + dev; + uclass_next_device(&dev)) { + printf("%-20s %5d %10s\n", dev->name, dev->seq, + dev->driver->name); + } + + return 0; +} + +static int do_misc_op(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[], enum misc_op op) +{ + int (*misc_op)(struct udevice *, int, void *, int); + struct udevice *dev; + int offset; + void *buf; + int size; + int ret; + + ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev); + if (ret) { + printf("Unable to find device %s\n", argv[0]); + return ret; + } + + offset = simple_strtoul(argv[1], NULL, 16); + buf = (void *)simple_strtoul(argv[2], NULL, 16); + size = simple_strtoul(argv[3], NULL, 16); + + if (op == MISC_OP_READ) + misc_op = misc_read; + else + misc_op = misc_write; + + ret = misc_op(dev, offset, buf, size); + if (ret < 0) { + if (ret == -ENOSYS) { + printf("The device does not support %s\n", + misc_op_str[op]); + ret = 0; + } + } else { + if (ret == size) + ret = 0; + else + printf("Partially %s %d bytes\n", misc_op_str[op], ret); + } + + return ret; +} + +static int do_misc_read(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ); +} + +static int do_misc_write(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE); +} + +static struct cmd_tbl misc_commands[] = { + U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""), + U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""), + U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""), +}; + +static int do_misc(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + struct cmd_tbl *misc_cmd; + int ret; + + if (argc < 2) + return CMD_RET_USAGE; + misc_cmd = find_cmd_tbl(argv[1], misc_commands, + ARRAY_SIZE(misc_commands)); + argc -= 2; + argv += 2; + if (!misc_cmd || argc != misc_cmd->maxargs) + return CMD_RET_USAGE; + + ret = misc_cmd->cmd(misc_cmd, flag, argc, argv); + + return cmd_process_error(misc_cmd, ret); +} + +U_BOOT_CMD( + misc, 6, 1, do_misc, + "Access miscellaneous devices with MISC uclass driver APIs", + "list - list all miscellaneous devices\n" + "misc read name offset addr len - read `len' bytes starting at\n" + " `offset' of device `name'\n" + " to memory at `addr'\n" + "misc write name offset addr len - write `len' bytes starting at\n" + " `offset' of device `name'\n" + " from memory at `addr'" +);