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

Commit 2a75fc56 authored by Melody Olvera's avatar Melody Olvera
Browse files

Revert "soc: qcom: Remove watchdog percpu interrupts"



This reverts commit d71acda6.
This is being reverted because sdxlemur uses percpu interrupts
in its watchdog. This change also adds back in fields used by
this code and fixes issues introduced by new code.

Change-Id: Ic5ddbebd6c6f4b4c5d157a86a3ecd827e1b5376f
Signed-off-by: default avatarMelody Olvera <molvera@codeaurora.org>
parent b20ec664
Loading
Loading
Loading
Loading
+61 −10
Original line number Diff line number Diff line
@@ -10,6 +10,11 @@
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/of.h>
#include <linux/cpu_pm.h>
#include <linux/platform_device.h>
#include <linux/wait.h>
#include <linux/reboot.h>
#include <linux/qcom_scm.h>
@@ -458,7 +463,15 @@ static void qcom_wdt_unregister_die_notifier(struct msm_watchdog_data *wdog_dd)
static void qcom_wdt_disable(struct msm_watchdog_data *wdog_dd)
{
	wdog_dd->ops->disable_wdt(wdog_dd);

	if (wdog_dd->irq_ppi) {
		disable_percpu_irq(wdog_dd->bark_irq);
		free_percpu_irq(wdog_dd->bark_irq,
				(void __percpu *)wdog_dd->wdog_cpu_dd);
	} else {
		devm_free_irq(wdog_dd->dev, wdog_dd->bark_irq, wdog_dd);
	}

	wdog_dd->enabled = false;
	/*Ensure all cpus see update to enable*/
	smp_mb();
@@ -733,6 +746,8 @@ int qcom_wdt_remove(struct platform_device *pdev)

	mutex_unlock(&wdog_dd->disable_lock);
	device_remove_file(wdog_dd->dev, &dev_attr_disable);
	if (wdog_dd->irq_ppi)
		free_percpu((void __percpu *)wdog_dd->wdog_cpu_dd);
	irq_dispose_mapping(wdog_dd->bark_irq);
	dev_info(wdog_dd->dev, "QCOM Apps Watchdog Exit - Deactivated\n");
	del_timer_sync(&wdog_dd->pet_timer);
@@ -798,6 +813,14 @@ static irqreturn_t qcom_wdt_bark_handler(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static irqreturn_t qcom_wdt_ppi_bark(int irq, void *dev_id_percpu)
{
	void *dev_id = raw_cpu_ptr((void __percpu *)dev_id_percpu);
	struct msm_watchdog_data *wdog_dd = *((struct msm_watchdog_data **)dev_id);

	return qcom_wdt_bark_handler(irq, wdog_dd);
}

static int qcom_wdt_init_sysfs(struct msm_watchdog_data *wdog_dd)
{
	int error = 0;
@@ -820,17 +843,35 @@ static int qcom_wdt_init(struct msm_watchdog_data *wdog_dd,
	unsigned long delay_time;
	uint32_t val;
	int ret;

	void *wdog_cpu_dd_v;

	if (wdog_dd->irq_ppi) {
		wdog_dd->wdog_cpu_dd = alloc_percpu(struct msm_watchdog_data *);
		if (!wdog_dd->wdog_cpu_dd) {
			dev_err(wdog_dd->dev, "failed to allocate cpu data\n");
			return -ENOMEM;
		}
		wdog_cpu_dd_v = raw_cpu_ptr((void __percpu *)wdog_dd->wdog_cpu_dd);
		*((struct msm_watchdog_data **)wdog_cpu_dd_v) = wdog_dd;
		ret = request_percpu_irq(wdog_dd->bark_irq, qcom_wdt_ppi_bark,
					"apps_wdog_bark",
					(void __percpu *)wdog_dd->wdog_cpu_dd);
		if (ret) {
			dev_err(wdog_dd->dev, "failed to request bark irq\n");
			free_percpu((void __percpu *)wdog_dd->wdog_cpu_dd);
			return ret;
		}
	} else {
		ret = devm_request_irq(wdog_dd->dev, wdog_dd->bark_irq,
				qcom_wdt_bark_handler,
			       IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
				IRQF_TRIGGER_RISING,
				"apps_wdog_bark", wdog_dd);
		if (ret) {
		dev_err(wdog_dd->dev, "failed to request bark irq\n");
			dev_err(wdog_dd->dev, "failed to request bark irq: %d\n", ret);
			return -EINVAL;
		}
	INIT_WORK(&wdog_dd->irq_counts_work, compute_irq_stat);
	atomic_set(&wdog_dd->irq_counts_running, 0);
	}

	delay_time = msecs_to_jiffies(wdog_dd->pet_time);
	wdog_dd->ops->set_bark_time(wdog_dd->bark_time, wdog_dd);
	wdog_dd->ops->set_bite_time(wdog_dd->bark_time + 3 * 1000, wdog_dd);
@@ -863,6 +904,13 @@ static int qcom_wdt_init(struct msm_watchdog_data *wdog_dd,
						 &wdog_dd->panic_blk);
		qcom_wdt_unregister_die_notifier(wdog_dd);
		unregister_restart_handler(&wdog_dd->restart_blk);

		if (wdog_dd->irq_ppi) {
			free_percpu_irq(wdog_dd->bark_irq,
					(void __percpu *)wdog_dd->wdog_cpu_dd);
			free_percpu((void __percpu *)wdog_dd->wdog_cpu_dd);
		}

		del_timer_sync(&wdog_dd->pet_timer);
		flush_work(&wdog_dd->irq_counts_work);
		dev_err(wdog_dd->dev, "Failed Initializing QCOM Apps Watchdog\n");
@@ -875,6 +923,8 @@ static int qcom_wdt_init(struct msm_watchdog_data *wdog_dd,

	qcom_wdt_init_sysfs(wdog_dd);

	if (wdog_dd->irq_ppi)
		enable_percpu_irq(wdog_dd->bark_irq, 0);
	if (!IPI_CORES_IN_LPM) {
		wdog_dd->wdog_cpu_pm_nb.notifier_call = qcom_wdt_cpu_pm_notify;
		cpu_pm_register_notifier(&wdog_dd->wdog_cpu_pm_nb);
@@ -897,6 +947,7 @@ static void qcom_wdt_dt_to_pdata(struct platform_device *pdev,
				struct msm_watchdog_data *pdata)
{
	pdata->bark_irq = platform_get_irq(pdev, 0);
	pdata->irq_ppi = irq_is_percpu(pdata->bark_irq);
	pdata->bark_time = QCOM_WATCHDOG_BARK_TIME;
	pdata->pet_time = QCOM_WATCHDOG_PET_TIME;
	pdata->do_ipi_ping = QCOM_WATCHDOG_IPI_PING;
+2 −0
Original line number Diff line number Diff line
@@ -118,9 +118,11 @@ struct msm_watchdog_data {
	bool do_ipi_ping;
	bool in_panic;
	bool wakeup_irq_enable;
	bool irq_ppi;
	unsigned long long last_pet;
	cpumask_t alive_mask;
	struct mutex disable_lock;
	struct msm_watchdog_data * __percpu *wdog_cpu_dd;
	struct notifier_block panic_blk;
	struct notifier_block die_blk;
	struct notifier_block wdog_cpu_pm_nb;