serial: Cache the terminal size

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>
This commit is contained in:
Simon Glass
2025-08-24 16:21:32 -06:00
parent aa1cd00676
commit 9f7600b270
2 changed files with 62 additions and 0 deletions

View File

@@ -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

View File

@@ -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