--- zzzz-none-000/linux-4.4.271/drivers/mtd/cmdlinepart.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/drivers/mtd/cmdlinepart.c 2023-04-19 10:22:29.000000000 +0000 @@ -46,6 +46,22 @@ * * 1 NOR Flash with 2 partitions, 1 NAND with one * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) + * + * ========================================================================== + * AVM extensions + * -------------- + * + * A new command line parameter 'mtdparts_ext' was introduced with + * same format as 'mtdparts' above. + * + * The semantics of 'mtdparts' force a complete override of previously + * given parameters in case another 'mtdparts' entry is found. + * + * All 'mtdparts_ext' entries however are appended. + * When the parser kicks in the first time, the kernel's 'mtdparts' + * is appended to the 'mtdparts_ext' collection, so that the system is fed + * with the complete information. + * ========================================================================== */ #define pr_fmt(fmt) "mtd: " fmt @@ -83,6 +99,9 @@ static char *mtdparts; static char *cmdline; static int cmdline_parsed; +#define AVM_MAX_MTDPARTS_EXT 64 +static const char *avm_cmdline_ext[AVM_MAX_MTDPARTS_EXT + 1] __maybe_unused; +static unsigned int num_avm_cmdline_ext __maybe_unused; /* * Parse one partition definition for an MTD. Since there can be many @@ -216,6 +235,51 @@ return parts; } +#ifdef CONFIG_MTD_CMDLINE_PARTS_EXT +static char *mtdpart_ext_build_cmdline(void) +{ + char *cmdline_joined; + unsigned int arg_n; + size_t len; + + if (cmdline) + avm_cmdline_ext[num_avm_cmdline_ext++] = cmdline; + + if (num_avm_cmdline_ext == 0) + return NULL; + + len = 0; + for (arg_n = 0; arg_n < num_avm_cmdline_ext; ++arg_n) + len += strlen(avm_cmdline_ext[arg_n]); + + /* Reserve room for added ';' */ + len += num_avm_cmdline_ext - 1; + + cmdline_joined = kzalloc(len + 1, GFP_KERNEL); + if (!cmdline_joined) + return ERR_PTR(-ENOMEM); + + for (arg_n = 0; arg_n < num_avm_cmdline_ext; ++arg_n) { + if (arg_n) + strcat(cmdline_joined, ";"); + strcat(cmdline_joined, avm_cmdline_ext[arg_n]); + } + + return cmdline_joined; +} + +static int __init mtdpart_setup_ext(char *s) +{ + if (num_avm_cmdline_ext < AVM_MAX_MTDPARTS_EXT) + avm_cmdline_ext[num_avm_cmdline_ext++] = s; + else + pr_err("Too many mtdparts_ext arguments, discarding arg \"%s\"\n", + s); + return 1; +} +__setup("mtdparts_ext=", mtdpart_setup_ext); +#endif + /* * Parse the command line. */ @@ -343,7 +407,18 @@ /* parse command line */ if (!cmdline_parsed) { - err = mtdpart_setup_real(cmdline); + char *ext_cmdline = cmdline; + +#ifdef CONFIG_MTD_CMDLINE_PARTS_EXT + ext_cmdline = mtdpart_ext_build_cmdline(); + if (IS_ERR(ext_cmdline)) + return PTR_ERR(ext_cmdline); +#endif + err = mtdpart_setup_real(ext_cmdline); + + if (ext_cmdline != cmdline) + kfree(ext_cmdline); + if (err) return err; } @@ -407,7 +482,6 @@ cmdline = s; return 1; } - __setup("mtdparts=", mtdpart_setup); static struct mtd_part_parser cmdline_parser = {