arm: tegra: support for FIQ debugger with secure OS
Varun Wadekar [Fri, 11 Oct 2013 07:13:03 +0000 (12:13 +0530)]
Most of the set up for the debugger is done by the secure
OS, but the kernel setup that needs to be done is done here.

Use the following config options to enable the debugger -

CONFIG_FIQ=y
CONFIG_TEGRA_FIQ_DEBUGGER=y
CONFIG_FIQ_GLUE=y
CONFIG_FIQ_DEBUGGER=y
CONFIG_FIQ_DEBUGGER_CONSOLE=y
CONFIG_TEGRA_WATCHDOG=y
CONFIG_TEGRA_WATCHDOG_ENABLE_ON_PROBE=y

Bug 1326082

Original-author: Hyung Taek Ryoo <hryoo@nvidia.com>

Change-Id: If1a5dd4f158530dea6c0455ead74a8eeaa226163
Reviewed-on: http://git-master/r/#/c/261217
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/289165

arch/arm/mach-tegra/board-ardbeg.c
arch/arm/mach-tegra/board-loki.c
arch/arm/mach-tegra/devices.c
arch/arm/mach-tegra/fiq.c
drivers/watchdog/tegra_wdt.c

index 70ab7b5..cfda8d5 100644 (file)
@@ -434,6 +434,9 @@ static struct platform_device *ardbeg_devices[] __initdata = {
        &tegra_pmu_device,
        &tegra_rtc_device,
        &tegra_udc_device,
+#if defined(CONFIG_TEGRA_WATCHDOG)
+       &tegra_wdt0_device,
+#endif
 #if defined(CONFIG_TEGRA_AVP)
        &tegra_avp_device,
 #endif
@@ -1098,7 +1101,6 @@ static void __init tegra_ardbeg_late_init(void)
        ardbeg_setup_bluedroid_pm();
        tegra_register_fuse();
        bonaire_sata_init();
-       tegra_serial_debug_init(TEGRA_UARTD_BASE, INT_WDT_CPU, NULL, -1, -1);
 }
 
 static void __init ardbeg_ramconsole_reserve(unsigned long size)
