Commit 33a15310 authored by Alex Elder's avatar Alex Elder Committed by David S. Miller
Browse files

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: 530f9216 ("soc: qcom: ipa: AP/modem communications")
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bd08ee23
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -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);
}