Merge branch '2023-09-28-assorted-minor-fixes'
[platform/kernel/u-boot.git] / cmd / misc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2020 Wind River Systems, Inc.
4  *
5  * Author:
6  *   Bin Meng <bin.meng@windriver.com>
7  *
8  * A command interface to access misc devices with MISC uclass driver APIs.
9  */
10
11 #include <common.h>
12 #include <command.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <misc.h>
16
17 enum misc_op {
18         MISC_OP_READ,
19         MISC_OP_WRITE
20 };
21
22 static char *misc_op_str[] = {
23         "read",
24         "write"
25 };
26
27 static int do_misc_list(struct cmd_tbl *cmdtp, int flag,
28                         int argc, char *const argv[])
29 {
30         struct udevice *dev;
31
32         printf("Device               Index     Driver\n");
33         printf("-------------------------------------\n");
34         for (uclass_first_device(UCLASS_MISC, &dev);
35              dev;
36              uclass_next_device(&dev)) {
37                 printf("%-20s %5d %10s\n", dev->name, dev_seq(dev),
38                        dev->driver->name);
39         }
40
41         return 0;
42 }
43
44 static int do_misc_op(struct cmd_tbl *cmdtp, int flag,
45                       int argc, char *const argv[], enum misc_op op)
46 {
47         struct udevice *dev;
48         int offset;
49         void *buf;
50         int size;
51         int ret;
52
53         ret = uclass_get_device_by_name(UCLASS_MISC, argv[0], &dev);
54         if (ret) {
55                 printf("Unable to find device %s\n", argv[0]);
56                 return ret;
57         }
58
59         offset = hextoul(argv[1], NULL);
60         buf = (void *)hextoul(argv[2], NULL);
61         size = hextoul(argv[3], NULL);
62
63         if (op == MISC_OP_READ)
64                 ret = misc_read(dev, offset, buf, size);
65         else
66                 ret = misc_write(dev, offset, buf, size);
67
68         if (ret < 0) {
69                 if (ret == -ENOSYS) {
70                         printf("The device does not support %s\n",
71                                misc_op_str[op]);
72                         ret = 0;
73                 }
74         } else {
75                 if (ret == size)
76                         ret = 0;
77                 else
78                         printf("Partially %s %d bytes\n", misc_op_str[op], ret);
79         }
80
81         return ret;
82 }
83
84 static int do_misc_read(struct cmd_tbl *cmdtp, int flag,
85                         int argc, char *const argv[])
86 {
87         return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_READ);
88 }
89
90 static int do_misc_write(struct cmd_tbl *cmdtp, int flag,
91                          int argc, char *const argv[])
92 {
93         return do_misc_op(cmdtp, flag, argc, argv, MISC_OP_WRITE);
94 }
95
96 static struct cmd_tbl misc_commands[] = {
97         U_BOOT_CMD_MKENT(list, 0, 1, do_misc_list, "", ""),
98         U_BOOT_CMD_MKENT(read, 4, 1, do_misc_read, "", ""),
99         U_BOOT_CMD_MKENT(write, 4, 1, do_misc_write, "", ""),
100 };
101
102 static int do_misc(struct cmd_tbl *cmdtp, int flag,
103                    int argc, char *const argv[])
104 {
105         struct cmd_tbl *misc_cmd;
106         int ret;
107
108         if (argc < 2)
109                 return CMD_RET_USAGE;
110         misc_cmd = find_cmd_tbl(argv[1], misc_commands,
111                                 ARRAY_SIZE(misc_commands));
112         argc -= 2;
113         argv += 2;
114         if (!misc_cmd || argc != misc_cmd->maxargs)
115                 return CMD_RET_USAGE;
116
117         ret = misc_cmd->cmd(misc_cmd, flag, argc, argv);
118
119         return cmd_process_error(misc_cmd, ret);
120 }
121
122 U_BOOT_CMD(
123         misc,   6,      1,      do_misc,
124         "Access miscellaneous devices with MISC uclass driver APIs",
125         "list                       - list all miscellaneous devices\n"
126         "misc read  name offset addr len - read `len' bytes starting at\n"
127         "                                 `offset' of device `name'\n"
128         "                                 to memory at `addr'\n"
129         "misc write name offset addr len - write `len' bytes starting at\n"
130         "                                 `offset' of device `name'\n"
131         "                                 from memory at `addr'"
132 );