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