2 * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
4 * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
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.
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.
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
24 #include <linux/module.h>
26 #include <linux/poll.h>
27 #include <linux/sched.h>
28 #include <asm/uaccess.h>
29 #include "dsp_mbcmd.h"
33 static DECLARE_WAIT_QUEUE_HEAD(read_wait_q);
34 static unsigned int change_cnt;
36 void dsp_twch_touch(void)
39 wake_up_interruptible(&read_wait_q);
43 * @count: represents the device counts of the user's interst
45 static ssize_t dsp_twch_read(struct file *file, char __user *buf, size_t count,
48 long taskstat[TASKDEV_MAX];
49 int devcount = count / sizeof(long);
52 if (dsp_cfgstat_get_stat() != CFGSTAT_READY) {
53 printk(KERN_ERR "omapdsp: dsp has not been configured.\n");
57 if (change_cnt == 0) {
59 DECLARE_WAITQUEUE(wait, current);
61 add_wait_queue(&read_wait_q, &wait);
62 current_state = current->state;
63 set_current_state(TASK_INTERRUPTIBLE);
64 if (change_cnt == 0) /* last check */
66 set_current_state(current_state);
67 remove_wait_queue(&read_wait_q, &wait);
69 /* unconfigured while waiting ;-( */
70 if (dsp_cfgstat_get_stat() != CFGSTAT_READY)
74 if (devcount > TASKDEV_MAX)
75 devcount = TASKDEV_MAX;
77 count = devcount * sizeof(long);
79 for (i = 0; i < devcount; i++) {
81 * once the device state is read, the 'STALE' bit will be set
82 * so that the Dynamic Loader can distinguish the new request
85 taskstat[i] = taskdev_state_stale(i);
88 if (copy_to_user(buf, taskstat, count))
94 static unsigned int dsp_twch_poll(struct file *file, poll_table *wait)
96 unsigned int mask = 0;
98 poll_wait(file, &read_wait_q, wait);
100 mask |= POLLIN | POLLRDNORM;
105 static int dsp_twch_ioctl(struct inode *inode, struct file *file,
106 unsigned int cmd, unsigned long arg)
111 case TWCH_IOCTL_MKDEV:
114 if (copy_from_user(name, (void __user *)arg, TNM_LEN))
116 name[TNM_LEN-1] = '\0';
117 ret = dsp_mkdev(name);
121 case TWCH_IOCTL_RMDEV:
124 if (copy_from_user(name, (void __user *)arg, TNM_LEN))
126 name[TNM_LEN-1] = '\0';
127 ret = dsp_rmdev(name);
131 case TWCH_IOCTL_TADD:
133 struct omap_dsp_taddinfo ti;
134 if (copy_from_user(&ti, (void __user *)arg, sizeof(ti)))
136 ret = dsp_tadd_minor(ti.minor, ti.taskadr);
140 case TWCH_IOCTL_TDEL:
141 ret = dsp_tdel_minor(arg);
144 case TWCH_IOCTL_TKILL:
145 ret = dsp_tkill_minor(arg);
155 struct file_operations dsp_twch_fops = {
156 .owner = THIS_MODULE,
157 .read = dsp_twch_read,
158 .poll = dsp_twch_poll,
159 .ioctl = dsp_twch_ioctl,
162 void dsp_twch_start(void)
164 change_cnt = 1; /* first read will not wait */
167 void dsp_twch_stop(void)
169 wake_up_interruptible(&read_wait_q);