Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c165ad06 authored by Jinesh K. Jayakumar's avatar Jinesh K. Jayakumar Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: generic uC loaded event notifier support



Existing uC loaded event notifier allows only a single client per uC
hardware feature to register for the notification. With uC offload
feature shared among multiple networking hardware, we need to allow
multiple offload clients to register for the uC loaded event. Since
uC loaded event is generic in nature, add a generic uC loaded event
notifier mechanism usable by all clients.

CRs-Fixed: 2304918, 2337876
Change-Id: Iadaa9382e15f35103ea5ee896901ccf81f086e55
Signed-off-by: default avatarJinesh K. Jayakumar <jineshk@codeaurora.org>
parent ca81ce5a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
#include <linux/mutex.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/notifier.h>

#include <linux/ipa.h>
#include <linux/ipa_usb.h>
#include <asm/dma-iommu.h>
@@ -2481,6 +2483,8 @@ int ipa3_uc_interface_init(void);
int ipa3_uc_is_gsi_channel_empty(enum ipa_client_type ipa_client);
int ipa3_uc_state_check(void);
int ipa3_uc_loaded_check(void);
int ipa3_uc_register_ready_cb(struct notifier_block *nb);
int ipa3_uc_unregister_ready_cb(struct notifier_block *nb);
int ipa3_uc_send_cmd(u32 cmd, u32 opcode, u32 expected_status,
		    bool polling_mode, unsigned long timeout_jiffies);
void ipa3_uc_register_handlers(enum ipa3_hw_features feature,
+60 −0
Original line number Diff line number Diff line
@@ -170,6 +170,9 @@ struct IpaHwDbAddrInfo_t {
	uint32_t mboxN;
} __packed;

static DEFINE_MUTEX(uc_loaded_nb_lock);
static BLOCKING_NOTIFIER_HEAD(uc_loaded_notifier);

struct ipa3_uc_hdlrs ipa3_uc_hdlrs[IPA_HW_NUM_FEATURES] = { { 0 } };

const char *ipa_hw_error_str(enum ipa3_hw_errors err_type)
@@ -297,6 +300,50 @@ int ipa3_uc_loaded_check(void)
}
EXPORT_SYMBOL(ipa3_uc_loaded_check);

/**
 * ipa3_uc_register_ready_cb() - register a uC ready callback notifier block
 * @nb: notifier
 *
 * Register a callback to be called when uC is ready to receive commands. uC is
 * considered to be ready when it sends %IPA_HW_2_CPU_RESPONSE_INIT_COMPLETED.
 *
 * Return: 0 on successful registration, negative errno otherwise
 *
 * See blocking_notifier_chain_register() for possible errno values
 */
int ipa3_uc_register_ready_cb(struct notifier_block *nb)
{
	int rc;

	mutex_lock(&uc_loaded_nb_lock);

	rc = blocking_notifier_chain_register(&uc_loaded_notifier, nb);
	if (!rc && ipa3_ctx->uc_ctx.uc_loaded)
		(void) nb->notifier_call(nb, false, ipa3_ctx);

	mutex_unlock(&uc_loaded_nb_lock);

	return rc;
}
EXPORT_SYMBOL(ipa3_uc_register_ready_cb);

/**
 * ipa3_uc_unregister_ready_cb() - unregister a uC ready callback
 * @nb: notifier
 *
 * Unregister a uC loaded notifier block that was previously registered by
 * ipa3_uc_register_ready_cb().
 *
 * Return: 0 on successful unregistration, negative errno otherwise
 *
 * See blocking_notifier_chain_unregister() for possible errno values
 */
int ipa3_uc_unregister_ready_cb(struct notifier_block *nb)
{
	return blocking_notifier_chain_unregister(&uc_loaded_notifier, nb);
}
EXPORT_SYMBOL(ipa3_uc_unregister_ready_cb);

static void ipa3_uc_event_handler(enum ipa_irq_type interrupt,
				 void *private_data,
				 void *interrupt_data)
@@ -423,8 +470,21 @@ static void ipa3_uc_response_hdlr(enum ipa_irq_type interrupt,
	/* General handling */
	if (ipa3_ctx->uc_ctx.uc_sram_mmio->responseOp ==
			IPA_HW_2_CPU_RESPONSE_INIT_COMPLETED) {

		if (ipa3_ctx->uc_ctx.uc_loaded) {
			IPADBG("uC resp op INIT_COMPLETED is unexpected\n");
			return;
		}

		mutex_lock(&uc_loaded_nb_lock);

		ipa3_ctx->uc_ctx.uc_loaded = true;

		(void) blocking_notifier_call_chain(&uc_loaded_notifier, true,
			ipa3_ctx);

		mutex_unlock(&uc_loaded_nb_lock);

		IPADBG("IPA uC loaded\n");
		/*
		 * The proxy vote is held until uC is loaded to ensure that