[PATCH 02/27] console: Unify console_simple.c and pbl/console.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Move all of the shared code into lib/console.c and convert both files
to use that.

Signed-off-by: Andrey Smirnov <andrew.smirnov@xxxxxxxxx>
---
 common/console_simple.c |  11 +---
 include/console.h       |   8 +++
 lib/Makefile            |   6 +-
 lib/console.c           | 130 ++++++++++++++++++++++++++++++++++++++++
 pbl/console.c           |  15 +----
 5 files changed, 148 insertions(+), 22 deletions(-)
 create mode 100644 lib/console.c

diff --git a/common/console_simple.c b/common/console_simple.c
index 9675cbb0a..62b811b3f 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -7,7 +7,7 @@
 
 LIST_HEAD(console_list);
 EXPORT_SYMBOL(console_list);
-static struct console_device *console;
+extern struct console_device *console;
 
 int console_puts(unsigned int ch, const char *str)
 {
@@ -28,14 +28,7 @@ EXPORT_SYMBOL(console_puts);
 
 void console_putc(unsigned int ch, char c)
 {
-	if (!console) {
-		putc_ll(c);
-		return;
-	}
-
-	console->putc(console, c);
-	if (c == '\n')
-		console->putc(console, '\r');
+	__console_putc(__console_get_default(), c);
 }
 EXPORT_SYMBOL(console_putc);
 
diff --git a/include/console.h b/include/console.h
index c671be859..b3001ad16 100644
--- a/include/console.h
+++ b/include/console.h
@@ -69,6 +69,7 @@ struct console_device {
 	struct cdev_operations fops;
 
 	struct serdev_device serdev;
+	void *ctx;
 };
 
 static inline struct serdev_device *to_serdev_device(struct device_d *d)
@@ -209,4 +210,11 @@ static inline void pbl_set_putc(putc_func_t putcf, void *ctx) {}
 
 bool console_allow_color(void);
 
+void __cdev_putc(struct console_device *cdev, char c);
+void __console_putc(struct console_device *cdev, char c);
+
+struct console_device *__console_get_default(void);
+void __console_set_putc(struct console_device *cdev,
+			putc_func_t putcf, void *ctx);
+
 #endif
diff --git a/lib/Makefile b/lib/Makefile
index 09c250a1c..44188dc5a 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -65,4 +65,8 @@ obj-y			+= int_sqrt.o
 obj-y			+= parseopt.o
 obj-y			+= clz_ctz.o
 obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
-obj-pbl-y		+= clock.o
\ No newline at end of file
+obj-pbl-y		+= clock.o
+pbl-$(CONFIG_PBL_CONSOLE)	+= console.o
+obj-$(CONFIG_CONSOLE_FULL)	+= console.o
+obj-$(CONFIG_CONSOLE_SIMPLE)	+= console.o
+
diff --git a/lib/console.c b/lib/console.c
new file mode 100644
index 000000000..d2d2ae775
--- /dev/null
+++ b/lib/console.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * File containing all of the console-related code that is used by all
+ * possible consumers: PBL, CONSOLE_FULL, CONSOLE_SIMPLE, etc.
+ *
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ * Author: Andrey Smirnov <andrew.smirnov@xxxxxxxxx>
+ */
+
+#include <debug_ll.h>
+#include <console.h>
+
+/*
+ * Put this in the data section so that it survives the clearing of
+ * the BSS segment.
+ */
+#define __data __attribute__ ((section(".data")))
+
+/**
+ * console_ll - most basic low-level console
+ */
+__data struct console_device console_ll = {
+	.putc = NULL,
+	.ctx  = NULL,
+};
+__data struct console_device *console;
+
+/**
+ * __console_ll_putc - Early, most primitive putc() implemenatation
+ *
+ * Internal function used as a .putc() callback in console_ll when
+ * nothing better is configured.
+ */
+static void __console_ll_putc(struct console_device *cdev, char c)
+{
+	putc_ll(c);
+}
+
+/**
+ * __console_get_default - Return default output console
+ *
+ * Internal function used to determine which console to use for early
+ * output. It has the following two use-cases:
+ *
+ *   1. PBL, where it falls back onto console_ll and whatever it is
+ *      set up to (either putc_ll or custome callback set with
+ *      pbl_set_putc())
+ *
+ *   2. CONSOLE_SIMPLE, where it falls back onto console_ll (which in
+ *      this case always boils down to a putc_ll() call) until first
+ *      (and only) console is registered via console_register().
+ */
+struct console_device *__console_get_default(void)
+{
+	/*
+	 * Doing on-demand initialization here as opposed to in the
+	 * definition of console_ll above has that advantage that on
+	 * some architecutres (e.g. AArch64) it allows us to avoid
+	 * additional relocation and makes it possible to use console
+	 * infrastructure before any relocation happens
+	 */
+	if (unlikely(!console_ll.putc))
+		console_ll.putc = __console_ll_putc;
+
+	if (IS_ENABLED(__PBL__) || !console)
+		return &console_ll;
+
+	return console;
+}
+
+/**
+ * __console_set_putc - Early console initalization helper
+ *
+ * @cdev:	Console device to initialize
+ * @putcf:	putc() implementation to be used for this console
+ * @ctx:	Context to pass to putc()
+ *
+ * Internal function used to initialize early/trivial console devices
+ * capable of only outputting a single character
+ */
+void __console_set_putc(struct console_device *cdev,
+			putc_func_t putcf, void *ctx)
+{
+	cdev->putc = (void *)putcf;
+	cdev->ctx = ctx;
+}
+
+/**
+ * __cdev_putc - Internal .putc() callback dispatcher
+ *
+ * @cdev:	Console device to use
+ * @c:		Character to print
+ *
+ * Internal .putc() callback dispatcher needed to correctly select
+ * which context to pass.
+ *
+ * This is needed becuase when being used in PBL in conjunction with
+ * pbl_set_putc(), .putc() callback is expecting to receive a void *
+ * context that was registered earlier.
+ *
+ * In the "normal" world, however all of the .putc() callback are
+ * written with expectation of receiving struct console_device * as a
+ * first argument.
+ *
+ * Accomodation of both of those use-cases is the purpoese of this
+ * function
+ */
+void __cdev_putc(struct console_device *cdev, char c)
+{
+	void *ctx = cdev->ctx ? : cdev;
+
+	cdev->putc(ctx, c);
+}
+
+/**
+ * __console_putc - Internal high-level putc() implementation
+ *
+ * @cdev:	Console device to use
+ * @c:		Character to print
+ *
+ * Internal high-level putc() implementation based on __cdev_putc()
+ * that performs correct '\n' -> '\n\r' substitution.
+ */
+void __console_putc(struct console_device *cdev, char c)
+{
+	__cdev_putc(cdev, c);
+	if (c == '\n')
+		__cdev_putc(cdev, '\r');
+}
diff --git a/pbl/console.c b/pbl/console.c
index 75576ec79..c1c3e1dde 100644
--- a/pbl/console.c
+++ b/pbl/console.c
@@ -2,12 +2,7 @@
 #include <debug_ll.h>
 #include <linux/err.h>
 
-/*
- * Put these in the data section so that they survive the clearing of the
- * BSS segment.
- */
-static __attribute__ ((section(".data"))) putc_func_t __putc;
-static __attribute__ ((section(".data"))) void *putc_ctx;
+extern struct console_device console_ll;
 
 /**
  * pbl_set_putc() - setup UART used for PBL console
@@ -19,16 +14,12 @@ static __attribute__ ((section(".data"))) void *putc_ctx;
  */
 void pbl_set_putc(putc_func_t putcf, void *ctx)
 {
-	__putc = putcf;
-	putc_ctx = ctx;
+	__console_set_putc(&console_ll, putcf, ctx);
 }
 
 void console_putc(unsigned int ch, char c)
 {
-	if (__putc)
-		__putc(putc_ctx, c);
-	else
-		putc_ll(c);
+	__cdev_putc(__console_get_default(), c);
 }
 
 int console_puts(unsigned int ch, const char *str)
-- 
2.17.0


_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux