| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Doug Anderson <dianders@chromium.org> |
| Date: Thu, 2 Feb 2012 22:58:28 -0800 |
| Subject: 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 <dianders@chromium.org> |
| CC: devicetree-discuss@lists.ozlabs.org |
| CC: Grant Likely <grant.likely@secretlab.ca> |
| CC: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| CC: Rob Herring <rob.herring@calxeda.com> |
| Bug: 120440972 |
| Change-Id: I40ace250847f813358125dfcaa8998fd32cf7ea3 |
| Signed-off-by: Colin Cross <ccross@android.com> |
| [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 <amit.pundir@linaro.org> |
| --- |
| drivers/of/fdt.c | 74 ++++++++++++++++++++++++++++-------------- |
| include/linux/of_fdt.h | 21 ++++++++++++ |
| 2 files changed, 70 insertions(+), 25 deletions(-) |
| |
| diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c |
| index 223d617ecfe1..650c028de779 100644 |
| --- a/drivers/of/fdt.c |
| +++ b/drivers/of/fdt.c |
| @@ -1040,43 +1040,67 @@ 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) |
| { |
| - int l; |
| - const char *p; |
| + int l = 0; |
| + const char *p = NULL; |
| const void *rng_seed; |
| + char *cmdline = data; |
| |
| pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); |
| |
| - if (depth != 1 || !data || |
| + if (depth != 1 || !cmdline || |
| (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) |
| return 0; |
| |
| 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(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(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 */ |
| + /* Put CONFIG_CMDLINE in if forced or if data had nothing in it to start */ |
| + if (overwrite_incoming_cmdline || !cmdline[0]) |
| + strlcpy(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 { |
| + strlcpy(cmdline, p, min(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 acf820e88952..9bbd5c06cb39 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(unsigned long node, const char *uname, |
| int depth, void *data); |
| extern int early_init_dt_scan_memory(unsigned long node, const char *uname, |