
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(+) diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 1204fb5d4c4..27de461d196 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -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 diff --git a/include/serial.h b/include/serial.h index 2aba4c313c2..9ed3793b647 100644 --- a/include/serial.h +++ b/include/serial.h @@ -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 -- 2.43.0