Commit 709ea543 authored by Simon Glass's avatar Simon Glass

stdio: Pass device pointer to stdio methods

At present stdio device functions do not get any clue as to which stdio
device is being acted on. Some implementations go to great lengths to work
around this, such as defining a whole separate set of functions for each
possible device.

For driver model we need to associate a stdio_dev with a device. It doesn't
seem possible to continue with this work-around approach.

Instead, add a stdio_dev pointer to each of the stdio member functions.

Note: The serial drivers have the same problem, but it is not strictly
necessary to fix that to get driver model running. Also, if we convert
serial over to driver model the problem will go away.

Code size increases by 244 bytes for Thumb2 and 428 for PowerPC.

22: stdio: Pass device pointer to stdio methods
       arm: (for 2/2 boards)  all +244.0  bss -4.0  text +248.0
   powerpc: (for 1/1 boards)  all +428.0  text +428.0
Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
Acked-by: default avatarMarek Vasut <marex@denx.de>
Reviewed-by: default avatarMarek Vasut <marex@denx.de>
parent 91d0be1d
......@@ -112,11 +112,11 @@ static void jtag_send(const char *raw_str, uint32_t len)
if (cooked_str != raw_str)
free((char *)cooked_str);
}
static void jtag_putc(const char c)
static void jtag_putc(struct stdio_dev *dev, const char c)
{
jtag_send(&c, 1);
}
static void jtag_puts(const char *s)
static void jtag_puts(struct stdio_dev *dev, const char *s)
{
jtag_send(s, strlen(s));
}
......@@ -133,7 +133,7 @@ static int jtag_tstc_dbg(void)
}
/* Higher layers want to know when any data is available */
static int jtag_tstc(void)
static int jtag_tstc(struct stdio_dev *dev)
{
return jtag_tstc_dbg() || leftovers_len;
}
......@@ -142,7 +142,7 @@ static int jtag_tstc(void)
* [32bit length][actual data]
*/
static uint32_t leftovers;
static int jtag_getc(void)
static int jtag_getc(struct stdio_dev *dev)
{
int ret;
uint32_t emudat;
......@@ -173,7 +173,7 @@ static int jtag_getc(void)
leftovers = emudat;
}
return jtag_getc();
return jtag_getc(dev);
}
int drv_jtag_console_init(void)
......
......@@ -384,7 +384,7 @@ struct stdio_dev *open_port(int num, int baudrate)
sprintf(env_val, "%d", baudrate);
setenv(env_var, env_val);
if (port->start())
if (port->start(port))
return NULL;
set_bit(num, &initialized);
......@@ -407,7 +407,7 @@ int close_port(int num)
if (!port)
return -1;
ret = port->stop();
ret = port->stop(port);
clear_bit(num, &initialized);
return ret;
......@@ -418,7 +418,7 @@ int write_port(struct stdio_dev *port, char *buf)
if (!port || !buf)
return -1;
port->puts(buf);
port->puts(port, buf);
return 0;
}
......@@ -433,8 +433,8 @@ int read_port(struct stdio_dev *port, char *buf, int size)
if (!size)
return 0;
while (port->tstc()) {
buf[cnt++] = port->getc();
while (port->tstc(port)) {
buf[cnt++] = port->getc(port);
if (cnt > size)
break;
}
......
......@@ -948,7 +948,7 @@ static inline void console_newline (void)
}
}
void video_putc (const char c)
void video_putc(struct stdio_dev *dev, const char c)
{
if (!video_enable) {
serial_putc (c);
......@@ -985,7 +985,7 @@ void video_putc (const char c)
}
}
void video_puts (const char *s)
void video_puts(struct stdio_dev *dev, const char *s)
{
int count = strlen (s);
......@@ -994,7 +994,7 @@ void video_puts (const char *s)
serial_putc (*s++);
else
while (count--)
video_putc (*s++);
video_putc(dev, *s++);
}
/************************************************************************/
......
......@@ -104,7 +104,7 @@ static void __video_putc(const char c, int *x, int *y)
}
}
static void video_putc(const char c)
static void video_putc(struct stdio_dev *dev, const char c)
{
int x, y, pos;
......@@ -123,7 +123,7 @@ static void video_putc(const char c)
outb_p(0xff & (pos >> 1), vidport+1);
}
static void video_puts(const char *s)
static void video_puts(struct stdio_dev *dev, const char *s)
{
int x, y, pos;
char c;
......
......@@ -248,7 +248,7 @@ void kbd_put_queue(char data)
}
/* test if a character is in the queue */
int kbd_testc(void)
int kbd_testc(struct stdio_dev *dev)
{
if(in_pointer==out_pointer)
return(0); /* no data */
......@@ -256,7 +256,7 @@ int kbd_testc(void)
return(1);
}
/* gets the character from the queue */
int kbd_getc(void)
int kbd_getc(struct stdio_dev *dev)
{
char c;
while(in_pointer==out_pointer);
......
......@@ -8,8 +8,10 @@
#ifndef _KBD_H_
#define _KBD_H_
extern int kbd_testc(void);
extern int kbd_getc(void);
struct stdio_dev;
int kbd_testc(struct stdio_dev *sdev);
int kbd_getc(struct stdio_dev *sdev);
extern void kbd_interrupt(void);
extern char *kbd_initialize(void);
......
......@@ -445,7 +445,7 @@ void pci_con_put_it(const char c)
PCICON_SET_REG(PCICON_DBELL_REG,PCIMSG_CON_DATA);
}
void pci_con_putc(const char c)
void pci_con_putc(struct stdio_dev *dev, const char c)
{
pci_con_put_it(c);
if(c == '\n')
......@@ -453,7 +453,7 @@ void pci_con_putc(const char c)
}
int pci_con_getc(void)
int pci_con_getc(struct stdio_dev *dev)
{
int res;
int diff;
......@@ -473,14 +473,14 @@ int pci_con_getc(void)
return res;
}
int pci_con_tstc(void)
int pci_con_tstc(struct stdio_dev *dev)
{
if(r_ptr==(volatile int)w_ptr)
return 0;
return 1;
}
void pci_con_puts (const char *s)
void pci_con_puts(struct stdio_dev *dev, const char *s)
{
while (*s) {
pci_con_putc(*s);
......
......@@ -585,7 +585,7 @@ static void rx51_kp_fill(u8 k, u8 mods)
* Routine: rx51_kp_tstc
* Description: Test if key was pressed (from buffer).
*/
int rx51_kp_tstc(void)
int rx51_kp_tstc(struct stdio_dev *sdev)
{
u8 c, r, dk, i;
u8 intr;
......@@ -641,10 +641,10 @@ int rx51_kp_tstc(void)
* Routine: rx51_kp_getc
* Description: Get last pressed key (from buffer).
*/
int rx51_kp_getc(void)
int rx51_kp_getc(struct stdio_dev *sdev)
{
keybuf_head %= KEYBUF_SIZE;
while (!rx51_kp_tstc())
while (!rx51_kp_tstc(sdev))
WATCHDOG_RESET();
return keybuf[keybuf_head++];
}
......
......@@ -33,8 +33,8 @@
DECLARE_GLOBAL_DATA_PTR;
/* Local prototypes */
static void logbuff_putc(const char c);
static void logbuff_puts(const char *s);
static void logbuff_putc(struct stdio_dev *dev, const char c);
static void logbuff_puts(struct stdio_dev *dev, const char *s);
static int logbuff_printk(const char *line);
static char buf[1024];
......@@ -143,7 +143,7 @@ int drv_logbuff_init(void)
return (rc == 0) ? 1 : rc;
}
static void logbuff_putc(const char c)
static void logbuff_putc(struct stdio_dev *dev, const char c)
{
char buf[2];
buf[0] = c;
......@@ -151,7 +151,7 @@ static void logbuff_putc(const char c)
logbuff_printk(buf);
}
static void logbuff_puts(const char *s)
static void logbuff_puts(struct stdio_dev *dev, const char *s)
{
logbuff_printk (s);
}
......@@ -181,6 +181,7 @@ void logbuff_log(char *msg)
*/
int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct stdio_dev *sdev = NULL;
char *s;
unsigned long i, start, size;
......@@ -188,7 +189,7 @@ int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* Log concatenation of all arguments separated by spaces */
for (i = 2; i < argc; i++) {
logbuff_printk(argv[i]);
logbuff_putc((i < argc - 1) ? ' ' : '\n');
logbuff_putc(sdev, (i < argc - 1) ? ' ' : '\n');
}
return 0;
}
......
......@@ -109,7 +109,7 @@ static int console_setfile(int file, struct stdio_dev * dev)
case stderr:
/* Start new device */
if (dev->start) {
error = dev->start();
error = dev->start(dev);
/* If it's not started dont use it */
if (error < 0)
break;
......@@ -159,7 +159,7 @@ static int console_getc(int file)
unsigned char ret;
/* This is never called with testcdev == NULL */
ret = tstcdev->getc();
ret = tstcdev->getc(tstcdev);
tstcdev = NULL;
return ret;
}
......@@ -173,7 +173,7 @@ static int console_tstc(int file)
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->tstc != NULL) {
ret = dev->tstc();
ret = dev->tstc(dev);
if (ret > 0) {
tstcdev = dev;
disable_ctrlc(0);
......@@ -194,7 +194,7 @@ static void console_putc(int file, const char c)
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->putc != NULL)
dev->putc(c);
dev->putc(dev, c);
}
}
......@@ -206,7 +206,7 @@ static void console_puts(int file, const char *s)
for (i = 0; i < cd_count[file]; i++) {
dev = console_devices[file][i];
if (dev->puts != NULL)
dev->puts(s);
dev->puts(dev, s);
}
}
......@@ -222,22 +222,22 @@ static inline void console_doenv(int file, struct stdio_dev *dev)
#else
static inline int console_getc(int file)
{
return stdio_devices[file]->getc();
return stdio_devices[file]->getc(stdio_devices[file]);
}
static inline int console_tstc(int file)
{
return stdio_devices[file]->tstc();
return stdio_devices[file]->tstc(stdio_devices[file]);
}
static inline void console_putc(int file, const char c)
{
stdio_devices[file]->putc(c);
stdio_devices[file]->putc(stdio_devices[file], c);
}
static inline void console_puts(int file, const char *s)
{
stdio_devices[file]->puts(s);
stdio_devices[file]->puts(stdio_devices[file], s);
}
static inline void console_printdevs(int file)
......
......@@ -214,6 +214,11 @@ static inline void console_newline(void)
/*----------------------------------------------------------------------*/
static void lcd_stub_putc(struct stdio_dev *dev, const char c)
{
lcd_putc(c);
}
void lcd_putc(const char c)
{
if (!lcd_is_enabled) {
......@@ -253,6 +258,11 @@ void lcd_putc(const char c)
/*----------------------------------------------------------------------*/
static void lcd_stub_puts(struct stdio_dev *dev, const char *s)
{
lcd_puts(s);
}
void lcd_puts(const char *s)
{
if (!lcd_is_enabled) {
......@@ -426,8 +436,8 @@ int drv_lcd_init(void)
strcpy(lcddev.name, "lcd");
lcddev.ext = 0; /* No extensions */
lcddev.flags = DEV_FLAGS_OUTPUT; /* Output only */
lcddev.putc = lcd_putc; /* 'putc' function */
lcddev.puts = lcd_puts; /* 'puts' function */
lcddev.putc = lcd_stub_putc; /* 'putc' function */
lcddev.puts = lcd_stub_puts; /* 'puts' function */
rc = stdio_register(&lcddev);
......
......@@ -35,23 +35,43 @@ char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
#ifdef CONFIG_SYS_DEVICE_NULLDEV
void nulldev_putc(const char c)
void nulldev_putc(struct stdio_dev *dev, const char c)
{
/* nulldev is empty! */
}
void nulldev_puts(const char *s)
void nulldev_puts(struct stdio_dev *dev, const char *s)
{
/* nulldev is empty! */
}
int nulldev_input(void)
int nulldev_input(struct stdio_dev *dev)
{
/* nulldev is empty! */
return 0;
}
#endif
void stdio_serial_putc(struct stdio_dev *dev, const char c)
{
serial_putc(c);
}
void stdio_serial_puts(struct stdio_dev *dev, const char *s)
{
serial_puts(s);
}
int stdio_serial_getc(struct stdio_dev *dev)
{
return serial_getc();
}
int stdio_serial_tstc(struct stdio_dev *dev)
{
return serial_tstc();
}
/**************************************************************************
* SYSTEM DRIVERS
**************************************************************************
......@@ -65,10 +85,10 @@ static void drv_system_init (void)
strcpy (dev.name, "serial");
dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
dev.putc = serial_putc;
dev.puts = serial_puts;
dev.getc = serial_getc;
dev.tstc = serial_tstc;
dev.putc = stdio_serial_putc;
dev.puts = stdio_serial_puts;
dev.getc = stdio_serial_getc;
dev.tstc = stdio_serial_tstc;
stdio_register (&dev);
#ifdef CONFIG_SYS_DEVICE_NULLDEV
......
......@@ -360,7 +360,7 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
}
/* test if a character is in the queue */
static int usb_kbd_testc(void)
static int usb_kbd_testc(struct stdio_dev *sdev)
{
struct stdio_dev *dev;
struct usb_device *usb_kbd_dev;
......@@ -386,7 +386,7 @@ static int usb_kbd_testc(void)
}
/* gets the character from the queue */
static int usb_kbd_getc(void)
static int usb_kbd_getc(struct stdio_dev *sdev)
{
struct stdio_dev *dev;
struct usb_device *usb_kbd_dev;
......
......@@ -93,7 +93,7 @@ static int check_for_keys(struct keyb *config,
*
* @return 0 if no keys available, 1 if keys are available
*/
static int kbd_tstc(void)
static int kbd_tstc(struct stdio_dev *dev)
{
/* Just get input to do this for us */
return config.inited ? input_tstc(&config.input) : 0;
......@@ -104,7 +104,7 @@ static int kbd_tstc(void)
*
* @return ASCII key code, or 0 if no key, or -1 if error
*/
static int kbd_getc(void)
static int kbd_getc(struct stdio_dev *dev)
{
/* Just get input to do this for us */
return config.inited ? input_getc(&config.input) : 0;
......@@ -214,7 +214,7 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
*
* @return 0 if ok, -1 on error
*/
static int cros_ec_init_keyboard(void)
static int cros_ec_init_keyboard(struct stdio_dev *dev)
{
const void *blob = gd->fdt_blob;
int node;
......
......@@ -398,7 +398,7 @@ int i8042_kbd_init(void)
* i8042_tstc - test if keyboard input is available
* option: cursor blinking if called in a loop
*/
int i8042_tstc(void)
int i8042_tstc(struct stdio_dev *dev)
{
unsigned char scan_code = 0;
......@@ -432,7 +432,7 @@ int i8042_tstc(void)
* i8042_getc - wait till keyboard input is available
* option: turn on/off cursor while waiting
*/
int i8042_getc(void)
int i8042_getc(struct stdio_dev *dev)
{
int ret_chr;
unsigned char scan_code;
......
......@@ -70,7 +70,7 @@ static void kbd_put_queue(char data)
}
/* test if a character is in the queue */
static int kbd_testc(void)
static int kbd_testc(struct stdio_dev *dev)
{
#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555)
/* no ISR is used, so received chars must be polled */
......@@ -83,7 +83,7 @@ static int kbd_testc(void)
}
/* gets the character from the queue */
static int kbd_getc(void)
static int kbd_getc(struct stdio_dev *dev)
{
char c;
while(in_pointer==out_pointer) {
......
......@@ -194,7 +194,7 @@ int tegra_kbc_check(struct input_config *input)
*
* @return 0 if no keys available, 1 if keys are available
*/
static int kbd_tstc(void)
static int kbd_tstc(struct stdio_dev *dev)
{
/* Just get input to do this for us */
return input_tstc(&config.input);
......@@ -207,7 +207,7 @@ static int kbd_tstc(void)
*
* @return ASCII key code, or 0 if no key, or -1 if error
*/
static int kbd_getc(void)
static int kbd_getc(struct stdio_dev *dev)
{
/* Just get input to do this for us */
return input_getc(&config.input);
......@@ -289,7 +289,7 @@ static void tegra_kbc_open(void)
*
* @return 0 if ok, -ve on error
*/
static int init_tegra_keyboard(void)
static int init_tegra_keyboard(struct stdio_dev *dev)
{
/* check if already created */
if (config.created)
......
......@@ -31,7 +31,7 @@ struct cbmem_console {
static struct cbmem_console *cbmem_console_p;
void cbmemc_putc(char data)
void cbmemc_putc(struct stdio_dev *dev, char data)
{
int cursor;
......@@ -40,12 +40,12 @@ void cbmemc_putc(char data)
cbmem_console_p->buffer_body[cursor] = data;
}
void cbmemc_puts(const char *str)
void cbmemc_puts(struct stdio_dev *dev, const char *str)
{
char c;
while ((c = *str++) != 0)
cbmemc_putc(c);
cbmemc_putc(dev, c);
}
int cbmemc_init(void)
......
......@@ -215,7 +215,7 @@ static void nc_send_packet(const char *buf, int len)
}
}
static int nc_start(void)
static int nc_start(struct stdio_dev *dev)
{
int retval;
......@@ -235,7 +235,7 @@ static int nc_start(void)
return 0;
}
static void nc_putc(char c)
static void nc_putc(struct stdio_dev *dev, char c)
{
if (output_recursion)
return;
......@@ -246,7 +246,7 @@ static void nc_putc(char c)
output_recursion = 0;
}
static void nc_puts(const char *s)
static void nc_puts(struct stdio_dev *dev, const char *s)
{
int len;
......@@ -265,7 +265,7 @@ static void nc_puts(const char *s)
output_recursion = 0;
}
static int nc_getc(void)
static int nc_getc(struct stdio_dev *dev)
{
uchar c;
......@@ -286,7 +286,7 @@ static int nc_getc(void)
return c;
}
static int nc_tstc(void)
static int nc_tstc(struct stdio_dev *dev)
{
struct eth_device *eth;
......
......@@ -254,6 +254,48 @@ void serial_initialize(void)
serial_assign(default_serial_console()->name);
}
int serial_stub_start(struct stdio_dev *sdev)
{
struct serial_device *dev = sdev->priv;
return dev->start();
}
int serial_stub_stop(struct stdio_dev *sdev)
{
struct serial_device *dev = sdev->priv;
return dev->stop();
}
void serial_stub_putc(struct stdio_dev *sdev, const char ch)
{
struct serial_device *dev = sdev->priv;
dev->putc(ch);
}
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
{
struct serial_device *dev = sdev->priv;
dev->puts(str);
}
int serial_stub_getc(struct stdio_dev *sdev)
{
struct serial_device *dev = sdev->priv;
return dev->getc();
}
int serial_stub_tstc(struct stdio_dev *sdev)
{
struct serial_device *dev = sdev->priv;
return dev->tstc();
}
/**
* serial_stdio_init() - Register serial ports with STDIO core
*
......@@ -272,12 +314,12 @@ void serial_stdio_init(void)
strcpy(dev.name, s->name);
dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
dev.start = s->start;
dev.stop = s->stop;
dev.putc = s->putc;
dev.puts = s->puts;
dev.getc = s->getc;
dev.tstc = s->tstc;
dev.start = serial_stub_start;
dev.stop = serial_stub_stop;
dev.putc = serial_stub_putc;
dev.puts = serial_stub_puts;
dev.getc = serial_stub_getc;
dev.tstc = serial_stub_tstc;
stdio_register(&dev);
......
......@@ -389,7 +389,7 @@ static void str2wide (char *str, u16 * wide)
* Test whether a character is in the RX buffer
*/
int usbtty_tstc (void)
int usbtty_tstc(struct stdio_dev *dev)
{
struct usb_endpoint_instance *endpoint =
&endpoint_instance[rx_endpoint];
......@@ -409,7 +409,7 @@ int usbtty_tstc (void)
* written into its argument c.
*/
int usbtty_getc (void)
int usbtty_getc(struct stdio_dev *dev)
{
char c;
struct usb_endpoint_instance *endpoint =
......@@ -429,7 +429,7 @@ int usbtty_getc (void)
/*
* Output a single byte to the usb client port.
*/
void usbtty_putc (const char c)
void usbtty_putc(struct stdio_dev *dev, const char c)
{
if (!usbtty_configured ())
return;
......@@ -484,7 +484,7 @@ static void __usbtty_puts (const char *str, int len)
}
}
void usbtty_puts (const char *str)
void usbtty_puts(struct stdio_dev *dev, const char *str)
{
int n;
int len;
......
......@@ -944,7 +944,7 @@ static void parse_putc(const char c)
CURSOR_SET;
}
void video_putc(const char c)
void video_putc(struct stdio_dev *dev, const char c)
{
#ifdef CONFIG_CFB_CONSOLE_ANSI
int i;
......@@ -1158,12 +1158,12 @@ void video_putc(const char c)
flush_cache(VIDEO_FB_ADRS, VIDEO_SIZE);
}
void video_puts(const char *s)
void video_puts(struct stdio_dev *dev, const char *s)
{
int count = strlen(s);
while (count--)
video_putc(*s++);
video_putc(dev, *s++);
}
/*
......
......@@ -639,6 +639,11 @@ void serial_puts (const char *);
int serial_getc (void);
int serial_tstc (void);
/* These versions take a stdio_dev pointer */
struct stdio_dev;
int serial_stub_getc(struct stdio_dev *sdev);
int serial_stub_tstc(struct stdio_dev *sdev);
void _serial_setbrg (const int);
void _serial_putc (const char, const int);
void _serial_putc_raw(const char, const int);
......