#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/serial_core.h>
#include <linux/init.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
#include "suncore.h"
-int sunserial_current_minor = 64;
+static int sunserial_current_minor = 64;
-EXPORT_SYMBOL(sunserial_current_minor);
-
-void
-sunserial_console_termios(struct console *con)
+int sunserial_register_minors(struct uart_driver *drv, int count)
{
- char mode[16], buf[16], *s;
- char *mode_prop = "ttyX-mode";
- char *cd_prop = "ttyX-ignore-cd";
- char *dtr_prop = "ttyX-rts-dtr-off";
- char *ssp_console_modes_prop = "ssp-console-modes";
- int baud, bits, stop, cflag;
- char parity;
- int carrier = 0;
- int rtsdtr = 1;
- int topnd, nd;
-
- if (!serial_console)
- return;
-
- switch (serial_console) {
- case PROMDEV_OTTYA:
- mode_prop[3] = 'a';
- cd_prop[3] = 'a';
- dtr_prop[3] = 'a';
- break;
-
- case PROMDEV_OTTYB:
- mode_prop[3] = 'b';
- cd_prop[3] = 'b';
- dtr_prop[3] = 'b';
- break;
-
- case PROMDEV_ORSC:
-
- nd = prom_pathtoinode("rsc");
- if (!nd) {
- strcpy(mode, "115200,8,n,1,-");
- goto no_options;
- }
+ int err = 0;
+
+ drv->minor = sunserial_current_minor;
+ drv->nr += count;
+ /* Register the driver on the first call */
+ if (drv->nr == count)
+ err = uart_register_driver(drv);
+ if (err == 0) {
+ sunserial_current_minor += count;
+ drv->tty_driver->name_base = drv->minor - 64;
+ }
+ return err;
+}
+EXPORT_SYMBOL(sunserial_register_minors);
- if (!prom_node_has_property(nd, ssp_console_modes_prop)) {
- strcpy(mode, "115200,8,n,1,-");
- goto no_options;
- }
+void sunserial_unregister_minors(struct uart_driver *drv, int count)
+{
+ drv->nr -= count;
+ sunserial_current_minor -= count;
- memset(mode, 0, sizeof(mode));
- prom_getstring(nd, ssp_console_modes_prop, mode, sizeof(mode));
- goto no_options;
+ if (drv->nr == 0)
+ uart_unregister_driver(drv);
+}
+EXPORT_SYMBOL(sunserial_unregister_minors);
- default:
- strcpy(mode, "9600,8,n,1,-");
- goto no_options;
- }
+int sunserial_console_match(struct console *con, struct device_node *dp,
+ struct uart_driver *drv, int line)
+{
+ int off;
- topnd = prom_getchild(prom_root_node);
- nd = prom_searchsiblings(topnd, "options");
- if (!nd) {
- strcpy(mode, "9600,8,n,1,-");
- goto no_options;
- }
+ if (!con || of_console_device != dp)
+ return 0;
- if (!prom_node_has_property(nd, mode_prop)) {
- strcpy(mode, "9600,8,n,1,-");
- goto no_options;
- }
+ off = 0;
+ if (of_console_options &&
+ *of_console_options == 'b')
+ off = 1;
- memset(mode, 0, sizeof(mode));
- prom_getstring(nd, mode_prop, mode, sizeof(mode));
+ if ((line & 1) != off)
+ return 0;
- if (prom_node_has_property(nd, cd_prop)) {
- memset(buf, 0, sizeof(buf));
- prom_getstring(nd, cd_prop, buf, sizeof(buf));
- if (!strcmp(buf, "false"))
- carrier = 1;
+ con->index = line;
+ drv->cons = con;
+ add_preferred_console(con->name, line, NULL);
- /* XXX: this is unused below. */
- }
+ return 1;
+}
+EXPORT_SYMBOL(sunserial_console_match);
- if (prom_node_has_property(nd, dtr_prop)) {
- memset(buf, 0, sizeof(buf));
- prom_getstring(nd, dtr_prop, buf, sizeof(buf));
- if (!strcmp(buf, "false"))
- rtsdtr = 0;
+void
+sunserial_console_termios(struct console *con)
+{
+ struct device_node *dp;
+ const char *od, *mode, *s;
+ char mode_prop[] = "ttyX-mode";
+ int baud, bits, stop, cflag;
+ char parity;
- /* XXX: this is unused below. */
+ dp = of_find_node_by_path("/options");
+ od = of_get_property(dp, "output-device", NULL);
+ if (!strcmp(od, "rsc")) {
+ mode = of_get_property(of_console_device,
+ "ssp-console-modes", NULL);
+ if (!mode)
+ mode = "115200,8,n,1,-";
+ } else {
+ char c;
+
+ c = 'a';
+ if (of_console_options)
+ c = *of_console_options;
+
+ mode_prop[3] = c;
+
+ mode = of_get_property(dp, mode_prop, NULL);
+ if (!mode)
+ mode = "9600,8,n,1,-";
}
-no_options:
cflag = CREAD | HUPCL | CLOCAL;
s = mode;
con->cflag = cflag;
}
-EXPORT_SYMBOL(sunserial_console_termios);
-
/* Sun serial MOUSE auto baud rate detection. */
static struct mouse_baud_cflag {
int baud;