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