1 /* 2 * Copyright (c) 2014 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <fdtdec.h> 11 #include <os.h> 12 #include <serial.h> 13 #include <stdio_dev.h> 14 #include <watchdog.h> 15 #include <dm/lists.h> 16 #include <dm/device-internal.h> 17 18 #include <ns16550.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #ifndef CONFIG_SYS_MALLOC_F_LEN 23 #error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work" 24 #endif 25 26 static void serial_find_console_or_panic(void) 27 { 28 struct udevice *dev; 29 30 #ifdef CONFIG_OF_CONTROL 31 int node; 32 33 /* Check for a chosen console */ 34 node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path"); 35 if (node < 0) 36 node = fdtdec_get_alias_node(gd->fdt_blob, "console"); 37 if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) { 38 gd->cur_serial_dev = dev; 39 return; 40 } 41 42 /* 43 * If the console is not marked to be bound before relocation, bind 44 * it anyway. 45 */ 46 if (node > 0 && 47 !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) { 48 if (!device_probe(dev)) { 49 gd->cur_serial_dev = dev; 50 return; 51 } 52 } 53 #endif 54 /* 55 * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!). 56 * 57 * Failing that, get the device with sequence number 0, or in extremis 58 * just the first serial device we can find. But we insist on having 59 * a console (even if it is silent). 60 */ 61 #ifdef CONFIG_CONS_INDEX 62 #define INDEX (CONFIG_CONS_INDEX - 1) 63 #else 64 #define INDEX 0 65 #endif 66 if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) && 67 uclass_get_device(UCLASS_SERIAL, INDEX, &dev) && 68 (uclass_first_device(UCLASS_SERIAL, &dev) || !dev)) 69 panic("No serial driver found"); 70 #undef INDEX 71 gd->cur_serial_dev = dev; 72 } 73 74 /* Called prior to relocation */ 75 int serial_init(void) 76 { 77 serial_find_console_or_panic(); 78 gd->flags |= GD_FLG_SERIAL_READY; 79 80 return 0; 81 } 82 83 /* Called after relocation */ 84 void serial_initialize(void) 85 { 86 serial_find_console_or_panic(); 87 } 88 89 static void _serial_putc(struct udevice *dev, char ch) 90 { 91 struct dm_serial_ops *ops = serial_get_ops(dev); 92 int err; 93 94 do { 95 err = ops->putc(dev, ch); 96 } while (err == -EAGAIN); 97 if (ch == '\n') 98 _serial_putc(dev, '\r'); 99 } 100 101 static void _serial_puts(struct udevice *dev, const char *str) 102 { 103 while (*str) 104 _serial_putc(dev, *str++); 105 } 106 107 static int _serial_getc(struct udevice *dev) 108 { 109 struct dm_serial_ops *ops = serial_get_ops(dev); 110 int err; 111 112 do { 113 err = ops->getc(dev); 114 if (err == -EAGAIN) 115 WATCHDOG_RESET(); 116 } while (err == -EAGAIN); 117 118 return err >= 0 ? err : 0; 119 } 120 121 static int _serial_tstc(struct udevice *dev) 122 { 123 struct dm_serial_ops *ops = serial_get_ops(dev); 124 125 if (ops->pending) 126 return ops->pending(dev, true); 127 128 return 1; 129 } 130 131 void serial_putc(char ch) 132 { 133 _serial_putc(gd->cur_serial_dev, ch); 134 } 135 136 void serial_puts(const char *str) 137 { 138 _serial_puts(gd->cur_serial_dev, str); 139 } 140 141 int serial_getc(void) 142 { 143 return _serial_getc(gd->cur_serial_dev); 144 } 145 146 int serial_tstc(void) 147 { 148 return _serial_tstc(gd->cur_serial_dev); 149 } 150 151 void serial_setbrg(void) 152 { 153 struct dm_serial_ops *ops = serial_get_ops(gd->cur_serial_dev); 154 155 if (ops->setbrg) 156 ops->setbrg(gd->cur_serial_dev, gd->baudrate); 157 } 158 159 void serial_stdio_init(void) 160 { 161 } 162 163 static void serial_stub_putc(struct stdio_dev *sdev, const char ch) 164 { 165 _serial_putc(sdev->priv, ch); 166 } 167 168 void serial_stub_puts(struct stdio_dev *sdev, const char *str) 169 { 170 _serial_puts(sdev->priv, str); 171 } 172 173 int serial_stub_getc(struct stdio_dev *sdev) 174 { 175 return _serial_getc(sdev->priv); 176 } 177 178 int serial_stub_tstc(struct stdio_dev *sdev) 179 { 180 return _serial_tstc(sdev->priv); 181 } 182 183 static int serial_post_probe(struct udevice *dev) 184 { 185 struct stdio_dev sdev; 186 struct dm_serial_ops *ops = serial_get_ops(dev); 187 struct serial_dev_priv *upriv = dev->uclass_priv; 188 int ret; 189 190 /* Set the baud rate */ 191 if (ops->setbrg) { 192 ret = ops->setbrg(dev, gd->baudrate); 193 if (ret) 194 return ret; 195 } 196 197 if (!(gd->flags & GD_FLG_RELOC)) 198 return 0; 199 200 memset(&sdev, '\0', sizeof(sdev)); 201 202 strncpy(sdev.name, dev->name, sizeof(sdev.name)); 203 sdev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 204 sdev.priv = dev; 205 sdev.putc = serial_stub_putc; 206 sdev.puts = serial_stub_puts; 207 sdev.getc = serial_stub_getc; 208 sdev.tstc = serial_stub_tstc; 209 stdio_register_dev(&sdev, &upriv->sdev); 210 211 return 0; 212 } 213 214 static int serial_pre_remove(struct udevice *dev) 215 { 216 #ifdef CONFIG_SYS_STDIO_DEREGISTER 217 struct serial_dev_priv *upriv = dev->uclass_priv; 218 219 if (stdio_deregister_dev(upriv->sdev, 0)) 220 return -EPERM; 221 #endif 222 223 return 0; 224 } 225 226 UCLASS_DRIVER(serial) = { 227 .id = UCLASS_SERIAL, 228 .name = "serial", 229 .post_probe = serial_post_probe, 230 .pre_remove = serial_pre_remove, 231 .per_device_auto_alloc_size = sizeof(struct serial_dev_priv), 232 }; 233