]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/dsp/dspgateway/taskwatch.c
REMOVE OMAP LEGACY CODE: Reset mach-omap1/board-*.c files to mainline
[linux-2.6-omap-h63xx.git] / drivers / dsp / dspgateway / taskwatch.c
1 /*
2  * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
3  *
4  * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
5  *
6  * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.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/module.h>
25 #include <linux/fs.h>
26 #include <linux/poll.h>
27 #include <linux/sched.h>
28 #include <asm/uaccess.h>
29 #include <mach/dsp.h>
30 #include <asm/io.h>
31 #include "dsp_mbcmd.h"
32 #include "dsp.h"
33
34 static DECLARE_WAIT_QUEUE_HEAD(read_wait_q);
35 static unsigned int change_cnt;
36
37 void dsp_twch_touch(void)
38 {
39         change_cnt++;
40         wake_up_interruptible(&read_wait_q);
41 }
42
43 /*
44  * @count: represents the device counts of the user's interst
45  */
46 static ssize_t dsp_twch_read(struct file *file, char __user *buf, size_t count,
47                              loff_t *ppos)
48 {
49         long taskstat[TASKDEV_MAX];
50         int devcount = count / sizeof(long);
51         int i;
52         DEFINE_WAIT(wait);
53
54         if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
55                 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
56                 return -EINVAL;
57         }
58
59         prepare_to_wait(&read_wait_q, &wait, TASK_INTERRUPTIBLE);
60         if (change_cnt == 0)    /* last check */
61                 schedule();
62         finish_wait(&read_wait_q, &wait);
63
64         /* unconfigured while waiting ;-( */
65         if ((change_cnt == 0) && (dsp_cfgstat_get_stat() != CFGSTAT_READY))
66                 return -EINVAL;
67
68         if (devcount > TASKDEV_MAX)
69                 devcount = TASKDEV_MAX;
70
71         count = devcount * sizeof(long);
72         change_cnt = 0;
73         for (i = 0; i < devcount; i++) {
74                 /*
75                  * once the device state is read, the 'STALE' bit will be set
76                  * so that the Dynamic Loader can distinguish the new request
77                  * from the old one.
78                  */
79                 taskstat[i] = taskdev_state_stale(i);
80         }
81
82         if (copy_to_user(buf, taskstat, count))
83                 return -EFAULT;
84
85         return count;
86 }
87
88 static unsigned int dsp_twch_poll(struct file *file, poll_table *wait)
89 {
90         unsigned int mask = 0;
91
92         poll_wait(file, &read_wait_q, wait);
93         if (change_cnt)
94                 mask |= POLLIN | POLLRDNORM;
95
96         return mask;
97 }
98
99 static int dsp_twch_ioctl(struct inode *inode, struct file *file,
100                           unsigned int cmd, unsigned long arg)
101 {
102         int ret;
103
104         switch (cmd) {
105         case TWCH_IOCTL_MKDEV:
106                 {
107                         char name[TNM_LEN];
108                         if (copy_from_user(name, (void __user *)arg, TNM_LEN))
109                                 return -EFAULT;
110                         name[TNM_LEN-1] = '\0';
111                         ret = dsp_mkdev(name);
112                         break;
113                 }
114
115         case TWCH_IOCTL_RMDEV:
116                 {
117                         char name[TNM_LEN];
118                         if (copy_from_user(name, (void __user *)arg, TNM_LEN))
119                                 return -EFAULT;
120                         name[TNM_LEN-1] = '\0';
121                         ret = dsp_rmdev(name);
122                         break;
123                 }
124
125         case TWCH_IOCTL_TADD:
126                 {
127                         struct omap_dsp_taddinfo ti;
128                         if (copy_from_user(&ti, (void __user *)arg, sizeof(ti)))
129                                 return -EFAULT;
130                         ret = dsp_tadd_minor(ti.minor, ti.taskadr);
131                         break;
132                 }
133
134         case TWCH_IOCTL_TDEL:
135                 ret = dsp_tdel_minor(arg);
136                 break;
137
138         case TWCH_IOCTL_TKILL:
139                 ret = dsp_tkill_minor(arg);
140                 break;
141
142         default:
143                 return -ENOIOCTLCMD;
144         }
145
146         return ret;
147 }
148
149 struct file_operations dsp_twch_fops = {
150         .owner = THIS_MODULE,
151         .read  = dsp_twch_read,
152         .poll  = dsp_twch_poll,
153         .ioctl = dsp_twch_ioctl,
154 };
155
156 void dsp_twch_start(void)
157 {
158         change_cnt = 1;         /* first read will not wait */
159 }
160
161 void dsp_twch_stop(void)
162 {
163         wake_up_interruptible(&read_wait_q);
164 }