hv:use spinlock_irqsave_obtain api for uart

replace spinlock_obtain/spinlock_release with spinlock_irqsave_obtain
and spinlock_irqrestore_release to avoid dead lock for uart module.

this uart lock may be accessed in ISR context like this path:
   dispatch_interrupt->pr_err/pr_xxx or printf
   ->console_write->uart16550_puts

Tracked-On: #4958

Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
This commit is contained in:
Mingqiang Chi 2020-07-01 14:53:25 +08:00 committed by wenlingz
parent 0080c6ca72
commit b1357cdc0d
1 changed files with 8 additions and 5 deletions

View File

@ -172,20 +172,20 @@ void uart16550_init(bool early_boot)
char uart16550_getc(void)
{
char ret = -1;
uint64_t rflags;
if (!uart.enabled) {
return ret;
}
spinlock_obtain(&uart.rx_lock);
spinlock_irqsave_obtain(&uart.rx_lock, &rflags);
/* If a character has been received, read it */
if ((uart16550_read_reg(uart, UART16550_LSR) & LSR_DR) == LSR_DR) {
/* Read a character */
ret = uart16550_read_reg(uart, UART16550_RBR);
}
spinlock_release(&uart.rx_lock);
spinlock_irqrestore_release(&uart.rx_lock, rflags);
return ret;
}
@ -210,10 +210,13 @@ static void uart16550_putc(char c)
size_t uart16550_puts(const char *buf, uint32_t len)
{
uint32_t i;
uint64_t rflags;
if (!uart.enabled) {
return len;
}
spinlock_obtain(&uart.tx_lock);
spinlock_irqsave_obtain(&uart.tx_lock, &rflags);
for (i = 0U; i < len; i++) {
/* Transmit character */
uart16550_putc(*buf);
@ -223,7 +226,7 @@ size_t uart16550_puts(const char *buf, uint32_t len)
}
buf++;
}
spinlock_release(&uart.tx_lock);
spinlock_irqrestore_release(&uart.tx_lock, rflags);
return len;
}