aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAngela Stegmaier <angelabaker@ti.com>2010-09-09 11:10:25 -0400
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:19:08 -0400
commit77508e0bdabffccd9106c79b74170a8a4a87f321 (patch)
tree1515220d899d78e1f58d20d61ed79564ba6a73c0 /drivers
parent2b09254c67d989214783096b140ff10c6dea0825 (diff)
SYSLINK:devh: adding devh to syslink tree
This patch adds devh to syslink tree Signed-off-by: Angela Stegmaier <angelabaker@ti.com> Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com> SYSLINK: Devh - Add device event handling and SYSERROR support for OMAP4 SYSLINK: Devh - Add event handling and SYSERROR support DSP exceptions that are unrecoverable need to be communicated to the host processor so that it can print debug information, do resource cleanup and ultimately reload DSP. The notification mechanism for sending events to the host processor has been consolidated in a new module named Device Error Handler on the remote processor. The notification mechanism relies on a NotifyShm event to know about error events on the remote cores. The support has been built into the existing Devh module which registers a call back for the previously agreed event id to be used for error events. Upon receving an error event, the module will notify other kernel modules which have registered with it. It will also notify userspace applicatios through an agreed fd event. This support will be built in a following patch. For now, the module uses event id 4 to receive notify messages from remote processor. Enhacements that will follow include using a reserved event for sending notify messages. Initialize the Device Error Handler functionality in Devh. Devh registers a callback for NotifyShm event to be triggered when an error occurs on the remote core. Devh module has the support for receiving notifications from remote cores about irrecoverble errors. Userspace processes need to be notified for such events as well in order to do cleanup and recovery. Besides, such notifications can also be used to output valuable debug information about error scenarios. [Suman A] Corrected err_event_id from 4 to use as err_event_id = (4 | (NOTIFY_SYSTEMKEY << 16)), Change-Id: I961d83e62e5ce21b32f5e2c461644e6f2bd8cb3c Signed-off-by: Wajahat Khan <w-khan@ti.com> Signed-off-by: Hari Kanigeri <h-kangieri2@ti.com> SYSLINK: devh - add possibility of register for specific events New paratemer is added to event register ioctl to allow users register for a specific event. Modified to register notifier for IPU_PM watch-dog timer [Hari K] Added the call to ipc_recover_schedule on sys error and watchdog timer Change-Id: I5fcfc28bc424a47f95c32104d2200ad946ef9027 Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com> Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com> SYSLINK: Devh - Add userspace events unregistration support Implement the unregister ioctl which lets an application unregister an fd it had registered with the module earlier. The call returns successfully even if no matching fd was present or duplicates were present. Also fixed traces because of addition of watch dog event. Change-Id: Idd075c6a96a5c5438e02cfc1efa19d3e3859c0af Signed-off-by: Wajahat Khan <w-khan@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dsp/syslink/devh/44xx/Kbuild7
-rw-r--r--drivers/dsp/syslink/devh/44xx/devh44xx.c956
-rw-r--r--drivers/dsp/syslink/devh/Kbuild7
-rw-r--r--drivers/dsp/syslink/devh/devh.c273
-rw-r--r--drivers/dsp/syslink/devh/devh.h87
5 files changed, 1330 insertions, 0 deletions
diff --git a/drivers/dsp/syslink/devh/44xx/Kbuild b/drivers/dsp/syslink/devh/44xx/Kbuild
new file mode 100644
index 00000000000..1cc02051301
--- /dev/null
+++ b/drivers/dsp/syslink/devh/44xx/Kbuild
@@ -0,0 +1,7 @@
1
2obj-$(CONFIG_OMAP_DEVICE_HANDLER) += devh44xx.o
3
4ccflags-y += -Wno-strict-prototypes
5
6#Header files
7ccflags-y += -Iarch/arm/plat-omap/include/syslink
diff --git a/drivers/dsp/syslink/devh/44xx/devh44xx.c b/drivers/dsp/syslink/devh/44xx/devh44xx.c
new file mode 100644
index 00000000000..f76f8922c8b
--- /dev/null
+++ b/drivers/dsp/syslink/devh/44xx/devh44xx.c
@@ -0,0 +1,956 @@
1/*
2 * Device Handler machine-specific module for OMAP4
3 *
4 * Copyright (C) 2010 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21#include <linux/kernel.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/platform_device.h>
26#include <linux/io.h>
27#include <linux/pm_runtime.h>
28#include <linux/sched.h>
29#include <linux/eventfd.h>
30#include <mach/irqs.h>
31#include <plat/omap_device.h>
32#include <plat/iommu.h>
33#include <plat/remoteproc.h>
34#include <linux/slab.h>
35#include <linux/pagemap.h>
36#if defined(CONFIG_TILER_OMAP)
37#include <mach/tiler.h>
38#endif
39
40#include <syslink/ipc.h>
41
42#include "../devh.h"
43#include "../../ipu_pm/ipu_pm.h"
44
45static struct mutex local_gate;
46
47struct omap_devh_runtime_info {
48 int brd_state;
49 struct iommu *iommu;
50 struct omap_rproc *rproc;
51};
52
53enum {
54 DEVH_BRDST_RUNNING,
55 DEVH_BRDST_STOPPED,
56 DEVH_BRDST_ERROR,
57};
58
59struct deh_event_ntfy {
60 u32 fd;
61 u32 event;
62 struct eventfd_ctx *evt_ctx;
63 struct list_head list;
64};
65
66struct omap_devh *devh_get_obj(int dev_index);
67
68static struct omap_devh_platform_data *devh_get_plat_data_by_name(char *name)
69{
70 int i, j = devh_get_plat_data_size();
71 struct omap_devh_platform_data *pdata = devh_get_plat_data();
72
73 if (name) {
74 for (i = 0; i < j; i++) {
75 if (!(strcmp(name, pdata[i].name)))
76 return &pdata[i];
77 }
78 }
79 return NULL;
80}
81
82static int devh_notify_event(struct omap_devh *devh , u32 event)
83{
84 struct deh_event_ntfy *fd_reg;
85
86 spin_lock_irq(&(devh->event_lock));
87 list_for_each_entry(fd_reg, &(devh->event_list), list)
88 if (fd_reg->event == event)
89 eventfd_signal(fd_reg->evt_ctx, 1);
90 spin_unlock_irq(&(devh->event_lock));
91
92 return 0;
93}
94
95static void devh_notification_handler(u16 proc_id, u16 line_id, u32 event_id,
96 uint *arg, u32 payload)
97{
98 pr_warning("Sys Error occured in Ducati for proc_id = %d\n",
99 proc_id);
100
101 /* schedule the recovery */
102 ipc_recover_schedule();
103
104 devh_notify_event((struct omap_devh *)arg, DEV_SYS_ERROR);
105}
106
107static int devh44xx_notifier_call(struct notifier_block *nb,
108 unsigned long val, void *v,
109 struct omap_devh_platform_data *pdata)
110{
111 int err = 0;
112 pid_t my_pid = current->tgid;
113 struct omap_devh_runtime_info *pinfo = NULL;
114 struct omap_devh_platform_data *pdata2 = NULL;
115
116 if (pdata)
117 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
118 else
119 return -EINVAL;
120
121 if (pinfo->brd_state == DEVH_BRDST_RUNNING) {
122 err = mutex_lock_interruptible(&local_gate);
123 if (err)
124 goto exit;
125 err = ipu_pm_notifications(PM_PID_DEATH, (void *)my_pid);
126 if (err) {
127 pinfo->brd_state = DEVH_BRDST_ERROR;
128 if (!strcmp(pdata->name, "SysM3")) {
129 pdata2 = devh_get_plat_data_by_name("AppM3");
130 if (pdata2) {
131 pinfo =
132 (struct omap_devh_runtime_info *)
133 pdata2->private_data;
134 pinfo->brd_state = DEVH_BRDST_ERROR;
135 }
136 }
137 }
138 mutex_unlock(&local_gate);
139 }
140
141exit:
142 return err;
143}
144
145static int devh44xx_sysm3_iommu_notifier_call(struct notifier_block *nb,
146 unsigned long val, void *v)
147{
148 struct omap_devh_platform_data *pdata =
149 devh_get_plat_data_by_name("SysM3");
150 struct omap_devh_runtime_info *pinfo = NULL;
151
152 if (!pdata)
153 return 0;
154
155 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
156
157 switch ((int)val) {
158 case IOMMU_CLOSE:
159 return devh44xx_notifier_call(nb, val, v, pdata);
160 case IOMMU_FAULT:
161 pinfo->brd_state = DEVH_BRDST_ERROR;
162 return 0;
163 default:
164 return 0;
165 }
166}
167
168static int devh44xx_appm3_iommu_notifier_call(struct notifier_block *nb,
169 unsigned long val, void *v)
170{
171 struct omap_devh_platform_data *pdata =
172 devh_get_plat_data_by_name("AppM3");
173 struct omap_devh_runtime_info *pinfo = NULL;
174
175 if (!pdata)
176 return 0;
177
178 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
179
180 switch ((int)val) {
181 case IOMMU_CLOSE:
182 return devh44xx_notifier_call(nb, val, v, pdata);
183 case IOMMU_FAULT:
184 pinfo->brd_state = DEVH_BRDST_ERROR;
185 return 0;
186 default:
187 return 0;
188 }
189}
190
191static int devh44xx_tesla_iommu_notifier_call(struct notifier_block *nb,
192 unsigned long val, void *v)
193{
194 struct omap_devh_platform_data *pdata =
195 devh_get_plat_data_by_name("Tesla");
196 struct omap_devh_runtime_info *pinfo = NULL;
197
198 if (!pdata)
199 return 0;
200
201 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
202
203 switch ((int)val) {
204 case IOMMU_CLOSE:
205 return devh44xx_notifier_call(nb, val, v, pdata);
206 case IOMMU_FAULT:
207 pinfo->brd_state = DEVH_BRDST_ERROR;
208 return 0;
209 default:
210 return 0;
211 }
212}
213
214static struct notifier_block devh_notify_nb_iommu_tesla = {
215 .notifier_call = devh44xx_tesla_iommu_notifier_call,
216};
217static struct notifier_block devh_notify_nb_iommu_ducati0 = {
218 .notifier_call = devh44xx_sysm3_iommu_notifier_call,
219};
220static struct notifier_block devh_notify_nb_iommu_ducati1 = {
221 .notifier_call = devh44xx_appm3_iommu_notifier_call,
222};
223
224static int devh44xx_wdt_ipc_notifier_call(struct notifier_block *nb,
225 unsigned long val, void *v)
226{
227 struct omap_devh *obj;
228 int i = devh_get_plat_data_size();
229
230 pr_warning("Ducati Watch Dog fired\n");
231
232 /* schedule the recovery */
233 ipc_recover_schedule();
234
235 while (i--) {
236 obj = devh_get_obj(i);
237 devh_notify_event(obj, DEV_WATCHDOG_ERROR);
238 }
239
240 return 0;
241}
242
243static struct notifier_block devh_notify_nb_ipc_wdt = {
244 .notifier_call = devh44xx_wdt_ipc_notifier_call,
245};
246
247static int devh44xx_sysm3_ipc_notifier_call(struct notifier_block *nb,
248 unsigned long val, void *v)
249{
250 struct omap_devh_platform_data *pdata =
251 devh_get_plat_data_by_name("SysM3");
252 u16 *proc_id = (u16 *)v;
253 struct omap_devh *obj;
254 int status;
255
256 switch ((int)val) {
257 case IPC_CLOSE:
258 return devh44xx_notifier_call(nb, val, v, pdata);
259 case IPC_START:
260 /*
261 * TODO - hack hack - clean this up to use a define proc id
262 * and use this to get the devh object
263 */
264 if (*proc_id == multiproc_get_id("SysM3")) {
265 obj = devh_get_obj(1);
266 if (WARN_ON(obj == NULL)) {
267 status = -1;
268 pr_err("devh_44xx_notifier_call: cannot grab "
269 "device devh1 instance\n");
270 } else {
271 status = notify_register_event(pdata->proc_id,
272 pdata->line_id,
273 pdata->err_event_id,
274 (notify_fn_notify_cbck) \
275 devh_notification_handler,
276 (void *)obj);
277 }
278 if (status == 0)
279 status = ipu_pm_register_notifier(
280 &devh_notify_nb_ipc_wdt);
281 } else {
282 status = 0;
283 }
284 return status;
285 case IPC_STOP:
286 if (*proc_id == multiproc_get_id("SysM3")) {
287 ipu_pm_unregister_notifier(&devh_notify_nb_ipc_wdt);
288 obj = devh_get_obj(1);
289 if (WARN_ON(obj == NULL)) {
290 status = -1;
291 pr_err("devh_44xx_notifier_call: cannot grab "
292 "device devh1 instance\n");
293 } else {
294 status = notify_unregister_event(pdata->proc_id,
295 pdata->line_id,
296 pdata->err_event_id,
297 (notify_fn_notify_cbck) \
298 devh_notification_handler,
299 (void *)obj);
300 }
301 } else {
302 status = 0;
303 }
304 return status;
305 default:
306 return 0;
307 }
308}
309
310static int devh44xx_appm3_ipc_notifier_call(struct notifier_block *nb,
311 unsigned long val, void *v)
312{
313 struct omap_devh_platform_data *pdata =
314 devh_get_plat_data_by_name("AppM3");
315 struct omap_devh *obj;
316
317 u16* proc_id = (u16 *)v;
318 int status;
319 switch ((int)val) {
320 case IPC_CLOSE:
321 return devh44xx_notifier_call(nb, val, v, pdata);
322 case IPC_START:
323 /*
324 * TODO - hack hack - clean this up to use a define proc id
325 * and use this to get the devh object
326 */
327 if (*proc_id == multiproc_get_id("AppM3")) {
328 obj = devh_get_obj(2);
329 if (WARN_ON(obj == NULL)) {
330 status = -1;
331 pr_err("devh_44xx_notifier_call: cannot grab "
332 "device devh2 instance\n");
333 } else {
334 status = notify_register_event(pdata->proc_id,
335 pdata->line_id,
336 pdata->err_event_id,
337 (notify_fn_notify_cbck) \
338 devh_notification_handler,
339 (void *)obj);
340 }
341 } else {
342 status = 0;
343 }
344 return status;
345 case IPC_STOP:
346 if (*proc_id == multiproc_get_id("AppM3")) {
347 obj = devh_get_obj(2);
348 if (WARN_ON(obj == NULL)) {
349 status = -1;
350 pr_err("devh_44xx_notifier_call: cannot grab "
351 "device devh2 instance\n");
352 } else {
353 status = notify_unregister_event(pdata->proc_id,
354 pdata->line_id,
355 pdata->err_event_id,
356 (notify_fn_notify_cbck) \
357 devh_notification_handler,
358 (void *)obj);
359 }
360 } else {
361 status = 0;
362 }
363 return status;
364 default:
365 return 0;
366 }
367}
368
369static int devh44xx_tesla_ipc_notifier_call(struct notifier_block *nb,
370 unsigned long val, void *v)
371{
372 struct omap_devh_platform_data *pdata =
373 devh_get_plat_data_by_name("Tesla");
374
375 switch ((int)val) {
376 case IPC_CLOSE:
377 return devh44xx_notifier_call(nb, val, v, pdata);
378 default:
379 return 0;
380 }
381}
382
383static struct notifier_block devh_notify_nb_ipc_tesla = {
384 .notifier_call = devh44xx_tesla_ipc_notifier_call,
385};
386static struct notifier_block devh_notify_nb_ipc_ducati1 = {
387 .notifier_call = devh44xx_appm3_ipc_notifier_call,
388};
389static struct notifier_block devh_notify_nb_ipc_ducati0 = {
390 .notifier_call = devh44xx_sysm3_ipc_notifier_call,
391};
392
393static int devh44xx_sysm3_rproc_notifier_call(struct notifier_block *nb,
394 unsigned long val, void *v)
395{
396 struct omap_devh_platform_data *pdata =
397 devh_get_plat_data_by_name("SysM3");
398 struct omap_devh_runtime_info *pinfo = NULL;
399
400 if (pdata)
401 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
402 else
403 return -EINVAL;
404
405 switch ((int)val) {
406 case OMAP_RPROC_START:
407 pinfo->brd_state = DEVH_BRDST_RUNNING;
408 pinfo->iommu = iommu_get("ducati");
409 if (pinfo->iommu != ERR_PTR(-ENODEV) &&
410 pinfo->iommu != ERR_PTR(-EINVAL))
411 iommu_register_notifier(pinfo->iommu,
412 &devh_notify_nb_iommu_ducati0);
413 else
414 pinfo->iommu = NULL;
415 return 0;
416 case OMAP_RPROC_STOP:
417 pinfo->brd_state = DEVH_BRDST_STOPPED;
418 if (pinfo->iommu != NULL) {
419 iommu_unregister_notifier(pinfo->iommu,
420 &devh_notify_nb_iommu_ducati0);
421 iommu_put(pinfo->iommu);
422 pinfo->iommu = NULL;
423 }
424 return 0;
425 default:
426 return 0;
427 }
428}
429
430static int devh44xx_appm3_rproc_notifier_call(struct notifier_block *nb,
431 unsigned long val, void *v)
432{
433 struct omap_devh_platform_data *pdata =
434 devh_get_plat_data_by_name("AppM3");
435 struct omap_devh_runtime_info *pinfo = NULL;
436
437 if (pdata)
438 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
439 else
440 return -EINVAL;
441
442 switch ((int)val) {
443 case OMAP_RPROC_START:
444 pinfo->brd_state = DEVH_BRDST_RUNNING;
445 pinfo->iommu = iommu_get("ducati");
446 if (pinfo->iommu != ERR_PTR(-ENODEV) &&
447 pinfo->iommu != ERR_PTR(-EINVAL))
448 iommu_register_notifier(pinfo->iommu,
449 &devh_notify_nb_iommu_ducati1);
450 else
451 pinfo->iommu = NULL;
452 return 0;
453 case OMAP_RPROC_STOP:
454 pinfo->brd_state = DEVH_BRDST_STOPPED;
455 if (pinfo->iommu != NULL) {
456 iommu_unregister_notifier(pinfo->iommu,
457 &devh_notify_nb_iommu_ducati1);
458 iommu_put(pinfo->iommu);
459 pinfo->iommu = NULL;
460 }
461 return 0;
462 default:
463 return 0;
464 }
465}
466
467static int devh44xx_tesla_rproc_notifier_call(struct notifier_block *nb,
468 unsigned long val, void *v)
469{
470 struct omap_devh_platform_data *pdata =
471 devh_get_plat_data_by_name("Tesla");
472 struct omap_devh_runtime_info *pinfo = NULL;
473
474 if (pdata)
475 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
476 else
477 return -EINVAL;
478
479 switch ((int)val) {
480 case OMAP_RPROC_START:
481 pinfo->brd_state = DEVH_BRDST_RUNNING;
482 pinfo->iommu = iommu_get("tesla");
483 if (pinfo->iommu != ERR_PTR(-ENODEV) &&
484 pinfo->iommu != ERR_PTR(-EINVAL))
485 iommu_register_notifier(pinfo->iommu,
486 &devh_notify_nb_iommu_tesla);
487 else
488 pinfo->iommu = NULL;
489 return 0;
490 case OMAP_RPROC_STOP:
491 pinfo->brd_state = DEVH_BRDST_STOPPED;
492 if (pinfo->iommu != NULL) {
493 iommu_unregister_notifier(pinfo->iommu,
494 &devh_notify_nb_iommu_tesla);
495 iommu_put(pinfo->iommu);
496 pinfo->iommu = NULL;
497 }
498 return 0;
499 default:
500 return 0;
501 }
502}
503
504static struct notifier_block devh_notify_nb_rproc_tesla = {
505 .notifier_call = devh44xx_tesla_rproc_notifier_call,
506};
507static struct notifier_block devh_notify_nb_rproc_ducati0 = {
508 .notifier_call = devh44xx_sysm3_rproc_notifier_call,
509};
510static struct notifier_block devh_notify_nb_rproc_ducati1 = {
511 .notifier_call = devh44xx_appm3_rproc_notifier_call,
512};
513
514#if defined(CONFIG_TILER_OMAP)
515static int devh44xx_sysm3_tiler_notifier_call(struct notifier_block *nb,
516 unsigned long val, void *v)
517{
518 struct omap_devh_platform_data *pdata =
519 devh_get_plat_data_by_name("SysM3");
520
521 switch ((int)val) {
522 case TILER_DEVICE_CLOSE:
523 return devh44xx_notifier_call(nb, val, v, pdata);
524 default:
525 return 0;
526 }
527}
528
529static int devh44xx_appm3_tiler_notifier_call(struct notifier_block *nb,
530 unsigned long val, void *v)
531{
532 struct omap_devh_platform_data *pdata =
533 devh_get_plat_data_by_name("AppM3");
534
535 switch ((int)val) {
536 case TILER_DEVICE_CLOSE:
537 return devh44xx_notifier_call(nb, val, v, pdata);
538 default:
539 return 0;
540 }
541}
542
543static int devh44xx_tesla_tiler_notifier_call(struct notifier_block *nb,
544 unsigned long val, void *v)
545{
546 struct omap_devh_platform_data *pdata =
547 devh_get_plat_data_by_name("Tesla");
548
549 switch ((int)val) {
550 case TILER_DEVICE_CLOSE:
551 return devh44xx_notifier_call(nb, val, v, pdata);
552 default:
553 return 0;
554 }
555}
556
557static struct notifier_block devh_notify_nb_tiler_tesla = {
558 .notifier_call = devh44xx_tesla_tiler_notifier_call,
559};
560static struct notifier_block devh_notify_nb_tiler_ducati0 = {
561 .notifier_call = devh44xx_sysm3_tiler_notifier_call,
562};
563static struct notifier_block devh_notify_nb_tiler_ducati1 = {
564 .notifier_call = devh44xx_appm3_tiler_notifier_call,
565};
566#endif
567
568static inline int devh44xx_sysm3_register(struct omap_devh *devh)
569{
570 int retval = 0;
571 struct omap_devh_platform_data *pdata = NULL;
572 struct omap_devh_runtime_info *pinfo = NULL;
573 if (!devh->dev)
574 return -EINVAL;
575
576 pdata = (struct omap_devh_platform_data *)devh->dev->platform_data;
577
578 if (!pdata)
579 return -EINVAL;
580
581 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
582
583 /* register will kernel modules for event notifications. */
584 ipc_register_notifier(&devh_notify_nb_ipc_ducati0);
585 pinfo->rproc = omap_rproc_get("ducati-proc0");
586 if (pinfo->rproc != ERR_PTR(-ENODEV))
587 omap_rproc_register_notifier(pinfo->rproc,
588 &devh_notify_nb_rproc_ducati0);
589 else
590 pinfo->rproc = NULL;
591#if defined(CONFIG_TILER_OMAP)
592 tiler_reg_notifier(&devh_notify_nb_tiler_ducati0);
593#endif
594
595 return retval;
596}
597
598static inline int devh44xx_appm3_register(struct omap_devh *devh)
599{
600 int retval = 0;
601 struct omap_devh_platform_data *pdata = NULL;
602 struct omap_devh_runtime_info *pinfo = NULL;
603 if (!devh->dev)
604 return -EINVAL;
605
606 pdata = (struct omap_devh_platform_data *)devh->dev->platform_data;
607
608 if (!pdata)
609 return -EINVAL;
610
611 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
612
613 /* register will kernel modules for event notifications. */
614 ipc_register_notifier(&devh_notify_nb_ipc_ducati1);
615 pinfo->rproc = omap_rproc_get("ducati-proc1");
616 if (pinfo->rproc != ERR_PTR(-ENODEV))
617 omap_rproc_register_notifier(pinfo->rproc,
618 &devh_notify_nb_rproc_ducati1);
619 else
620 pinfo->rproc = NULL;
621#if defined(CONFIG_TILER_OMAP)
622 tiler_reg_notifier(&devh_notify_nb_tiler_ducati1);
623#endif
624
625 return retval;
626}
627
628static inline int devh44xx_tesla_register(struct omap_devh *devh)
629{
630 int retval = 0;
631 struct omap_devh_platform_data *pdata = NULL;
632 struct omap_devh_runtime_info *pinfo = NULL;
633 if (!devh->dev)
634 return -EINVAL;
635
636 pdata = (struct omap_devh_platform_data *)devh->dev->platform_data;
637
638 if (!pdata)
639 return -EINVAL;
640
641 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
642
643 /* register will kernel modules for event notifications. */
644 ipc_register_notifier(&devh_notify_nb_ipc_tesla);
645 pinfo->rproc = omap_rproc_get("tesla");
646 if (pinfo->rproc != ERR_PTR(-ENODEV))
647 omap_rproc_register_notifier(pinfo->rproc,
648 &devh_notify_nb_rproc_tesla);
649 else
650 pinfo->rproc = NULL;
651#if defined(CONFIG_TILER_OMAP)
652 tiler_reg_notifier(&devh_notify_nb_tiler_tesla);
653#endif
654
655 return retval;
656}
657
658static inline int devh44xx_sysm3_unregister(struct omap_devh *devh)
659{
660 int retval = 0;
661 struct omap_devh_platform_data *pdata = NULL;
662 struct omap_devh_runtime_info *pinfo = NULL;
663
664 if (!devh->dev)
665 return -EINVAL;
666
667 pdata = (struct omap_devh_platform_data *)devh->dev->platform_data;
668
669 if (!pdata)
670 return -EINVAL;
671
672 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
673
674 /* un-register will kernel modules for event notifications. */
675 ipc_unregister_notifier(&devh_notify_nb_ipc_ducati0);
676 if (pinfo->rproc) {
677 omap_rproc_unregister_notifier(pinfo->rproc,
678 &devh_notify_nb_rproc_ducati0);
679 omap_rproc_put(pinfo->rproc);
680 }
681 if (pinfo->iommu) {
682 iommu_unregister_notifier(pinfo->iommu,
683 &devh_notify_nb_iommu_ducati0);
684 iommu_put(pinfo->iommu);
685 }
686#if defined(CONFIG_TILER_OMAP)
687 tiler_unreg_notifier(&devh_notify_nb_tiler_ducati0);
688#endif
689
690 return retval;
691}
692
693static inline int devh44xx_appm3_unregister(struct omap_devh *devh)
694{
695 int retval = 0;
696 struct omap_devh_platform_data *pdata = NULL;
697 struct omap_devh_runtime_info *pinfo = NULL;
698
699 if (!devh->dev)
700 return -EINVAL;
701
702 pdata = (struct omap_devh_platform_data *)devh->dev->platform_data;
703
704 if (!pdata)
705 return -EINVAL;
706
707 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
708
709 /* un-register will kernel modules for event notifications. */
710 ipc_unregister_notifier(&devh_notify_nb_ipc_ducati1);
711 if (pinfo->rproc) {
712 omap_rproc_unregister_notifier(pinfo->rproc,
713 &devh_notify_nb_rproc_ducati1);
714 omap_rproc_put(pinfo->rproc);
715 }
716 if (pinfo->iommu) {
717 iommu_unregister_notifier(pinfo->iommu,
718 &devh_notify_nb_iommu_ducati1);
719 iommu_put(pinfo->iommu);
720 }
721#if defined(CONFIG_TILER_OMAP)
722 tiler_unreg_notifier(&devh_notify_nb_tiler_ducati1);
723#endif
724
725 return retval;
726}
727
728static inline int devh44xx_tesla_unregister(struct omap_devh *devh)
729{
730 int retval = 0;
731 struct omap_devh_platform_data *pdata = NULL;
732 struct omap_devh_runtime_info *pinfo = NULL;
733
734 if (!devh->dev)
735 return -EINVAL;
736
737 pdata = (struct omap_devh_platform_data *)devh->dev->platform_data;
738
739 if (!pdata)
740 return -EINVAL;
741
742 pinfo = (struct omap_devh_runtime_info *)pdata->private_data;
743
744 /* un-register will kernel modules for event notifications. */
745 ipc_unregister_notifier(&devh_notify_nb_ipc_tesla);
746 if (pinfo->rproc) {
747 omap_rproc_unregister_notifier(pinfo->rproc,
748 &devh_notify_nb_rproc_tesla);
749 omap_rproc_put(pinfo->rproc);
750 }
751 if (pinfo->iommu) {
752 iommu_unregister_notifier(pinfo->iommu,
753 &devh_notify_nb_iommu_tesla);
754 iommu_put(pinfo->iommu);
755 }
756#if defined(CONFIG_TILER_OMAP)
757 tiler_unreg_notifier(&devh_notify_nb_tiler_tesla);
758#endif
759 return retval;
760}
761
762static struct omap_devh_runtime_info omap4_sysm3_runtime_info = {
763 .brd_state = DEVH_BRDST_STOPPED,
764 .iommu = NULL,
765 .rproc = NULL,
766};
767
768static struct omap_devh_runtime_info omap4_appm3_runtime_info = {
769 .brd_state = DEVH_BRDST_STOPPED,
770 .iommu = NULL,
771 .rproc = NULL,
772};
773
774static struct omap_devh_runtime_info omap4_tesla_runtime_info = {
775 .brd_state = DEVH_BRDST_STOPPED,
776 .iommu = NULL,
777 .rproc = NULL,
778};
779
780static inline int devh44xx_register_event
781 (struct omap_devh *devh, const void __user *args)
782{
783 struct deh_event_ntfy *fd_reg;
784 struct deh_reg_event_args re_args;
785
786 if (copy_from_user(&re_args, args, sizeof(re_args)))
787 return -EFAULT;
788
789 fd_reg = kzalloc(sizeof(struct deh_event_ntfy), GFP_KERNEL);
790 if (!fd_reg) {
791 dev_err(devh->dev, "%s: kzalloc failed\n", __func__);
792 return -ENOMEM;
793 }
794
795 fd_reg->fd = re_args.fd;
796 fd_reg->event = re_args.event;
797 fd_reg->evt_ctx = eventfd_ctx_fdget(re_args.fd);
798
799 INIT_LIST_HEAD(&fd_reg->list);
800
801 spin_lock_irq(&(devh->event_lock));
802 list_add_tail(&fd_reg->list, &(devh->event_list));
803 spin_unlock_irq(&(devh->event_lock));
804
805 pr_info("Registered user-space process for %s event in %s\n",
806 (re_args.event == 1 ? "DEV_SYS_ERROR" :
807 (re_args.event == 2 ? "DEV_WATCHDOG_ERROR" : "UNKNOWN EVENT")),
808 devh->name);
809 return 0;
810}
811
812static inline int devh44xx_unregister_event(struct omap_devh *devh,
813 const void __user *args)
814{
815 struct deh_event_ntfy *fd_reg, *tmp_reg;
816 struct deh_reg_event_args re_args;
817 if (copy_from_user(&re_args, args, sizeof(re_args)))
818 return -EFAULT;
819
820 spin_lock_irq(&(devh->event_lock));
821 list_for_each_entry_safe(fd_reg, tmp_reg, &(devh->event_list), list)
822 {
823 if (fd_reg->fd == re_args.fd) {
824 list_del(&fd_reg->list);
825 kfree(fd_reg);
826 }
827 }
828 spin_unlock_irq(&(devh->event_lock));
829 return 0;
830}
831
832static struct omap_devh_ops omap4_sysm3_ops = {
833 .register_notifiers = devh44xx_sysm3_register,
834 .unregister_notifiers = devh44xx_sysm3_unregister,
835 .register_event_notification = devh44xx_register_event,
836 .unregister_event_notification = devh44xx_unregister_event,
837};
838
839static struct omap_devh_ops omap4_appm3_ops = {
840 .register_notifiers = devh44xx_appm3_register,
841 .unregister_notifiers = devh44xx_appm3_unregister,
842 .register_event_notification = devh44xx_register_event,
843 .unregister_event_notification = devh44xx_unregister_event,
844};
845
846static struct omap_devh_ops omap4_tesla_ops = {
847 .register_notifiers = devh44xx_tesla_register,
848 .unregister_notifiers = devh44xx_tesla_unregister,
849};
850
851static struct omap_devh_platform_data omap4_devh_data[] = {
852 {
853 .name = "Tesla",
854 .ops = &omap4_tesla_ops,
855 .proc_id = 0,
856 .err_event_id = -1,
857 .line_id = -1,
858 .private_data = &omap4_tesla_runtime_info,
859 },
860 {
861 .name = "SysM3",
862 .ops = &omap4_sysm3_ops,
863 .proc_id = 2,
864 .err_event_id = (4 | (NOTIFY_SYSTEMKEY << 16)),
865 .line_id = 0,
866 .private_data = &omap4_sysm3_runtime_info,
867 },
868 {
869 .name = "AppM3",
870 .ops = &omap4_appm3_ops,
871 .proc_id = 1,
872 .err_event_id = (4 | (NOTIFY_SYSTEMKEY << 16)),
873 .line_id = 0,
874 .private_data = &omap4_appm3_runtime_info,
875 },
876};
877
878int devh_get_plat_data_size(void)
879{
880 return ARRAY_SIZE(omap4_devh_data);
881}
882EXPORT_SYMBOL(devh_get_plat_data_size);
883
884
885#define NR_DEVH_DEVICES ARRAY_SIZE(omap4_devh_data)
886
887static struct platform_device *omap4_devh_pdev[NR_DEVH_DEVICES];
888
889struct omap_devh_platform_data *devh_get_plat_data(void)
890{
891 return omap4_devh_data;
892}
893
894/* returns devh object based on the device index */
895struct omap_devh *devh_get_obj(int dev_index)
896{
897 struct platform_device *pdev;
898 struct omap_devh *obj = NULL;
899 int max_num_devices;
900
901 max_num_devices = devh_get_plat_data_size();
902
903 if (WARN_ON((dev_index > (max_num_devices - 1))))
904 return NULL;
905
906 pdev = omap4_devh_pdev[dev_index];
907
908 if (pdev)
909 obj = (struct omap_devh *)platform_get_drvdata(pdev);
910
911 return obj;
912}
913
914static int __init omap4_devh_init(void)
915{
916 int i, err;
917
918 mutex_init(&local_gate);
919 for (i = 0; i < NR_DEVH_DEVICES; i++) {
920 struct platform_device *pdev;
921
922 pdev = platform_device_alloc("omap-devicehandler", i);
923 if (!pdev) {
924 err = -ENOMEM;
925 goto err_out;
926 }
927
928 err = platform_device_add_data(pdev, &omap4_devh_data[i],
929 sizeof(omap4_devh_data[0]));
930 sema_init(&(omap4_devh_data[i].sem_handle), 0);
931 err = platform_device_add(pdev);
932 if (err)
933 goto err_out;
934 omap4_devh_pdev[i] = pdev;
935 }
936 return 0;
937
938err_out:
939 while (i--)
940 platform_device_put(omap4_devh_pdev[i]);
941 return err;
942}
943module_init(omap4_devh_init);
944
945static void __exit omap4_devh_exit(void)
946{
947 int i;
948
949 for (i = 0; i < NR_DEVH_DEVICES; i++)
950 platform_device_unregister(omap4_devh_pdev[i]);
951}
952module_exit(omap4_devh_exit);
953
954MODULE_LICENSE("GPL v2");
955MODULE_DESCRIPTION("OMAP4 Device Handler module");
956MODULE_AUTHOR("Angela Stegmaier <angelabaker@ti.com>");
diff --git a/drivers/dsp/syslink/devh/Kbuild b/drivers/dsp/syslink/devh/Kbuild
new file mode 100644
index 00000000000..65184bd3b59
--- /dev/null
+++ b/drivers/dsp/syslink/devh/Kbuild
@@ -0,0 +1,7 @@
1
2obj-$(CONFIG_OMAP_DEVICE_HANDLER) += devh.o
3
4ccflags-y += -Wno-strict-prototypes
5
6#Header files
7ccflags-y += -Iarch/arm/plat-omap/include/syslink
diff --git a/drivers/dsp/syslink/devh/devh.c b/drivers/dsp/syslink/devh/devh.c
new file mode 100644
index 00000000000..0e3cabe665f
--- /dev/null
+++ b/drivers/dsp/syslink/devh/devh.c
@@ -0,0 +1,273 @@
1/*
2 * OMAP Device Handler driver
3 *
4 * Copyright (C) 2010 Texas Instruments Inc.
5 *
6 * Written by Angela Stegmaier <angelabaker@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/interrupt.h>
27#include <linux/device.h>
28#include <linux/delay.h>
29#include <linux/file.h>
30#include <linux/poll.h>
31#include <linux/mm.h>
32#include <linux/slab.h>
33#include <linux/platform_device.h>
34
35#include "devh.h"
36
37#define OMAP_DEVH_NAME "omap-devh"
38#define DRV_NAME "omap-devicehandler"
39
40static struct class *omap_devh_class;
41static dev_t omap_devh_dev;
42static atomic_t num_of_devhs;
43static struct platform_driver omap_devh_driver;
44
45static int omap_devh_open(struct inode *inode, struct file *filp)
46{
47 int ret = 0;
48 struct omap_devh *devh;
49
50 devh = container_of(inode->i_cdev, struct omap_devh, cdev);
51 if (!devh->dev)
52 return -EINVAL;
53
54 filp->private_data = devh;
55
56 return ret;
57}
58
59static int omap_devh_release(struct inode *inode, struct file *filp)
60{
61 struct omap_devh *devh = filp->private_data;
62 if (!devh || !devh->dev)
63 return -EINVAL;
64
65 return 0;
66}
67
68static int omap_devh_ioctl(struct inode *inode, struct file *filp,
69 unsigned int cmd, unsigned long arg)
70{
71 int rc = 0;
72 struct omap_devh *devh = filp->private_data;
73 struct omap_devh_platform_data *pdata =
74 (struct omap_devh_platform_data *)devh->dev->platform_data;
75
76 if (!devh)
77 return -EINVAL;
78
79 if (_IOC_TYPE(cmd) != DEVH_IOC_MAGIC)
80 return -ENOTTY;
81 if (_IOC_NR(cmd) > DEVH_IOC_MAXNR)
82 return -ENOTTY;
83 if (_IOC_DIR(cmd) & _IOC_READ) {
84 if (!access_ok(VERIFY_WRITE, (void __user *)arg,
85 _IOC_SIZE(cmd)))
86 return -EFAULT;
87 } else if (_IOC_DIR(cmd) & _IOC_WRITE) {
88 if (!access_ok(VERIFY_READ, (void __user *)arg,
89 _IOC_SIZE(cmd)))
90 return -EFAULT;
91 }
92
93 switch (cmd) {
94
95 /*
96 * this will be updated to support user registering for event
97 * notifications.
98 */
99 case DEVH_IOCWAITONEVENTS:
100 /*rc = omap_devh_wait_on_events(devh);*/
101 break;
102 case DEVH_IOCEVENTREG:
103 rc = pdata->ops->register_event_notification(devh,
104 (const void __user *)arg);
105 break;
106 case DEVH_IOCEVENTUNREG:
107 rc = pdata->ops->unregister_event_notification(devh,
108 (const void __user *)arg);
109 break;
110 default:
111 return -ENOTTY;
112 }
113
114 return rc;
115}
116
117static const struct file_operations omap_devh_fops = {
118 .open = omap_devh_open,
119 .release = omap_devh_release,
120 .ioctl = omap_devh_ioctl,
121 .owner = THIS_MODULE,
122};
123
124static int omap_devh_probe(struct platform_device *pdev)
125{
126 int ret = 0, major, minor;
127 struct device *tmpdev;
128 struct device *dev = &pdev->dev;
129 struct omap_devh_platform_data *pdata = dev->platform_data;
130 struct omap_devh *devh;
131
132 if (!pdata || !pdata->name || !pdata->ops)
133 return -EINVAL;
134
135 dev_info(dev, "%s: adding devh %s\n", __func__, pdata->name);
136
137 devh = kzalloc(sizeof(struct omap_devh), GFP_KERNEL);
138 if (!devh) {
139 dev_err(dev, "%s: kzalloc failed\n", __func__);
140 ret = -ENOMEM;
141 goto out;
142 }
143
144 platform_set_drvdata(pdev, devh);
145 major = MAJOR(omap_devh_dev);
146 minor = atomic_read(&num_of_devhs);
147 atomic_inc(&num_of_devhs);
148
149 devh->dev = dev;
150 devh->minor = minor;
151 devh->name = pdata->name;
152
153 cdev_init(&devh->cdev, &omap_devh_fops);
154 devh->cdev.owner = THIS_MODULE;
155 ret = cdev_add(&devh->cdev, MKDEV(major, minor), 1);
156 if (ret) {
157 dev_err(dev, "%s: cdev_add failed: %d\n", __func__, ret);
158 goto free_devh;
159 }
160
161 tmpdev = device_create(omap_devh_class, NULL,
162 MKDEV(major, minor),
163 NULL,
164 OMAP_DEVH_NAME "%d", minor);
165 if (IS_ERR(tmpdev)) {
166 ret = PTR_ERR(tmpdev);
167 pr_err("%s: device_create failed: %d\n", __func__, ret);
168 goto clean_cdev;
169 }
170
171 pr_info("%s initialized %s, major: %d, base-minor: %d\n",
172 OMAP_DEVH_NAME,
173 pdata->name,
174 MAJOR(omap_devh_dev),
175 minor);
176
177 INIT_LIST_HEAD(&(devh->event_list));
178 spin_lock_init(&(devh->event_lock));
179 if (pdata->ops->register_notifiers)
180 pdata->ops->register_notifiers(devh);
181
182 return 0;
183
184clean_cdev:
185 cdev_del(&devh->cdev);
186free_devh:
187 kfree(devh);
188out:
189 return ret;
190}
191
192static int omap_devh_remove(struct platform_device *pdev)
193{
194 int major = MAJOR(omap_devh_dev);
195 struct device *dev = &pdev->dev;
196 struct omap_devh_platform_data *pdata = dev->platform_data;
197 struct omap_devh *devh = platform_get_drvdata(pdev);
198
199 if (!pdata || !devh)
200 return -EINVAL;
201
202 if (pdata->ops->unregister_notifiers)
203 pdata->ops->unregister_notifiers(devh);
204
205 dev_info(dev, "%s removing %s, major: %d, base-minor: %d\n",
206 OMAP_DEVH_NAME,
207 pdata->name,
208 major,
209 devh->minor);
210
211 device_destroy(omap_devh_class, MKDEV(major, devh->minor));
212 cdev_del(&devh->cdev);
213 kfree(devh);
214
215 return 0;
216}
217
218static struct platform_driver omap_devh_driver = {
219 .probe = omap_devh_probe,
220 .remove = omap_devh_remove,
221 .driver = {
222 .name = DRV_NAME,
223 .owner = THIS_MODULE,
224 },
225};
226
227static int __init omap_devh_init(void)
228{
229 int num = devh_get_plat_data_size();
230 int ret;
231
232 ret = alloc_chrdev_region(&omap_devh_dev, 0, num, OMAP_DEVH_NAME);
233 if (ret) {
234 pr_err("%s: alloc_chrdev_region failed: %d\n", __func__, ret);
235 goto out;
236 }
237
238 omap_devh_class = class_create(THIS_MODULE, OMAP_DEVH_NAME);
239 if (IS_ERR(omap_devh_class)) {
240 ret = PTR_ERR(omap_devh_class);
241 pr_err("%s: class_create failed: %d\n", __func__, ret);
242 goto unreg_region;
243 }
244
245 atomic_set(&num_of_devhs, 0);
246
247 ret = platform_driver_register(&omap_devh_driver);
248 if (ret) {
249 pr_err("%s: platform_driver_register failed: %d\n",
250 __func__, ret);
251 goto out;
252 }
253 return 0;
254unreg_region:
255 unregister_chrdev_region(omap_devh_dev, num);
256out:
257 return ret;
258}
259module_init(omap_devh_init);
260
261static void __exit omap_devh_exit(void)
262{
263 int num = devh_get_plat_data_size();
264 pr_info("%s\n", __func__);
265 platform_driver_unregister(&omap_devh_driver);
266 class_destroy(omap_devh_class);
267 unregister_chrdev_region(omap_devh_dev, num);
268}
269module_exit(omap_devh_exit);
270
271MODULE_LICENSE("GPL v2");
272MODULE_DESCRIPTION("OMAP Device Handler driver");
273MODULE_AUTHOR("Angela Stegmaier <angelabaker@ti.com>");
diff --git a/drivers/dsp/syslink/devh/devh.h b/drivers/dsp/syslink/devh/devh.h
new file mode 100644
index 00000000000..a77af52184e
--- /dev/null
+++ b/drivers/dsp/syslink/devh/devh.h
@@ -0,0 +1,87 @@
1/*
2 * OMAP Device Handler driver
3 *
4 * Copyright (C) 2010 Texas Instruments Inc.
5 *
6 * Written by Angela Stegmaier <angelabaker@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef DEVH_H
25#define DEVH_H
26
27#include <linux/ioctl.h>
28#include <linux/cdev.h>
29#include <linux/semaphore.h>
30
31#define DEVH_IOC_MAGIC 'E'
32
33#define DEVH_IOCWAITONEVENTS _IO(DEVH_IOC_MAGIC, 0)
34#define DEVH_IOCEVENTREG _IOW(DEVH_IOC_MAGIC, 1, \
35 struct deh_reg_event_args)
36#define DEVH_IOCEVENTUNREG _IOW(DEVH_IOC_MAGIC, 2, \
37 struct deh_reg_event_args)
38
39#define DEVH_IOC_MAXNR (2)
40
41/* Device error types */
42enum {
43 DEV_SYS_ERROR = 1,
44 DEV_WATCHDOG_ERROR,
45};
46
47struct omap_devh;
48
49struct omap_devh_ops {
50 int (*register_notifiers)(struct omap_devh *devh);
51 int (*unregister_notifiers)(struct omap_devh *devh);
52 int (*register_event_notification)(struct omap_devh *devh,
53 const void __user *args);
54 int (*unregister_event_notification)(struct omap_devh *devh,
55 const void __user *args);
56};
57
58struct omap_devh_platform_data {
59 struct omap_devh_ops *ops;
60 char *name;
61 int proc_id;
62 int err_event_id;
63 int line_id;
64 struct semaphore sem_handle;
65 void *private_data;
66};
67
68struct omap_devh {
69 struct device *dev;
70 struct cdev cdev;
71 atomic_t count;
72 int state;
73 int minor;
74 char *name;
75 struct list_head event_list;
76 spinlock_t event_lock;
77};
78
79struct deh_reg_event_args {
80 int fd;
81 u32 event;
82};
83
84extern struct omap_devh_platform_data *devh_get_plat_data(void);
85extern int devh_get_plat_data_size(void);
86
87#endif /* DEVH_H */