From 8689a2067103d14812e7bc958e75c1b56c58d429 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Thu, 2 Feb 2012 22:58:28 -0800 Subject: [PATCH] ANDROID: of: Support CONFIG_CMDLINE_EXTEND config option The old logic assumes CMDLINE_FROM_BOOTLOADER vs. CMDLINE_FORCE and ignores CMDLINE_EXTEND. Here's the old logic: - CONFIG_CMDLINE_FORCE=true CONFIG_CMDLINE - dt bootargs=non-empty: dt bootargs - dt bootargs=empty, @data is non-empty string @data is left unchanged - dt bootargs=empty, @data is empty string CONFIG_CMDLINE (or "" if that's not defined) The new logic is now documented in of_fdt.h and is copied here for reference: - CONFIG_CMDLINE_FORCE=true CONFIG_CMDLINE - CONFIG_CMDLINE_EXTEND=true, @data is non-empty string @data + dt bootargs (even if dt bootargs are empty) - CONFIG_CMDLINE_EXTEND=true, @data is empty string CONFIG_CMDLINE + dt bootargs (even if dt bootargs are empty) - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=non-empty: dt bootargs - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is non-empty string @data is left unchanged - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is empty string CONFIG_CMDLINE (or "" if that's not defined) Signed-off-by: Doug Anderson CC: devicetree-discuss@lists.ozlabs.org CC: Grant Likely CC: Benjamin Herrenschmidt CC: Rob Herring Bug: 120440972 Bug: 261894961 Change-Id: I40ace250847f813358125dfcaa8998fd32cf7ea3 Signed-off-by: Colin Cross [AmitP: Folded following android-4.9 commit changes into this patch e820270abb5d ("ANDROID: of: fix CONFIG_CMDLINE_EXTEND") 9a4a74055444 ("ANDROID: of: Fix build warnings")] Signed-off-by: Amit Pundir [eberman: Resolve conflicts due to commit 60f20d84dc81 ("of/fdt: Rework early_init_dt_scan_chosen() to call directly") commit 7a12dd077e52 ("of: move from strlcpy with unused retval to strscpy")] Signed-off-by: Elliot Berman --- drivers/of/fdt.c | 68 ++++++++++++++++++++++++++++-------------- include/linux/of_fdt.h | 21 +++++++++++++ 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 7b571a631639..bbf65f636337 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -1150,10 +1150,32 @@ int __init early_init_dt_scan_memory(void) return 0; } +/* + * Convert configs to something easy to use in C code + */ +#if defined(CONFIG_CMDLINE_FORCE) +static const int overwrite_incoming_cmdline = 1; +static const int read_dt_cmdline; +static const int concat_cmdline; +#elif defined(CONFIG_CMDLINE_EXTEND) +static const int overwrite_incoming_cmdline; +static const int read_dt_cmdline = 1; +static const int concat_cmdline = 1; +#else /* CMDLINE_FROM_BOOTLOADER */ +static const int overwrite_incoming_cmdline; +static const int read_dt_cmdline = 1; +static const int concat_cmdline; +#endif +#ifdef CONFIG_CMDLINE +static const char *config_cmdline = CONFIG_CMDLINE; +#else +static const char *config_cmdline = ""; +#endif + int __init early_init_dt_scan_chosen(char *cmdline) { - int l, node; - const char *p; + int l = 0, node; + const char *p = NULL; const void *rng_seed; const void *fdt = initial_boot_params; @@ -1168,28 +1190,28 @@ int __init early_init_dt_scan_chosen(char *cmdline) early_init_dt_check_for_initrd(node); early_init_dt_check_for_elfcorehdr(node); - /* Retrieve command line */ - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else - * managed to set the command line, unless CONFIG_CMDLINE_FORCE - * is set in which case we override whatever was found earlier. - */ -#ifdef CONFIG_CMDLINE -#if defined(CONFIG_CMDLINE_EXTEND) - strlcat(cmdline, " ", COMMAND_LINE_SIZE); - strlcat(cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -#elif defined(CONFIG_CMDLINE_FORCE) - strscpy(cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -#else - /* No arguments from boot loader, use kernel's cmdl*/ - if (!((char *)cmdline)[0]) - strscpy(cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -#endif -#endif /* CONFIG_CMDLINE */ + /* Put CONFIG_CMDLINE in if forced or if data had nothing in it to start */ + if (overwrite_incoming_cmdline || !cmdline[0]) + strscpy(cmdline, config_cmdline, COMMAND_LINE_SIZE); + + /* Retrieve command line unless forcing */ + if (read_dt_cmdline) + p = of_get_flat_dt_prop(node, "bootargs", &l); + if (p != NULL && l > 0) { + if (concat_cmdline) { + int cmdline_len; + int copy_len; + strlcat(cmdline, " ", COMMAND_LINE_SIZE); + cmdline_len = strlen(cmdline); + copy_len = COMMAND_LINE_SIZE - cmdline_len - 1; + copy_len = min((int)l, copy_len); + strncpy(cmdline + cmdline_len, p, copy_len); + cmdline[cmdline_len + copy_len] = '\0'; + } else { + strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); + } + } pr_debug("Command line is: %s\n", (char *)cmdline); diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index d69ad5bb1eb1..991e4c1c87ba 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -58,6 +58,27 @@ extern int of_flat_dt_is_compatible(unsigned long node, const char *name); extern unsigned long of_get_flat_dt_root(void); extern uint32_t of_get_flat_dt_phandle(unsigned long node); +/* + * early_init_dt_scan_chosen - scan the device tree for ramdisk and bootargs + * + * The boot arguments will be placed into the memory pointed to by @data. + * That memory should be COMMAND_LINE_SIZE big and initialized to be a valid + * (possibly empty) string. Logic for what will be in @data after this + * function finishes: + * + * - CONFIG_CMDLINE_FORCE=true + * CONFIG_CMDLINE + * - CONFIG_CMDLINE_EXTEND=true, @data is non-empty string + * @data + dt bootargs (even if dt bootargs are empty) + * - CONFIG_CMDLINE_EXTEND=true, @data is empty string + * CONFIG_CMDLINE + dt bootargs (even if dt bootargs are empty) + * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=non-empty: + * dt bootargs + * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is non-empty string + * @data is left unchanged + * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is empty string + * CONFIG_CMDLINE (or "" if that's not defined) + */ extern int early_init_dt_scan_chosen(char *cmdline); extern int early_init_dt_scan_memory(void); extern void early_init_dt_check_for_usable_mem_range(void);