1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net> 4 * 5 * Changes for multibus/multiadapter I2C support. 6 * 7 * (C) Copyright 2000 8 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it 9 */ 10 11 #include <config.h> 12 #include <common.h> 13 #include <dm.h> 14 #include <errno.h> 15 #include <stdarg.h> 16 #include <malloc.h> 17 #include <stdio_dev.h> 18 #include <serial.h> 19 20 #if defined(CONFIG_SYS_I2C) 21 #include <i2c.h> 22 #endif 23 24 #include <dm/device-internal.h> 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 static struct stdio_dev devs; 29 struct stdio_dev *stdio_devices[] = { NULL, NULL, NULL }; 30 char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" }; 31 32 #if defined(CONFIG_SPLASH_SCREEN) && !defined(CONFIG_SYS_DEVICE_NULLDEV) 33 #define CONFIG_SYS_DEVICE_NULLDEV 1 34 #endif 35 36 #if CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER) 37 #define CONFIG_SYS_DEVICE_NULLDEV 1 38 #endif 39 40 #ifdef CONFIG_SYS_DEVICE_NULLDEV 41 static void nulldev_putc(struct stdio_dev *dev, const char c) 42 { 43 /* nulldev is empty! */ 44 } 45 46 static void nulldev_puts(struct stdio_dev *dev, const char *s) 47 { 48 /* nulldev is empty! */ 49 } 50 51 static int nulldev_input(struct stdio_dev *dev) 52 { 53 /* nulldev is empty! */ 54 return 0; 55 } 56 #endif 57 58 static void stdio_serial_putc(struct stdio_dev *dev, const char c) 59 { 60 serial_putc(c); 61 } 62 63 static void stdio_serial_puts(struct stdio_dev *dev, const char *s) 64 { 65 serial_puts(s); 66 } 67 68 static int stdio_serial_getc(struct stdio_dev *dev) 69 { 70 return serial_getc(); 71 } 72 73 static int stdio_serial_tstc(struct stdio_dev *dev) 74 { 75 return serial_tstc(); 76 } 77 78 /************************************************************************** 79 * SYSTEM DRIVERS 80 ************************************************************************** 81 */ 82 83 static void drv_system_init (void) 84 { 85 struct stdio_dev dev; 86 87 memset (&dev, 0, sizeof (dev)); 88 89 strcpy (dev.name, "serial"); 90 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 91 dev.putc = stdio_serial_putc; 92 dev.puts = stdio_serial_puts; 93 dev.getc = stdio_serial_getc; 94 dev.tstc = stdio_serial_tstc; 95 stdio_register (&dev); 96 97 #ifdef CONFIG_SYS_DEVICE_NULLDEV 98 memset (&dev, 0, sizeof (dev)); 99 100 strcpy (dev.name, "nulldev"); 101 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 102 dev.putc = nulldev_putc; 103 dev.puts = nulldev_puts; 104 dev.getc = nulldev_input; 105 dev.tstc = nulldev_input; 106 107 stdio_register (&dev); 108 #endif 109 } 110 111 /************************************************************************** 112 * DEVICES 113 ************************************************************************** 114 */ 115 struct list_head* stdio_get_list(void) 116 { 117 return &(devs.list); 118 } 119 120 #ifdef CONFIG_DM_VIDEO 121 /** 122 * stdio_probe_device() - Find a device which provides the given stdio device 123 * 124 * This looks for a device of the given uclass which provides a particular 125 * stdio device. It is currently really only useful for UCLASS_VIDEO. 126 * 127 * Ultimately we want to be able to probe a device by its stdio name. At 128 * present devices register in their probe function (for video devices this 129 * is done in vidconsole_post_probe()) and we don't know what name they will 130 * use until they do so. 131 * TODO(sjg@chromium.org): We should be able to determine the name before 132 * probing, and probe the required device. 133 * 134 * @name: stdio device name (e.g. "vidconsole") 135 * id: Uclass ID of device to look for (e.g. UCLASS_VIDEO) 136 * @sdevp: Returns stdout device, if found, else NULL 137 * @return 0 if found, -ENOENT if no device found with that name, other -ve 138 * on other error 139 */ 140 static int stdio_probe_device(const char *name, enum uclass_id id, 141 struct stdio_dev **sdevp) 142 { 143 struct stdio_dev *sdev; 144 struct udevice *dev; 145 int seq, ret; 146 147 *sdevp = NULL; 148 seq = trailing_strtoln(name, NULL); 149 if (seq == -1) 150 seq = 0; 151 ret = uclass_get_device_by_seq(id, seq, &dev); 152 if (ret == -ENODEV) 153 ret = uclass_first_device_err(id, &dev); 154 if (ret) { 155 debug("No %s device for seq %d (%s)\n", uclass_get_name(id), 156 seq, name); 157 return ret; 158 } 159 /* The device should be be the last one registered */ 160 sdev = list_empty(&devs.list) ? NULL : 161 list_last_entry(&devs.list, struct stdio_dev, list); 162 if (!sdev || strcmp(sdev->name, name)) { 163 debug("Device '%s' did not register with stdio as '%s'\n", 164 dev->name, name); 165 return -ENOENT; 166 } 167 *sdevp = sdev; 168 169 return 0; 170 } 171 #endif 172 173 struct stdio_dev *stdio_get_by_name(const char *name) 174 { 175 struct list_head *pos; 176 struct stdio_dev *sdev; 177 178 if (!name) 179 return NULL; 180 181 list_for_each(pos, &(devs.list)) { 182 sdev = list_entry(pos, struct stdio_dev, list); 183 if (strcmp(sdev->name, name) == 0) 184 return sdev; 185 } 186 #ifdef CONFIG_DM_VIDEO 187 /* 188 * We did not find a suitable stdio device. If there is a video 189 * driver with a name starting with 'vidconsole', we can try probing 190 * that in the hope that it will produce the required stdio device. 191 * 192 * This function is sometimes called with the entire value of 193 * 'stdout', which may include a list of devices separate by commas. 194 * Obviously this is not going to work, so we ignore that case. The 195 * call path in that case is console_init_r() -> search_device() -> 196 * stdio_get_by_name(). 197 */ 198 if (!strncmp(name, "vidconsole", 10) && !strchr(name, ',') && 199 !stdio_probe_device(name, UCLASS_VIDEO, &sdev)) 200 return sdev; 201 #endif 202 203 return NULL; 204 } 205 206 struct stdio_dev* stdio_clone(struct stdio_dev *dev) 207 { 208 struct stdio_dev *_dev; 209 210 if(!dev) 211 return NULL; 212 213 _dev = calloc(1, sizeof(struct stdio_dev)); 214 215 if(!_dev) 216 return NULL; 217 218 memcpy(_dev, dev, sizeof(struct stdio_dev)); 219 220 return _dev; 221 } 222 223 int stdio_register_dev(struct stdio_dev *dev, struct stdio_dev **devp) 224 { 225 struct stdio_dev *_dev; 226 227 _dev = stdio_clone(dev); 228 if(!_dev) 229 return -ENODEV; 230 list_add_tail(&(_dev->list), &(devs.list)); 231 if (devp) 232 *devp = _dev; 233 234 return 0; 235 } 236 237 int stdio_register(struct stdio_dev *dev) 238 { 239 return stdio_register_dev(dev, NULL); 240 } 241 242 /* deregister the device "devname". 243 * returns 0 if success, -1 if device is assigned and 1 if devname not found 244 */ 245 #if CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER) 246 int stdio_deregister_dev(struct stdio_dev *dev, int force) 247 { 248 int l; 249 struct list_head *pos; 250 char temp_names[3][16]; 251 252 /* get stdio devices (ListRemoveItem changes the dev list) */ 253 for (l=0 ; l< MAX_FILES; l++) { 254 if (stdio_devices[l] == dev) { 255 if (force) { 256 strcpy(temp_names[l], "nulldev"); 257 continue; 258 } 259 /* Device is assigned -> report error */ 260 return -1; 261 } 262 memcpy (&temp_names[l][0], 263 stdio_devices[l]->name, 264 sizeof(temp_names[l])); 265 } 266 267 list_del(&(dev->list)); 268 free(dev); 269 270 /* reassign Device list */ 271 list_for_each(pos, &(devs.list)) { 272 dev = list_entry(pos, struct stdio_dev, list); 273 for (l=0 ; l< MAX_FILES; l++) { 274 if(strcmp(dev->name, temp_names[l]) == 0) 275 stdio_devices[l] = dev; 276 } 277 } 278 return 0; 279 } 280 281 int stdio_deregister(const char *devname, int force) 282 { 283 struct stdio_dev *dev; 284 285 dev = stdio_get_by_name(devname); 286 287 if (!dev) /* device not found */ 288 return -ENODEV; 289 290 return stdio_deregister_dev(dev, force); 291 } 292 #endif /* CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER) */ 293 294 int stdio_init_tables(void) 295 { 296 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 297 /* already relocated for current ARM implementation */ 298 ulong relocation_offset = gd->reloc_off; 299 int i; 300 301 /* relocate device name pointers */ 302 for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) { 303 stdio_names[i] = (char *) (((ulong) stdio_names[i]) + 304 relocation_offset); 305 } 306 #endif /* CONFIG_NEEDS_MANUAL_RELOC */ 307 308 /* Initialize the list */ 309 INIT_LIST_HEAD(&(devs.list)); 310 311 return 0; 312 } 313 314 int stdio_add_devices(void) 315 { 316 #ifdef CONFIG_DM_KEYBOARD 317 struct udevice *dev; 318 struct uclass *uc; 319 int ret; 320 321 /* 322 * For now we probe all the devices here. At some point this should be 323 * done only when the devices are required - e.g. we have a list of 324 * input devices to start up in the stdin environment variable. That 325 * work probably makes more sense when stdio itself is converted to 326 * driver model. 327 * 328 * TODO(sjg@chromium.org): Convert changing uclass_first_device() etc. 329 * to return the device even on error. Then we could use that here. 330 */ 331 ret = uclass_get(UCLASS_KEYBOARD, &uc); 332 if (ret) 333 return ret; 334 335 /* Don't report errors to the caller - assume that they are non-fatal */ 336 uclass_foreach_dev(dev, uc) { 337 ret = device_probe(dev); 338 if (ret) 339 printf("Failed to probe keyboard '%s'\n", dev->name); 340 } 341 #endif 342 #ifdef CONFIG_SYS_I2C 343 i2c_init_all(); 344 #else 345 #endif 346 #ifdef CONFIG_DM_VIDEO 347 /* 348 * If the console setting is not in environment variables then 349 * console_init_r() will not be calling iomux_doenv() (which calls 350 * search_device()). So we will not dynamically add devices by 351 * calling stdio_probe_device(). 352 * 353 * So just probe all video devices now so that whichever one is 354 * required will be available. 355 */ 356 #ifndef CONFIG_SYS_CONSOLE_IS_IN_ENV 357 struct udevice *vdev; 358 # ifndef CONFIG_DM_KEYBOARD 359 int ret; 360 # endif 361 362 for (ret = uclass_first_device(UCLASS_VIDEO, &vdev); 363 vdev; 364 ret = uclass_next_device(&vdev)) 365 ; 366 if (ret) 367 printf("%s: Video device failed (ret=%d)\n", __func__, ret); 368 #endif /* !CONFIG_SYS_CONSOLE_IS_IN_ENV */ 369 #else 370 # if defined(CONFIG_LCD) 371 drv_lcd_init (); 372 # endif 373 # if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) 374 drv_video_init (); 375 # endif 376 #endif /* CONFIG_DM_VIDEO */ 377 #if defined(CONFIG_KEYBOARD) && !defined(CONFIG_DM_KEYBOARD) 378 drv_keyboard_init (); 379 #endif 380 drv_system_init (); 381 serial_stdio_init (); 382 #ifdef CONFIG_USB_TTY 383 drv_usbtty_init (); 384 #endif 385 #ifdef CONFIG_NETCONSOLE 386 drv_nc_init (); 387 #endif 388 #ifdef CONFIG_JTAG_CONSOLE 389 drv_jtag_console_init (); 390 #endif 391 #ifdef CONFIG_CBMEM_CONSOLE 392 cbmemc_init(); 393 #endif 394 395 return 0; 396 } 397 398 int stdio_init(void) 399 { 400 stdio_init_tables(); 401 stdio_add_devices(); 402 403 return 0; 404 } 405