console-server: Fix tty paths with Linux 6.8+

The sysfs files are found in a different path with newer Linux
versions, so update the vuart config search code.

The relevant linux change is [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b286f4e87e325b76789f30337c98ba72e00532e2
Change-Id: Iab686d384b20d8e2495ebbc04a1632be85919cb9
Co-authored-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Eddie James <eajames@linux.ibm.com>
diff --git a/console-server.c b/console-server.c
index 222f215..b38de9b 100644
--- a/console-server.c
+++ b/console-server.c
@@ -216,31 +216,62 @@
 	// Default to non-VUART
 	server->tty.type = TTY_DEVICE_UART;
 
-	rc = asprintf(&tty_device_reldir, "%s/../../", tty_device_tty_dir);
-	if (rc < 0) {
-		goto out_free;
-	}
-
-	tty_sysfs_devnode = realpath(tty_device_reldir, NULL);
-	/* not really an error, but it'd be unusual if we cannot resolve
-	 * two parent dirs...
+	/* Prior to 6.8, we have the tty device directly under the platform
+	 * device:
+	 *
+	 *  1e787000.serial/lpc_address
+	 *  1e787000.serial/tty/ttySx/
+	 *
+	 * As of 6.8, those serial devices now use the port/serdev (:m.n)
+	 * layout reflected in the sysfs structure:
+	 *
+	 *  1e787000.serial/lpc_address
+	 *  1e787000.serial/1e787000.serial:0/1e787000.serial:0.0/tty/ttySx/
+	 *
+	 * - so we need to check for both
 	 */
-	if (!tty_sysfs_devnode) {
-		warn("Can't find parent device for %s", tty_kname_real);
-		rc = 0;
-		goto out_free;
-	}
+	const char *rel_dirs[] = {
+		"../../../../",
+		"../../",
+	};
 
-	/* Arbitrarily pick an attribute to differentiate UART vs VUART */
-	rc = asprintf(&tty_vuart_lpc_addr, "%s/lpc_address", tty_sysfs_devnode);
-	if (rc < 0) {
-		goto out_free;
-	}
+	for (unsigned int i = 0; i < (sizeof(rel_dirs) / sizeof(rel_dirs[0]));
+	     i++) {
+		const char *rel_dir = rel_dirs[i];
 
-	rc = access(tty_vuart_lpc_addr, F_OK);
-	if (!rc) {
-		server->tty.type = TTY_DEVICE_VUART;
-		server->tty.vuart.sysfs_devnode = strdup(tty_sysfs_devnode);
+		free(tty_device_reldir);
+		free(tty_sysfs_devnode);
+
+		rc = asprintf(&tty_device_reldir, "%s/%s", tty_device_tty_dir,
+			      rel_dir);
+		if (rc < 0) {
+			goto out_free;
+		}
+
+		tty_sysfs_devnode = realpath(tty_device_reldir, NULL);
+		/* not really an error, but it'd be unusual if we cannot
+		 * resolve two parent dirs...
+		 */
+		if (!tty_sysfs_devnode) {
+			warn("Can't find parent device for %s", tty_kname_real);
+			rc = 0;
+			goto out_free;
+		}
+
+		/* Arbitrarily pick an attribute to determine UART vs VUART */
+		rc = asprintf(&tty_vuart_lpc_addr, "%s/lpc_address",
+			      tty_sysfs_devnode);
+		if (rc < 0) {
+			goto out_free;
+		}
+
+		rc = access(tty_vuart_lpc_addr, F_OK);
+		if (!rc) {
+			server->tty.type = TTY_DEVICE_VUART;
+			server->tty.vuart.sysfs_devnode =
+				strdup(tty_sysfs_devnode);
+			break;
+		}
 	}
 
 	rc = 0;