expo: Add a function to poll for input

Both bootflow_menu and cedit use similar logic to poll an expo. Move
this into the expo library so the code can be shared.

Update bootflow_menu_run() to return -EPIPE when the user quits without
choosing anything, since -EAGAIN is ambiguous and elsewhere means that
there is no input yet.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/expo.c b/boot/expo.c
index 9c042f1..301bbfa 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -10,8 +10,12 @@
 
 #include <dm.h>
 #include <expo.h>
+#include <log.h>
 #include <malloc.h>
+#include <menu.h>
 #include <video.h>
+#include <watchdog.h>
+#include <linux/delay.h>
 #include "scene_internal.h"
 
 int expo_new(const char *name, void *priv, struct expo **expp)
@@ -286,3 +290,43 @@
 
 	return 0;
 }
+
+int expo_poll(struct expo *exp, struct expo_action *act)
+{
+	int ichar, key, ret;
+
+	ret = expo_render(exp);
+	if (ret)
+		return log_msg_ret("ere", ret);
+
+	ichar = cli_ch_process(&exp->cch, 0);
+	if (!ichar) {
+		while (!ichar && !tstc()) {
+			schedule();
+			mdelay(2);
+			ichar = cli_ch_process(&exp->cch, -ETIMEDOUT);
+		}
+		if (!ichar) {
+			ichar = getchar();
+			ichar = cli_ch_process(&exp->cch, ichar);
+		}
+	}
+
+	key = 0;
+	if (ichar) {
+		key = bootmenu_conv_key(ichar);
+		if (key == BKEY_NONE || key >= BKEY_FIRST_EXTRA)
+			key = ichar;
+	}
+	if (!key)
+		return -EAGAIN;
+
+	ret = expo_send_key(exp, key);
+	if (ret)
+		return log_msg_ret("epk", ret);
+	ret = expo_action_get(exp, act);
+	if (ret)
+		return log_msg_ret("eag", ret);
+
+	return 0;
+}