0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <stdarg.h>
0015 #include <stddef.h>
0016 #include "types.h"
0017 #include "string.h"
0018 #include "stdio.h"
0019 #include "io.h"
0020 #include "ops.h"
0021
0022 static int serial_open(void)
0023 {
0024 struct serial_console_data *scdp = console_ops.data;
0025 return scdp->open();
0026 }
0027
0028 static void serial_write(const char *buf, int len)
0029 {
0030 struct serial_console_data *scdp = console_ops.data;
0031
0032 while (*buf != '\0')
0033 scdp->putc(*buf++);
0034 }
0035
0036 static void serial_edit_cmdline(char *buf, int len, unsigned int timeout)
0037 {
0038 int timer = 0, count;
0039 char ch, *cp;
0040 struct serial_console_data *scdp = console_ops.data;
0041
0042 cp = buf;
0043 count = strlen(buf);
0044 cp = &buf[count];
0045 count++;
0046
0047 do {
0048 if (scdp->tstc()) {
0049 while (((ch = scdp->getc()) != '\n') && (ch != '\r')) {
0050
0051 if ((ch == '\b') || (ch == '\177')) {
0052 if (cp != buf) {
0053 cp--;
0054 count--;
0055 printf("\b \b");
0056 }
0057
0058 } else if ((ch == '\030') || (ch == '\025')) {
0059 while (cp != buf) {
0060 cp--;
0061 count--;
0062 printf("\b \b");
0063 }
0064 } else if (count < len) {
0065 *cp++ = ch;
0066 count++;
0067 scdp->putc(ch);
0068 }
0069 }
0070 break;
0071 }
0072 udelay(1000);
0073 } while (timer++ < timeout);
0074 *cp = 0;
0075 }
0076
0077 static void serial_close(void)
0078 {
0079 struct serial_console_data *scdp = console_ops.data;
0080
0081 if (scdp->close)
0082 scdp->close();
0083 }
0084
0085 static void *serial_get_stdout_devp(void)
0086 {
0087 void *devp;
0088 char devtype[MAX_PROP_LEN];
0089 char path[MAX_PATH_LEN];
0090
0091 devp = finddevice("/chosen");
0092 if (devp == NULL)
0093 goto err_out;
0094
0095 if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0 ||
0096 getprop(devp, "stdout-path", path, MAX_PATH_LEN) > 0) {
0097 devp = finddevice(path);
0098 if (devp == NULL)
0099 goto err_out;
0100
0101 if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
0102 && !strcmp(devtype, "serial"))
0103 return devp;
0104 }
0105 err_out:
0106 return NULL;
0107 }
0108
0109 static struct serial_console_data serial_cd;
0110
0111
0112 int serial_console_init(void)
0113 {
0114 void *devp;
0115 int rc = -1;
0116
0117 devp = serial_get_stdout_devp();
0118 if (devp == NULL)
0119 goto err_out;
0120
0121 if (dt_is_compatible(devp, "ns16550") ||
0122 dt_is_compatible(devp, "pnpPNP,501"))
0123 rc = ns16550_console_init(devp, &serial_cd);
0124 #ifdef CONFIG_CPM
0125 else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") ||
0126 dt_is_compatible(devp, "fsl,cpm1-smc-uart") ||
0127 dt_is_compatible(devp, "fsl,cpm2-scc-uart") ||
0128 dt_is_compatible(devp, "fsl,cpm2-smc-uart"))
0129 rc = cpm_console_init(devp, &serial_cd);
0130 #endif
0131 #ifdef CONFIG_PPC_MPC52xx
0132 else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart"))
0133 rc = mpc5200_psc_console_init(devp, &serial_cd);
0134 #endif
0135 #ifdef CONFIG_PPC_POWERNV
0136 else if (dt_is_compatible(devp, "ibm,opal-console-raw"))
0137 rc = opal_console_init(devp, &serial_cd);
0138 #endif
0139
0140
0141
0142 if (!rc) {
0143 console_ops.open = serial_open;
0144 console_ops.write = serial_write;
0145 console_ops.close = serial_close;
0146 console_ops.data = &serial_cd;
0147
0148 if (serial_cd.getc)
0149 console_ops.edit_cmdline = serial_edit_cmdline;
0150
0151 return 0;
0152 }
0153 err_out:
0154 return -1;
0155 }