1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2020 Linaro Limited
4  */
5 
6 #include <dm.h>
7 #include <mtd.h>
8 
9 #include <linux/string.h>
10 
11 #define MTDPARTS_LEN		256
12 #define MTDIDS_LEN		128
13 
board_get_mtdparts(const char * dev,const char * partition,char * mtdids,char * mtdparts)14 static void board_get_mtdparts(const char *dev, const char *partition,
15 			       char *mtdids, char *mtdparts)
16 {
17 	/* mtdids: "<dev>=<dev>, ...." */
18 	if (mtdids[0] != '\0')
19 		strcat(mtdids, ",");
20 	strcat(mtdids, dev);
21 	strcat(mtdids, "=");
22 	strcat(mtdids, dev);
23 
24 	/* mtdparts: "mtdparts=<dev>:<mtdparts_<dev>>;..." */
25 	if (mtdparts[0] != '\0')
26 		strncat(mtdparts, ";", MTDPARTS_LEN);
27 	else
28 		strcat(mtdparts, "mtdparts=");
29 
30 	strncat(mtdparts, dev, MTDPARTS_LEN);
31 	strncat(mtdparts, ":", MTDPARTS_LEN);
32 	strncat(mtdparts, partition, MTDPARTS_LEN);
33 }
34 
board_mtdparts_default(const char ** mtdids,const char ** mtdparts)35 void board_mtdparts_default(const char **mtdids, const char **mtdparts)
36 {
37 	struct mtd_info *mtd;
38 	struct udevice *dev;
39 	const char *mtd_partition;
40 	static char parts[3 * MTDPARTS_LEN + 1];
41 	static char ids[MTDIDS_LEN + 1];
42 	static bool mtd_initialized;
43 
44 	if (mtd_initialized) {
45 		*mtdids = ids;
46 		*mtdparts = parts;
47 		return;
48 	}
49 
50 	memset(parts, 0, sizeof(parts));
51 	memset(ids, 0, sizeof(ids));
52 
53 	/* Currently mtdparts is needed on Qemu ARM64 for capsule updates */
54 	if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT) &&
55 	    IS_ENABLED(CONFIG_TARGET_QEMU_ARM_64BIT)) {
56 		/* probe all MTD devices */
57 		for (uclass_first_device(UCLASS_MTD, &dev); dev;
58 		     uclass_next_device(&dev)) {
59 			debug("mtd device = %s\n", dev->name);
60 		}
61 
62 		mtd = get_mtd_device_nm("nor0");
63 		if (!IS_ERR_OR_NULL(mtd)) {
64 			mtd_partition = CONFIG_MTDPARTS_NOR0;
65 			board_get_mtdparts("nor0", mtd_partition, ids, parts);
66 			put_mtd_device(mtd);
67 		}
68 
69 		mtd = get_mtd_device_nm("nor1");
70 		if (!IS_ERR_OR_NULL(mtd)) {
71 			mtd_partition = CONFIG_MTDPARTS_NOR1;
72 			board_get_mtdparts("nor1", mtd_partition, ids, parts);
73 			put_mtd_device(mtd);
74 		}
75 	}
76 
77 	mtd_initialized = true;
78 	*mtdids = ids;
79 	*mtdparts = parts;
80 	debug("%s:mtdids=%s & mtdparts=%s\n", __func__, ids, parts);
81 }
82