From 4db7f78711fde5d1f7812a27ab2f7862215ab671 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 Change-Id: I40ace250847f813358125dfcaa8998fd32cf7ea3 Signed-off-by: Colin Cross --- drivers/of/fdt.c | 60 +++++++++++++++++++++++++++--------------- include/linux/of_fdt.h | 21 +++++++++++++++ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c89d5d231a0e..d3ac492fbb59 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -1054,6 +1054,29 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname, 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(unsigned long node, const char *uname, int depth, void *data) { @@ -1068,28 +1091,23 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, early_init_dt_check_for_initrd(node); - /* Retrieve command line */ - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + /* Put CONFIG_CMDLINE in if forced or if data had nothing in it to start */ + if (overwrite_incoming_cmdline || !((char *)data)[0]) + strlcpy(data, config_cmdline, 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(data, " ", COMMAND_LINE_SIZE); - strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -#elif defined(CONFIG_CMDLINE_FORCE) - strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -#else - /* No arguments from boot loader, use kernel's cmdl*/ - if (!((char *)data)[0]) - strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -#endif -#endif /* CONFIG_CMDLINE */ + /* 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) { + strlcat(data, " ", COMMAND_LINE_SIZE); + strlcat(data, p, min_t(int, (int)l, + COMMAND_LINE_SIZE)); + } else + strlcpy(data, p, min_t(int, (int)l, + COMMAND_LINE_SIZE)); + } + } pr_debug("Command line is: %s\n", (char*)data); diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 4341f32516d8..501d461a6a1d 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -63,6 +63,27 @@ extern int of_flat_dt_match(unsigned long node, const char *const *matches); extern unsigned long of_get_flat_dt_root(void); extern int of_get_flat_dt_size(void); +/* + * 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(unsigned long node, const char *uname, int depth, void *data); extern int early_init_dt_scan_memory(unsigned long node, const char *uname,