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

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

Merge "soc: qcom: ssr: Wait for smp2p ack after sending sysmon shutdown message"

parents 1b9549a5 38875be8
Loading
Loading
Loading
Loading
+28 −0
Original line number Original line Diff line number Diff line
@@ -48,6 +48,10 @@ module_param(disable_restart_work, uint, S_IRUGO | S_IWUSR);
static int enable_debug;
static int enable_debug;
module_param(enable_debug, int, S_IRUGO | S_IWUSR);
module_param(enable_debug, int, S_IRUGO | S_IWUSR);


/* The maximum shutdown timeout is the product of MAX_LOOPS and DELAY_MS. */
#define SHUTDOWN_ACK_MAX_LOOPS	100
#define SHUTDOWN_ACK_DELAY_MS	100

/**
/**
 * enum p_subsys_state - state of a subsystem (private)
 * enum p_subsys_state - state of a subsystem (private)
 * @SUBSYS_NORMAL: subsystem is operating normally
 * @SUBSYS_NORMAL: subsystem is operating normally
@@ -550,6 +554,25 @@ static void disable_all_irqs(struct subsys_device *dev)
		disable_irq(dev->desc->stop_ack_irq);
		disable_irq(dev->desc->stop_ack_irq);
}
}


int wait_for_shutdown_ack(struct subsys_desc *desc)
{
	int count;

	if (desc && !desc->shutdown_ack_gpio)
		return 0;

	for (count = SHUTDOWN_ACK_MAX_LOOPS; count > 0; count--) {
		if (gpio_get_value(desc->shutdown_ack_gpio))
			return count;
		msleep(SHUTDOWN_ACK_DELAY_MS);
	}

	pr_err("[%s]: Timed out waiting for shutdown ack\n", desc->name);

	return -ETIMEDOUT;
}
EXPORT_SYMBOL(wait_for_shutdown_ack);

static int wait_for_err_ready(struct subsys_device *subsys)
static int wait_for_err_ready(struct subsys_device *subsys)
{
{
	int ret;
	int ret;
@@ -1443,6 +1466,11 @@ static int subsys_parse_devicetree(struct subsys_desc *desc)
	if (ret && ret != -ENOENT)
	if (ret && ret != -ENOENT)
		return ret;
		return ret;


	ret = __get_gpio(desc, "qcom,gpio-shutdown-ack",
			&desc->shutdown_ack_gpio);
	if (ret && ret != -ENOENT)
		return ret;

	ret = platform_get_irq(pdev, 0);
	ret = platform_get_irq(pdev, 0);
	if (ret > 0)
	if (ret > 0)
		desc->wdog_bite_irq = ret;
		desc->wdog_bite_irq = ret;
+12 −1
Original line number Original line Diff line number Diff line
@@ -416,7 +416,7 @@ int sysmon_send_shutdown(struct subsys_desc *dest_desc)
	struct sysmon_qmi_data *data = NULL, *temp;
	struct sysmon_qmi_data *data = NULL, *temp;
	const char *dest_ss = dest_desc->name;
	const char *dest_ss = dest_desc->name;
	char req = 0;
	char req = 0;
	int ret;
	int ret, shutdown_ack_ret;


	if (dest_ss == NULL)
	if (dest_ss == NULL)
		return -EINVAL;
		return -EINVAL;
@@ -465,6 +465,17 @@ int sysmon_send_shutdown(struct subsys_desc *dest_desc)
		goto out;
		goto out;
	}
	}


	shutdown_ack_ret = wait_for_shutdown_ack(dest_desc);
	if (shutdown_ack_ret < 0) {
		pr_err("shutdown_ack SMP2P bit for %s not set\n", data->name);
		if (!&data->ind_recv.done) {
			pr_err("QMI shutdown indication not received\n");
			ret = shutdown_ack_ret;
		}
		goto out;
	} else if (shutdown_ack_ret > 0)
		goto out;

	if (!wait_for_completion_timeout(&data->ind_recv,
	if (!wait_for_completion_timeout(&data->ind_recv,
					msecs_to_jiffies(SHUTDOWN_TIMEOUT))) {
					msecs_to_jiffies(SHUTDOWN_TIMEOUT))) {
		pr_err("Timed out waiting for shutdown indication from %s\n",
		pr_err("Timed out waiting for shutdown indication from %s\n",
+6 −0
Original line number Original line Diff line number Diff line
@@ -74,6 +74,7 @@ struct subsys_desc {
	unsigned int wdog_bite_irq;
	unsigned int wdog_bite_irq;
	int force_stop_gpio;
	int force_stop_gpio;
	int ramdump_disable_gpio;
	int ramdump_disable_gpio;
	int shutdown_ack_gpio;
	int ramdump_disable;
	int ramdump_disable;
	bool no_auth;
	bool no_auth;
	int ssctl_instance_id;
	int ssctl_instance_id;
@@ -119,6 +120,7 @@ extern void subsys_set_crash_status(struct subsys_device *dev, bool crashed);
extern bool subsys_get_crash_status(struct subsys_device *dev);
extern bool subsys_get_crash_status(struct subsys_device *dev);
void notify_proxy_vote(struct device *device);
void notify_proxy_vote(struct device *device);
void notify_proxy_unvote(struct device *device);
void notify_proxy_unvote(struct device *device);
extern int wait_for_shutdown_ack(struct subsys_desc *desc);
#else
#else


static inline int subsys_get_restart_level(struct subsys_device *dev)
static inline int subsys_get_restart_level(struct subsys_device *dev)
@@ -170,6 +172,10 @@ static inline bool subsys_get_crash_status(struct subsys_device *dev)
}
}
static inline void notify_proxy_vote(struct device *device) { }
static inline void notify_proxy_vote(struct device *device) { }
static inline void notify_proxy_unvote(struct device *device) { }
static inline void notify_proxy_unvote(struct device *device) { }
static inline int wait_for_shutdown_ack(struct subsys_desc *desc)
{
	return -ENOSYS;
}
#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */


#endif
#endif