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

Commit 00e8a85c authored by Sarangdhar Joshi's avatar Sarangdhar Joshi
Browse files

soc: qcom: watchdog_v2: add support to enable watchdog feature



Currently we disable Non secure watchdog during suspend and
re-enable it during resume. This leaves suspend / resume path
unprotected by Non secure watchdog. There is a feature in
hardware where watchdog freezes automatically when all online
cores are in suspend and unfreezes watchdog upon wakeup event
from low power mode. Set the bit in watchdog control register to
enable this feature and protect suspend / resume path by Non
secure watchdog.

Change-Id: Ibca425a661c74bd1d46513783780ea213a51f87f
Signed-off-by: default avatarSarangdhar Joshi <spjoshi@codeaurora.org>
parent f388a43a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ Required properties:
Optional properties:

- qcom,ipi-ping : (boolean) send keep alive ping to other cpus if present
- qcom,wakeup-enable : (boolean) enable non secure watchdog to freeze / unfreeze
			automatically across suspend / resume path.

Example:

@@ -37,4 +39,5 @@ Example:
		qcom,bark-time = <11000>;
		qcom,pet-time = <10000>;
		qcom,ipi-ping;
		qcom,wakeup-enable;
	};
+17 −2
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@

#define WDOG_ABSENT	0

#define EN		0
#define UNMASKED_INT_EN 1

#define MASK_SIZE		32
#define SCM_SET_REGSAVE_CMD	0x2
#define SCM_SVC_SEC_WDOG_DIS	0x7
@@ -62,6 +65,7 @@ struct msm_watchdog_data {
	unsigned int bark_irq;
	unsigned int bite_irq;
	bool do_ipi_ping;
	bool wakeup_irq_enable;
	unsigned long long last_pet;
	unsigned min_slack_ticks;
	unsigned long long min_slack_ns;
@@ -118,6 +122,10 @@ static int msm_watchdog_suspend(struct device *dev)
	if (!enable)
		return 0;
	__raw_writel(1, wdog_dd->base + WDT0_RST);
	if (wdog_dd->wakeup_irq_enable) {
		wdog_dd->last_pet = sched_clock();
		return 0;
	}
	__raw_writel(0, wdog_dd->base + WDT0_EN);
	mb();
	wdog_dd->enabled = false;
@@ -129,7 +137,7 @@ static int msm_watchdog_resume(struct device *dev)
{
	struct msm_watchdog_data *wdog_dd =
			(struct msm_watchdog_data *)dev_get_drvdata(dev);
	if (!enable)
	if (!enable || wdog_dd->wakeup_irq_enable)
		return 0;
	__raw_writel(1, wdog_dd->base + WDT0_EN);
	__raw_writel(1, wdog_dd->base + WDT0_RST);
@@ -521,6 +529,7 @@ static void init_watchdog_work(struct work_struct *work)
						struct msm_watchdog_data,
							init_dogwork_struct);
	unsigned long delay_time;
	uint32_t val;
	int error;
	u64 timeout;
	int ret;
@@ -570,7 +579,10 @@ static void init_watchdog_work(struct work_struct *work)
	mutex_init(&wdog_dd->disable_lock);
	queue_delayed_work(wdog_wq, &wdog_dd->dogwork_struct,
			delay_time);
	__raw_writel(1, wdog_dd->base + WDT0_EN);
	val = BIT(EN);
	if (wdog_dd->wakeup_irq_enable)
		val |= BIT(UNMASKED_INT_EN);
	__raw_writel(val, wdog_dd->base + WDT0_EN);
	__raw_writel(1, wdog_dd->base + WDT0_RST);
	wdog_dd->last_pet = sched_clock();
	wdog_dd->enabled = true;
@@ -663,6 +675,9 @@ static int msm_wdog_dt_to_pdata(struct platform_device *pdev,
								__func__);
		return -ENXIO;
	}
	pdata->wakeup_irq_enable = of_property_read_bool(node,
							 "qcom,wakeup-enable");

	pdata->irq_ppi = irq_is_percpu(pdata->bark_irq);
	dump_pdata(pdata);
	return 0;