Skip to content

Commit

Permalink
DM: Mark thre_int_pending as true when THR is empty
Browse files Browse the repository at this point in the history
This patch marks thre_int_pending as true when THR is empty.

Tracked-On: #2713
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Kaige Fu <kaige.fu@intel.com>
  • Loading branch information
KaigeFu authored and dongyaozu committed Mar 14, 2019
1 parent 9b1e2f4 commit b147c5c
Showing 1 changed file with 29 additions and 15 deletions.
44 changes: 29 additions & 15 deletions devicemodel/hw/uart_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,19 +368,6 @@ uart_intr_reason(struct uart_vdev *uart)
return IIR_NOPEND;
}

static void
uart_reset(struct uart_vdev *uart)
{
uint16_t divisor;

divisor = DEFAULT_RCLK / DEFAULT_BAUD / 16;
uart->dll = divisor;
uart->dlh = divisor >> 16;
uart->msr = modem_status(uart->mcr);

rxfifo_reset(uart, 1); /* no fifo until enabled by software */
}

/*
* Toggle the COM port's intr pin depending on whether or not we have an
* interrupt condition to report to the processor.
Expand All @@ -398,6 +385,24 @@ uart_toggle_intr(struct uart_vdev *uart)
(*uart->intr_assert)(uart->arg);
}

static void
uart_reset(struct uart_vdev *uart)
{
uint16_t divisor;

divisor = DEFAULT_RCLK / DEFAULT_BAUD / 16;
uart->dll = divisor;
uart->dlh = divisor >> 16;
uart->msr = modem_status(uart->mcr);

rxfifo_reset(uart, 1); /* no fifo until enabled by software */

/* set the right reset state here */
uart->ier = 0;
uart->thre_int_pending = true;
uart_toggle_intr(uart);
}

static void
uart_drain(int fd, enum ev_type ev, void *arg)
{
Expand Down Expand Up @@ -454,12 +459,17 @@ uart_write(struct uart_vdev *uart, int offset, uint8_t value)

switch (offset) {
case REG_DATA:
/* THRE INT is cleared after writing data into THR register */
uart->thre_int_pending = false;
uart_toggle_intr(uart);
if (uart->mcr & MCR_LOOPBACK) {
if (rxfifo_putchar(uart, value) != 0)
uart->lsr |= LSR_OE;
} else if (uart->tty.opened) {
ttywrite(&uart->tty, value);
} /* else drop on floor */

/* We view the transmission is completed immediately */
uart->thre_int_pending = true;
break;
case REG_IER:
Expand Down Expand Up @@ -580,10 +590,14 @@ uart_read(struct uart_vdev *uart, int offset)
intr_reason = uart_intr_reason(uart);

/*
* Deal with side effects of reading the IIR register
* Reading the IIR register clears the THRE INT.
*/
if (intr_reason == IIR_TXRDY)
if (intr_reason == IIR_TXRDY) {
uart->thre_int_pending = false;
uart_toggle_intr(uart);
}
/* THRE INT is re-generated since the THR register is always empty in here */
uart->thre_int_pending = true;

iir |= intr_reason;

Expand Down

0 comments on commit b147c5c

Please sign in to comment.