]> Git Repo - u-boot.git/blob - cmd/rkmtd.c
Merge tag 'v2024.01-rc5' into next
[u-boot.git] / cmd / rkmtd.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *
4  * Driver interface derived from:
5  * /cmd/host.c
6  * Copyright (c) 2012, Google Inc.
7  *
8  * Copyright (C) 2023 Johan Jonker <[email protected]>
9  */
10
11 #include <common.h>
12 #include <blk.h>
13 #include <command.h>
14 #include <dm.h>
15 #include <rkmtd.h>
16 #include <stdio.h>
17 #include <dm/device-internal.h>
18 #include <dm/uclass-internal.h>
19
20 static int do_rkmtd_bind(struct cmd_tbl *cmdtp, int flag, int argc,
21                          char *const argv[])
22 {
23         struct udevice *dev;
24         const char *label;
25         int ret;
26
27         argc--;
28         argv++;
29
30         if (argc < 1)
31                 return CMD_RET_USAGE;
32
33         if (argc > 1)
34                 return CMD_RET_USAGE;
35
36         label = argv[0];
37         ret = rkmtd_create_attach_mtd(label, &dev);
38         if (ret) {
39                 printf("Cannot create device / bind mtd\n");
40                 return CMD_RET_FAILURE;
41         }
42
43         return 0;
44 }
45
46 static struct udevice *parse_rkmtd_label(const char *label)
47 {
48         struct udevice *dev;
49
50         dev = rkmtd_find_by_label(label);
51         if (!dev) {
52                 int devnum;
53                 char *ep;
54
55                 devnum = hextoul(label, &ep);
56                 if (*ep ||
57                     uclass_find_device_by_seq(UCLASS_RKMTD, devnum, &dev)) {
58                         printf("No such device '%s'\n", label);
59                         return NULL;
60                 }
61         }
62
63         return dev;
64 }
65
66 static int do_rkmtd_unbind(struct cmd_tbl *cmdtp, int flag, int argc,
67                            char *const argv[])
68 {
69         struct udevice *dev;
70         const char *label;
71         int ret;
72
73         if (argc < 2)
74                 return CMD_RET_USAGE;
75
76         label = argv[1];
77         dev = parse_rkmtd_label(label);
78         if (!dev)
79                 return CMD_RET_FAILURE;
80
81         ret = rkmtd_detach(dev);
82         if (ret) {
83                 printf("Cannot detach mtd\n");
84                 return CMD_RET_FAILURE;
85         }
86
87         ret = device_unbind(dev);
88         if (ret) {
89                 printf("Cannot unbind device '%s'\n", dev->name);
90                 return CMD_RET_FAILURE;
91         }
92
93         return 0;
94 }
95
96 static void show_rkmtd_dev(struct udevice *dev)
97 {
98         struct rkmtd_dev *plat = dev_get_plat(dev);
99         struct blk_desc *desc;
100         struct udevice *blk;
101         int ret;
102
103         printf("%3d ", dev_seq(dev));
104
105         ret = blk_get_from_parent(dev, &blk);
106         if (ret)
107                 return;
108
109         desc = dev_get_uclass_plat(blk);
110         printf("%12lu %-15s\n", (unsigned long)desc->lba, plat->label);
111 }
112
113 static int do_rkmtd_info(struct cmd_tbl *cmdtp, int flag, int argc,
114                          char *const argv[])
115 {
116         struct udevice *dev;
117
118         if (argc < 1)
119                 return CMD_RET_USAGE;
120
121         dev = NULL;
122         if (argc >= 2) {
123                 dev = parse_rkmtd_label(argv[1]);
124                 if (!dev)
125                         return CMD_RET_FAILURE;
126         }
127
128         printf("%3s %12s %-15s\n", "dev", "blocks", "label");
129         if (dev) {
130                 show_rkmtd_dev(dev);
131         } else {
132                 struct uclass *uc;
133
134                 uclass_id_foreach_dev(UCLASS_RKMTD, dev, uc)
135                         show_rkmtd_dev(dev);
136         }
137
138         return 0;
139 }
140
141 static int do_rkmtd_dev(struct cmd_tbl *cmdtp, int flag, int argc,
142                         char *const argv[])
143 {
144         struct udevice *dev;
145         const char *label;
146
147         if (argc < 1 || argc > 3)
148                 return CMD_RET_USAGE;
149
150         if (argc == 1) {
151                 struct rkmtd_dev *plat;
152
153                 dev = rkmtd_get_cur_dev();
154                 if (!dev) {
155                         printf("No current rkmtd device\n");
156                         return CMD_RET_FAILURE;
157                 }
158                 plat = dev_get_plat(dev);
159                 printf("Current rkmtd device: %d: %s\n", dev_seq(dev),
160                        plat->label);
161                 return 0;
162         }
163
164         label = argv[1];
165         dev = parse_rkmtd_label(argv[1]);
166         if (!dev)
167                 return CMD_RET_FAILURE;
168
169         rkmtd_set_cur_dev(dev);
170
171         return 0;
172 }
173
174 static struct cmd_tbl cmd_rkmtd_sub[] = {
175         U_BOOT_CMD_MKENT(bind, 4, 0, do_rkmtd_bind, "", ""),
176         U_BOOT_CMD_MKENT(unbind, 4, 0, do_rkmtd_unbind, "", ""),
177         U_BOOT_CMD_MKENT(info, 3, 0, do_rkmtd_info, "", ""),
178         U_BOOT_CMD_MKENT(dev, 0, 1, do_rkmtd_dev, "", ""),
179 };
180
181 static int do_rkmtd(struct cmd_tbl *cmdtp, int flag, int argc,
182                     char *const argv[])
183 {
184         struct cmd_tbl *c;
185
186         argc--;
187         argv++;
188
189         c = find_cmd_tbl(argv[0], cmd_rkmtd_sub, ARRAY_SIZE(cmd_rkmtd_sub));
190
191         if (c)
192                 return c->cmd(cmdtp, flag, argc, argv);
193         else
194                 return CMD_RET_USAGE;
195 }
196
197 U_BOOT_CMD(
198         rkmtd, 8, 1, do_rkmtd,
199         "Rockchip MTD sub-system",
200         "bind <label>      - bind RKMTD device\n"
201         "rkmtd unbind <label>    - unbind RKMTD device\n"
202         "rkmtd info [<label>]    - show all available RKMTD devices\n"
203         "rkmtd dev [<label>]     - show or set current RKMTD device\n"
204 );
This page took 0.034404 seconds and 4 git commands to generate.