diff options
author | Tom Rini <trini@konsulko.com> | 2024-10-16 15:54:38 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-10-16 15:54:38 -0600 |
commit | 98a36deb9ab7aaea70b0b0db47718100e08cf3e8 (patch) | |
tree | c224ea18c371a89993455d988545a1693cc1bcd1 | |
parent | 608a31bdec6284ad6f821226e4c62c9cd3052874 (diff) | |
parent | 6cc6a2f6992ebe0c087a0da29d1ded3f8799d6ca (diff) |
Merge patch series "some serial rx buffer patches"
Rasmus Villemoes <ravi@prevas.dk> says:
Some small improvements to the serial rx buffer feature.
CI seems happy: https://github.com/u-boot/u-boot/pull/674
Link: https://lore.kernel.org/r/20241003141029.920035-1-ravi@prevas.dk
-rw-r--r-- | drivers/serial/serial-uclass.c | 23 | ||||
-rw-r--r-- | include/serial.h | 8 |
2 files changed, 17 insertions, 14 deletions
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 9feaa1eceec..a08678dde4e 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -18,6 +18,7 @@ #include <dm/lists.h> #include <dm/device-internal.h> #include <dm/of_access.h> +#include <linux/build_bug.h> #include <linux/delay.h> DECLARE_GLOBAL_DATA_PTR; @@ -328,11 +329,15 @@ static int __serial_tstc(struct udevice *dev) static int _serial_tstc(struct udevice *dev) { struct serial_dev_priv *upriv = dev_get_uclass_priv(dev); + uint wr, avail; - /* Read all available chars into the RX buffer */ - while (__serial_tstc(dev)) { - upriv->buf[upriv->wr_ptr++] = __serial_getc(dev); - upriv->wr_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE; + BUILD_BUG_ON_NOT_POWER_OF_2(CONFIG_SERIAL_RX_BUFFER_SIZE); + + /* Read all available chars into the RX buffer while there's room */ + avail = CONFIG_SERIAL_RX_BUFFER_SIZE - (upriv->wr_ptr - upriv->rd_ptr); + while (avail-- && __serial_tstc(dev)) { + wr = upriv->wr_ptr++ % CONFIG_SERIAL_RX_BUFFER_SIZE; + upriv->buf[wr] = __serial_getc(dev); } return upriv->rd_ptr != upriv->wr_ptr ? 1 : 0; @@ -342,12 +347,13 @@ static int _serial_getc(struct udevice *dev) { struct serial_dev_priv *upriv = dev_get_uclass_priv(dev); char val; + uint rd; if (upriv->rd_ptr == upriv->wr_ptr) return __serial_getc(dev); - val = upriv->buf[upriv->rd_ptr++]; - upriv->rd_ptr %= CONFIG_SERIAL_RX_BUFFER_SIZE; + rd = upriv->rd_ptr++ % CONFIG_SERIAL_RX_BUFFER_SIZE; + val = upriv->buf[rd]; return val; } @@ -582,11 +588,6 @@ static int serial_post_probe(struct udevice *dev) sdev.getc = serial_stub_getc; sdev.tstc = serial_stub_tstc; -#if CONFIG_IS_ENABLED(SERIAL_RX_BUFFER) - /* Allocate the RX buffer */ - upriv->buf = malloc(CONFIG_SERIAL_RX_BUFFER_SIZE); -#endif - stdio_register_dev(&sdev, &upriv->sdev); #endif return 0; diff --git a/include/serial.h b/include/serial.h index d129dc3253c..eabc49f820f 100644 --- a/include/serial.h +++ b/include/serial.h @@ -298,9 +298,11 @@ struct dm_serial_ops { struct serial_dev_priv { struct stdio_dev *sdev; - char *buf; - int rd_ptr; - int wr_ptr; +#if CONFIG_IS_ENABLED(SERIAL_RX_BUFFER) + char buf[CONFIG_SERIAL_RX_BUFFER_SIZE]; + uint rd_ptr; + uint wr_ptr; +#endif }; /* Access the serial operations for a device */ |