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

Commit 853ee082 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ARM: dts: msm: Add support for early assert indication"

parents f9e34111 07f6ba20
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ Optional properties:
  - qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass
  - qcom,wlan-msa-fixed-region: phandle, specifier pairs to children of /reserved-memory
  - qcom,gpio-force-fatal-error: SMP2P bit triggered by WLAN FW to force error fatal.
  - qcom,gpio-early-crash-ind: SMP2P bit triggered by WLAN FW to indicate FW is in assert.

Example:

@@ -61,4 +62,5 @@ Example:
	vdd-0.8-cx-mx-supply = <&pm8998_l5>;
	qcom,vdd-0.8-cx-mx-config = <800000 800000 2400 1000>;
	qcom,gpio-forced-fatal-error = <&smp2pgpio_wlan_1_in 0 0>;
	qcom,gpio-early-crash-ind = <&smp2pgpio_wlan_1_in 1 0>;
    };
+1 −0
Original line number Diff line number Diff line
@@ -3307,6 +3307,7 @@
			     <0 425 0 /* CE11 */ >;
		qcom,wlan-msa-memory = <0x100000>;
		qcom,gpio-force-fatal-error = <&smp2pgpio_wlan_1_in 0 0>;
		qcom,gpio-early-crash-ind = <&smp2pgpio_wlan_1_in 1 0>;
		qcom,smmu-s1-bypass;

		vdd-cx-mx-supply = <&pm855_l1>;
+80 −4
Original line number Diff line number Diff line
@@ -272,6 +272,8 @@ static char *icnss_driver_event_to_str(enum icnss_driver_event_type type)
		return "UNREGISTER_DRIVER";
	case ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN:
		return "PD_SERVICE_DOWN";
	case ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND:
		return "FW_EARLY_CRASH_IND";
	case ICNSS_DRIVER_EVENT_MAX:
		return "EVENT_MAX";
	}
@@ -633,7 +635,24 @@ static irqreturn_t fw_error_fatal_handler(int irq, void *ctx)
	return IRQ_HANDLED;
}

static void icnss_register_force_error_fatal(struct icnss_priv *priv)
static irqreturn_t fw_crash_indication_handler(int irq, void *ctx)
{
	struct icnss_priv *priv = ctx;

	icnss_pr_err("Received early crash indication from FW\n");

	if (priv) {
		set_bit(ICNSS_FW_DOWN, &priv->state);
		icnss_ignore_fw_timeout(true);
	}

	icnss_driver_event_post(ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND,
				0, NULL);

	return IRQ_HANDLED;
}

static void register_fw_error_notifications(struct icnss_priv *priv)
{
	int gpio, irq, ret;

@@ -656,11 +675,38 @@ static void icnss_register_force_error_fatal(struct icnss_priv *priv)
	ret = request_irq(irq, fw_error_fatal_handler,
			IRQF_TRIGGER_RISING, "wlanfw-err", priv);
	if (ret < 0) {
		icnss_pr_err("Unable to regiser for error fatal IRQ handler %d",
		icnss_pr_err("Unable to register for error fatal IRQ handler %d",
				irq);
		return;
	}
	icnss_pr_dbg("FW force error fatal handler registered\n");

	if (!of_find_property(priv->pdev->dev.of_node,
				"qcom,gpio-early-crash-ind", NULL)) {
		icnss_pr_dbg("FW early crash indication handler not registered\n");
		return;
	}
	gpio = of_get_named_gpio(priv->pdev->dev.of_node,
				"qcom,gpio-early-crash-ind", 0);
	if (!gpio_is_valid(gpio)) {
		icnss_pr_err("Invalid GPIO for early crash indication %d\n",
				gpio);
		return;
	}
	irq = gpio_to_irq(gpio);
	if (irq < 0) {
		icnss_pr_err("Invalid IRQ for early crash indication %u\n",
				irq);
		return;
	}
	ret = request_irq(irq, fw_crash_indication_handler,
			IRQF_TRIGGER_RISING, "wlanfw-early-crash-ind", priv);
	if (ret < 0) {
		icnss_pr_err("Unable to register for early crash indication IRQ handler %d",
				irq);
		return;
	}
	icnss_pr_dbg("FW crash indication handler registered\n");
}

int icnss_call_driver_uevent(struct icnss_priv *priv,
@@ -733,7 +779,7 @@ static int icnss_driver_event_server_arrive(void *data)
	wlfw_dynamic_feature_mask_send_sync_msg(penv,
						dynamic_feature_mask);

	icnss_register_force_error_fatal(penv);
	register_fw_error_notifications(penv);

	return ret;

@@ -825,6 +871,7 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv)
	icnss_call_driver_shutdown(priv);

	clear_bit(ICNSS_PD_RESTART, &priv->state);
	priv->early_crash_ind = false;

	if (!priv->ops || !priv->ops->reinit)
		goto out;
@@ -979,7 +1026,7 @@ static int icnss_fw_crashed(struct icnss_priv *priv,
	if (test_bit(ICNSS_DRIVER_PROBED, &priv->state))
		icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_CRASHED, NULL);

	if (event_data->fw_rejuvenate)
	if (event_data && event_data->fw_rejuvenate)
		wlfw_rejuvenate_ack_send_sync_msg(priv);

	return 0;
@@ -994,6 +1041,12 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv,
	if (!test_bit(ICNSS_WLFW_EXISTS, &priv->state))
		goto out;

	if (priv->early_crash_ind) {
		icnss_pr_dbg("PD Down ignored as early indication is processed: %d, state: 0x%lx\n",
			     event_data->crashed, priv->state);
		goto out;
	}

	if (test_bit(ICNSS_PD_RESTART, &priv->state) && event_data->crashed) {
		icnss_pr_err("PD Down while recovery inprogress, crashed: %d, state: 0x%lx\n",
			     event_data->crashed, priv->state);
@@ -1015,6 +1068,25 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv,
	return ret;
}

static int icnss_driver_event_early_crash_ind(struct icnss_priv *priv,
					      void *data)
{
	int ret = 0;

	if (!test_bit(ICNSS_WLFW_EXISTS, &priv->state))
		goto out;

	priv->early_crash_ind = true;
	icnss_fw_crashed(priv, NULL);

out:
	kfree(data);
	icnss_ignore_fw_timeout(false);

	return ret;
}


static void icnss_driver_event_work(struct work_struct *work)
{
	struct icnss_driver_event *event;
@@ -1056,6 +1128,10 @@ static void icnss_driver_event_work(struct work_struct *work)
			ret = icnss_driver_event_pd_service_down(penv,
								 event->data);
			break;
		case ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND:
			ret = icnss_driver_event_early_crash_ind(penv,
								 event->data);
			break;
		default:
			icnss_pr_err("Invalid Event type: %d", event->type);
			kfree(event);
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ enum icnss_driver_event_type {
	ICNSS_DRIVER_EVENT_REGISTER_DRIVER,
	ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
	ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
	ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND,
	ICNSS_DRIVER_EVENT_MAX,
};

@@ -340,6 +341,7 @@ struct icnss_priv {
	bool bypass_s1_smmu;
	bool force_err_fatal;
	bool allow_recursive_recovery;
	bool early_crash_ind;
	u8 cause_for_rejuvenation;
	u8 requesting_sub_system;
	u16 line_number;