]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/tidspbridge/core/ue_deh.c
staging: ti dspbridge: remove unused code
[net-next-2.6.git] / drivers / staging / tidspbridge / core / ue_deh.c
CommitLineData
999e07d6
ORL
1/*
2 * ue_deh.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Implements upper edge DSP exception handling (DEH) functions.
7 *
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19/* ----------------------------------- Host OS */
20#include <dspbridge/host_os.h>
21
22/* ----------------------------------- DSP/BIOS Bridge */
23#include <dspbridge/std.h>
24#include <dspbridge/dbdefs.h>
25
26/* ----------------------------------- Trace & Debug */
27#include <dspbridge/dbc.h>
28
29/* ----------------------------------- OS Adaptation Layer */
30#include <dspbridge/cfg.h>
31#include <dspbridge/clk.h>
32#include <dspbridge/ntfy.h>
33#include <dspbridge/drv.h>
34
35/* ----------------------------------- Link Driver */
36#include <dspbridge/dspdeh.h>
37
38/* ----------------------------------- Platform Manager */
39#include <dspbridge/dev.h>
40#include <dspbridge/dspapi.h>
41#include <dspbridge/wdt.h>
42
43/* ------------------------------------ Hardware Abstraction Layer */
44#include <hw_defs.h>
45#include <hw_mmu.h>
46
47/* ----------------------------------- This */
48#include "mmu_fault.h"
49#include "_tiomap.h"
50#include "_deh.h"
51#include "_tiomap_pwr.h"
52#include <dspbridge/io_sm.h>
53
54
999e07d6
ORL
55int bridge_deh_create(struct deh_mgr **ret_deh_mgr,
56 struct dev_object *hdev_obj)
57{
58 int status = 0;
59 struct deh_mgr *deh_mgr;
60 struct bridge_dev_context *hbridge_context = NULL;
61
62 /* Message manager will be created when a file is loaded, since
63 * size of message buffer in shared memory is configurable in
64 * the base image. */
65 /* Get Bridge context info. */
66 dev_get_bridge_context(hdev_obj, &hbridge_context);
999e07d6
ORL
67 /* Allocate IO manager object: */
68 deh_mgr = kzalloc(sizeof(struct deh_mgr), GFP_KERNEL);
69 if (!deh_mgr) {
70 status = -ENOMEM;
0a466f69 71 goto err;
999e07d6
ORL
72 }
73
74 /* Create an NTFY object to manage notifications */
75 deh_mgr->ntfy_obj = kmalloc(sizeof(struct ntfy_object), GFP_KERNEL);
0a466f69 76 if (!deh_mgr->ntfy_obj) {
999e07d6
ORL
77 status = -ENOMEM;
78 goto err;
79 }
0a466f69 80 ntfy_init(deh_mgr->ntfy_obj);
999e07d6
ORL
81
82 /* Create a MMUfault DPC */
83 tasklet_init(&deh_mgr->dpc_tasklet, mmu_fault_dpc, (u32) deh_mgr);
84
85 /* Fill in context structure */
86 deh_mgr->hbridge_context = hbridge_context;
87 deh_mgr->err_info.dw_err_mask = 0L;
88 deh_mgr->err_info.dw_val1 = 0L;
89 deh_mgr->err_info.dw_val2 = 0L;
90 deh_mgr->err_info.dw_val3 = 0L;
91
92 /* Install ISR function for DSP MMU fault */
0a466f69
FC
93 status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0,
94 "DspBridge\tiommu fault", deh_mgr);
95 if (status < 0)
96 goto err;
999e07d6 97
999e07d6 98 *ret_deh_mgr = deh_mgr;
0a466f69 99 return 0;
999e07d6 100
0a466f69
FC
101err:
102 bridge_deh_destroy(deh_mgr);
103 *ret_deh_mgr = NULL;
999e07d6
ORL
104 return status;
105}
106
107int bridge_deh_destroy(struct deh_mgr *deh_mgr)
108{
109 if (!deh_mgr)
110 return -EFAULT;
111
999e07d6
ORL
112 /* If notification object exists, delete it */
113 if (deh_mgr->ntfy_obj) {
114 ntfy_delete(deh_mgr->ntfy_obj);
115 kfree(deh_mgr->ntfy_obj);
116 }
117 /* Disable DSP MMU fault */
118 free_irq(INT_DSP_MMU_IRQ, deh_mgr);
119
120 /* Free DPC object */
121 tasklet_kill(&deh_mgr->dpc_tasklet);
122
123 /* Deallocate the DEH manager object */
124 kfree(deh_mgr);
125
126 return 0;
127}
128
129int bridge_deh_register_notify(struct deh_mgr *deh_mgr, u32 event_mask,
130 u32 notify_type,
131 struct dsp_notification *hnotification)
132{
999e07d6
ORL
133 if (!deh_mgr)
134 return -EFAULT;
135
136 if (event_mask)
0a466f69
FC
137 return ntfy_register(deh_mgr->ntfy_obj, hnotification,
138 event_mask, notify_type);
999e07d6 139 else
0a466f69 140 return ntfy_unregister(deh_mgr->ntfy_obj, hnotification);
999e07d6
ORL
141}
142
143void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
144{
145 struct bridge_dev_context *dev_context;
999e07d6 146 struct cfg_hostres *resources;
0a466f69
FC
147 struct hw_mmu_map_attrs_t map_attrs = {
148 .endianism = HW_LITTLE_ENDIAN,
149 .element_size = HW_ELEM_SIZE16BIT,
150 .mixed_size = HW_MMU_CPUES,
151 };
0d8631d2 152 void *dummy_va_addr;
999e07d6
ORL
153
154 if (!deh_mgr)
155 return;
156
157 dev_info(bridge, "%s: device exception\n", __func__);
0a466f69 158 dev_context = deh_mgr->hbridge_context;
999e07d6
ORL
159 resources = dev_context->resources;
160
161 switch (ulEventMask) {
162 case DSP_SYSERROR:
163 /* reset err_info structure before use */
164 deh_mgr->err_info.dw_err_mask = DSP_SYSERROR;
165 deh_mgr->err_info.dw_val1 = 0L;
166 deh_mgr->err_info.dw_val2 = 0L;
167 deh_mgr->err_info.dw_val3 = 0L;
168 deh_mgr->err_info.dw_val1 = dwErrInfo;
169 dev_err(bridge, "%s: %s, err_info = 0x%x\n",
170 __func__, "DSP_SYSERROR", dwErrInfo);
171 dump_dl_modules(dev_context);
172 dump_dsp_stack(dev_context);
173 break;
174 case DSP_MMUFAULT:
175 /* MMU fault routine should have set err info structure. */
176 deh_mgr->err_info.dw_err_mask = DSP_MMUFAULT;
177 dev_err(bridge, "%s: %s, err_info = 0x%x\n",
178 __func__, "DSP_MMUFAULT", dwErrInfo);
179 dev_info(bridge, "%s: %s, high=0x%x, low=0x%x, "
180 "fault=0x%x\n", __func__, "DSP_MMUFAULT",
181 (unsigned int) deh_mgr->err_info.dw_val1,
182 (unsigned int) deh_mgr->err_info.dw_val2,
183 (unsigned int) fault_addr);
184 dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC);
999e07d6
ORL
185
186 print_dsp_trace_buffer(dev_context);
187 dump_dl_modules(dev_context);
188
0a466f69
FC
189 hw_mmu_tlb_add(resources->dw_dmmu_base,
190 virt_to_phys(dummy_va_addr), fault_addr,
191 HW_PAGE_SIZE4KB, 1,
192 &map_attrs, HW_SET, HW_SET);
999e07d6
ORL
193
194 dsp_clk_enable(DSP_CLK_GPT8);
195
196 dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);
197
198 /* Clear MMU interrupt */
199 hw_mmu_event_ack(resources->dw_dmmu_base,
200 HW_MMU_TRANSLATION_FAULT);
0a466f69 201 dump_dsp_stack(dev_context);
999e07d6 202 dsp_clk_disable(DSP_CLK_GPT8);
0d8631d2
FC
203
204 hw_mmu_disable(resources->dw_dmmu_base);
205 free_page((unsigned long)dummy_va_addr);
999e07d6
ORL
206 break;
207#ifdef CONFIG_BRIDGE_NTFY_PWRERR
208 case DSP_PWRERROR:
209 /* reset err_info structure before use */
210 deh_mgr->err_info.dw_err_mask = DSP_PWRERROR;
211 deh_mgr->err_info.dw_val1 = 0L;
212 deh_mgr->err_info.dw_val2 = 0L;
213 deh_mgr->err_info.dw_val3 = 0L;
214 deh_mgr->err_info.dw_val1 = dwErrInfo;
215 dev_err(bridge, "%s: %s, err_info = 0x%x\n",
216 __func__, "DSP_PWRERROR", dwErrInfo);
217 break;
218#endif /* CONFIG_BRIDGE_NTFY_PWRERR */
219 case DSP_WDTOVERFLOW:
220 deh_mgr->err_info.dw_err_mask = DSP_WDTOVERFLOW;
221 deh_mgr->err_info.dw_val1 = 0L;
222 deh_mgr->err_info.dw_val2 = 0L;
223 deh_mgr->err_info.dw_val3 = 0L;
224 dev_err(bridge, "%s: DSP_WDTOVERFLOW\n", __func__);
225 break;
226 default:
227 dev_dbg(bridge, "%s: Unknown Error, err_info = 0x%x\n",
228 __func__, dwErrInfo);
229 break;
230 }
231
232 /* Filter subsequent notifications when an error occurs */
233 if (dev_context->dw_brd_state != BRD_ERROR) {
234 ntfy_notify(deh_mgr->ntfy_obj, ulEventMask);
235#ifdef CONFIG_BRIDGE_RECOVERY
236 bridge_recover_schedule();
237#endif
238 }
239
240 /* Set the Board state as ERROR */
241 dev_context->dw_brd_state = BRD_ERROR;
242 /* Disable all the clocks that were enabled by DSP */
243 dsp_clock_disable_all(dev_context->dsp_per_clks);
244 /*
245 * Avoid the subsequent WDT if it happens once,
246 * also if fatal error occurs.
247 */
248 dsp_wdt_enable(false);
249}
250
251int bridge_deh_get_info(struct deh_mgr *deh_mgr,
252 struct dsp_errorinfo *pErrInfo)
253{
999e07d6
ORL
254 if (!deh_mgr)
255 return -EFAULT;
256
257 /* Copy DEH error info structure to PROC error info structure. */
258 pErrInfo->dw_err_mask = deh_mgr->err_info.dw_err_mask;
259 pErrInfo->dw_val1 = deh_mgr->err_info.dw_val1;
260 pErrInfo->dw_val2 = deh_mgr->err_info.dw_val2;
261 pErrInfo->dw_val3 = deh_mgr->err_info.dw_val3;
262
263 return 0;
264}