[U-Boot] [PATCH v2 03/33] dm: serial: Move current serial port pointer to global_data

Simon Glass sjg at chromium.org
Tue Nov 11 02:00:20 CET 2014


In general we can't store things in the data section until we have inited
SDRAM. Some platforms allow this (e.g. those with SPL) but some don't. Move
the pointer to global_data so that it will work on all platforms.

Without this fix the serial port will not work prior to relocation with
driver model on some platforms.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2: None

 drivers/serial/serial-uclass.c    | 35 +++++++++++++++++++----------------
 include/asm-generic/global_data.h |  1 +
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 71f1a5c..0f019c8 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -19,15 +19,14 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* The currently-selected console serial device */
-struct udevice *cur_dev __attribute__ ((section(".data")));
-
 #ifndef CONFIG_SYS_MALLOC_F_LEN
 #error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work"
 #endif
 
 static void serial_find_console_or_panic(void)
 {
+	struct udevice *dev;
+
 #ifdef CONFIG_OF_CONTROL
 	int node;
 
@@ -35,18 +34,21 @@ static void serial_find_console_or_panic(void)
 	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
 	if (node < 0)
 		node = fdtdec_get_alias_node(gd->fdt_blob, "console");
-	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &cur_dev))
+	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) {
+		gd->cur_serial_dev = dev;
 		return;
+	}
 
 	/*
 	 * If the console is not marked to be bound before relocation, bind
 	 * it anyway.
 	 */
 	if (node > 0 &&
-	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &cur_dev)) {
-		if (!device_probe(cur_dev))
+	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
+		if (!device_probe(dev)) {
+			gd->cur_serial_dev = dev;
 			return;
-		cur_dev = NULL;
+		}
 	}
 #endif
 	/*
@@ -61,11 +63,12 @@ static void serial_find_console_or_panic(void)
 #else
 #define INDEX 0
 #endif
-	if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &cur_dev) &&
-	    uclass_get_device(UCLASS_SERIAL, INDEX, &cur_dev) &&
-	    (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
+	if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
+	    uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
+	    (uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
 		panic("No serial driver found");
 #undef INDEX
+	gd->cur_serial_dev = dev;
 }
 
 /* Called prior to relocation */
@@ -127,30 +130,30 @@ static int _serial_tstc(struct udevice *dev)
 
 void serial_putc(char ch)
 {
-	_serial_putc(cur_dev, ch);
+	_serial_putc(gd->cur_serial_dev, ch);
 }
 
 void serial_puts(const char *str)
 {
-	_serial_puts(cur_dev, str);
+	_serial_puts(gd->cur_serial_dev, str);
 }
 
 int serial_getc(void)
 {
-	return _serial_getc(cur_dev);
+	return _serial_getc(gd->cur_serial_dev);
 }
 
 int serial_tstc(void)
 {
-	return _serial_tstc(cur_dev);
+	return _serial_tstc(gd->cur_serial_dev);
 }
 
 void serial_setbrg(void)
 {
-	struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+	struct dm_serial_ops *ops = serial_get_ops(gd->cur_serial_dev);
 
 	if (ops->setbrg)
-		ops->setbrg(cur_dev, gd->baudrate);
+		ops->setbrg(gd->cur_serial_dev, gd->baudrate);
 }
 
 void serial_stdio_init(void)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 74df210..f61acbc 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -91,6 +91,7 @@ typedef struct global_data {
 	unsigned long malloc_limit;	/* limit address */
 	unsigned long malloc_ptr;	/* current address */
 #endif
+	struct udevice *cur_serial_dev;	/* current serial device */
 	struct arch_global_data arch;	/* architecture-specific data */
 } gd_t;
 #endif
-- 
2.1.0.rc2.206.gedb03e5



More information about the U-Boot mailing list