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