diff --git a/init/Kconfig b/init/Kconfig index 3b36a1d5365..9fb403af108 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1,3 +1,11 @@ +config DEFCONFIG_LIST + string + option defconfig_list + default "/lib/modules/$UNAME_RELEASE/.config" + default "/etc/kernel-config" + default "/boot/config-$UNAME_RELEASE" + default "arch/$ARCH/defconfig" + menu "Code maturity level options" config EXPERIMENTAL diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index e28cd0c2ca0..5bd66f45118 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -25,15 +25,6 @@ const char conf_def_filename[] = ".config"; const char conf_defname[] = "arch/$ARCH/defconfig"; -const char *conf_confnames[] = { - ".config", - "/lib/modules/$UNAME_RELEASE/.config", - "/etc/kernel-config", - "/boot/config-$UNAME_RELEASE", - conf_defname, - NULL, -}; - static void conf_warning(const char *fmt, ...) { va_list ap; @@ -98,16 +89,21 @@ int conf_read_simple(const char *name, int def) if (name) { in = zconf_fopen(name); } else { - const char **names = conf_confnames; - name = *names++; - if (!name) - return 1; + struct property *prop; + + name = conf_def_filename; in = zconf_fopen(name); if (in) goto load; sym_change_count++; - while ((name = *names++)) { - name = conf_expand_value(name); + if (!sym_defconfig_list) + return 1; + + for_all_defaults(sym_defconfig_list, prop) { + if (expr_calc_value(prop->visible.expr) == no || + prop->expr->type != E_SYMBOL) + continue; + name = conf_expand_value(prop->expr->left.sym->name); in = zconf_fopen(name); if (in) { printf(_("#\n" diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index ffd42c7007e..6084525f604 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -156,6 +156,7 @@ struct file *lookup_file(const char *name); extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol *modules_sym; +extern struct symbol *sym_defconfig_list; extern int cdebug; struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 8e89d342889..2d3d4ed3c9f 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -104,6 +104,7 @@ const char *str_get(struct gstr *gs); /* symbol.c */ void sym_init(void); void sym_clear_all_valid(void); +void sym_set_all_changed(void); void sym_set_changed(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym); diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 151ef2168a2..a8afce24fb1 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -154,6 +154,20 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) void menu_add_option(int token, char *arg) { + struct property *prop; + + switch (token) { + case T_OPT_MODULES: + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(current_entry->sym); + break; + case T_OPT_DEFCONFIG_LIST: + if (!sym_defconfig_list) + sym_defconfig_list = current_entry->sym; + else if (sym_defconfig_list != current_entry->sym) + zconf_error("trying to redefine defconfig symbol"); + break; + } } static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 78a60ba39e5..ee225ced2ce 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -31,6 +31,7 @@ struct symbol symbol_yes = { }; int sym_change_count; +struct symbol *sym_defconfig_list; struct symbol *modules_sym; tristate modules_val; @@ -352,10 +353,13 @@ void sym_calc_value(struct symbol *sym) sym->curr.val = sym_calc_choice(sym); sym_validate_range(sym); - if (memcmp(&oldval, &sym->curr, sizeof(oldval))) + if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { sym_set_changed(sym); - if (modules_sym == sym) - modules_val = modules_sym->curr.tri; + if (modules_sym == sym) { + sym_set_all_changed(); + modules_val = modules_sym->curr.tri; + } + } if (sym_is_choice(sym)) { int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); @@ -449,11 +453,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val) } sym->def[S_DEF_USER].tri = val; - if (oldval != val) { + if (oldval != val) sym_clear_all_valid(); - if (sym == modules_sym) - sym_set_all_changed(); - } return true; } diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped index 137426e507e..2fb0a4fc61d 100644 --- a/scripts/kconfig/zconf.tab.c_shipped +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -2112,7 +2112,9 @@ void conf_parse(const char *name) sym_init(); menu_init(); - modules_sym = sym_lookup("MODULES", 0); + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); #if YYDEBUG @@ -2122,6 +2124,12 @@ void conf_parse(const char *name) zconfparse(); if (zconfnerrs) exit(1); + if (!modules_sym->prop) { + struct property *prop; + + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); + } menu_finalize(&rootmenu); for_all_symbols(i, sym) { sym_check_deps(sym); diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y index 9d08582f2aa..ab44feb3c60 100644 --- a/scripts/kconfig/zconf.y +++ b/scripts/kconfig/zconf.y @@ -481,7 +481,9 @@ void conf_parse(const char *name) sym_init(); menu_init(); - modules_sym = sym_lookup("MODULES", 0); + modules_sym = sym_lookup(NULL, 0); + modules_sym->type = S_BOOLEAN; + modules_sym->flags |= SYMBOL_AUTO; rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); #if YYDEBUG @@ -491,6 +493,12 @@ void conf_parse(const char *name) zconfparse(); if (zconfnerrs) exit(1); + if (!modules_sym->prop) { + struct property *prop; + + prop = prop_alloc(P_DEFAULT, modules_sym); + prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0)); + } menu_finalize(&rootmenu); for_all_symbols(i, sym) { sym_check_deps(sym);