dm: serial: Move current serial port pointer to global_data
authorSimon Glass <sjg@chromium.org>
Tue, 11 Nov 2014 01:00:20 +0000 (18:00 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 21 Nov 2014 06:24:11 +0000 (07:24 +0100)
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@chromium.org>
drivers/serial/serial-uclass.c
include/asm-generic/global_data.h

index 71f1a5cb91024e9fc473e2a5e61f0deb82efd3c1..0f019c8f505bf717fefe0b240d7524d09829f537 100644 (file)
 
 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)
index 74df21003363305e98a7b84d27275612df1a98fe..f61acbc4fc12f5cd815965eedba5cc6f25140826 100644 (file)
@@ -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