boards: cxd56xx: Fix a deadlock in cxd56_gs2200m.c

Summary:
- During streaming test, I noticed a dealock when controlling IRQ
- Actually, it will send an IPI when the cpu index is not 0
- However, up_cpu_pause() also sends IPI with critical section
- So the IRQ control must follow the same rule

Impact:
- Affects SMP only

Testing:
- Tested with spresense:wifi_smp

Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa 2020-10-08 12:59:58 +09:00 committed by Alin Jerpelea
parent bebc2d2405
commit cb6dd70082
1 changed files with 6 additions and 40 deletions

View File

@ -112,35 +112,18 @@ static int gs2200m_irq_attach(xcpt_t handler, FAR void *arg)
static void gs2200m_irq_enable(void)
{
irqstate_t flags = spin_lock_irqsave();
irqstate_t flags = enter_critical_section();
wlinfo("== ec:%d called=%d \n", _enable_count, _n_called++);
if (0 == _enable_count)
{
#ifdef CONFIG_SMP
bool unlock = false;
if (0 != up_cpu_index())
{
unlock = true;
spin_unlock_irqrestore(flags);
}
#endif
cxd56_gpioint_enable(PIN_UART2_CTS);
#ifdef CONFIG_SMP
if (unlock)
{
flags = spin_lock_irqsave();
}
#endif
}
_enable_count++;
spin_unlock_irqrestore(flags);
leave_critical_section(flags);
}
/****************************************************************************
@ -149,7 +132,7 @@ static void gs2200m_irq_enable(void)
static void gs2200m_irq_disable(void)
{
irqstate_t flags = spin_lock_irqsave();
irqstate_t flags = enter_critical_section();
wlinfo("== ec:%d called=%d \n", _enable_count, _n_called++);
@ -157,27 +140,10 @@ static void gs2200m_irq_disable(void)
if (0 == _enable_count)
{
#ifdef CONFIG_SMP
bool unlock = false;
if (0 != up_cpu_index())
{
unlock = true;
spin_unlock_irqrestore(flags);
}
#endif
cxd56_gpioint_disable(PIN_UART2_CTS);
#ifdef CONFIG_SMP
if (unlock)
{
flags = spin_lock_irqsave();
}
#endif
}
spin_unlock_irqrestore(flags);
leave_critical_section(flags);
}
/****************************************************************************
@ -186,7 +152,7 @@ static void gs2200m_irq_disable(void)
static uint32_t gs2200m_dready(int *ec)
{
irqstate_t flags = spin_lock_irqsave();
irqstate_t flags = enter_critical_section();
uint32_t r = cxd56_gpio_read(PIN_UART2_CTS);
@ -197,7 +163,7 @@ static uint32_t gs2200m_dready(int *ec)
*ec = _enable_count;
}
spin_unlock_irqrestore(flags);
leave_critical_section(flags);
return r;
}