mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
ANDROID: tty: hvc_dcc: Save irq flags when locking
Disable interrupts when using DCC fifo to prevent deadlock if interrupt
occurs that causes a console write.
Bug: 175415911
Fixes: 61d87acb93 ("FROMLIST: hvc_dcc: bind driver to core0 for reads
and writes")
Change-Id: I645bafef1d8bc58ee93b086b46d822c046aece2d
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
parent
0edac9cb95
commit
37f671817b
|
|
@ -128,8 +128,9 @@ static DEFINE_KFIFO(outbuf, unsigned char, 1024);
|
|||
static void dcc_put_work_fn(struct work_struct *work)
|
||||
{
|
||||
unsigned char ch;
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock(&dcc_lock);
|
||||
spin_lock_irqsave(&dcc_lock, irqflags);
|
||||
|
||||
/* While there's data in the output FIFO, write it to the DCC */
|
||||
while (kfifo_get(&outbuf, &ch))
|
||||
|
|
@ -142,7 +143,7 @@ static void dcc_put_work_fn(struct work_struct *work)
|
|||
kfifo_put(&inbuf, ch);
|
||||
}
|
||||
|
||||
spin_unlock(&dcc_lock);
|
||||
spin_unlock_irqrestore(&dcc_lock, irqflags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -152,19 +153,20 @@ static void dcc_put_work_fn(struct work_struct *work)
|
|||
static void dcc_get_work_fn(struct work_struct *work)
|
||||
{
|
||||
unsigned char ch;
|
||||
unsigned long irqflags;
|
||||
|
||||
/*
|
||||
* Read characters from DCC and put them into the input FIFO, as
|
||||
* long as there is room and we have characters to read.
|
||||
*/
|
||||
spin_lock(&dcc_lock);
|
||||
spin_lock_irqsave(&dcc_lock, irqflags);
|
||||
|
||||
while (!kfifo_is_full(&inbuf)) {
|
||||
if (!hvc_dcc_get_chars(0, &ch, 1))
|
||||
break;
|
||||
kfifo_put(&inbuf, ch);
|
||||
}
|
||||
spin_unlock(&dcc_lock);
|
||||
spin_unlock_irqrestore(&dcc_lock, irqflags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -175,11 +177,12 @@ static int hvc_dcc0_put_chars(uint32_t vt, const char *buf,
|
|||
int count)
|
||||
{
|
||||
int len;
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock(&dcc_lock);
|
||||
spin_lock_irqsave(&dcc_lock, irqflags);
|
||||
if (smp_processor_id() || (!kfifo_is_empty(&outbuf))) {
|
||||
len = kfifo_in(&outbuf, buf, count);
|
||||
spin_unlock(&dcc_lock);
|
||||
spin_unlock_irqrestore(&dcc_lock, irqflags);
|
||||
/*
|
||||
* We just push data to the output FIFO, so schedule the
|
||||
* workqueue that will actually write that data to DCC.
|
||||
|
|
@ -193,7 +196,7 @@ static int hvc_dcc0_put_chars(uint32_t vt, const char *buf,
|
|||
* write the data to DCC.
|
||||
*/
|
||||
len = hvc_dcc_put_chars(vt, buf, count);
|
||||
spin_unlock(&dcc_lock);
|
||||
spin_unlock_irqrestore(&dcc_lock, irqflags);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
@ -205,12 +208,13 @@ static int hvc_dcc0_put_chars(uint32_t vt, const char *buf,
|
|||
static int hvc_dcc0_get_chars(uint32_t vt, char *buf, int count)
|
||||
{
|
||||
int len;
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock(&dcc_lock);
|
||||
spin_lock_irqsave(&dcc_lock, irqflags);
|
||||
|
||||
if (smp_processor_id() || (!kfifo_is_empty(&inbuf))) {
|
||||
len = kfifo_out(&inbuf, buf, count);
|
||||
spin_unlock(&dcc_lock);
|
||||
spin_unlock_irqrestore(&dcc_lock, irqflags);
|
||||
|
||||
/*
|
||||
* If the FIFO was empty, there may be characters in the DCC
|
||||
|
|
@ -229,7 +233,7 @@ static int hvc_dcc0_get_chars(uint32_t vt, char *buf, int count)
|
|||
* read the data from DCC.
|
||||
*/
|
||||
len = hvc_dcc_get_chars(vt, buf, count);
|
||||
spin_unlock(&dcc_lock);
|
||||
spin_unlock_irqrestore(&dcc_lock, irqflags);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user