4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Implements upper edge DSP exception handling (DEH) functions.
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
9 * Copyright (C) 2010 Felipe Contreras
11 * This package is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 #include <linux/kernel.h>
21 #include <linux/interrupt.h>
22 #include <plat/dmtimer.h>
24 #include <dspbridge/dbdefs.h>
25 #include <dspbridge/dspdeh.h>
26 #include <dspbridge/dev.h>
30 #include <dspbridge/io_sm.h>
31 #include <dspbridge/drv.h>
32 #include <dspbridge/wdt.h>
34 int bridge_deh_create(struct deh_mgr
**ret_deh
,
35 struct dev_object
*hdev_obj
)
39 struct bridge_dev_context
*hbridge_context
= NULL
;
41 /* Message manager will be created when a file is loaded, since
42 * size of message buffer in shared memory is configurable in
44 /* Get Bridge context info. */
45 dev_get_bridge_context(hdev_obj
, &hbridge_context
);
46 /* Allocate IO manager object: */
47 deh
= kzalloc(sizeof(*deh
), GFP_KERNEL
);
53 /* Create an NTFY object to manage notifications */
54 deh
->ntfy_obj
= kmalloc(sizeof(struct ntfy_object
), GFP_KERNEL
);
59 ntfy_init(deh
->ntfy_obj
);
61 /* Fill in context structure */
62 deh
->hbridge_context
= hbridge_context
;
68 bridge_deh_destroy(deh
);
73 int bridge_deh_destroy(struct deh_mgr
*deh
)
78 /* If notification object exists, delete it */
80 ntfy_delete(deh
->ntfy_obj
);
84 /* Deallocate the DEH manager object */
90 int bridge_deh_register_notify(struct deh_mgr
*deh
, u32 event_mask
,
92 struct dsp_notification
*hnotification
)
98 return ntfy_register(deh
->ntfy_obj
, hnotification
,
99 event_mask
, notify_type
);
101 return ntfy_unregister(deh
->ntfy_obj
, hnotification
);
104 static inline const char *event_to_string(int event
)
107 case DSP_SYSERROR
: return "DSP_SYSERROR"; break;
108 case DSP_MMUFAULT
: return "DSP_MMUFAULT"; break;
109 case DSP_PWRERROR
: return "DSP_PWRERROR"; break;
110 case DSP_WDTOVERFLOW
: return "DSP_WDTOVERFLOW"; break;
111 default: return "unkown event"; break;
115 void bridge_deh_notify(struct deh_mgr
*deh
, int event
, int info
)
117 struct bridge_dev_context
*dev_context
;
118 const char *str
= event_to_string(event
);
123 dev_dbg(bridge
, "%s: device exception", __func__
);
124 dev_context
= deh
->hbridge_context
;
128 dev_err(bridge
, "%s: %s, info=0x%x", __func__
,
130 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
131 dump_dl_modules(dev_context
);
132 dump_dsp_stack(dev_context
);
136 dev_err(bridge
, "%s: %s, addr=0x%x", __func__
, str
, info
);
139 dev_err(bridge
, "%s: %s", __func__
, str
);
143 /* Filter subsequent notifications when an error occurs */
144 if (dev_context
->dw_brd_state
!= BRD_ERROR
) {
145 ntfy_notify(deh
->ntfy_obj
, event
);
146 #ifdef CONFIG_TIDSPBRIDGE_RECOVERY
147 bridge_recover_schedule();
151 /* Set the Board state as ERROR */
152 dev_context
->dw_brd_state
= BRD_ERROR
;
153 /* Disable all the clocks that were enabled by DSP */
154 dsp_clock_disable_all(dev_context
->dsp_per_clks
);
156 * Avoid the subsequent WDT if it happens once,
157 * also if fatal error occurs.
159 dsp_wdt_enable(false);