Skip to content

Commit 1031cfd

Browse files
niedzwiecki-dawidcfriedt
authored andcommitted
drivers: serial: ns16550: fill full fifo
Put the maximum number of bytes into Tx FIFO in the fill_fifo routine to reduce CPU usage. Previously, the THRE bit was checked in a loop, but, according to doc - "In the FIFO mode, it is set when the XMIT FIFO is empty, and is cleared when at least one byte is written to XMIT FIFO.", so only one byte was transferred every interrupt. That was generating a big amount of interrupts, which consumes CPU time. Signed-off-by: Dawid Niedzwiecki <[email protected]>
1 parent d3a5585 commit 1031cfd

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

drivers/serial/uart_ns16550.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
8787
#define IIR_LS 0x06 /* receiver line status interrupt */
8888
#define IIR_MASK 0x07 /* interrupt id bits mask */
8989
#define IIR_ID 0x06 /* interrupt ID mask without NIP */
90+
#define IIR_FE 0xC0 /* FIFO mode enabled */
9091

9192
/* equates for FIFO control register */
9293

@@ -262,6 +263,7 @@ struct uart_ns16550_dev_data {
262263
#endif
263264
struct uart_config uart_config;
264265
struct k_spinlock lock;
266+
uint8_t fifo_size;
265267

266268
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
267269
uint8_t iir_cache; /**< cache of IIR since it clears when read */
@@ -464,6 +466,16 @@ static int uart_ns16550_configure(const struct device *dev,
464466
#endif
465467
);
466468

469+
if ((INBYTE(IIR(dev)) & IIR_FE) == IIR_FE) {
470+
#ifdef CONFIG_UART_NS16750
471+
dev_data->fifo_size = 64;
472+
#else
473+
dev_data->fifo_size = 16;
474+
#endif
475+
} else {
476+
dev_data->fifo_size = 1;
477+
}
478+
467479
/* clear the port */
468480
INBYTE(RDR(dev));
469481

@@ -601,7 +613,7 @@ static int uart_ns16550_fifo_fill(const struct device *dev,
601613
int i;
602614
k_spinlock_key_t key = k_spin_lock(&DEV_DATA(dev)->lock);
603615

604-
for (i = 0; (i < size) && (INBYTE(LSR(dev)) & LSR_THRE) != 0; i++) {
616+
for (i = 0; (i < size) && (i < DEV_DATA(dev)->fifo_size); i++) {
605617
OUTBYTE(THR(dev), tx_data[i]);
606618
}
607619

0 commit comments

Comments
 (0)