RE: DSPBRIDGE: Implement WDT3 to notify DSP hangs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Hi All,

        I forgot to mention that you need DSP side changes too, at lest you need 4.57-P2 DSP binaries. They will be updated in userspace-dspbridge project in d.o.z

Regards,
Fernando.

>-----Original Message-----
>From: linux-omap-owner@xxxxxxxxxxxxxxx [mailto:linux-omap-
>owner@xxxxxxxxxxxxxxx] On Behalf Of Guzman Lugo, Fernando
>Sent: Tuesday, March 30, 2010 9:44 PM
>To: linux-omap@xxxxxxxxxxxxxxx
>Cc: Hiroshi DOYU; Ameya Palande; felipe.contreras@xxxxxxxxx
>Subject: DSPBRIDGE: Implement WDT3 to notify DSP hangs
>
>From 7349444302a782997d6eba64d46908c0915c12a1 Mon Sep 17 00:00:00 2001
>From: Fernando Guzman Lugo <x0095840@xxxxxx>
>Date: Tue, 30 Mar 2010 21:52:25 -0600
>Subject: [PATCH] DSPBRIDGE: Implement WDT3 to notify DSP hangs
>
>This patch implements wdt3 feature to notify wdt3 overflow.
>This new feature can be chosen by doing make menuconfig,
>default is disabled.
>
>WDT3 is upcount Timer incrementing every functional clock tick
>till it reaches programmed timeout value. On reaching timeout
>value, if INTerrupt bit for WDT3 is enabled, then an interrupt
>is generated to MPU.
>
>After receiving this Interrupt, any client can register within
>bridge driver to be notified of this event and prepare for
>DSP recovery.
>
>Signed-off-by: Fernando Guzman Lugo <x0095840@xxxxxx>
>Signed-off-by: Armando Uribe <x0095078@xxxxxx>
>Signed-off-by: Somashekar Chandrappa <somashekar.c@xxxxxx>
>---
> arch/arm/plat-omap/include/dspbridge/_chnl_sm.h |    7 +
> arch/arm/plat-omap/include/dspbridge/cfgdefs.h  |    1 -
> arch/arm/plat-omap/include/dspbridge/dbdefs.h   |    3 +
> arch/arm/plat-omap/include/dspbridge/wdt.h      |   79 ++++++++++++
> arch/arm/plat-omap/include/plat/omap34xx.h      |    3 +
> drivers/dsp/bridge/Kconfig                      |   17 +++
> drivers/dsp/bridge/Makefile                     |    2 +-
> drivers/dsp/bridge/rmgr/drv.c                   |    8 --
> drivers/dsp/bridge/rmgr/proc.c                  |    8 +-
> drivers/dsp/bridge/wmd/io_sm.c                  |    4 +
> drivers/dsp/bridge/wmd/tiomap3430.c             |    7 +
> drivers/dsp/bridge/wmd/tiomap3430_pwr.c         |    7 +
> drivers/dsp/bridge/wmd/tiomap_io.c              |    2 +
> drivers/dsp/bridge/wmd/ue_deh.c                 |   13 ++
> drivers/dsp/bridge/wmd/wdt.c                    |  148
>+++++++++++++++++++++++
> 15 files changed, 296 insertions(+), 13 deletions(-)
> create mode 100644 arch/arm/plat-omap/include/dspbridge/wdt.h
> create mode 100644 drivers/dsp/bridge/wmd/wdt.c
>
>diff --git a/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h
>b/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h
>index f394ba6..f8bdc93 100644
>--- a/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h
>+++ b/arch/arm/plat-omap/include/dspbridge/_chnl_sm.h
>@@ -99,7 +99,14 @@ struct shm {
>        struct opp_rqst_struct opp_request;
>        /* load monitor information structure */
>        struct load_mon_struct load_mon_info;
>+#ifdef CONFIG_BRIDGE_WDT3
>+       /* Flag for WDT enable/disable F/I clocks */
>+       u32 wdt_setclocks;
>+       u32 wdt_overflow;       /* WDT overflow time */
>+       char dummy[176];        /* padding to 256 byte boundary */
>+#else
>        char dummy[184];        /* padding to 256 byte boundary */
>+#endif
>        u32 shm_dbg_var[64];    /* shared memory debug variables */
> };
>
>diff --git a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h
>b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h
>index bd24611..a71fc7b 100644
>--- a/arch/arm/plat-omap/include/dspbridge/cfgdefs.h
>+++ b/arch/arm/plat-omap/include/dspbridge/cfgdefs.h
>@@ -70,7 +70,6 @@ struct cfg_hostres {
>        void __iomem *dw_per_base;
>        u32 dw_per_pm_base;
>        u32 dw_core_pm_base;
>-       void __iomem *dw_wd_timer_dsp_base;
>        void __iomem *dw_dmmu_base;
>        void __iomem *dw_sys_ctrl_base;
> };
>diff --git a/arch/arm/plat-omap/include/dspbridge/dbdefs.h b/arch/arm/plat-
>omap/include/dspbridge/dbdefs.h
>index 7fcc4aa..b5d3097 100644
>--- a/arch/arm/plat-omap/include/dspbridge/dbdefs.h
>+++ b/arch/arm/plat-omap/include/dspbridge/dbdefs.h
>@@ -53,6 +53,7 @@
> #define DSP_SYSERROR                0x00000020
> #define DSP_EXCEPTIONABORT          0x00000300
> #define DSP_PWRERROR                0x00000080
>+#define DSP_WDTOVERFLOW        0x00000040
>
> /* IVA exception events (IVA MMU fault) */
> #define IVA_MMUFAULT                0x00000040
>@@ -124,6 +125,7 @@ typedef u32 dsp_status;             /* API return code
>type */
>                                    DSP_STREAMIOCOMPLETION | \
>                                    DSP_MMUFAULT | \
>                                    DSP_SYSERROR | \
>+                                   DSP_WDTOVERFLOW | \
>                                    DSP_PWRERROR)) && \
>                                !((x) & ~(DSP_PROCESSORSTATECHANGE | \
>                                    DSP_PROCESSORATTACH | \
>@@ -134,6 +136,7 @@ typedef u32 dsp_status;             /* API return code
>type */
>                                    DSP_STREAMIOCOMPLETION | \
>                                    DSP_MMUFAULT | \
>                                    DSP_SYSERROR | \
>+                                   DSP_WDTOVERFLOW | \
>                                    DSP_PWRERROR))))
>
> #define IS_VALID_NODE_EVENT(x)    (((x) == 0) || \
>diff --git a/arch/arm/plat-omap/include/dspbridge/wdt.h b/arch/arm/plat-
>omap/include/dspbridge/wdt.h
>new file mode 100644
>index 0000000..4c00ba5
>--- /dev/null
>+++ b/arch/arm/plat-omap/include/dspbridge/wdt.h
>@@ -0,0 +1,79 @@
>+/*
>+ * wdt.h
>+ *
>+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
>+ *
>+ * IO dispatcher for a shared memory channel driver.
>+ *
>+ * Copyright (C) 2010 Texas Instruments, Inc.
>+ *
>+ * This package is free software; you can redistribute it and/or modify
>+ * it under the terms of the GNU General Public License version 2 as
>+ * published by the Free Software Foundation.
>+ *
>+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
>+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
>+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
>+ */
>+#ifndef __DSP_WDT3_H_
>+#define __DSP_WDT3_H_
>+
>+/* WDT defines */
>+#define OMAP3_WDT3_ISR_OFFSET  0x0018
>+
>+
>+/**
>+ * struct dsp_wdt_setting - the basic dsp_wdt_setting structure
>+ * @reg_base:  pointer to the base of the wdt registers
>+ * @sm_wdt:    pointer to flags in shared memory
>+ * @wdt3_tasklet       tasklet to manage wdt event
>+ * @fclk               handle to wdt3 functional clock
>+ * @iclk               handle to wdt3 interface clock
>+ *
>+ * This struct is used in the function to manage wdt3.
>+ */
>+
>+struct dsp_wdt_setting {
>+       void __iomem *reg_base;
>+       struct shm *sm_wdt;
>+       struct tasklet_struct wdt3_tasklet;
>+       struct clk *fclk;
>+       struct clk *iclk;
>+};
>+
>+/**
>+ * dsp_wdt_init() - initialize wdt3 module.
>+ *
>+ * This function initilize to wdt3 module, so that
>+ * other wdt3 function can be used.
>+ */
>+int dsp_wdt_init(void);
>+
>+/**
>+ * dsp_wdt_exit() - initialize wdt3 module.
>+ *
>+ * This function frees all resources allocated for wdt3 module.
>+ */
>+void dsp_wdt_exit(void);
>+
>+/**
>+ * dsp_wdt_enable() - enable/disable wdt3
>+ * @enable:    bool value to enable/disable wdt3
>+ *
>+ * This function enables or disables wdt3 base on @enable value.
>+ *
>+ */
>+void dsp_wdt_enable(bool enable);
>+
>+/**
>+ * dsp_wdt_sm_set() - store pointer to the share memory
>+ * @data:              pointer to dspbridge share memory
>+ *
>+ * This function is used to pass a valid pointer to share memory,
>+ * so that the flags can be set in order DSP side can read them.
>+ *
>+ */
>+void dsp_wdt_sm_set(void *data);
>+
>+#endif
>+
>diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-
>omap/include/plat/omap34xx.h
>index 077f059..dded9cc 100644
>--- a/arch/arm/plat-omap/include/plat/omap34xx.h
>+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
>@@ -82,5 +82,8 @@
>
> #define OMAP34XX_MAILBOX_BASE          (L4_34XX_BASE + 0x94000)
>
>+#define OMAP34XX_WDT3_BASE             (L4_PER_34XX_BASE + 0x30000)
>+
>+
> #endif /* __ASM_ARCH_OMAP34XX_H */
>
>diff --git a/drivers/dsp/bridge/Kconfig b/drivers/dsp/bridge/Kconfig
>index 23b2afc..fcd035c 100644
>--- a/drivers/dsp/bridge/Kconfig
>+++ b/drivers/dsp/bridge/Kconfig
>@@ -45,6 +45,23 @@ config BRIDGE_RECOVERY
>          In case of DSP fatal error, BRIDGE driver will try to
>          recover itself.
>
>+config BRIDGE_WDT3
>+       bool "Enable WDT3 interruptions"
>+       depends on MPU_BRIDGE
>+       default n
>+       help
>+         WTD3 is managed by DSP and once it is enabled, DSP side bridge is
>in
>+         charge of refreshing the timer before overflow, if the DSP hangs
>MPU
>+         will caught the interrupt and try to recover DSP.
>+
>+config WDT_TIMEOUT
>+       int "DSP watchdog timer timeout (in secs)"
>+       depends on BRIDGE_WDT3
>+       default 5
>+       help
>+          Watchdog timer timeout value, after that time if the watchdog
>timer
>+          counter is not reset the wdt overflow interrupt will be
>triggered
>+
> comment "Bridge Notifications"
>        depends on MPU_BRIDGE
>
>diff --git a/drivers/dsp/bridge/Makefile b/drivers/dsp/bridge/Makefile
>index 2b4f92c..ce85ba6 100644
>--- a/drivers/dsp/bridge/Makefile
>+++ b/drivers/dsp/bridge/Makefile
>@@ -7,7 +7,7 @@ libservices = services/mem.o services/sync.o \
>                services/services.o
> libwmd = wmd/chnl_sm.o wmd/msg_sm.o wmd/io_sm.o wmd/tiomap3430.o \
>                wmd/tiomap3430_pwr.o wmd/tiomap_io.o \
>-               wmd/mmu_fault.o wmd/ue_deh.o
>+               wmd/mmu_fault.o wmd/ue_deh.o wmd/wdt.o
> libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o
>pmgr/wcd.o \
>                pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o
> librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \
>diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c
>index 98f9b78..fe9ae06 100644
>--- a/drivers/dsp/bridge/rmgr/drv.c
>+++ b/drivers/dsp/bridge/rmgr/drv.c
>@@ -904,8 +904,6 @@ static dsp_status request_bridge_resources(u32
>dw_context, s32 bRequest)
>                                iounmap((void *)host_res->dw_mem_base[3]);
>                        if (host_res->dw_mem_base[4])
>                                iounmap((void *)host_res->dw_mem_base[4]);
>-                       if (host_res->dw_wd_timer_dsp_base)
>-                               iounmap(host_res->dw_wd_timer_dsp_base);
>                        if (host_res->dw_dmmu_base)
>                                iounmap(host_res->dw_dmmu_base);
>                        if (host_res->dw_per_base)
>@@ -923,7 +921,6 @@ static dsp_status request_bridge_resources(u32
>dw_context, s32 bRequest)
>                        host_res->dw_mem_base[2] = (u32) NULL;
>                        host_res->dw_mem_base[3] = (u32) NULL;
>                        host_res->dw_mem_base[4] = (u32) NULL;
>-                       host_res->dw_wd_timer_dsp_base = NULL;
>                        host_res->dw_dmmu_base = NULL;
>                        host_res->dw_sys_ctrl_base = NULL;
>
>@@ -956,8 +953,6 @@ static dsp_status request_bridge_resources(u32
>dw_context, s32 bRequest)
>                        host_res->dw_mem_base[3]);
>                dev_dbg(bridge, "dw_prm_base %p\n", host_res->dw_prm_base);
>                dev_dbg(bridge, "dw_cm_base %p\n", host_res->dw_cm_base);
>-               dev_dbg(bridge, "dw_wd_timer_dsp_base %p\n",
>-                       host_res->dw_wd_timer_dsp_base);
>                dev_dbg(bridge, "dw_dmmu_base %p\n", host_res-
>>dw_dmmu_base);
>
>                /* for 24xx base port is not mapping the mamory for DSP
>@@ -1032,7 +1027,6 @@ static dsp_status request_bridge_resources_dsp(u32
>dw_context, s32 bRequest)
>
>OMAP_CORE_PRM_SIZE);
>                host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE,
>                                                 OMAP_DMMU_SIZE);
>-               host_res->dw_wd_timer_dsp_base = NULL;
>
>                dev_dbg(bridge, "dw_mem_base[0] 0x%x\n",
>                        host_res->dw_mem_base[0]);
>@@ -1046,8 +1040,6 @@ static dsp_status request_bridge_resources_dsp(u32
>dw_context, s32 bRequest)
>                        host_res->dw_mem_base[4]);
>                dev_dbg(bridge, "dw_prm_base %p\n", host_res->dw_prm_base);
>                dev_dbg(bridge, "dw_cm_base %p\n", host_res->dw_cm_base);
>-               dev_dbg(bridge, "dw_wd_timer_dsp_base %p\n",
>-                       host_res->dw_wd_timer_dsp_base);
>                dev_dbg(bridge, "dw_dmmu_base %p\n", host_res-
>>dw_dmmu_base);
>                dw_buff_size = sizeof(shm_size);
>                status =
>diff --git a/drivers/dsp/bridge/rmgr/proc.c
>b/drivers/dsp/bridge/rmgr/proc.c
>index 1556285..2892041 100644
>--- a/drivers/dsp/bridge/rmgr/proc.c
>+++ b/drivers/dsp/bridge/rmgr/proc.c
>@@ -1149,8 +1149,9 @@ dsp_status proc_register_notify(void *hprocessor, u32
>event_mask,
>        }
>        /* Check if event mask is a valid processor related event */
>        if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
>-                          DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
>-                          DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR))
>+                       DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
>+                       DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR |
>+                       DSP_WDTOVERFLOW))
>                status = DSP_EVALUE;
>
>        /* Check if notify type is valid */
>@@ -1161,7 +1162,8 @@ dsp_status proc_register_notify(void *hprocessor, u32
>event_mask,
>                /* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
>                 * or DSP_PWRERROR then register event immediately. */
>                if (event_mask &
>-                   ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR)) {
>+                   ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
>+                               DSP_WDTOVERFLOW)) {
>                        status = ntfy_register(p_proc_object->ntfy_obj,
>                                               hnotification, event_mask,
>                                               notify_type);
>diff --git a/drivers/dsp/bridge/wmd/io_sm.c
>b/drivers/dsp/bridge/wmd/io_sm.c
>index 1b5d977..545cca0 100644
>--- a/drivers/dsp/bridge/wmd/io_sm.c
>+++ b/drivers/dsp/bridge/wmd/io_sm.c
>@@ -51,6 +51,7 @@
> #include <dspbridge/wmddeh.h>
> #include <dspbridge/wmdio.h>
> #include <dspbridge/wmdioctl.h>
>+#include <dspbridge/wdt.h>
> #include <_tiomap.h>
> #include <tiomap_io.h>
> #include <_tiomap_pwr.h>
>@@ -244,6 +245,8 @@ dsp_status bridge_io_create(OUT struct io_mgr
>**phIOMgr,
>        if (DSP_SUCCEEDED(status)) {
>                pio_mgr->hwmd_context = hwmd_context;
>                pio_mgr->shared_irq = pMgrAttrs->irq_shared;
>+               if (dsp_wdt_init())
>+                       status = DSP_EFAIL;
>        } else {
>                status = CHNL_E_ISR;
>        }
>@@ -279,6 +282,7 @@ dsp_status bridge_io_destroy(struct io_mgr *hio_mgr)
> #ifndef DSP_TRACEBUF_DISABLED
>                kfree(hio_mgr->pmsg);
> #endif
>+               dsp_wdt_exit();
>                /* Free this IO manager object */
>                MEM_FREE_OBJECT(hio_mgr);
>        } else {
>diff --git a/drivers/dsp/bridge/wmd/tiomap3430.c
>b/drivers/dsp/bridge/wmd/tiomap3430.c
>index ed51875..7a1093c 100644
>--- a/drivers/dsp/bridge/wmd/tiomap3430.c
>+++ b/drivers/dsp/bridge/wmd/tiomap3430.c
>@@ -60,6 +60,7 @@
> #include <dspbridge/dev.h>
> #include <dspbridge/wcd.h>
> #include <dspbridge/dmm.h>
>+#include <dspbridge/wdt.h>
>
> /*  ----------------------------------- Local */
> #include "_tiomap.h"
>@@ -724,6 +725,10 @@ static dsp_status bridge_brd_start(struct
>wmd_dev_context *hDevContext,
>                if (!wait_for_start(dev_context, dw_sync_addr))
>                        status = WMD_E_TIMEOUT;
>
>+               /* Start wdt */
>+               dsp_wdt_sm_set((void *)ul_shm_base);
>+               dsp_wdt_enable(true);
>+
>                status = dev_get_io_mgr(dev_context->hdev_obj, &hio_mgr);
>                if (DSP_SUCCEEDED(status)) {
>                        io_sh_msetting(hio_mgr, SHM_OPPINFO, NULL);
>@@ -799,6 +804,8 @@ static dsp_status bridge_brd_stop(struct
>wmd_dev_context *hDevContext)
>
>        dev_context->dw_brd_state = BRD_STOPPED;        /* update board
>state */
>
>+       dsp_wdt_enable(false);
>+
>        /* This is a good place to clear the MMU page tables as well */
>        if (dev_context->pt_attrs) {
>                pt_attrs = dev_context->pt_attrs;
>diff --git a/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
>b/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
>index 9174a80..f21be4b 100644
>--- a/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
>+++ b/drivers/dsp/bridge/wmd/tiomap3430_pwr.c
>@@ -41,6 +41,7 @@
>
> /*  ----------------------------------- Mini Driver */
> #include <dspbridge/wmddeh.h>
>+#include <dspbridge/wdt.h>
>
> /*  ----------------------------------- specific to this file */
> #include "_tiomap.h"
>@@ -125,6 +126,9 @@ dsp_status handle_hibernation_from_dsp(struct
>wmd_dev_context *dev_context)
>                /* Turn off DSP Peripheral clocks and DSP Load monitor
>timer */
>                status = dsp_peripheral_clocks_disable(dev_context, NULL);
>
>+               /* Disable wdt on hibernation. */
>+               dsp_wdt_enable(false);
>+
>                if (DSP_SUCCEEDED(status)) {
>                        /* Update the Bridger Driver state */
>                        dev_context->dw_brd_state = BRD_DSP_HIBERNATION;
>@@ -239,6 +243,9 @@ dsp_status sleep_dsp(struct wmd_dev_context
>*dev_context, IN u32 dw_cmd,
>                else
>                        dev_context->dw_brd_state = BRD_RETENTION;
>
>+               /* Disable wdt on hibernation. */
>+               dsp_wdt_enable(false);
>+
>                /* Turn off DSP Peripheral clocks */
>                status = dsp_peripheral_clocks_disable(dev_context, NULL);
>                if (DSP_FAILED(status)) {
>diff --git a/drivers/dsp/bridge/wmd/tiomap_io.c
>b/drivers/dsp/bridge/wmd/tiomap_io.c
>index b5504a9..728db33 100644
>--- a/drivers/dsp/bridge/wmd/tiomap_io.c
>+++ b/drivers/dsp/bridge/wmd/tiomap_io.c
>@@ -30,6 +30,7 @@
> /*  ----------------------------------- OS Adaptation Layer */
> #include <dspbridge/mem.h>
> #include <dspbridge/cfg.h>
>+#include <dspbridge/wdt.h>
>
> /*  ----------------------------------- specific to this file */
> #include "_tiomap.h"
>@@ -426,6 +427,7 @@ dsp_status sm_interrupt_dsp(struct wmd_dev_context
>*dev_context, u16 mb_val)
> #endif
>                /* Restart the peripheral clocks */
>                dsp_peripheral_clocks_enable(dev_context, NULL);
>+               dsp_wdt_enable(true);
>
>                /*
>                 * 2:0 AUTO_IVA2_DPLL - Enabling IVA2 DPLL auto control
>diff --git a/drivers/dsp/bridge/wmd/ue_deh.c
>b/drivers/dsp/bridge/wmd/ue_deh.c
>index 14dd8ae..75a62b0 100644
>--- a/drivers/dsp/bridge/wmd/ue_deh.c
>+++ b/drivers/dsp/bridge/wmd/ue_deh.c
>@@ -39,6 +39,7 @@
> /*  ----------------------------------- Platform Manager */
> #include <dspbridge/dev.h>
> #include <dspbridge/wcd.h>
>+#include <dspbridge/wdt.h>
>
> /* ------------------------------------ Hardware Abstraction Layer */
> #include <hw_defs.h>
>@@ -281,6 +282,13 @@ void bridge_deh_notify(struct deh_mgr *hdeh_mgr, u32
>ulEventMask, u32 dwErrInfo)
>                               "= 0x%x\n", dwErrInfo);
>                        break;
> #endif /* CONFIG_BRIDGE_NTFY_PWRERR */
>+               case DSP_WDTOVERFLOW:
>+                       deh_mgr_obj->err_info.dw_err_mask =
>DSP_WDTOVERFLOW;
>+                       deh_mgr_obj->err_info.dw_val1 = 0L;
>+                       deh_mgr_obj->err_info.dw_val2 = 0L;
>+                       deh_mgr_obj->err_info.dw_val3 = 0L;
>+                       pr_err("bridge_deh_notify: DSP_WDTOVERFLOW \n ");
>+                       break;
>                default:
>                        dev_dbg(bridge, "%s: Unknown Error, err_info =
>0x%x\n",
>                                __func__, dwErrInfo);
>@@ -301,6 +309,11 @@ void bridge_deh_notify(struct deh_mgr *hdeh_mgr, u32
>ulEventMask, u32 dwErrInfo)
>                (void)dsp_peripheral_clocks_disable(dev_context, NULL);
>                /* Call DSP Trace Buffer */
>                print_dsp_trace_buffer(hdeh_mgr->hwmd_context);
>+               /*
>+                * Avoid the subsequent WDT if it happens once,
>+                * also If fatal error occurs
>+                */
>+               dsp_wdt_enable(false);
>
>        }
> }
>diff --git a/drivers/dsp/bridge/wmd/wdt.c b/drivers/dsp/bridge/wmd/wdt.c
>new file mode 100644
>index 0000000..7a007f2
>--- /dev/null
>+++ b/drivers/dsp/bridge/wmd/wdt.c
>@@ -0,0 +1,148 @@
>+/*
>+ * wdt.c
>+ *
>+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
>+ *
>+ * IO dispatcher for a shared memory channel driver.
>+ *
>+ * Copyright (C) 2010 Texas Instruments, Inc.
>+ *
>+ * This package is free software; you can redistribute it and/or modify
>+ * it under the terms of the GNU General Public License version 2 as
>+ * published by the Free Software Foundation.
>+ *
>+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
>+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
>+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
>+ */
>+
>+#include <dspbridge/std.h>
>+#include <dspbridge/dbdefs.h>
>+#include <dspbridge/errbase.h>
>+#include <dspbridge/wmddeh.h>
>+#include <dspbridge/dev.h>
>+#include <dspbridge/_chnl_sm.h>
>+#include <dspbridge/wdt.h>
>+#include <dspbridge/host_os.h>
>+
>+
>+#ifdef CONFIG_BRIDGE_WDT3
>+static struct dsp_wdt_setting dsp_wdt;
>+
>+void dsp_wdt_dpc(unsigned long data)
>+{
>+       struct deh_mgr *deh_mgr;
>+       dev_get_deh_mgr(dev_get_first(), &deh_mgr);
>+       if (deh_mgr)
>+               bridge_deh_notify(deh_mgr, DSP_WDTOVERFLOW, 0);
>+}
>+
>+irqreturn_t dsp_wdt_isr(int irq, void *data)
>+{
>+       u32 value;
>+       /* ack wdt3 interrupt */
>+       value = __raw_readl(dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
>+       __raw_writel(value, dsp_wdt.reg_base + OMAP3_WDT3_ISR_OFFSET);
>+
>+       tasklet_schedule(&dsp_wdt.wdt3_tasklet);
>+       return IRQ_HANDLED;
>+}
>+
>+int dsp_wdt_init(void)
>+{
>+       int ret = 0;
>+
>+       dsp_wdt.sm_wdt = NULL;
>+       dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE);
>+       tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0);
>+
>+       dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
>+
>+       if (dsp_wdt.fclk) {
>+               dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
>+               if (!dsp_wdt.iclk) {
>+                       clk_put(dsp_wdt.fclk);
>+                       dsp_wdt.fclk = NULL;
>+                       ret = -EFAULT;
>+               }
>+       } else
>+               ret = -EFAULT;
>+
>+       if (!ret)
>+               ret = request_irq(INT_34XX_WDT3_IRQ, dsp_wdt_isr, 0,
>+                                                       "dsp_wdt",
>&dsp_wdt);
>+
>+       /* Disable at this moment, it will be enabled when DSP starts */
>+       if (!ret)
>+               disable_irq(INT_34XX_WDT3_IRQ);
>+
>+       return ret;
>+}
>+
>+void dsp_wdt_sm_set(void *data)
>+{
>+       dsp_wdt.sm_wdt = data;
>+       dsp_wdt.sm_wdt->wdt_overflow = CONFIG_WDT_TIMEOUT;
>+}
>+
>+
>+void dsp_wdt_exit(void)
>+{
>+       free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
>+       tasklet_kill(&dsp_wdt.wdt3_tasklet);
>+
>+       if (dsp_wdt.fclk)
>+               clk_put(dsp_wdt.fclk);
>+       if (dsp_wdt.iclk)
>+               clk_put(dsp_wdt.iclk);
>+
>+       dsp_wdt.fclk = NULL;
>+       dsp_wdt.iclk = NULL;
>+       dsp_wdt.sm_wdt = NULL;
>+       dsp_wdt.reg_base = NULL;
>+}
>+
>+void dsp_wdt_enable(bool enable)
>+{
>+       u32 tmp;
>+       static bool wdt_enable;
>+
>+       if (wdt_enable == enable || !dsp_wdt.fclk || !dsp_wdt.iclk)
>+               return;
>+
>+       wdt_enable = enable;
>+
>+       if (enable) {
>+               clk_enable(dsp_wdt.fclk);
>+               clk_enable(dsp_wdt.iclk);
>+               dsp_wdt.sm_wdt->wdt_setclocks = 1;
>+               tmp = __raw_readl(dsp_wdt.reg_base +
>OMAP3_WDT3_ISR_OFFSET);
>+               __raw_writel(tmp, dsp_wdt.reg_base +
>OMAP3_WDT3_ISR_OFFSET);
>+               enable_irq(INT_34XX_WDT3_IRQ);
>+       } else {
>+               disable_irq(INT_34XX_WDT3_IRQ);
>+               dsp_wdt.sm_wdt->wdt_setclocks = 0;
>+               clk_disable(dsp_wdt.iclk);
>+               clk_disable(dsp_wdt.fclk);
>+       }
>+}
>+
>+#else
>+void dsp_wdt_enable(bool enable)
>+{
>+}
>+
>+void dsp_wdt_sm_set(void *data)
>+{
>+}
>+
>+int dsp_wdt_init(void)
>+{
>+       return 0;
>+}
>+
>+void dsp_wdt_exit(void)
>+{
>+}
>+#endif
>+
>--
>1.6.0.4
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>the body of a message to majordomo@xxxxxxxxxxxxxxx
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux