diff options
author | Simon Glass <sjg@chromium.org> | 2014-11-10 18:00:20 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-11-21 07:24:11 +0100 |
commit | 469a579df2907a421afec06e37d50e61b7d80227 (patch) | |
tree | 6c122952681674360e6360b0d6d923c6741824e3 | |
parent | a9f04d49e519383f98689d603facdee227a2f94d (diff) |
dm: serial: Move current serial port pointer to global_data
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>
-rw-r--r-- | drivers/serial/serial-uclass.c | 35 | ||||
-rw-r--r-- | 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 71f1a5cb91..0f019c8f50 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 74df210033..f61acbc4fc 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 |