+/**
+ * console_dev_is_serial() - Check if a stdio device is a serial device
+ *
+ * @sdev: Device to check
+ * @return true if this device is in the serial uclass (or for pre-driver-model,
+ * whether it is called "serial".
+ */
+static bool console_dev_is_serial(struct stdio_dev *sdev)
+{
+ bool is_serial;
+
+#ifdef CONFIG_DM_SERIAL
+ if (sdev->flags & DEV_FLAGS_DM) {
+ struct udevice *dev = sdev->priv;
+
+ is_serial = device_get_uclass_id(dev) == UCLASS_SERIAL;
+ } else
+#endif
+ is_serial = !strcmp(sdev->name, "serial");
+
+ return is_serial;
+}
+
+#if CONFIG_IS_ENABLED(CONSOLE_MUX)
+/** Console I/O multiplexing *******************************************/
+
+static struct stdio_dev *tstcdev;
+struct stdio_dev **console_devices[MAX_FILES];
+int cd_count[MAX_FILES];
+
+/*
+ * This depends on tstc() always being called before getc().
+ * This is guaranteed to be true because this routine is called
+ * only from fgetc() which assures it.
+ * No attempt is made to demultiplex multiple input sources.
+ */
+static int console_getc(int file)
+{
+ unsigned char ret;
+
+ /* This is never called with testcdev == NULL */
+ ret = tstcdev->getc(tstcdev);
+ tstcdev = NULL;
+ return ret;
+}
+
+static int console_tstc(int file)
+{
+ int i, ret;
+ struct stdio_dev *dev;
+
+ disable_ctrlc(1);
+ for (i = 0; i < cd_count[file]; i++) {
+ dev = console_devices[file][i];
+ if (dev->tstc != NULL) {
+ ret = dev->tstc(dev);
+ if (ret > 0) {
+ tstcdev = dev;
+ disable_ctrlc(0);
+ return ret;
+ }
+ }
+ }
+ disable_ctrlc(0);
+
+ return 0;
+}
+
+static void console_putc(int file, const char c)
+{
+ int i;
+ struct stdio_dev *dev;
+
+ for (i = 0; i < cd_count[file]; i++) {
+ dev = console_devices[file][i];
+ if (dev->putc != NULL)
+ dev->putc(dev, c);
+ }
+}
+
+static void console_puts_noserial(int file, const char *s)
+{
+ int i;
+ struct stdio_dev *dev;
+
+ for (i = 0; i < cd_count[file]; i++) {
+ dev = console_devices[file][i];
+ if (dev->puts != NULL && !console_dev_is_serial(dev))
+ dev->puts(dev, s);
+ }
+}
+
+static void console_puts(int file, const char *s)
+{
+ int i;
+ struct stdio_dev *dev;
+
+ for (i = 0; i < cd_count[file]; i++) {
+ dev = console_devices[file][i];
+ if (dev->puts != NULL)
+ dev->puts(dev, s);
+ }
+}
+
+static inline void console_doenv(int file, struct stdio_dev *dev)
+{
+ iomux_doenv(file, dev->name);
+}
+#else
+static inline int console_getc(int file)
+{
+ return stdio_devices[file]->getc(stdio_devices[file]);
+}
+
+static inline int console_tstc(int file)
+{
+ return stdio_devices[file]->tstc(stdio_devices[file]);
+}
+
+static inline void console_putc(int file, const char c)
+{
+ stdio_devices[file]->putc(stdio_devices[file], c);
+}
+
+static inline void console_puts_noserial(int file, const char *s)
+{
+ if (!console_dev_is_serial(stdio_devices[file]))
+ stdio_devices[file]->puts(stdio_devices[file], s);
+}
+
+static inline void console_puts(int file, const char *s)
+{
+ stdio_devices[file]->puts(stdio_devices[file], s);
+}
+
+static inline void console_doenv(int file, struct stdio_dev *dev)
+{
+ console_setfile(file, dev);
+}
+#endif /* CONIFIG_IS_ENABLED(CONSOLE_MUX) */
+