Skip to content

Commit 8afc7e4

Browse files
Alex Elderdavem330
authored andcommitted
net: ipa: separate disabling setup from modem stop
The IPA setup_complete flag is set at the end of ipa_setup(), when the setup phase of initialization has completed successfully. This occurs as part of driver probe processing, or (if "modem-init" is specified in the DTS file) it is triggered by the "ipa-setup-ready" SMP2P interrupt generated by the modem. In the latter case, it's possible for driver shutdown (or remove) to begin while setup processing is underway, and this can't be allowed. The problem is that the setup_complete flag is not adequate to signal that setup is underway. If setup_complete is set, it will never be un-set, so that case is not a problem. But if setup_complete is false, there's a chance setup is underway. Because setup is triggered by an interrupt on a "modem-init" system, there is a simple way to ensure the value of setup_complete is safe to read. The threaded handler--if it is executing--will complete as part of a request to disable the "ipa-modem-ready" interrupt. This means that ipa_setup() (which is called from the handler) will run to completion if it was underway, or will never be called otherwise. The request to disable the "ipa-setup-ready" interrupt is currently made within ipa_modem_stop(). Instead, disable the interrupt outside that function in the two places it's called. In the case of ipa_remove(), this ensures the setup_complete flag is safe to read before we read it. Rename ipa_smp2p_disable() to be ipa_smp2p_irq_disable_setup(), to be more specific about its effect. Fixes: 530f921 ("soc: qcom: ipa: AP/modem communications") Signed-off-by: Alex Elder <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 33a1531 commit 8afc7e4

File tree

4 files changed

+13
-8
lines changed

4 files changed

+13
-8
lines changed

drivers/net/ipa/ipa_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ipa_reg.h"
2929
#include "ipa_mem.h"
3030
#include "ipa_table.h"
31+
#include "ipa_smp2p.h"
3132
#include "ipa_modem.h"
3233
#include "ipa_uc.h"
3334
#include "ipa_interrupt.h"
@@ -801,6 +802,11 @@ static int ipa_remove(struct platform_device *pdev)
801802
struct device *dev = &pdev->dev;
802803
int ret;
803804

805+
/* Prevent the modem from triggering a call to ipa_setup(). This
806+
* also ensures a modem-initiated setup that's underway completes.
807+
*/
808+
ipa_smp2p_irq_disable_setup(ipa);
809+
804810
ret = pm_runtime_get_sync(dev);
805811
if (WARN_ON(ret < 0))
806812
goto out_power_put;

drivers/net/ipa/ipa_modem.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,6 @@ int ipa_modem_stop(struct ipa *ipa)
339339
if (state != IPA_MODEM_STATE_RUNNING)
340340
return -EBUSY;
341341

342-
/* Prevent the modem from triggering a call to ipa_setup() */
343-
ipa_smp2p_disable(ipa);
344-
345342
/* Clean up the netdev and endpoints if it was started */
346343
if (netdev) {
347344
struct ipa_priv *priv = netdev_priv(netdev);
@@ -369,6 +366,9 @@ static void ipa_modem_crashed(struct ipa *ipa)
369366
struct device *dev = &ipa->pdev->dev;
370367
int ret;
371368

369+
/* Prevent the modem from triggering a call to ipa_setup() */
370+
ipa_smp2p_irq_disable_setup(ipa);
371+
372372
ret = pm_runtime_get_sync(dev);
373373
if (ret < 0) {
374374
dev_err(dev, "error %d getting power to handle crash\n", ret);

drivers/net/ipa/ipa_smp2p.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ void ipa_smp2p_exit(struct ipa *ipa)
309309
kfree(smp2p);
310310
}
311311

312-
void ipa_smp2p_disable(struct ipa *ipa)
312+
void ipa_smp2p_irq_disable_setup(struct ipa *ipa)
313313
{
314314
struct ipa_smp2p *smp2p = ipa->smp2p;
315315

drivers/net/ipa/ipa_smp2p.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ int ipa_smp2p_init(struct ipa *ipa, bool modem_init);
2727
void ipa_smp2p_exit(struct ipa *ipa);
2828

2929
/**
30-
* ipa_smp2p_disable() - Prevent "ipa-setup-ready" interrupt handling
30+
* ipa_smp2p_irq_disable_setup() - Disable the "setup ready" interrupt
3131
* @ipa: IPA pointer
3232
*
33-
* Prevent handling of the "setup ready" interrupt from the modem.
34-
* This is used before initiating shutdown of the driver.
33+
* Disable the "ipa-setup-ready" interrupt from the modem.
3534
*/
36-
void ipa_smp2p_disable(struct ipa *ipa);
35+
void ipa_smp2p_irq_disable_setup(struct ipa *ipa);
3736

3837
/**
3938
* ipa_smp2p_notify_reset() - Reset modem notification state

0 commit comments

Comments
 (0)