linux-stable/drivers/net/ipa/ipa_smp2p.h
Alex Elder 8afc7e471a 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: 530f9216a9 ("soc: qcom: ipa: AP/modem communications")
Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-11-23 12:06:40 +00:00

47 lines
1.2 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2019-2020 Linaro Ltd.
*/
#ifndef _IPA_SMP2P_H_
#define _IPA_SMP2P_H_
#include <linux/types.h>
struct ipa;
/**
* ipa_smp2p_init() - Initialize the IPA SMP2P subsystem
* @ipa: IPA pointer
* @modem_init: Whether the modem is responsible for GSI initialization
*
* Return: 0 if successful, or a negative error code
*
*/
int ipa_smp2p_init(struct ipa *ipa, bool modem_init);
/**
* ipa_smp2p_exit() - Inverse of ipa_smp2p_init()
* @ipa: IPA pointer
*/
void ipa_smp2p_exit(struct ipa *ipa);
/**
* ipa_smp2p_irq_disable_setup() - Disable the "setup ready" interrupt
* @ipa: IPA pointer
*
* Disable the "ipa-setup-ready" interrupt from the modem.
*/
void ipa_smp2p_irq_disable_setup(struct ipa *ipa);
/**
* ipa_smp2p_notify_reset() - Reset modem notification state
* @ipa: IPA pointer
*
* If the modem crashes it queries the IPA power state. In cleaning
* up after such a crash this is used to reset some state maintained
* for managing this notification.
*/
void ipa_smp2p_notify_reset(struct ipa *ipa);
#endif /* _IPA_SMP2P_H_ */