diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 66b435bca80c..95dc058a236f 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1180,13 +1180,19 @@ struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
 }
 
 static void
-expr_print_newline(struct expr *e,
-		   void (*fn)(void *, struct symbol *, const char *),
-		   void *data,
-		   int prevtoken)
+expr_print_revdep(struct expr *e,
+		  void (*fn)(void *, struct symbol *, const char *),
+		  void *data,
+		  int prevtoken,
+		  enum print_type type)
 {
-	fn(data, NULL, "\n  - ");
-	expr_print(e, fn, data, prevtoken);
+	if (type == PRINT_REVDEP_ALL				  ||
+	    type == PRINT_REVDEP_YES && expr_calc_value(e) == yes ||
+	    type == PRINT_REVDEP_MOD && expr_calc_value(e) == mod ||
+	    type == PRINT_REVDEP_NO  && expr_calc_value(e) == no) {
+		fn(data, NULL, "\n  - ");
+		expr_print(e, fn, data, prevtoken);
+	}
 }
 
 static void
@@ -1211,7 +1217,10 @@ __expr_print(struct expr *e,
 				fn(data, e->left.sym, e->left.sym->name);
 				break;
 			case PRINT_REVDEP_ALL:
-				expr_print_newline(e, fn, data, E_OR);
+			case PRINT_REVDEP_YES:
+			case PRINT_REVDEP_MOD:
+			case PRINT_REVDEP_NO:
+				expr_print_revdep(e, fn, data, E_OR, type);
 				break;
 			}
 		else
@@ -1269,7 +1278,10 @@ __expr_print(struct expr *e,
 			expr_print(e->right.expr, fn, data, E_AND);
 			break;
 		case PRINT_REVDEP_ALL:
-			expr_print_newline(e, fn, data, E_OR);
+		case PRINT_REVDEP_YES:
+		case PRINT_REVDEP_MOD:
+		case PRINT_REVDEP_NO:
+			expr_print_revdep(e, fn, data, E_OR, type);
 			break;
 		}
 		break;
@@ -1349,10 +1361,43 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
 	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
 }
 
+/*
+ * Allow front ends to check if a specific reverse dependency expression
+ * has at least one top level "||" member which evaluates to "val". This,
+ * will allow front ends to, as example, avoid printing "Selected by [y]:"
+ * line when there are actually no top level "||" sub-expressions which
+ * evaluate to =y.
+ */
+bool expr_revdep_contains(struct expr *e, tristate val)
+{
+	bool ret = false;
+
+	if (!e)
+		return ret;
+
+	switch (e->type) {
+	case E_SYMBOL:
+	case E_AND:
+		if (expr_calc_value(e) == val)
+			ret = true;
+		break;
+	case E_OR:
+		if (expr_revdep_contains(e->left.expr, val))
+			ret = true;
+		else if (expr_revdep_contains(e->right.expr, val))
+			ret = true;
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
 /*
  * Transform the top level "||" tokens into newlines and prepend each
  * line with a minus. This makes expressions much easier to read.
- * Suitable for reverse dependency expressions.
+ * Suitable for reverse dependency expressions. In addition, allow
+ * selective printing of tokens/sub-expressions by their tristate value.
  */
 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, enum print_type t)
 {
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 21cb67c15091..d5b096725ca8 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -37,6 +37,9 @@ enum expr_type {
 enum print_type {
 	PRINT_NORMAL,
 	PRINT_REVDEP_ALL,
+	PRINT_REVDEP_YES,
+	PRINT_REVDEP_MOD,
+	PRINT_REVDEP_NO,
 };
 
 union expr_data {
@@ -316,6 +319,7 @@ void expr_fprint(struct expr *e, FILE *out);
 struct gstr; /* forward */
 void expr_gstr_print(struct expr *e, struct gstr *gs);
 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, enum print_type t);
+bool expr_revdep_contains(struct expr *e, tristate val);
 
 static inline int expr_is_yes(struct expr *e)
 {
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 9dc8abfb1dc3..69ed1477e4ef 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -25,6 +25,7 @@ bool menu_has_help(struct menu *menu);
 const char * menu_get_help(struct menu *menu);
 struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
 void menu_get_ext_help(struct menu *menu, struct gstr *help);
+void get_revdep_by_type(struct expr *e, char *s, struct gstr *r);
 
 /* symbol.c */
 extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 5b8edba105f2..029da77fe1b0 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -790,6 +790,31 @@ static void get_symbol_props_str(struct gstr *r, struct symbol *sym,
 		str_append(r, "\n");
 }
 
+void get_revdep_by_type(struct expr *e, char *s, struct gstr *r)
+{
+	if (!e)
+		return;
+
+	if (expr_revdep_contains(e, yes)) {
+		str_append(r, s);
+		str_append(r, " [y]:");
+		expr_gstr_print_revdep(e, r, PRINT_REVDEP_YES);
+		str_append(r, "\n");
+	}
+	if (expr_revdep_contains(e, mod)) {
+		str_append(r, s);
+		str_append(r, " [m]:");
+		expr_gstr_print_revdep(e, r, PRINT_REVDEP_MOD);
+		str_append(r, "\n");
+	}
+	if (expr_revdep_contains(e, no)) {
+		str_append(r, s);
+		str_append(r, " [n]:");
+		expr_gstr_print_revdep(e, r, PRINT_REVDEP_NO);
+		str_append(r, "\n");
+	}
+}
+
 /*
  * head is optional and may be NULL
  */
@@ -826,18 +851,10 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
 	}
 
 	get_symbol_props_str(r, sym, P_SELECT, _("  Selects: "));
-	if (sym->rev_dep.expr) {
-		str_append(r, _("  Selected by: "));
-		expr_gstr_print_revdep(sym->rev_dep.expr, r, PRINT_REVDEP_ALL);
-		str_append(r, "\n");
-	}
+	get_revdep_by_type(sym->rev_dep.expr, "  Selected by", r);
 
 	get_symbol_props_str(r, sym, P_IMPLY, _("  Implies: "));
-	if (sym->implied.expr) {
-		str_append(r, _("  Implied by: "));
-		expr_gstr_print_revdep(sym->implied.expr, r, PRINT_REVDEP_ALL);
-		str_append(r, "\n");
-	}
+	get_revdep_by_type(sym->implied.expr, "  Implied by", r);
 
 	str_append(r, "\n\n");
 }