index ecfc61b..c81c558 100644 (file)
@@ -302,6 +302,9 @@ static struct platform_device *loki_devices[] __initdata = {
        &tegra_pmu_device,
        &tegra_rtc_device,
        &tegra_udc_device,
+#if defined(CONFIG_TEGRA_WATCHDOG)
+       &tegra_wdt0_device,
+#endif
 #if defined(CONFIG_TEGRA_AVP)
        &tegra_avp_device,
 #endif
index 35f5793..bc2cee0 100644 (file)
@@ -2424,6 +2424,11 @@ static struct resource tegra_wdt_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [2] = {
+               .start  = TEGRA_PMC_BASE,
+               .end    = TEGRA_PMC_BASE + TEGRA_PMC_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [3] = {
                .start  = INT_TMR1,
                .end    = INT_TMR1,
                .flags  = IORESOURCE_IRQ,
@@ -2449,18 +2454,36 @@ static struct resource tegra_wdt0_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [2] = {
+               .start  = TEGRA_PMC_BASE,
+               .end    = TEGRA_PMC_BASE + TEGRA_PMC_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [3] = {
                .start  = INT_WDT_CPU,
                .end    = INT_WDT_CPU,
                .flags  = IORESOURCE_IRQ,
        },
 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
-       [3] = {
+       [4] = {
                .start  = TEGRA_QUATERNARY_ICTLR_BASE,
                .end    = TEGRA_QUATERNARY_ICTLR_BASE + \
                                TEGRA_QUATERNARY_ICTLR_SIZE -1,
                .flags  = IORESOURCE_MEM,
        },
 #endif
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       [5] = {
+               .start  = TEGRA_WDT4_BASE,
+               .end    = TEGRA_WDT4_BASE + TEGRA_WDT4_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [6] = {
+               .start  = INT_WDT_AVP,
+               .end    = INT_WDT_AVP,
+               .flags  = IORESOURCE_IRQ,
+       },
+#endif
 };
 
 struct platform_device tegra_wdt0_device = {
index c4219da..4f650ac 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
  *
  * Author:
  *     Brian Swetland <swetland@google.com>
  *     Iliyan Malchev <malchev@google.com>
+ *     Lucas Dai <lucasd@nvidia.com>
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -81,7 +83,12 @@ static void tegra_fiq_unmask(struct irq_data *d)
 
 void tegra_fiq_enable(int irq)
 {
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
+       defined(CONFIG_ARCH_TEGRA_2x_SOC)
        void __iomem *base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100);
+#else
+       void __iomem *base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x2000);
+#endif
        /* enable FIQ */
        u32 val = readl(base + GIC_CPU_CTRL);
        val &= ~8; /* pass FIQs through */
index a2923d2..c3f513e 100644 (file)
@@ -39,7 +39,6 @@
 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
 #include <mach/irqs.h>
 #endif
-#include <mach/iomap.h>
 
 /* minimum and maximum watchdog trigger periods, in seconds */
 #define MIN_WDT_PERIOD 5
@@ -59,14 +58,21 @@ struct tegra_wdt {
        struct resource         *res_src;
        struct resource         *res_wdt;
        struct resource         *res_int_base;
+       struct resource         *res_pmc;
        unsigned long           users;
        void __iomem            *wdt_source;
        void __iomem            *wdt_timer;
        void __iomem            *int_base;
+       void __iomem            *pmc_base;
        int                     irq;
        int                     tmrsrc;
        int                     timeout;
        int                     status;
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       struct resource         *res_avp_src;
+       void __iomem            *wdt_avp_source;
+#endif
 };
 
 /*
@@ -119,7 +125,7 @@ static irqreturn_t tegra_wdt_interrupt(int irq, void *dev_id)
        writel(TIMER_PCR_INTR, wdt->wdt_timer + TIMER_PCR);
        return IRQ_HANDLED;
 }
-#elif defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_11x_SOC)
+#elif defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
 
 #define TIMER_PTV                      0
  #define TIMER_EN                      (1 << 31)
@@ -148,8 +154,14 @@ struct tegra_wdt *tegra_wdt[MAX_NR_CPU_WDT];
 static inline void tegra_wdt_ping(struct tegra_wdt *wdt)
 {
        writel(WDT_CMD_START_COUNTER, wdt->wdt_source + WDT_CMD);
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       /* Comment out to test FIQ debugger */
+       writel(WDT_CMD_START_COUNTER, wdt->wdt_avp_source + WDT_CMD);
+#endif
 }
 
+#if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
 static void tegra_wdt_int_priority(struct tegra_wdt *wdt)
 {
@@ -162,6 +174,7 @@ static void tegra_wdt_int_priority(struct tegra_wdt *wdt)
        writel(val, wdt->int_base + ICTLR_IEP_CLASS);
 }
 #endif
+#endif
 
 static void tegra_wdt_enable(struct tegra_wdt *wdt)
 {
@@ -180,11 +193,23 @@ static void tegra_wdt_enable(struct tegra_wdt *wdt)
         */
        val = wdt->tmrsrc | WDT_CFG_PERIOD | /*WDT_CFG_INT_EN |*/
                /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
+
+#if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
        val |= WDT_CFG_FIQ_INT_EN;
 #endif
+#endif
        writel(val, wdt->wdt_source + WDT_CFG);
        writel(WDT_CMD_START_COUNTER, wdt->wdt_source + WDT_CMD);
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       val = wdt->tmrsrc | (WDT_CFG_PERIOD << 1) | /*WDT_CFG_INT_EN |*/
+               /*WDT_CFG_SYS_RST_EN |*/ WDT_CFG_PMC2CAR_RST_EN;
+       writel(val, wdt->wdt_avp_source + WDT_CFG);
+       writel(WDT_CMD_START_COUNTER, wdt->wdt_avp_source + WDT_CMD);
+
+#endif
 }
 
 static void tegra_wdt_disable(struct tegra_wdt *wdt)
@@ -192,6 +217,12 @@ static void tegra_wdt_disable(struct tegra_wdt *wdt)
        writel(WDT_UNLOCK_PATTERN, wdt->wdt_source + WDT_UNLOCK);
        writel(WDT_CMD_DISABLE_COUNTER, wdt->wdt_source + WDT_CMD);
 
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       writel(WDT_UNLOCK_PATTERN, wdt->wdt_avp_source + WDT_UNLOCK);
+       writel(WDT_CMD_DISABLE_COUNTER, wdt->wdt_avp_source + WDT_CMD);
+#endif
+
        writel(0, wdt->wdt_timer + TIMER_PTV);
 }
 
@@ -210,6 +241,15 @@ static irqreturn_t tegra_wdt_interrupt(int irq, void *dev_id)
 
        return IRQ_HANDLED;
 }
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+static irqreturn_t tegra_wdt_avp_interrupt(int irq, void *dev_id)
+{
+       return IRQ_HANDLED;
+}
+#endif
+
 #endif
 
 static int tegra_wdt_notify(struct notifier_block *this,
@@ -258,7 +298,6 @@ static long tegra_wdt_ioctl(struct file *file, unsigned int cmd,
        struct tegra_wdt *wdt = file->private_data;
        static DEFINE_SPINLOCK(lock);
        int new_timeout;
-       int option;
        static const struct watchdog_info ident = {
                .identity = "Tegra Watchdog",
                .options = WDIOF_SETTIMEOUT,
@@ -326,7 +365,7 @@ static void tegra_wdt_log_reset_reason(struct platform_device *pdev,
                struct tegra_wdt *wdt)
 {
 
-#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_11x_SOC)
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
        /*
         * There are two pathes to make the WDT reset:
         *  (a) WDT -> PMC -> CAR
@@ -348,7 +387,6 @@ static void tegra_wdt_log_reset_reason(struct platform_device *pdev,
         *  source. We will not use this path.
         */
        u32 val;
-       void __iomem *pmc_base;
 #define RESET_STR(REASON) "last reset is due to "#REASON"\n"
        char *reset_reason[] = {
                RESET_STR(power on reset),
@@ -362,8 +400,7 @@ static void tegra_wdt_log_reset_reason(struct platform_device *pdev,
        if (pdev->id > 0)
                return;
 
-       pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-       val = readl(pmc_base + PMC_RST_STATUS) & 0x7;
+       val = readl(wdt->pmc_base + PMC_RST_STATUS) & 0x7;
        if (val >= ARRAY_SIZE(reset_reason))
                dev_info(&pdev->dev, "last reset value is invalid 0x%x\n", val);
        else
@@ -389,7 +426,11 @@ static const struct file_operations tegra_wdt_fops = {
 
 static int tegra_wdt_probe(struct platform_device *pdev)
 {
-       struct resource *res_src, *res_wdt, *res_irq;
+       struct resource *res_src, *res_wdt, *res_irq, *res_pmc;
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       struct resource *res_avp_src, *res_avp_irq;
+#endif
        struct resource *res_int_base = NULL;
        struct tegra_wdt *wdt;
        int ret = 0;
@@ -401,20 +442,35 @@ static int tegra_wdt_probe(struct platform_device *pdev)
 
        res_src = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        res_wdt = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       res_pmc = platform_get_resource(pdev, IORESOURCE_MEM, 2);
        res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
-       if (!res_src || !res_wdt || (!pdev->id && !res_irq)) {
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       res_avp_src = platform_get_resource(pdev, IORESOURCE_MEM, 4);
+       res_avp_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+#endif
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       if (!res_src || !res_wdt || !res_avp_src || (!pdev->id && !res_irq) ||
+           !res_pmc) {
+#else
+       if (!res_src || !res_wdt || (!pdev->id && !res_irq) || !res_pmc) {
+#endif
                dev_err(&pdev->dev, "incorrect resources\n");
                return -ENOENT;
        }
 
+#if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
-       res_int_base = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+       res_int_base = platform_get_resource(pdev, IORESOURCE_MEM, 3);
        if (!pdev->id && !res_int_base) {
                dev_err(&pdev->dev, "FIQ_DBG: INT base not defined\n");
                return -ENOENT;
        }
 #endif
+#endif
 
        if (pdev->id == -1 && !res_irq) {
                dev_err(&pdev->dev, "incorrect irq\n");
@@ -451,8 +507,22 @@ static int tegra_wdt_probe(struct platform_device *pdev)
                                     pdev->name);
        res_wdt = request_mem_region(res_wdt->start, resource_size(res_wdt),
                                     pdev->name);
+       res_pmc = request_mem_region(res_pmc->start, resource_size(res_pmc),
+                                    pdev->name);
 
-       if (!res_src || !res_wdt) {
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       res_avp_src = request_mem_region(res_avp_src->start,
+                                        resource_size(res_avp_src),
+                                        pdev->name);
+#endif
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       if (!res_src || !res_wdt || !res_avp_src || !res_pmc) {
+#else
+       if (!res_src || !res_wdt || !res_pmc) {
+#endif
                dev_err(&pdev->dev, "unable to request memory resources\n");
                ret = -EBUSY;
                goto fail;
@@ -460,9 +530,23 @@ static int tegra_wdt_probe(struct platform_device *pdev)
 
        wdt->wdt_source = ioremap(res_src->start, resource_size(res_src));
        wdt->wdt_timer = ioremap(res_wdt->start, resource_size(res_wdt));
+       wdt->pmc_base = ioremap(res_pmc->start, resource_size(res_pmc));
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       wdt->wdt_avp_source = ioremap(res_avp_src->start,
+                                     resource_size(res_avp_src));
+#endif
        /* tmrsrc will be used to set WDT_CFG */
        wdt->tmrsrc = (TMR_SRC_START + pdev->id) % 10;
-       if (!wdt->wdt_source || !wdt->wdt_timer) {
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       if (!wdt->wdt_source || !wdt->wdt_timer || !wdt->wdt_avp_source ||
+           !wdt->pmc_base) {
+#else
+       if (!wdt->wdt_source || !wdt->wdt_timer || !wdt->pmc_base) {
+#endif
                dev_err(&pdev->dev, "unable to map registers\n");
                ret = -ENOMEM;
                goto fail;
@@ -474,6 +558,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
        writel(TIMER_PCR_INTR, wdt->wdt_timer + TIMER_PCR);
 
        if (res_irq != NULL) {
+#if !defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_FIQ_DEBUGGER)
 #ifdef CONFIG_TEGRA_FIQ_DEBUGGER
                /* FIQ debugger enables FIQ priority for INT_WDT_CPU.
                 * But that will disable IRQ on WDT expiration.
@@ -492,18 +577,36 @@ static int tegra_wdt_probe(struct platform_device *pdev)
                        goto fail;
                tegra_wdt_int_priority(wdt);
 #endif
+#endif
                ret = request_irq(res_irq->start, tegra_wdt_interrupt,
                                  IRQF_DISABLED, dev_name(&pdev->dev), wdt);
                if (ret) {
                        dev_err(&pdev->dev, "unable to configure IRQ\n");
                        goto fail;
                }
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+               ret = request_irq(res_avp_irq->start, tegra_wdt_avp_interrupt,
+                               IRQF_DISABLED, "avp_wdt", wdt);
+               if (ret) {
+                       dev_err(&pdev->dev, "unable to configure WDT AVP IRQ\n");
+                       goto fail;
+               }
+#endif
+
                wdt->irq = res_irq->start;
        }
 
        wdt->res_src = res_src;
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       wdt->res_avp_src = res_avp_src;
+#endif
        wdt->res_wdt = res_wdt;
        wdt->res_int_base = res_int_base;
+       wdt->res_pmc = res_pmc;
        wdt->status = WDT_DISABLED;
 
        ret = register_reboot_notifier(&wdt->notifier);
@@ -532,6 +635,14 @@ static int tegra_wdt_probe(struct platform_device *pdev)
                val = readl(wdt->wdt_source + WDT_CFG);
                val |= WDT_CFG_INT_EN;
                writel(val, wdt->wdt_source + WDT_CFG);
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+               val = readl(wdt->wdt_avp_source + WDT_CFG);
+               val |= WDT_CFG_INT_EN;
+               writel(val, wdt->wdt_avp_source + WDT_CFG);
+
+#endif
                pr_info("WDT heartbeat enabled on probe\n");
        }
 #endif
@@ -548,6 +659,8 @@ fail:
                iounmap(wdt->wdt_timer);
        if (wdt->int_base)
                iounmap(wdt->int_base);
+       if (wdt->pmc_base)
+               iounmap(wdt->pmc_base);
        if (res_src)
                release_mem_region(res_src->start, resource_size(res_src));
        if (res_wdt)
@@ -555,6 +668,17 @@ fail:
        if (res_int_base)
                release_mem_region(res_int_base->start,
                                        resource_size(res_int_base));
+       if (res_pmc)
+               release_mem_region(res_pmc->start, resource_size(res_pmc));
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       if (wdt->wdt_avp_source)
+               iounmap(wdt->wdt_avp_source);
+       if (res_avp_src)
+               release_mem_region(res_avp_src->start,
+                                  resource_size(res_avp_src));
+#endif
        kfree(wdt);
        return ret;
 }
@@ -570,14 +694,30 @@ static int tegra_wdt_remove(struct platform_device *pdev)
        if (wdt->irq != -1)
                free_irq(wdt->irq, wdt);
        iounmap(wdt->wdt_source);
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       iounmap(wdt->wdt_avp_source);
+#endif
        iounmap(wdt->wdt_timer);
        if (wdt->int_base)
                iounmap(wdt->int_base);
+       if (wdt->pmc_base)
+               iounmap(wdt->pmc_base);
        release_mem_region(wdt->res_src->start, resource_size(wdt->res_src));
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+       release_mem_region(wdt->res_avp_src->start,
+                          resource_size(wdt->res_avp_src));
+#endif
        release_mem_region(wdt->res_wdt->start, resource_size(wdt->res_wdt));
        if (wdt->res_int_base)
                release_mem_region(wdt->res_int_base->start,
                                        resource_size(wdt->res_int_base));
+       if (wdt->res_pmc)
+               release_mem_region(wdt->res_pmc->start,
+                                       resource_size(wdt->res_pmc));
        kfree(wdt);
        platform_set_drvdata(pdev, NULL);
        return 0;
@@ -606,6 +746,13 @@ static int tegra_wdt_resume(struct platform_device *pdev)
                val = readl(wdt->wdt_source + WDT_CFG);
                val |= WDT_CFG_INT_EN;
                writel(val, wdt->wdt_source + WDT_CFG);
+
+#if defined(CONFIG_TEGRA_USE_SECURE_KERNEL) && \
+       defined(CONFIG_ARCH_TEGRA_12x_SOC) && defined(CONFIG_FIQ_DEBUGGER)
+               val = readl(wdt->wdt_avp_source + WDT_CFG);
+               val |= WDT_CFG_INT_EN;
+               writel(val, wdt->wdt_avp_source + WDT_CFG);
+#endif
                pr_info("WDT heartbeat enabled on probe\n");
        }
 #endif