net: ipa: directly disable ipa-setup-ready interrupt

We currently maintain a "disabled" Boolean flag to determine whether
the "ipa-setup-ready" SMP2P IRQ handler does anything.  That flag
must be accessed under protection of a mutex.

Instead, disable the SMP2P interrupt when requested, which prevents
the interrupt handler from ever being called.  More importantly, it
synchronizes a thread disabling the interrupt with the completion of
the interrupt handler in case they run concurrently.

Use the IPA setup_complete flag rather than the disabled flag in the
handler to determine whether to ignore any interrupts arriving after
the first.

Rename the "disabled" flag to be "setup_disabled", to be specific
about its purpose.

Fixes: 530f9216a9 ("soc: qcom: ipa: AP/modem communications")
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Alex Elder 2021-11-22 18:15:54 -06:00 committed by David S. Miller
parent bd08ee2315
commit 33a153100b
1 changed files with 9 additions and 10 deletions

View File

@ -53,7 +53,7 @@
* @setup_ready_irq: IPA interrupt triggered by modem to signal GSI ready
* @power_on: Whether IPA power is on
* @notified: Whether modem has been notified of power state
* @disabled: Whether setup ready interrupt handling is disabled
* @setup_disabled: Whether setup ready interrupt handler is disabled
* @mutex: Mutex protecting ready-interrupt/shutdown interlock
* @panic_notifier: Panic notifier structure
*/
@ -67,7 +67,7 @@ struct ipa_smp2p {
u32 setup_ready_irq;
bool power_on;
bool notified;
bool disabled;
bool setup_disabled;
struct mutex mutex;
struct notifier_block panic_notifier;
};
@ -155,11 +155,9 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
struct device *dev;
int ret;
mutex_lock(&smp2p->mutex);
if (smp2p->disabled)
goto out_mutex_unlock;
smp2p->disabled = true; /* If any others arrive, ignore them */
/* Ignore any (spurious) interrupts received after the first */
if (smp2p->ipa->setup_complete)
return IRQ_HANDLED;
/* Power needs to be active for setup */
dev = &smp2p->ipa->pdev->dev;
@ -176,8 +174,6 @@ static irqreturn_t ipa_smp2p_modem_setup_ready_isr(int irq, void *dev_id)
out_power_put:
pm_runtime_mark_last_busy(dev);
(void)pm_runtime_put_autosuspend(dev);
out_mutex_unlock:
mutex_unlock(&smp2p->mutex);
return IRQ_HANDLED;
}
@ -322,7 +318,10 @@ void ipa_smp2p_disable(struct ipa *ipa)
mutex_lock(&smp2p->mutex);
smp2p->disabled = true;
if (!smp2p->setup_disabled) {
disable_irq(smp2p->setup_ready_irq);
smp2p->setup_disabled = true;
}
mutex_unlock(&smp2p->mutex);
}