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

Commit d120d3ca authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: fix rmnet_ipa SSR cleanup to be called directly"

parents 12739ff7 ca1678ee
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -695,14 +695,18 @@ static void ipa_qmi_service_init_worker(struct work_struct *work)

destroy_clnt_resp_wq:
	destroy_workqueue(ipa_clnt_resp_workqueue);
	ipa_clnt_resp_workqueue = NULL;
destroy_clnt_req_wq:
	destroy_workqueue(ipa_clnt_req_workqueue);
	ipa_clnt_req_workqueue = NULL;
deregister_qmi_srv:
	qmi_svc_unregister(ipa_svc_handle);
destroy_qmi_handle:
	qmi_handle_destroy(ipa_svc_handle);
	ipa_svc_handle = 0;
destroy_ipa_A7_svc_wq:
	destroy_workqueue(ipa_svc_workqueue);
	ipa_svc_workqueue = NULL;
	return;
}

@@ -721,6 +725,7 @@ int ipa_qmi_service_init(bool load_uc, uint32_t wan_platform_type)
void ipa_qmi_service_exit(void)
{
	int ret = 0;

	/* qmi-service */
	if (ipa_svc_handle) {
		ret = qmi_svc_unregister(ipa_svc_handle);
@@ -731,7 +736,9 @@ void ipa_qmi_service_exit(void)
	if (ipa_svc_workqueue) {
		flush_workqueue(ipa_svc_workqueue);
		destroy_workqueue(ipa_svc_workqueue);
		ipa_svc_workqueue = NULL;
	}

	if (ipa_svc_handle) {
		ret = qmi_handle_destroy(ipa_svc_handle);
		if (ret < 0)
@@ -739,7 +746,6 @@ void ipa_qmi_service_exit(void)
			ipa_svc_handle, ret);
	}


	/* qmi-client */
	ret = qmi_svc_event_notifier_unregister(IPA_Q6_SERVICE_SVC_ID,
				IPA_Q6_SVC_VERS,
@@ -748,10 +754,15 @@ void ipa_qmi_service_exit(void)
		IPAWANERR(
		"Error qmi_svc_event_notifier_unregister service %d, ret=%d\n",
		IPA_Q6_SERVICE_SVC_ID, ret);
	if (ipa_clnt_req_workqueue)

	if (ipa_clnt_req_workqueue) {
		destroy_workqueue(ipa_clnt_req_workqueue);
	if (ipa_clnt_resp_workqueue)
		ipa_clnt_req_workqueue = NULL;
	}
	if (ipa_clnt_resp_workqueue) {
		destroy_workqueue(ipa_clnt_resp_workqueue);
		ipa_clnt_resp_workqueue = NULL;
	}

	ipa_svc_handle = 0;
}
+18 −28
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@ static int num_q6_rule, old_num_q6_rule;
static int rmnet_index;
static bool egress_set, a7_ul_flt_set;
static struct workqueue_struct *ipa_rm_q6_workqueue; /* IPA_RM workqueue*/
static struct workqueue_struct *ipa_ssr_workqueue; /* IPA SSR workqueue*/
static atomic_t is_initialized;
static atomic_t is_ssr;

@@ -172,7 +171,7 @@ static void ipa_del_a7_qmap_hdr(void)
	if (ret || hdl_entry->status)
		IPAWANERR("ipa_del_hdr failed\n");
	else
		IPAWANERR("hdrs deletion done\n");
		IPAWANDBG("hdrs deletion done\n");

	qmap_hdr_hdl = 0;
	kfree(del_hdr);
@@ -207,7 +206,7 @@ static void ipa_del_qmap_hdr(uint32_t hdr_hdl)
	if (ret || hdl_entry->status)
		IPAWANERR("ipa_del_hdr failed\n");
	else
		IPAWANERR("header deletion done\n");
		IPAWANDBG("header deletion done\n");

	qmap_hdr_hdl = 0;
	kfree(del_hdr);
@@ -1631,9 +1630,6 @@ static void ipa_rm_notify(void *dev, enum ipa_rm_event event,

/* IPA_RM related functions end*/

static void ssr_ipa_wwan_remove(struct work_struct *work);
static DECLARE_DELAYED_WORK(ssr_ipa_wwan_remove_request, ssr_ipa_wwan_remove);

static int ssr_notifier_cb(struct notifier_block *this,
			   unsigned long code,
			   void *data);
@@ -1650,12 +1646,12 @@ static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
	ipa_rmnet_drv_res->ipa_rmnet_ssr =
			of_property_read_bool(pdev->dev.of_node,
			"qcom,rmnet-ipa-ssr");
	IPAWANERR(": IPA SSR support = %s",
	pr_info("IPA SSR support = %s\n",
		ipa_rmnet_drv_res->ipa_rmnet_ssr ? "True" : "False");
	ipa_rmnet_drv_res->ipa_loaduC =
			of_property_read_bool(pdev->dev.of_node,
			"qcom,ipa-loaduC");
	IPAWANERR(": IPA ipa-loaduC = %s",
	pr_info("IPA ipa-loaduC = %s\n",
		ipa_rmnet_drv_res->ipa_loaduC ? "True" : "False");

	return 0;
@@ -1681,6 +1677,8 @@ static int ipa_wwan_probe(struct platform_device *pdev)
	struct ipa_rm_create_params ipa_rm_params;	/* IPA_RM */
	struct ipa_rm_perf_profile profile;			/* IPA_RM */

	pr_info("rmnet_ipa started initialization\n");

	if (!ipa_is_ready()) {
		IPAWANERR("IPA driver not loaded\n");
		return -ENODEV;
@@ -1816,6 +1814,7 @@ static int ipa_wwan_probe(struct platform_device *pdev)
	atomic_set(&is_initialized, 1);
	atomic_set(&is_ssr, 0);

	pr_info("rmnet_ipa completed initialization\n");
	return 0;
config_err:
	unregister_netdev(ipa_netdevs[0]);
@@ -1855,7 +1854,6 @@ setup_a7_qmap_hdr_err:
		IPAWANERR(
		"Error subsys_notif_unregister_notifier system %s, ret=%d\n",
		SUBSYS_MODEM, ret);
	destroy_workqueue(ipa_ssr_workqueue);
	atomic_set(&is_ssr, 0);
	return ret;
}
@@ -1864,6 +1862,7 @@ static int ipa_wwan_remove(struct platform_device *pdev)
{
	int ret;

	pr_info("rmnet_ipa started deinitialization\n");
	unregister_netdev(ipa_netdevs[0]);
	ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
		IPA_RM_RESOURCE_Q6_CONS);
@@ -1892,7 +1891,7 @@ static int ipa_wwan_remove(struct platform_device *pdev)
	wwan_del_ul_flt_rule_to_ipa();
	ipa_cleanup_deregister_intf();
	atomic_set(&is_initialized, 0);
	IPAWANDBG("rmnet_ipa completed deinitialization\n");
	pr_info("rmnet_ipa completed deinitialization\n");
	return 0;
}

@@ -1918,17 +1917,21 @@ static int ssr_notifier_cb(struct notifier_block *this,
{
	if (ipa_rmnet_ctx.ipa_rmnet_ssr) {
		if (SUBSYS_BEFORE_SHUTDOWN == code) {
			pr_info("IPA received MPSS BEFORE_SHUTDOWN\n");
			ipa_q6_cleanup();
			wan_ioctl_stop_qmi_messages();
			queue_delayed_work(ipa_ssr_workqueue,
				&ssr_ipa_wwan_remove_request, 0);
			atomic_set(&is_ssr, 1);
			if (atomic_read(&is_initialized))
				platform_driver_unregister(&rmnet_ipa_driver);
			pr_info("IPA BEFORE_SHUTDOWN handling is complete\n");
			return NOTIFY_DONE;
		}
		if (SUBSYS_AFTER_POWERUP == code) {
			pr_info("IPA received MPSS AFTER_POWERUP\n");
			if (!atomic_read(&is_initialized)
				&& atomic_read(&is_ssr))
				platform_driver_register(&rmnet_ipa_driver);
			pr_info("IPA AFTER_POWERUP handling is complete\n");
			return NOTIFY_DONE;
		}
	}
@@ -1941,33 +1944,20 @@ static int __init ipa_wwan_init(void)

	atomic_set(&is_initialized, 0);
	atomic_set(&is_ssr, 0);
	/* Initialize IPA SSR workqueue */
	ipa_ssr_workqueue = create_singlethread_workqueue("ssr_req");
	if (!ipa_ssr_workqueue)
		return -ENOMEM;

	/* Register for Modem SSR */
	subsys = subsys_notif_register_notifier(SUBSYS_MODEM, &ssr_notifier);
	if (!IS_ERR(subsys)) {
	if (!IS_ERR(subsys))
		return platform_driver_register(&rmnet_ipa_driver);
	} else {
		destroy_workqueue(ipa_ssr_workqueue);
	else
		return (int)PTR_ERR(subsys);
	}
}

static void __exit ipa_wwan_cleanup(void)
{
	platform_driver_unregister(&rmnet_ipa_driver);
}

static void ssr_ipa_wwan_remove(struct work_struct *work)
{
	if (!atomic_read(&is_initialized))
		return;

	platform_driver_unregister(&rmnet_ipa_driver);
}

late_initcall(ipa_wwan_init);
module_exit(ipa_wwan_cleanup);
MODULE_DESCRIPTION("WWAN Network Interface");