From: Simon Glass <sjg@chromium.org>
Add serial_priv structure to serial uclass to cache terminal dimensions.
When serial_query_size() successfully queries the terminal, store the
results in the uclass-private data for later retrieval.
This avoids repeated terminal queries and improves performance when
different subsystems need the terminal size.
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
drivers/serial/serial-uclass.c | 38 ++++++++++++++++++++++++++++++++++
include/serial.h | 24 +++++++++++++++++++++
2 files changed, 62 insertions(+)
@@ -24,6 +24,8 @@
DECLARE_GLOBAL_DATA_PTR;
+#define ESC "\x1b"
+
/*
* Table with supported baudrates (defined in config_xyz.h)
*/
@@ -666,8 +668,18 @@ int serial_query_size(int *rowsp, int *colsp)
/* Read {rows,cols} */
ret = term_read_reply(n, 2, 'R');
if (!ret) {
+ struct serial_priv *priv;
+ struct uclass *uc;
+
*colsp = n[1];
*rowsp = n[0];
+
+ /* Store in serial uclass private data if available */
+ if (!uclass_get(UCLASS_SERIAL, &uc)) {
+ priv = uclass_get_priv(uc);
+ priv->rows = n[0];
+ priv->cols = n[1];
+ }
}
printf(ESC "8"); /* Restore cursor position */
@@ -675,6 +687,31 @@ int serial_query_size(int *rowsp, int *colsp)
return ret;
}
+int serial_get_size(struct udevice *dev, int *rowsp, int *colsp)
+{
+ struct serial_priv *priv;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_SERIAL, &uc);
+ if (ret)
+ return ret;
+
+ priv = uclass_get_priv(uc);
+
+ /* Check if we have cached values */
+ if (priv->rows && priv->cols) {
+ *rowsp = priv->rows;
+ *colsp = priv->cols;
+ return 0;
+ }
+
+ /* No cached values, query the terminal */
+ ret = serial_query_size(rowsp, colsp);
+
+ return ret;
+}
+
#if CONFIG_IS_ENABLED(SERIAL_PRESENT)
static int serial_post_probe(struct udevice *dev)
{
@@ -730,5 +767,6 @@ UCLASS_DRIVER(serial) = {
.post_probe = serial_post_probe,
.pre_remove = serial_pre_remove,
.per_device_auto = sizeof(struct serial_dev_priv),
+ .priv_auto = sizeof(struct serial_priv),
};
#endif
@@ -291,6 +291,17 @@ struct dm_serial_ops {
int (*getinfo)(struct udevice *dev, struct serial_device_info *info);
};
+/**
+ * struct serial_priv - private data for serial uclass
+ *
+ * @rows: Number of terminal rows (0 if unknown)
+ * @cols: Number of terminal columns (0 if unknown)
+ */
+struct serial_priv {
+ int rows;
+ int cols;
+};
+
/**
* struct serial_dev_priv - information about a device used by the uclass
*
@@ -400,4 +411,17 @@ int serial_tstc(void);
*/
int serial_query_size(int *rowsp, int *colsp);
+/**
+ * serial_get_size() - get serial console size
+ *
+ * Get the terminal size, using cached values if available, or failing that,
+ * query the terminal
+ *
+ * @dev: serial device to query (may be NULL)
+ * @rowsp: returns number of rows
+ * @colsp: returns number of columns
+ * Returns: 0 on success, -ve on error
+ */
+int serial_get_size(struct udevice *dev, int *rowsp, int *colsp);
+
#endif