diff options
32 files changed, 673 insertions, 1569 deletions
diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index 769f925c8526..87f4d052e39c 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt | |||
@@ -130,8 +130,6 @@ Code Seq# Include File Comments | |||
130 | <mailto:zapman@interlan.net> | 130 | <mailto:zapman@interlan.net> |
131 | 'i' 00-3F linux/i2o.h | 131 | 'i' 00-3F linux/i2o.h |
132 | 'j' 00-3F linux/joystick.h | 132 | 'j' 00-3F linux/joystick.h |
133 | 'k' all asm-sparc/kbio.h | ||
134 | asm-sparc64/kbio.h | ||
135 | 'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system | 133 | 'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system |
136 | <http://mikonos.dia.unisa.it/tcfs> | 134 | <http://mikonos.dia.unisa.it/tcfs> |
137 | 'l' 40-7F linux/udf_fs_i.h in development: | 135 | 'l' 40-7F linux/udf_fs_i.h in development: |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 6537445dac0e..3cfb8be3ff6d 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -201,6 +201,14 @@ config SUN_OPENPROMFS | |||
201 | Only choose N if you know in advance that you will not need to modify | 201 | Only choose N if you know in advance that you will not need to modify |
202 | OpenPROM settings on the running system. | 202 | OpenPROM settings on the running system. |
203 | 203 | ||
204 | config SPARC_LED | ||
205 | tristate "Sun4m LED driver" | ||
206 | help | ||
207 | This driver toggles the front-panel LED on sun4m systems | ||
208 | in a user-specifyable manner. It's state can be probed | ||
209 | by reading /proc/led and it's blinking mode can be changed | ||
210 | via writes to /proc/led | ||
211 | |||
204 | source "fs/Kconfig.binfmt" | 212 | source "fs/Kconfig.binfmt" |
205 | 213 | ||
206 | config SUNOS_EMUL | 214 | config SUNOS_EMUL |
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 3d22ba2af01c..1b83e21841b5 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_SUN_AUXIO) += auxio.o | |||
21 | obj-$(CONFIG_PCI) += ebus.o | 21 | obj-$(CONFIG_PCI) += ebus.o |
22 | obj-$(CONFIG_SUN_PM) += apc.o pmc.o | 22 | obj-$(CONFIG_SUN_PM) += apc.o pmc.o |
23 | obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o | 23 | obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o |
24 | obj-$(CONFIG_SPARC_LED) += led.o | ||
24 | 25 | ||
25 | ifdef CONFIG_SUNOS_EMUL | 26 | ifdef CONFIG_SUNOS_EMUL |
26 | obj-y += sys_sunos.o sunos_ioctl.o | 27 | obj-y += sys_sunos.o sunos_ioctl.o |
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c new file mode 100644 index 000000000000..2a3afca453c9 --- /dev/null +++ b/arch/sparc/kernel/led.c | |||
@@ -0,0 +1,139 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/proc_fs.h> | ||
5 | #include <linux/string.h> | ||
6 | |||
7 | #include <asm/auxio.h> | ||
8 | |||
9 | #define LED_MAX_LENGTH 8 /* maximum chars written to proc file */ | ||
10 | |||
11 | static inline void led_toggle(void) | ||
12 | { | ||
13 | unsigned char val = get_auxio(); | ||
14 | unsigned char on, off; | ||
15 | |||
16 | if (val & AUXIO_LED) { | ||
17 | on = 0; | ||
18 | off = AUXIO_LED; | ||
19 | } else { | ||
20 | on = AUXIO_LED; | ||
21 | off = 0; | ||
22 | } | ||
23 | |||
24 | set_auxio(on, off); | ||
25 | } | ||
26 | |||
27 | static struct timer_list led_blink_timer; | ||
28 | |||
29 | static void led_blink(unsigned long timeout) | ||
30 | { | ||
31 | led_toggle(); | ||
32 | |||
33 | /* reschedule */ | ||
34 | if (!timeout) { /* blink according to load */ | ||
35 | led_blink_timer.expires = jiffies + | ||
36 | ((1 + (avenrun[0] >> FSHIFT)) * HZ); | ||
37 | led_blink_timer.data = 0; | ||
38 | } else { /* blink at user specified interval */ | ||
39 | led_blink_timer.expires = jiffies + (timeout * HZ); | ||
40 | led_blink_timer.data = timeout; | ||
41 | } | ||
42 | add_timer(&led_blink_timer); | ||
43 | } | ||
44 | |||
45 | static int led_read_proc(char *buf, char **start, off_t offset, int count, | ||
46 | int *eof, void *data) | ||
47 | { | ||
48 | int len = 0; | ||
49 | |||
50 | if (get_auxio() & AUXIO_LED) | ||
51 | len = sprintf(buf, "on\n"); | ||
52 | else | ||
53 | len = sprintf(buf, "off\n"); | ||
54 | |||
55 | return len; | ||
56 | } | ||
57 | |||
58 | static int led_write_proc(struct file *file, const char *buffer, | ||
59 | unsigned long count, void *data) | ||
60 | { | ||
61 | char *buf = NULL; | ||
62 | |||
63 | if (count > LED_MAX_LENGTH) | ||
64 | count = LED_MAX_LENGTH; | ||
65 | |||
66 | buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL); | ||
67 | if (!buf) | ||
68 | return -ENOMEM; | ||
69 | |||
70 | if (copy_from_user(buf, buffer, count)) { | ||
71 | kfree(buf); | ||
72 | return -EFAULT; | ||
73 | } | ||
74 | |||
75 | buf[count] = '\0'; | ||
76 | |||
77 | /* work around \n when echo'ing into proc */ | ||
78 | if (buf[count - 1] == '\n') | ||
79 | buf[count - 1] = '\0'; | ||
80 | |||
81 | /* before we change anything we want to stop any running timers, | ||
82 | * otherwise calls such as on will have no persistent effect | ||
83 | */ | ||
84 | del_timer_sync(&led_blink_timer); | ||
85 | |||
86 | if (!strcmp(buf, "on")) { | ||
87 | auxio_set_led(AUXIO_LED_ON); | ||
88 | } else if (!strcmp(buf, "toggle")) { | ||
89 | led_toggle(); | ||
90 | } else if ((*buf > '0') && (*buf <= '9')) { | ||
91 | led_blink(simple_strtoul(buf, NULL, 10)); | ||
92 | } else if (!strcmp(buf, "load")) { | ||
93 | led_blink(0); | ||
94 | } else { | ||
95 | auxio_set_led(AUXIO_LED_OFF); | ||
96 | } | ||
97 | |||
98 | kfree(buf); | ||
99 | |||
100 | return count; | ||
101 | } | ||
102 | |||
103 | static struct proc_dir_entry *led; | ||
104 | |||
105 | #define LED_VERSION "0.1" | ||
106 | |||
107 | static int __init led_init(void) | ||
108 | { | ||
109 | init_timer(&led_blink_timer); | ||
110 | led_blink_timer.function = led_blink; | ||
111 | |||
112 | led = create_proc_entry("led", 0, NULL); | ||
113 | if (!led) | ||
114 | return -ENOMEM; | ||
115 | |||
116 | led->read_proc = led_read_proc; /* reader function */ | ||
117 | led->write_proc = led_write_proc; /* writer function */ | ||
118 | led->owner = THIS_MODULE; | ||
119 | |||
120 | printk(KERN_INFO | ||
121 | "led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n", | ||
122 | LED_VERSION); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void __exit led_exit(void) | ||
128 | { | ||
129 | remove_proc_entry("led", NULL); | ||
130 | del_timer_sync(&led_blink_timer); | ||
131 | } | ||
132 | |||
133 | module_init(led_init); | ||
134 | module_exit(led_exit); | ||
135 | |||
136 | MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>"); | ||
137 | MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems."); | ||
138 | MODULE_LICENSE("GPL"); | ||
139 | MODULE_VERSION(LED_VERSION); | ||
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c index df1c0b31a930..a6ba3d26222c 100644 --- a/arch/sparc/kernel/sunos_ioctl.c +++ b/arch/sparc/kernel/sunos_ioctl.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
24 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
25 | #include <linux/file.h> | 25 | #include <linux/file.h> |
26 | #include <asm/kbio.h> | ||
27 | 26 | ||
28 | #if 0 | 27 | #if 0 |
29 | extern char sunkbd_type; | 28 | extern char sunkbd_type; |
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index e6a00325075a..92e26304de90 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c | |||
@@ -11,33 +11,14 @@ | |||
11 | 11 | ||
12 | #define INCLUDES | 12 | #define INCLUDES |
13 | #include "compat_ioctl.c" | 13 | #include "compat_ioctl.c" |
14 | #include <linux/ncp_fs.h> | ||
15 | #include <linux/syscalls.h> | 14 | #include <linux/syscalls.h> |
16 | #include <asm/fbio.h> | 15 | #include <asm/fbio.h> |
17 | #include <asm/kbio.h> | ||
18 | #include <asm/vuid_event.h> | ||
19 | #include <asm/envctrl.h> | ||
20 | #include <asm/display7seg.h> | ||
21 | #include <asm/openpromio.h> | ||
22 | #include <asm/audioio.h> | ||
23 | #include <asm/watchdog.h> | ||
24 | 16 | ||
25 | /* Use this to get at 32-bit user passed pointers. | 17 | /* Use this to get at 32-bit user passed pointers. |
26 | * See sys_sparc32.c for description about it. | 18 | * See sys_sparc32.c for description about it. |
27 | */ | 19 | */ |
28 | #define A(__x) compat_ptr(__x) | 20 | #define A(__x) compat_ptr(__x) |
29 | 21 | ||
30 | static __inline__ void *alloc_user_space(long len) | ||
31 | { | ||
32 | struct pt_regs *regs = current_thread_info()->kregs; | ||
33 | unsigned long usp = regs->u_regs[UREG_I6]; | ||
34 | |||
35 | if (!(test_thread_flag(TIF_32BIT))) | ||
36 | usp += STACK_BIAS; | ||
37 | |||
38 | return (void *) (usp - len); | ||
39 | } | ||
40 | |||
41 | #define CODE | 22 | #define CODE |
42 | #include "compat_ioctl.c" | 23 | #include "compat_ioctl.c" |
43 | 24 | ||
@@ -111,357 +92,6 @@ static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
111 | return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p); | 92 | return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p); |
112 | } | 93 | } |
113 | 94 | ||
114 | #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) | ||
115 | /* This really belongs in include/linux/drm.h -DaveM */ | ||
116 | #include "../../../drivers/char/drm/drm.h" | ||
117 | |||
118 | typedef struct drm32_version { | ||
119 | int version_major; /* Major version */ | ||
120 | int version_minor; /* Minor version */ | ||
121 | int version_patchlevel;/* Patch level */ | ||
122 | int name_len; /* Length of name buffer */ | ||
123 | u32 name; /* Name of driver */ | ||
124 | int date_len; /* Length of date buffer */ | ||
125 | u32 date; /* User-space buffer to hold date */ | ||
126 | int desc_len; /* Length of desc buffer */ | ||
127 | u32 desc; /* User-space buffer to hold desc */ | ||
128 | } drm32_version_t; | ||
129 | #define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t) | ||
130 | |||
131 | static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
132 | { | ||
133 | drm32_version_t __user *uversion = (drm32_version_t __user *)arg; | ||
134 | drm_version_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
135 | compat_uptr_t addr; | ||
136 | int n; | ||
137 | int ret; | ||
138 | |||
139 | if (clear_user(p, 3 * sizeof(int)) || | ||
140 | get_user(n, &uversion->name_len) || | ||
141 | put_user(n, &p->name_len) || | ||
142 | get_user(addr, &uversion->name) || | ||
143 | put_user(compat_ptr(addr), &p->name) || | ||
144 | get_user(n, &uversion->date_len) || | ||
145 | put_user(n, &p->date_len) || | ||
146 | get_user(addr, &uversion->date) || | ||
147 | put_user(compat_ptr(addr), &p->date) || | ||
148 | get_user(n, &uversion->desc_len) || | ||
149 | put_user(n, &p->desc_len) || | ||
150 | get_user(addr, &uversion->desc) || | ||
151 | put_user(compat_ptr(addr), &p->desc)) | ||
152 | return -EFAULT; | ||
153 | |||
154 | ret = sys_ioctl(fd, DRM_IOCTL_VERSION, (unsigned long)p); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | if (copy_in_user(uversion, p, 3 * sizeof(int)) || | ||
159 | get_user(n, &p->name_len) || | ||
160 | put_user(n, &uversion->name_len) || | ||
161 | get_user(n, &p->date_len) || | ||
162 | put_user(n, &uversion->date_len) || | ||
163 | get_user(n, &p->desc_len) || | ||
164 | put_user(n, &uversion->desc_len)) | ||
165 | return -EFAULT; | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | typedef struct drm32_unique { | ||
171 | int unique_len; /* Length of unique */ | ||
172 | u32 unique; /* Unique name for driver instantiation */ | ||
173 | } drm32_unique_t; | ||
174 | #define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t) | ||
175 | #define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t) | ||
176 | |||
177 | static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
178 | { | ||
179 | drm32_unique_t __user *uarg = (drm32_unique_t __user *)arg; | ||
180 | drm_unique_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
181 | compat_uptr_t addr; | ||
182 | int n; | ||
183 | int ret; | ||
184 | |||
185 | if (get_user(n, &uarg->unique_len) || | ||
186 | put_user(n, &p->unique_len) || | ||
187 | get_user(addr, &uarg->unique) || | ||
188 | put_user(compat_ptr(addr), &p->unique)) | ||
189 | return -EFAULT; | ||
190 | |||
191 | if (cmd == DRM32_IOCTL_GET_UNIQUE) | ||
192 | ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)p); | ||
193 | else | ||
194 | ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)p); | ||
195 | |||
196 | if (ret) | ||
197 | return ret; | ||
198 | |||
199 | if (get_user(n, &p->unique_len) || put_user(n, &uarg->unique_len)) | ||
200 | return -EFAULT; | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | typedef struct drm32_map { | ||
206 | u32 offset; /* Requested physical address (0 for SAREA)*/ | ||
207 | u32 size; /* Requested physical size (bytes) */ | ||
208 | drm_map_type_t type; /* Type of memory to map */ | ||
209 | drm_map_flags_t flags; /* Flags */ | ||
210 | u32 handle; /* User-space: "Handle" to pass to mmap */ | ||
211 | /* Kernel-space: kernel-virtual address */ | ||
212 | int mtrr; /* MTRR slot used */ | ||
213 | /* Private data */ | ||
214 | } drm32_map_t; | ||
215 | #define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t) | ||
216 | |||
217 | static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
218 | { | ||
219 | drm32_map_t __user *uarg = (drm32_map_t __user *) arg; | ||
220 | drm_map_t karg; | ||
221 | mm_segment_t old_fs; | ||
222 | u32 tmp; | ||
223 | int ret; | ||
224 | |||
225 | ret = get_user(karg.offset, &uarg->offset); | ||
226 | ret |= get_user(karg.size, &uarg->size); | ||
227 | ret |= get_user(karg.type, &uarg->type); | ||
228 | ret |= get_user(karg.flags, &uarg->flags); | ||
229 | ret |= get_user(tmp, &uarg->handle); | ||
230 | ret |= get_user(karg.mtrr, &uarg->mtrr); | ||
231 | if (ret) | ||
232 | return -EFAULT; | ||
233 | |||
234 | karg.handle = (void *) (unsigned long) tmp; | ||
235 | |||
236 | old_fs = get_fs(); | ||
237 | set_fs(KERNEL_DS); | ||
238 | ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg); | ||
239 | set_fs(old_fs); | ||
240 | |||
241 | if (!ret) { | ||
242 | ret = put_user(karg.offset, &uarg->offset); | ||
243 | ret |= put_user(karg.size, &uarg->size); | ||
244 | ret |= put_user(karg.type, &uarg->type); | ||
245 | ret |= put_user(karg.flags, &uarg->flags); | ||
246 | tmp = (u32) (long)karg.handle; | ||
247 | ret |= put_user(tmp, &uarg->handle); | ||
248 | ret |= put_user(karg.mtrr, &uarg->mtrr); | ||
249 | if (ret) | ||
250 | ret = -EFAULT; | ||
251 | } | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | typedef struct drm32_buf_info { | ||
257 | int count; /* Entries in list */ | ||
258 | u32 list; /* (drm_buf_desc_t *) */ | ||
259 | } drm32_buf_info_t; | ||
260 | #define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t) | ||
261 | |||
262 | static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
263 | { | ||
264 | drm32_buf_info_t __user *uarg = (drm32_buf_info_t __user *)arg; | ||
265 | drm_buf_info_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
266 | compat_uptr_t addr; | ||
267 | int n; | ||
268 | int ret; | ||
269 | |||
270 | if (get_user(n, &uarg->count) || put_user(n, &p->count) || | ||
271 | get_user(addr, &uarg->list) || put_user(compat_ptr(addr), &p->list)) | ||
272 | return -EFAULT; | ||
273 | |||
274 | ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long)p); | ||
275 | if (ret) | ||
276 | return ret; | ||
277 | |||
278 | if (get_user(n, &p->count) || put_user(n, &uarg->count)) | ||
279 | return -EFAULT; | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | typedef struct drm32_buf_free { | ||
285 | int count; | ||
286 | u32 list; /* (int *) */ | ||
287 | } drm32_buf_free_t; | ||
288 | #define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t) | ||
289 | |||
290 | static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
291 | { | ||
292 | drm32_buf_free_t __user *uarg = (drm32_buf_free_t __user *)arg; | ||
293 | drm_buf_free_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
294 | compat_uptr_t addr; | ||
295 | int n; | ||
296 | |||
297 | if (get_user(n, &uarg->count) || put_user(n, &p->count) || | ||
298 | get_user(addr, &uarg->list) || put_user(compat_ptr(addr), &p->list)) | ||
299 | return -EFAULT; | ||
300 | |||
301 | return sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long)p); | ||
302 | } | ||
303 | |||
304 | typedef struct drm32_buf_pub { | ||
305 | int idx; /* Index into master buflist */ | ||
306 | int total; /* Buffer size */ | ||
307 | int used; /* Amount of buffer in use (for DMA) */ | ||
308 | u32 address; /* Address of buffer (void *) */ | ||
309 | } drm32_buf_pub_t; | ||
310 | |||
311 | typedef struct drm32_buf_map { | ||
312 | int count; /* Length of buflist */ | ||
313 | u32 virtual; /* Mmaped area in user-virtual (void *) */ | ||
314 | u32 list; /* Buffer information (drm_buf_pub_t *) */ | ||
315 | } drm32_buf_map_t; | ||
316 | #define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t) | ||
317 | |||
318 | static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
319 | { | ||
320 | drm32_buf_map_t __user *uarg = (drm32_buf_map_t __user *)arg; | ||
321 | drm32_buf_pub_t __user *ulist; | ||
322 | drm_buf_map_t __user *arg64; | ||
323 | drm_buf_pub_t __user *list; | ||
324 | int orig_count, ret, i; | ||
325 | int n; | ||
326 | compat_uptr_t addr; | ||
327 | |||
328 | if (get_user(orig_count, &uarg->count)) | ||
329 | return -EFAULT; | ||
330 | |||
331 | arg64 = compat_alloc_user_space(sizeof(drm_buf_map_t) + | ||
332 | (size_t)orig_count * sizeof(drm_buf_pub_t)); | ||
333 | list = (void __user *)(arg64 + 1); | ||
334 | |||
335 | if (put_user(orig_count, &arg64->count) || | ||
336 | put_user(list, &arg64->list) || | ||
337 | get_user(addr, &uarg->virtual) || | ||
338 | put_user(compat_ptr(addr), &arg64->virtual) || | ||
339 | get_user(addr, &uarg->list)) | ||
340 | return -EFAULT; | ||
341 | |||
342 | ulist = compat_ptr(addr); | ||
343 | |||
344 | for (i = 0; i < orig_count; i++) { | ||
345 | if (get_user(n, &ulist[i].idx) || | ||
346 | put_user(n, &list[i].idx) || | ||
347 | get_user(n, &ulist[i].total) || | ||
348 | put_user(n, &list[i].total) || | ||
349 | get_user(n, &ulist[i].used) || | ||
350 | put_user(n, &list[i].used) || | ||
351 | get_user(addr, &ulist[i].address) || | ||
352 | put_user(compat_ptr(addr), &list[i].address)) | ||
353 | return -EFAULT; | ||
354 | } | ||
355 | |||
356 | ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) arg64); | ||
357 | if (ret) | ||
358 | return ret; | ||
359 | |||
360 | for (i = 0; i < orig_count; i++) { | ||
361 | void __user *p; | ||
362 | if (get_user(n, &list[i].idx) || | ||
363 | put_user(n, &ulist[i].idx) || | ||
364 | get_user(n, &list[i].total) || | ||
365 | put_user(n, &ulist[i].total) || | ||
366 | get_user(n, &list[i].used) || | ||
367 | put_user(n, &ulist[i].used) || | ||
368 | get_user(p, &list[i].address) || | ||
369 | put_user((unsigned long)p, &ulist[i].address)) | ||
370 | return -EFAULT; | ||
371 | } | ||
372 | |||
373 | if (get_user(n, &arg64->count) || put_user(n, &uarg->count)) | ||
374 | return -EFAULT; | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | typedef struct drm32_dma { | ||
380 | /* Indices here refer to the offset into | ||
381 | buflist in drm_buf_get_t. */ | ||
382 | int context; /* Context handle */ | ||
383 | int send_count; /* Number of buffers to send */ | ||
384 | u32 send_indices; /* List of handles to buffers (int *) */ | ||
385 | u32 send_sizes; /* Lengths of data to send (int *) */ | ||
386 | drm_dma_flags_t flags; /* Flags */ | ||
387 | int request_count; /* Number of buffers requested */ | ||
388 | int request_size; /* Desired size for buffers */ | ||
389 | u32 request_indices; /* Buffer information (int *) */ | ||
390 | u32 request_sizes; /* (int *) */ | ||
391 | int granted_count; /* Number of buffers granted */ | ||
392 | } drm32_dma_t; | ||
393 | #define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t) | ||
394 | |||
395 | /* RED PEN The DRM layer blindly dereferences the send/request | ||
396 | * index/size arrays even though they are userland | ||
397 | * pointers. -DaveM | ||
398 | */ | ||
399 | static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
400 | { | ||
401 | drm32_dma_t __user *uarg = (drm32_dma_t __user *) arg; | ||
402 | drm_dma_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
403 | compat_uptr_t addr; | ||
404 | int ret; | ||
405 | |||
406 | if (copy_in_user(p, uarg, 2 * sizeof(int)) || | ||
407 | get_user(addr, &uarg->send_indices) || | ||
408 | put_user(compat_ptr(addr), &p->send_indices) || | ||
409 | get_user(addr, &uarg->send_sizes) || | ||
410 | put_user(compat_ptr(addr), &p->send_sizes) || | ||
411 | copy_in_user(&p->flags, &uarg->flags, sizeof(drm_dma_flags_t)) || | ||
412 | copy_in_user(&p->request_count, &uarg->request_count, sizeof(int))|| | ||
413 | copy_in_user(&p->request_size, &uarg->request_size, sizeof(int)) || | ||
414 | get_user(addr, &uarg->request_indices) || | ||
415 | put_user(compat_ptr(addr), &p->request_indices) || | ||
416 | get_user(addr, &uarg->request_sizes) || | ||
417 | put_user(compat_ptr(addr), &p->request_sizes) || | ||
418 | copy_in_user(&p->granted_count, &uarg->granted_count, sizeof(int))) | ||
419 | return -EFAULT; | ||
420 | |||
421 | ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long)p); | ||
422 | if (ret) | ||
423 | return ret; | ||
424 | |||
425 | if (copy_in_user(uarg, p, 2 * sizeof(int)) || | ||
426 | copy_in_user(&uarg->flags, &p->flags, sizeof(drm_dma_flags_t)) || | ||
427 | copy_in_user(&uarg->request_count, &p->request_count, sizeof(int))|| | ||
428 | copy_in_user(&uarg->request_size, &p->request_size, sizeof(int)) || | ||
429 | copy_in_user(&uarg->granted_count, &p->granted_count, sizeof(int))) | ||
430 | return -EFAULT; | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | typedef struct drm32_ctx_res { | ||
436 | int count; | ||
437 | u32 contexts; /* (drm_ctx_t *) */ | ||
438 | } drm32_ctx_res_t; | ||
439 | #define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t) | ||
440 | |||
441 | static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
442 | { | ||
443 | drm32_ctx_res_t __user *uarg = (drm32_ctx_res_t __user *) arg; | ||
444 | drm_ctx_res_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
445 | compat_uptr_t addr; | ||
446 | int ret; | ||
447 | |||
448 | if (copy_in_user(p, uarg, sizeof(int)) || | ||
449 | get_user(addr, &uarg->contexts) || | ||
450 | put_user(compat_ptr(addr), &p->contexts)) | ||
451 | return -EFAULT; | ||
452 | |||
453 | ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long)p); | ||
454 | if (ret) | ||
455 | return ret; | ||
456 | |||
457 | if (copy_in_user(uarg, p, sizeof(int))) | ||
458 | return -EFAULT; | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | #endif | ||
464 | |||
465 | typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); | 95 | typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); |
466 | 96 | ||
467 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) | 97 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) |
@@ -485,103 +115,14 @@ COMPATIBLE_IOCTL(FBIOSCURPOS) | |||
485 | COMPATIBLE_IOCTL(FBIOGCURPOS) | 115 | COMPATIBLE_IOCTL(FBIOGCURPOS) |
486 | COMPATIBLE_IOCTL(FBIOGCURMAX) | 116 | COMPATIBLE_IOCTL(FBIOGCURMAX) |
487 | /* Little k */ | 117 | /* Little k */ |
488 | COMPATIBLE_IOCTL(KIOCTYPE) | ||
489 | COMPATIBLE_IOCTL(KIOCLAYOUT) | ||
490 | COMPATIBLE_IOCTL(KIOCGTRANS) | ||
491 | COMPATIBLE_IOCTL(KIOCTRANS) | ||
492 | COMPATIBLE_IOCTL(KIOCCMD) | ||
493 | COMPATIBLE_IOCTL(KIOCSDIRECT) | ||
494 | COMPATIBLE_IOCTL(KIOCSLED) | ||
495 | COMPATIBLE_IOCTL(KIOCGLED) | ||
496 | COMPATIBLE_IOCTL(KIOCSRATE) | ||
497 | COMPATIBLE_IOCTL(KIOCGRATE) | ||
498 | COMPATIBLE_IOCTL(VUIDSFORMAT) | ||
499 | COMPATIBLE_IOCTL(VUIDGFORMAT) | ||
500 | /* Little v, the video4linux ioctls */ | 118 | /* Little v, the video4linux ioctls */ |
501 | COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ | 119 | COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ |
502 | COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ | 120 | COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ |
503 | COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE) | ||
504 | COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE) | ||
505 | COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE) | ||
506 | COMPATIBLE_IOCTL(ENVCTRL_RD_FAN_STATUS) | ||
507 | COMPATIBLE_IOCTL(ENVCTRL_RD_VOLTAGE_STATUS) | ||
508 | COMPATIBLE_IOCTL(ENVCTRL_RD_SCSI_TEMPERATURE) | ||
509 | COMPATIBLE_IOCTL(ENVCTRL_RD_ETHERNET_TEMPERATURE) | ||
510 | COMPATIBLE_IOCTL(ENVCTRL_RD_MTHRBD_TEMPERATURE) | ||
511 | COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_VOLTAGE) | ||
512 | COMPATIBLE_IOCTL(ENVCTRL_RD_GLOBALADDRESS) | ||
513 | /* COMPATIBLE_IOCTL(D7SIOCRD) same value as ENVCTRL_RD_VOLTAGE_STATUS */ | ||
514 | COMPATIBLE_IOCTL(D7SIOCWR) | ||
515 | COMPATIBLE_IOCTL(D7SIOCTM) | ||
516 | /* OPENPROMIO, SunOS/Solaris only, the NetBSD one's have | ||
517 | * embedded pointers in the arg which we'd need to clean up... | ||
518 | */ | ||
519 | COMPATIBLE_IOCTL(OPROMGETOPT) | ||
520 | COMPATIBLE_IOCTL(OPROMSETOPT) | ||
521 | COMPATIBLE_IOCTL(OPROMNXTOPT) | ||
522 | COMPATIBLE_IOCTL(OPROMSETOPT2) | ||
523 | COMPATIBLE_IOCTL(OPROMNEXT) | ||
524 | COMPATIBLE_IOCTL(OPROMCHILD) | ||
525 | COMPATIBLE_IOCTL(OPROMGETPROP) | ||
526 | COMPATIBLE_IOCTL(OPROMNXTPROP) | ||
527 | COMPATIBLE_IOCTL(OPROMU2P) | ||
528 | COMPATIBLE_IOCTL(OPROMGETCONS) | ||
529 | COMPATIBLE_IOCTL(OPROMGETFBNAME) | ||
530 | COMPATIBLE_IOCTL(OPROMGETBOOTARGS) | ||
531 | COMPATIBLE_IOCTL(OPROMSETCUR) | ||
532 | COMPATIBLE_IOCTL(OPROMPCI2NODE) | ||
533 | COMPATIBLE_IOCTL(OPROMPATH2NODE) | ||
534 | /* Big L */ | ||
535 | COMPATIBLE_IOCTL(LOOP_SET_STATUS64) | ||
536 | COMPATIBLE_IOCTL(LOOP_GET_STATUS64) | ||
537 | /* Big A */ | ||
538 | COMPATIBLE_IOCTL(AUDIO_GETINFO) | ||
539 | COMPATIBLE_IOCTL(AUDIO_SETINFO) | ||
540 | COMPATIBLE_IOCTL(AUDIO_DRAIN) | ||
541 | COMPATIBLE_IOCTL(AUDIO_GETDEV) | ||
542 | COMPATIBLE_IOCTL(AUDIO_GETDEV_SUNOS) | ||
543 | COMPATIBLE_IOCTL(AUDIO_FLUSH) | ||
544 | COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) | ||
545 | #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) | ||
546 | COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC) | ||
547 | COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID) | ||
548 | COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC) | ||
549 | COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK) | ||
550 | COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK) | ||
551 | COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL) | ||
552 | COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS) | ||
553 | COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS) | ||
554 | COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX) | ||
555 | COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX) | ||
556 | COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX) | ||
557 | COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX) | ||
558 | COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX) | ||
559 | COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX) | ||
560 | COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW) | ||
561 | COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW) | ||
562 | COMPATIBLE_IOCTL(DRM_IOCTL_LOCK) | ||
563 | COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK) | ||
564 | COMPATIBLE_IOCTL(DRM_IOCTL_FINISH) | ||
565 | #endif /* DRM */ | ||
566 | COMPATIBLE_IOCTL(WIOCSTART) | ||
567 | COMPATIBLE_IOCTL(WIOCSTOP) | ||
568 | COMPATIBLE_IOCTL(WIOCGSTAT) | ||
569 | /* And these ioctls need translation */ | 121 | /* And these ioctls need translation */ |
570 | /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ | 122 | /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ |
571 | HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) | 123 | HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) |
572 | HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap) | 124 | HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap) |
573 | HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor) | 125 | HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor) |
574 | #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) | ||
575 | HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version) | ||
576 | HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique) | ||
577 | HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique) | ||
578 | HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap) | ||
579 | HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs) | ||
580 | HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs) | ||
581 | HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs) | ||
582 | HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma) | ||
583 | HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx) | ||
584 | #endif /* DRM */ | ||
585 | #if 0 | 126 | #if 0 |
586 | HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl) | 127 | HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl) |
587 | HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl) | 128 | HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl) |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index c1f34237cdf2..bf1849dd9c49 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -154,6 +154,7 @@ int prom_callback(long *args) | |||
154 | pud_t *pudp; | 154 | pud_t *pudp; |
155 | pmd_t *pmdp; | 155 | pmd_t *pmdp; |
156 | pte_t *ptep; | 156 | pte_t *ptep; |
157 | pte_t pte; | ||
157 | 158 | ||
158 | for_each_process(p) { | 159 | for_each_process(p) { |
159 | mm = p->mm; | 160 | mm = p->mm; |
@@ -178,8 +179,9 @@ int prom_callback(long *args) | |||
178 | * being called from inside OBP. | 179 | * being called from inside OBP. |
179 | */ | 180 | */ |
180 | ptep = pte_offset_map(pmdp, va); | 181 | ptep = pte_offset_map(pmdp, va); |
181 | if (pte_present(*ptep)) { | 182 | pte = *ptep; |
182 | tte = pte_val(*ptep); | 183 | if (pte_present(pte)) { |
184 | tte = pte_val(pte); | ||
183 | res = PROM_TRUE; | 185 | res = PROM_TRUE; |
184 | } | 186 | } |
185 | pte_unmap(ptep); | 187 | pte_unmap(ptep); |
@@ -218,6 +220,7 @@ int prom_callback(long *args) | |||
218 | pud_t *pudp; | 220 | pud_t *pudp; |
219 | pmd_t *pmdp; | 221 | pmd_t *pmdp; |
220 | pte_t *ptep; | 222 | pte_t *ptep; |
223 | pte_t pte; | ||
221 | int error; | 224 | int error; |
222 | 225 | ||
223 | if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) { | 226 | if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) { |
@@ -240,8 +243,9 @@ int prom_callback(long *args) | |||
240 | * being called from inside OBP. | 243 | * being called from inside OBP. |
241 | */ | 244 | */ |
242 | ptep = pte_offset_kernel(pmdp, va); | 245 | ptep = pte_offset_kernel(pmdp, va); |
243 | if (pte_present(*ptep)) { | 246 | pte = *ptep; |
244 | tte = pte_val(*ptep); | 247 | if (pte_present(pte)) { |
248 | tte = pte_val(pte); | ||
245 | res = PROM_TRUE; | 249 | res = PROM_TRUE; |
246 | } | 250 | } |
247 | goto done; | 251 | goto done; |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index aecccd0df1d1..009a86e5ded4 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -863,6 +863,7 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
863 | pud_t *pudp = pud_offset(pgdp, address); | 863 | pud_t *pudp = pud_offset(pgdp, address); |
864 | pmd_t *pmdp = pmd_offset(pudp, address); | 864 | pmd_t *pmdp = pmd_offset(pudp, address); |
865 | pte_t *ptep; | 865 | pte_t *ptep; |
866 | pte_t pte; | ||
866 | 867 | ||
867 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 868 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
868 | 869 | ||
@@ -873,9 +874,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
873 | 874 | ||
874 | preempt_disable(); | 875 | preempt_disable(); |
875 | ptep = pte_offset_map(pmdp, address); | 876 | ptep = pte_offset_map(pmdp, address); |
876 | if (pte_present(*ptep)) { | 877 | pte = *ptep; |
878 | if (pte_present(pte)) { | ||
877 | unsigned long page = (unsigned long) | 879 | unsigned long page = (unsigned long) |
878 | page_address(pte_page(*ptep)); | 880 | page_address(pte_page(pte)); |
879 | 881 | ||
880 | wmb(); | 882 | wmb(); |
881 | __asm__ __volatile__("flush %0 + %1" | 883 | __asm__ __volatile__("flush %0 + %1" |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b137fd63f5e1..5d90ee9aebf1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -839,43 +839,29 @@ void smp_flush_tlb_all(void) | |||
839 | * questionable (in theory the big win for threads is the massive sharing of | 839 | * questionable (in theory the big win for threads is the massive sharing of |
840 | * address space state across processors). | 840 | * address space state across processors). |
841 | */ | 841 | */ |
842 | |||
843 | /* This currently is only used by the hugetlb arch pre-fault | ||
844 | * hook on UltraSPARC-III+ and later when changing the pagesize | ||
845 | * bits of the context register for an address space. | ||
846 | */ | ||
842 | void smp_flush_tlb_mm(struct mm_struct *mm) | 847 | void smp_flush_tlb_mm(struct mm_struct *mm) |
843 | { | 848 | { |
844 | /* | 849 | u32 ctx = CTX_HWBITS(mm->context); |
845 | * This code is called from two places, dup_mmap and exit_mmap. In the | 850 | int cpu = get_cpu(); |
846 | * former case, we really need a flush. In the later case, the callers | ||
847 | * are single threaded exec_mmap (really need a flush), multithreaded | ||
848 | * exec_mmap case (do not need to flush, since the caller gets a new | ||
849 | * context via activate_mm), and all other callers of mmput() whence | ||
850 | * the flush can be optimized since the associated threads are dead and | ||
851 | * the mm is being torn down (__exit_mm and other mmput callers) or the | ||
852 | * owning thread is dissociating itself from the mm. The | ||
853 | * (atomic_read(&mm->mm_users) == 0) check ensures real work is done | ||
854 | * for single thread exec and dup_mmap cases. An alternate check might | ||
855 | * have been (current->mm != mm). | ||
856 | * Kanoj Sarcar | ||
857 | */ | ||
858 | if (atomic_read(&mm->mm_users) == 0) | ||
859 | return; | ||
860 | |||
861 | { | ||
862 | u32 ctx = CTX_HWBITS(mm->context); | ||
863 | int cpu = get_cpu(); | ||
864 | 851 | ||
865 | if (atomic_read(&mm->mm_users) == 1) { | 852 | if (atomic_read(&mm->mm_users) == 1) { |
866 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); | 853 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); |
867 | goto local_flush_and_out; | 854 | goto local_flush_and_out; |
868 | } | 855 | } |
869 | 856 | ||
870 | smp_cross_call_masked(&xcall_flush_tlb_mm, | 857 | smp_cross_call_masked(&xcall_flush_tlb_mm, |
871 | ctx, 0, 0, | 858 | ctx, 0, 0, |
872 | mm->cpu_vm_mask); | 859 | mm->cpu_vm_mask); |
873 | 860 | ||
874 | local_flush_and_out: | 861 | local_flush_and_out: |
875 | __flush_tlb_mm(ctx, SECONDARY_CONTEXT); | 862 | __flush_tlb_mm(ctx, SECONDARY_CONTEXT); |
876 | 863 | ||
877 | put_cpu(); | 864 | put_cpu(); |
878 | } | ||
879 | } | 865 | } |
880 | 866 | ||
881 | void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) | 867 | void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) |
@@ -883,34 +869,13 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long | |||
883 | u32 ctx = CTX_HWBITS(mm->context); | 869 | u32 ctx = CTX_HWBITS(mm->context); |
884 | int cpu = get_cpu(); | 870 | int cpu = get_cpu(); |
885 | 871 | ||
886 | if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { | 872 | if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) |
887 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); | 873 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); |
888 | goto local_flush_and_out; | 874 | else |
889 | } else { | 875 | smp_cross_call_masked(&xcall_flush_tlb_pending, |
890 | /* This optimization is not valid. Normally | 876 | ctx, nr, (unsigned long) vaddrs, |
891 | * we will be holding the page_table_lock, but | 877 | mm->cpu_vm_mask); |
892 | * there is an exception which is copy_page_range() | ||
893 | * when forking. The lock is held during the individual | ||
894 | * page table updates in the parent, but not at the | ||
895 | * top level, which is where we are invoked. | ||
896 | */ | ||
897 | if (0) { | ||
898 | cpumask_t this_cpu_mask = cpumask_of_cpu(cpu); | ||
899 | |||
900 | /* By virtue of running under the mm->page_table_lock, | ||
901 | * and mmu_context.h:switch_mm doing the same, the | ||
902 | * following operation is safe. | ||
903 | */ | ||
904 | if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask)) | ||
905 | goto local_flush_and_out; | ||
906 | } | ||
907 | } | ||
908 | |||
909 | smp_cross_call_masked(&xcall_flush_tlb_pending, | ||
910 | ctx, nr, (unsigned long) vaddrs, | ||
911 | mm->cpu_vm_mask); | ||
912 | 878 | ||
913 | local_flush_and_out: | ||
914 | __flush_tlb_pending(ctx, nr, vaddrs); | 879 | __flush_tlb_pending(ctx, nr, vaddrs); |
915 | 880 | ||
916 | put_cpu(); | 881 | put_cpu(); |
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c index 7654b8a7f03a..3f619ead22cc 100644 --- a/arch/sparc64/kernel/sunos_ioctl32.c +++ b/arch/sparc64/kernel/sunos_ioctl32.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/smp_lock.h> | 24 | #include <linux/smp_lock.h> |
25 | #include <linux/syscalls.h> | 25 | #include <linux/syscalls.h> |
26 | #include <linux/compat.h> | 26 | #include <linux/compat.h> |
27 | #include <asm/kbio.h> | ||
28 | 27 | ||
29 | #define SUNOS_NR_OPEN 256 | 28 | #define SUNOS_NR_OPEN 256 |
30 | 29 | ||
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 38c5525087a2..459c8fbe02b4 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -60,17 +60,6 @@ static void __iomem *mstk48t59_regs; | |||
60 | 60 | ||
61 | static int set_rtc_mmss(unsigned long); | 61 | static int set_rtc_mmss(unsigned long); |
62 | 62 | ||
63 | static __init unsigned long dummy_get_tick(void) | ||
64 | { | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static __initdata struct sparc64_tick_ops dummy_tick_ops = { | ||
69 | .get_tick = dummy_get_tick, | ||
70 | }; | ||
71 | |||
72 | struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops; | ||
73 | |||
74 | #define TICK_PRIV_BIT (1UL << 63) | 63 | #define TICK_PRIV_BIT (1UL << 63) |
75 | 64 | ||
76 | #ifdef CONFIG_SMP | 65 | #ifdef CONFIG_SMP |
@@ -200,6 +189,8 @@ static struct sparc64_tick_ops tick_operations __read_mostly = { | |||
200 | .softint_mask = 1UL << 0, | 189 | .softint_mask = 1UL << 0, |
201 | }; | 190 | }; |
202 | 191 | ||
192 | struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations; | ||
193 | |||
203 | static void stick_init_tick(unsigned long offset) | 194 | static void stick_init_tick(unsigned long offset) |
204 | { | 195 | { |
205 | tick_disable_protection(); | 196 | tick_disable_protection(); |
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c index c82abeb59d3a..071ae24be892 100644 --- a/drivers/sbus/char/cpwatchdog.c +++ b/drivers/sbus/char/cpwatchdog.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <linux/timer.h> | 28 | #include <linux/timer.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
30 | #include <asm/ebus.h> | 31 | #include <asm/ebus.h> |
31 | #include <asm/oplib.h> | 32 | #include <asm/oplib.h> |
@@ -394,6 +395,28 @@ static int wd_ioctl(struct inode *inode, struct file *file, | |||
394 | return(0); | 395 | return(0); |
395 | } | 396 | } |
396 | 397 | ||
398 | static long wd_compat_ioctl(struct file *file, unsigned int cmd, | ||
399 | unsigned long arg) | ||
400 | { | ||
401 | int rval = -ENOIOCTLCMD; | ||
402 | |||
403 | switch (cmd) { | ||
404 | /* solaris ioctls are specific to this driver */ | ||
405 | case WIOCSTART: | ||
406 | case WIOCSTOP: | ||
407 | case WIOCGSTAT: | ||
408 | lock_kernel(); | ||
409 | rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg); | ||
410 | lock_kernel(); | ||
411 | break; | ||
412 | /* everything else is handled by the generic compat layer */ | ||
413 | default: | ||
414 | break; | ||
415 | } | ||
416 | |||
417 | return rval; | ||
418 | } | ||
419 | |||
397 | static ssize_t wd_write(struct file *file, | 420 | static ssize_t wd_write(struct file *file, |
398 | const char __user *buf, | 421 | const char __user *buf, |
399 | size_t count, | 422 | size_t count, |
@@ -441,6 +464,7 @@ static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
441 | static struct file_operations wd_fops = { | 464 | static struct file_operations wd_fops = { |
442 | .owner = THIS_MODULE, | 465 | .owner = THIS_MODULE, |
443 | .ioctl = wd_ioctl, | 466 | .ioctl = wd_ioctl, |
467 | .compat_ioctl = wd_compat_ioctl, | ||
444 | .open = wd_open, | 468 | .open = wd_open, |
445 | .write = wd_write, | 469 | .write = wd_write, |
446 | .read = wd_read, | 470 | .read = wd_read, |
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 24ed5893b4f0..39f54213a6d5 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/miscdevice.h> | 16 | #include <linux/miscdevice.h> |
17 | #include <linux/ioport.h> /* request_region */ | 17 | #include <linux/ioport.h> /* request_region */ |
18 | #include <linux/smp_lock.h> | ||
18 | #include <asm/atomic.h> | 19 | #include <asm/atomic.h> |
19 | #include <asm/ebus.h> /* EBus device */ | 20 | #include <asm/ebus.h> /* EBus device */ |
20 | #include <asm/oplib.h> /* OpenProm Library */ | 21 | #include <asm/oplib.h> /* OpenProm Library */ |
@@ -114,22 +115,25 @@ static int d7s_release(struct inode *inode, struct file *f) | |||
114 | return 0; | 115 | return 0; |
115 | } | 116 | } |
116 | 117 | ||
117 | static int d7s_ioctl(struct inode *inode, struct file *f, | 118 | static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
118 | unsigned int cmd, unsigned long arg) | ||
119 | { | 119 | { |
120 | __u8 regs = readb(d7s_regs); | 120 | __u8 regs = readb(d7s_regs); |
121 | __u8 ireg = 0; | 121 | __u8 ireg = 0; |
122 | int error = 0 | ||
122 | 123 | ||
123 | if (D7S_MINOR != iminor(inode)) | 124 | if (D7S_MINOR != iminor(file->f_dentry->d_inode)) |
124 | return -ENODEV; | 125 | return -ENODEV; |
125 | 126 | ||
127 | lock_kernel(); | ||
126 | switch (cmd) { | 128 | switch (cmd) { |
127 | case D7SIOCWR: | 129 | case D7SIOCWR: |
128 | /* assign device register values | 130 | /* assign device register values |
129 | * we mask-out D7S_FLIP if in sol_compat mode | 131 | * we mask-out D7S_FLIP if in sol_compat mode |
130 | */ | 132 | */ |
131 | if (get_user(ireg, (int __user *) arg)) | 133 | if (get_user(ireg, (int __user *) arg)) { |
132 | return -EFAULT; | 134 | error = -EFAULT; |
135 | break; | ||
136 | } | ||
133 | if (0 != sol_compat) { | 137 | if (0 != sol_compat) { |
134 | (regs & D7S_FLIP) ? | 138 | (regs & D7S_FLIP) ? |
135 | (ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP); | 139 | (ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP); |
@@ -144,8 +148,10 @@ static int d7s_ioctl(struct inode *inode, struct file *f, | |||
144 | * This driver will not misinform you about the state | 148 | * This driver will not misinform you about the state |
145 | * of your hardware while in sol_compat mode | 149 | * of your hardware while in sol_compat mode |
146 | */ | 150 | */ |
147 | if (put_user(regs, (int __user *) arg)) | 151 | if (put_user(regs, (int __user *) arg)) { |
148 | return -EFAULT; | 152 | error = -EFAULT; |
153 | break; | ||
154 | } | ||
149 | break; | 155 | break; |
150 | 156 | ||
151 | case D7SIOCTM: | 157 | case D7SIOCTM: |
@@ -155,15 +161,17 @@ static int d7s_ioctl(struct inode *inode, struct file *f, | |||
155 | writeb(regs, d7s_regs); | 161 | writeb(regs, d7s_regs); |
156 | break; | 162 | break; |
157 | }; | 163 | }; |
164 | lock_kernel(); | ||
158 | 165 | ||
159 | return 0; | 166 | return error; |
160 | } | 167 | } |
161 | 168 | ||
162 | static struct file_operations d7s_fops = { | 169 | static struct file_operations d7s_fops = { |
163 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
164 | .ioctl = d7s_ioctl, | 171 | .unlocked_ioctl = d7s_ioctl, |
165 | .open = d7s_open, | 172 | .compat_ioctl = d7s_ioctl, |
166 | .release = d7s_release, | 173 | .open = d7s_open, |
174 | .release = d7s_release, | ||
167 | }; | 175 | }; |
168 | 176 | ||
169 | static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops }; | 177 | static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops }; |
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index ba56762b05f6..19e8eddf887a 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c | |||
@@ -654,9 +654,8 @@ envctrl_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
654 | /* Function Description: Command what to read. Mapped to user ioctl(). | 654 | /* Function Description: Command what to read. Mapped to user ioctl(). |
655 | * Return: Gives 0 for implemented commands, -EINVAL otherwise. | 655 | * Return: Gives 0 for implemented commands, -EINVAL otherwise. |
656 | */ | 656 | */ |
657 | static int | 657 | static long |
658 | envctrl_ioctl(struct inode *inode, struct file *file, | 658 | envctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
659 | unsigned int cmd, unsigned long arg) | ||
660 | { | 659 | { |
661 | char __user *infobuf; | 660 | char __user *infobuf; |
662 | 661 | ||
@@ -715,11 +714,14 @@ envctrl_release(struct inode *inode, struct file *file) | |||
715 | } | 714 | } |
716 | 715 | ||
717 | static struct file_operations envctrl_fops = { | 716 | static struct file_operations envctrl_fops = { |
718 | .owner = THIS_MODULE, | 717 | .owner = THIS_MODULE, |
719 | .read = envctrl_read, | 718 | .read = envctrl_read, |
720 | .ioctl = envctrl_ioctl, | 719 | .unlocked_ioctl = envctrl_ioctl, |
721 | .open = envctrl_open, | 720 | #ifdef CONFIG_COMPAT |
722 | .release = envctrl_release, | 721 | .compat_ioctl = envctrl_ioctl, |
722 | #endif | ||
723 | .open = envctrl_open, | ||
724 | .release = envctrl_release, | ||
723 | }; | 725 | }; |
724 | 726 | ||
725 | static struct miscdevice envctrl_dev = { | 727 | static struct miscdevice envctrl_dev = { |
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index 58ed33749571..5028ac214326 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
41 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
42 | #include <linux/smp_lock.h> | ||
42 | #include <linux/init.h> | 43 | #include <linux/init.h> |
43 | #include <linux/fs.h> | 44 | #include <linux/fs.h> |
44 | #include <asm/oplib.h> | 45 | #include <asm/oplib.h> |
@@ -565,6 +566,38 @@ static int openprom_ioctl(struct inode * inode, struct file * file, | |||
565 | } | 566 | } |
566 | } | 567 | } |
567 | 568 | ||
569 | static long openprom_compat_ioctl(struct file *file, unsigned int cmd, | ||
570 | unsigned long arg) | ||
571 | { | ||
572 | long rval = -ENOTTY; | ||
573 | |||
574 | /* | ||
575 | * SunOS/Solaris only, the NetBSD one's have embedded pointers in | ||
576 | * the arg which we'd need to clean up... | ||
577 | */ | ||
578 | switch (cmd) { | ||
579 | case OPROMGETOPT: | ||
580 | case OPROMSETOPT: | ||
581 | case OPROMNXTOPT: | ||
582 | case OPROMSETOPT2: | ||
583 | case OPROMNEXT: | ||
584 | case OPROMCHILD: | ||
585 | case OPROMGETPROP: | ||
586 | case OPROMNXTPROP: | ||
587 | case OPROMU2P: | ||
588 | case OPROMGETCONS: | ||
589 | case OPROMGETFBNAME: | ||
590 | case OPROMGETBOOTARGS: | ||
591 | case OPROMSETCUR: | ||
592 | case OPROMPCI2NODE: | ||
593 | case OPROMPATH2NODE: | ||
594 | lock_kernel(); | ||
595 | rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg); | ||
596 | lock_kernel(); | ||
597 | break; | ||
598 | } | ||
599 | } | ||
600 | |||
568 | static int openprom_open(struct inode * inode, struct file * file) | 601 | static int openprom_open(struct inode * inode, struct file * file) |
569 | { | 602 | { |
570 | DATA *data; | 603 | DATA *data; |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 656c0e8d160e..f0738533f39a 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1441,7 +1441,7 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1441 | * - initialize the serial port | 1441 | * - initialize the serial port |
1442 | * Return non-zero if we didn't find a serial port. | 1442 | * Return non-zero if we didn't find a serial port. |
1443 | */ | 1443 | */ |
1444 | static int __init sunsu_console_setup(struct console *co, char *options) | 1444 | static int sunsu_console_setup(struct console *co, char *options) |
1445 | { | 1445 | { |
1446 | struct uart_port *port; | 1446 | struct uart_port *port; |
1447 | int baud = 9600; | 1447 | int baud = 9600; |
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 3280bb9560e2..414c4409e924 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c | |||
@@ -653,12 +653,6 @@ static void cg6_chip_init(struct fb_info *info) | |||
653 | sbus_writel(0, &fbc->clipminy); | 653 | sbus_writel(0, &fbc->clipminy); |
654 | sbus_writel(info->var.xres - 1, &fbc->clipmaxx); | 654 | sbus_writel(info->var.xres - 1, &fbc->clipmaxx); |
655 | sbus_writel(info->var.yres - 1, &fbc->clipmaxy); | 655 | sbus_writel(info->var.yres - 1, &fbc->clipmaxy); |
656 | |||
657 | /* Disable cursor in Brooktree DAC. */ | ||
658 | sbus_writel(0x06 << 24, &par->bt->addr); | ||
659 | tmp = sbus_readl(&par->bt->control); | ||
660 | tmp &= ~(0x03 << 24); | ||
661 | sbus_writel(tmp, &par->bt->control); | ||
662 | } | 656 | } |
663 | 657 | ||
664 | struct all_info { | 658 | struct all_info { |
diff --git a/include/asm-m68k/kbio.h b/include/asm-m68k/kbio.h deleted file mode 100644 index e1fbf8fba3e8..000000000000 --- a/include/asm-m68k/kbio.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-sparc/kbio.h> | ||
diff --git a/include/asm-m68k/vuid_event.h b/include/asm-m68k/vuid_event.h deleted file mode 100644 index 52ecb521a395..000000000000 --- a/include/asm-m68k/vuid_event.h +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | #ifndef _M68K_VUID_EVENT_H | ||
2 | #define _M68K_VUID_EVENT_H | ||
3 | #include <asm-sparc/vuid_event.h> | ||
4 | #endif | ||
diff --git a/include/asm-sparc/audioio.h b/include/asm-sparc/audioio.h deleted file mode 100644 index cf16173f521b..000000000000 --- a/include/asm-sparc/audioio.h +++ /dev/null | |||
@@ -1,234 +0,0 @@ | |||
1 | /* | ||
2 | * include/asm-sparc/audioio.h | ||
3 | * | ||
4 | * Sparc Audio Midlayer | ||
5 | * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) | ||
6 | */ | ||
7 | |||
8 | #ifndef _AUDIOIO_H_ | ||
9 | #define _AUDIOIO_H_ | ||
10 | |||
11 | /* | ||
12 | * SunOS/Solaris /dev/audio interface | ||
13 | */ | ||
14 | |||
15 | #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/time.h> | ||
18 | #include <linux/ioctl.h> | ||
19 | #endif | ||
20 | |||
21 | /* | ||
22 | * This structure contains state information for audio device IO streams. | ||
23 | */ | ||
24 | typedef struct audio_prinfo { | ||
25 | /* | ||
26 | * The following values describe the audio data encoding. | ||
27 | */ | ||
28 | unsigned int sample_rate; /* samples per second */ | ||
29 | unsigned int channels; /* number of interleaved channels */ | ||
30 | unsigned int precision; /* bit-width of each sample */ | ||
31 | unsigned int encoding; /* data encoding method */ | ||
32 | |||
33 | /* | ||
34 | * The following values control audio device configuration | ||
35 | */ | ||
36 | unsigned int gain; /* gain level: 0 - 255 */ | ||
37 | unsigned int port; /* selected I/O port (see below) */ | ||
38 | unsigned int avail_ports; /* available I/O ports (see below) */ | ||
39 | unsigned int _xxx[2]; /* Reserved for future use */ | ||
40 | |||
41 | unsigned int buffer_size; /* I/O buffer size */ | ||
42 | |||
43 | /* | ||
44 | * The following values describe driver state | ||
45 | */ | ||
46 | unsigned int samples; /* number of samples converted */ | ||
47 | unsigned int eof; /* End Of File counter (play only) */ | ||
48 | |||
49 | unsigned char pause; /* non-zero for pause, zero to resume */ | ||
50 | unsigned char error; /* non-zero if overflow/underflow */ | ||
51 | unsigned char waiting; /* non-zero if a process wants access */ | ||
52 | unsigned char balance; /* stereo channel balance */ | ||
53 | |||
54 | unsigned short minordev; | ||
55 | |||
56 | /* | ||
57 | * The following values are read-only state flags | ||
58 | */ | ||
59 | unsigned char open; /* non-zero if open access permitted */ | ||
60 | unsigned char active; /* non-zero if I/O is active */ | ||
61 | } audio_prinfo_t; | ||
62 | |||
63 | |||
64 | /* | ||
65 | * This structure describes the current state of the audio device. | ||
66 | */ | ||
67 | typedef struct audio_info { | ||
68 | /* | ||
69 | * Per-stream information | ||
70 | */ | ||
71 | audio_prinfo_t play; /* output status information */ | ||
72 | audio_prinfo_t record; /* input status information */ | ||
73 | |||
74 | /* | ||
75 | * Per-unit/channel information | ||
76 | */ | ||
77 | unsigned int monitor_gain; /* input to output mix: 0 - 255 */ | ||
78 | unsigned char output_muted; /* non-zero if output is muted */ | ||
79 | unsigned char _xxx[3]; /* Reserved for future use */ | ||
80 | unsigned int _yyy[3]; /* Reserved for future use */ | ||
81 | } audio_info_t; | ||
82 | |||
83 | |||
84 | /* | ||
85 | * Audio encoding types | ||
86 | */ | ||
87 | #define AUDIO_ENCODING_NONE (0) /* no encoding assigned */ | ||
88 | #define AUDIO_ENCODING_ULAW (1) /* u-law encoding */ | ||
89 | #define AUDIO_ENCODING_ALAW (2) /* A-law encoding */ | ||
90 | #define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */ | ||
91 | #define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */ | ||
92 | #define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */ | ||
93 | #define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */ | ||
94 | #define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */ | ||
95 | |||
96 | /* | ||
97 | * These ranges apply to record, play, and monitor gain values | ||
98 | */ | ||
99 | #define AUDIO_MIN_GAIN (0) /* minimum gain value */ | ||
100 | #define AUDIO_MAX_GAIN (255) /* maximum gain value */ | ||
101 | |||
102 | /* | ||
103 | * These values apply to the balance field to adjust channel gain values | ||
104 | */ | ||
105 | #define AUDIO_LEFT_BALANCE (0) /* left channel only */ | ||
106 | #define AUDIO_MID_BALANCE (32) /* equal left/right channel */ | ||
107 | #define AUDIO_RIGHT_BALANCE (64) /* right channel only */ | ||
108 | #define AUDIO_BALANCE_SHIFT (3) | ||
109 | |||
110 | /* | ||
111 | * Generic minimum/maximum limits for number of channels, both modes | ||
112 | */ | ||
113 | #define AUDIO_MIN_PLAY_CHANNELS (1) | ||
114 | #define AUDIO_MAX_PLAY_CHANNELS (4) | ||
115 | #define AUDIO_MIN_REC_CHANNELS (1) | ||
116 | #define AUDIO_MAX_REC_CHANNELS (4) | ||
117 | |||
118 | /* | ||
119 | * Generic minimum/maximum limits for sample precision | ||
120 | */ | ||
121 | #define AUDIO_MIN_PLAY_PRECISION (8) | ||
122 | #define AUDIO_MAX_PLAY_PRECISION (32) | ||
123 | #define AUDIO_MIN_REC_PRECISION (8) | ||
124 | #define AUDIO_MAX_REC_PRECISION (32) | ||
125 | |||
126 | /* | ||
127 | * Define some convenient names for typical audio ports | ||
128 | */ | ||
129 | /* | ||
130 | * output ports (several may be enabled simultaneously) | ||
131 | */ | ||
132 | #define AUDIO_SPEAKER 0x01 /* output to built-in speaker */ | ||
133 | #define AUDIO_HEADPHONE 0x02 /* output to headphone jack */ | ||
134 | #define AUDIO_LINE_OUT 0x04 /* output to line out */ | ||
135 | |||
136 | /* | ||
137 | * input ports (usually only one at a time) | ||
138 | */ | ||
139 | #define AUDIO_MICROPHONE 0x01 /* input from microphone */ | ||
140 | #define AUDIO_LINE_IN 0x02 /* input from line in */ | ||
141 | #define AUDIO_CD 0x04 /* input from on-board CD inputs */ | ||
142 | #define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */ | ||
143 | #define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */ | ||
144 | |||
145 | |||
146 | /* | ||
147 | * This macro initializes an audio_info structure to 'harmless' values. | ||
148 | * Note that (~0) might not be a harmless value for a flag that was | ||
149 | * a signed int. | ||
150 | */ | ||
151 | #define AUDIO_INITINFO(i) { \ | ||
152 | unsigned int *__x__; \ | ||
153 | for (__x__ = (unsigned int *)(i); \ | ||
154 | (char *) __x__ < (((char *)(i)) + sizeof (audio_info_t)); \ | ||
155 | *__x__++ = ~0); \ | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * These allow testing for what the user wants to set | ||
160 | */ | ||
161 | #define AUD_INITVALUE (~0) | ||
162 | #define Modify(X) ((unsigned int)(X) != AUD_INITVALUE) | ||
163 | #define Modifys(X) ((X) != (unsigned short)AUD_INITVALUE) | ||
164 | #define Modifyc(X) ((X) != (unsigned char)AUD_INITVALUE) | ||
165 | |||
166 | /* | ||
167 | * Parameter for the AUDIO_GETDEV ioctl to determine current | ||
168 | * audio devices. | ||
169 | */ | ||
170 | #define MAX_AUDIO_DEV_LEN (16) | ||
171 | typedef struct audio_device { | ||
172 | char name[MAX_AUDIO_DEV_LEN]; | ||
173 | char version[MAX_AUDIO_DEV_LEN]; | ||
174 | char config[MAX_AUDIO_DEV_LEN]; | ||
175 | } audio_device_t; | ||
176 | |||
177 | |||
178 | /* | ||
179 | * Ioctl calls for the audio device. | ||
180 | */ | ||
181 | |||
182 | /* | ||
183 | * AUDIO_GETINFO retrieves the current state of the audio device. | ||
184 | * | ||
185 | * AUDIO_SETINFO copies all fields of the audio_info structure whose | ||
186 | * values are not set to the initialized value (-1) to the device state. | ||
187 | * It performs an implicit AUDIO_GETINFO to return the new state of the | ||
188 | * device. Note that the record.samples and play.samples fields are set | ||
189 | * to the last value before the AUDIO_SETINFO took effect. This allows | ||
190 | * an application to reset the counters while atomically retrieving the | ||
191 | * last value. | ||
192 | * | ||
193 | * AUDIO_DRAIN suspends the calling process until the write buffers are | ||
194 | * empty. | ||
195 | * | ||
196 | * AUDIO_GETDEV returns a structure of type audio_device_t which contains | ||
197 | * three strings. The string "name" is a short identifying string (for | ||
198 | * example, the SBus Fcode name string), the string "version" identifies | ||
199 | * the current version of the device, and the "config" string identifies | ||
200 | * the specific configuration of the audio stream. All fields are | ||
201 | * device-dependent -- see the device specific manual pages for details. | ||
202 | * | ||
203 | * AUDIO_GETDEV_SUNOS returns a number which is an audio device defined | ||
204 | * herein (making it not too portable) | ||
205 | * | ||
206 | * AUDIO_FLUSH stops all playback and recording, clears all queued buffers, | ||
207 | * resets error counters, and restarts recording and playback as appropriate | ||
208 | * for the current sampling mode. | ||
209 | */ | ||
210 | #define AUDIO_GETINFO _IOR('A', 1, audio_info_t) | ||
211 | #define AUDIO_SETINFO _IOWR('A', 2, audio_info_t) | ||
212 | #define AUDIO_DRAIN _IO('A', 3) | ||
213 | #define AUDIO_GETDEV _IOR('A', 4, audio_device_t) | ||
214 | #define AUDIO_GETDEV_SUNOS _IOR('A', 4, int) | ||
215 | #define AUDIO_FLUSH _IO('A', 5) | ||
216 | |||
217 | /* Define possible audio hardware configurations for | ||
218 | * old SunOS-style AUDIO_GETDEV ioctl */ | ||
219 | #define AUDIO_DEV_UNKNOWN (0) /* not defined */ | ||
220 | #define AUDIO_DEV_AMD (1) /* audioamd device */ | ||
221 | #define AUDIO_DEV_SPEAKERBOX (2) /* dbri device with speakerbox */ | ||
222 | #define AUDIO_DEV_CODEC (3) /* dbri device (internal speaker) */ | ||
223 | #define AUDIO_DEV_CS4231 (5) /* cs4231 device */ | ||
224 | |||
225 | /* | ||
226 | * The following ioctl sets the audio device into an internal loopback mode, | ||
227 | * if the hardware supports this. The argument is TRUE to set loopback, | ||
228 | * FALSE to reset to normal operation. If the hardware does not support | ||
229 | * internal loopback, the ioctl should fail with EINVAL. | ||
230 | * Causes ADC data to be digitally mixed in and sent to the DAC. | ||
231 | */ | ||
232 | #define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int) | ||
233 | |||
234 | #endif /* _AUDIOIO_H_ */ | ||
diff --git a/include/asm-sparc/kbio.h b/include/asm-sparc/kbio.h deleted file mode 100644 index 3cf496bdf399..000000000000 --- a/include/asm-sparc/kbio.h +++ /dev/null | |||
@@ -1,56 +0,0 @@ | |||
1 | #ifndef __LINUX_KBIO_H | ||
2 | #define __LINUX_KBIO_H | ||
3 | |||
4 | /* Return keyboard type */ | ||
5 | #define KIOCTYPE _IOR('k', 9, int) | ||
6 | /* Return Keyboard layout */ | ||
7 | #define KIOCLAYOUT _IOR('k', 20, int) | ||
8 | |||
9 | enum { | ||
10 | TR_NONE, | ||
11 | TR_ASCII, /* keyboard is in regular state */ | ||
12 | TR_EVENT, /* keystrokes sent as firm events */ | ||
13 | TR_UNTRANS_EVENT /* EVENT+up and down+no translation */ | ||
14 | }; | ||
15 | |||
16 | /* Return the current keyboard translation */ | ||
17 | #define KIOCGTRANS _IOR('k', 5, int) | ||
18 | /* Set the keyboard translation */ | ||
19 | #define KIOCTRANS _IOW('k', 0, int) | ||
20 | |||
21 | /* Send a keyboard command */ | ||
22 | #define KIOCCMD _IOW('k', 8, int) | ||
23 | |||
24 | /* Return if keystrokes are being sent to /dev/kbd */ | ||
25 | |||
26 | /* Set routing of keystrokes to /dev/kbd */ | ||
27 | #define KIOCSDIRECT _IOW('k', 10, int) | ||
28 | |||
29 | /* Set keyboard leds */ | ||
30 | #define KIOCSLED _IOW('k', 14, unsigned char) | ||
31 | |||
32 | /* Get keyboard leds */ | ||
33 | #define KIOCGLED _IOR('k', 15, unsigned char) | ||
34 | |||
35 | /* Used by KIOC[GS]RATE */ | ||
36 | struct kbd_rate { | ||
37 | unsigned char delay; /* Delay in Hz before first repeat. */ | ||
38 | unsigned char rate; /* In characters per second (0..50). */ | ||
39 | }; | ||
40 | |||
41 | /* Set keyboard rate */ | ||
42 | #define KIOCSRATE _IOW('k', 40, struct kbd_rate) | ||
43 | |||
44 | /* Get keyboard rate */ | ||
45 | #define KIOCGRATE _IOW('k', 41, struct kbd_rate) | ||
46 | |||
47 | /* Top bit records if the key is up or down */ | ||
48 | #define KBD_UP 0x80 | ||
49 | |||
50 | /* Usable information */ | ||
51 | #define KBD_KEYMASK 0x7f | ||
52 | |||
53 | /* All keys up */ | ||
54 | #define KBD_IDLE 0x75 | ||
55 | |||
56 | #endif /* __LINUX_KBIO_H */ | ||
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h index 0a8ad4cac125..d05f83c80989 100644 --- a/include/asm-sparc/termios.h +++ b/include/asm-sparc/termios.h | |||
@@ -38,15 +38,6 @@ struct sunos_ttysize { | |||
38 | int st_columns; /* Columns on the terminal */ | 38 | int st_columns; /* Columns on the terminal */ |
39 | }; | 39 | }; |
40 | 40 | ||
41 | /* Used for packet mode */ | ||
42 | #define TIOCPKT_DATA 0 | ||
43 | #define TIOCPKT_FLUSHREAD 1 | ||
44 | #define TIOCPKT_FLUSHWRITE 2 | ||
45 | #define TIOCPKT_STOP 4 | ||
46 | #define TIOCPKT_START 8 | ||
47 | #define TIOCPKT_NOSTOP 16 | ||
48 | #define TIOCPKT_DOSTOP 32 | ||
49 | |||
50 | struct winsize { | 41 | struct winsize { |
51 | unsigned short ws_row; | 42 | unsigned short ws_row; |
52 | unsigned short ws_col; | 43 | unsigned short ws_col; |
diff --git a/include/asm-sparc/vuid_event.h b/include/asm-sparc/vuid_event.h deleted file mode 100644 index 7781e9f2fdd3..000000000000 --- a/include/asm-sparc/vuid_event.h +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* SunOS Virtual User Input Device (VUID) compatibility */ | ||
2 | |||
3 | |||
4 | typedef struct firm_event { | ||
5 | unsigned short id; /* tag for this event */ | ||
6 | unsigned char pair_type; /* unused by X11 */ | ||
7 | unsigned char pair; /* unused by X11 */ | ||
8 | int value; /* VKEY_UP, VKEY_DOWN or delta */ | ||
9 | struct timeval time; | ||
10 | } Firm_event; | ||
11 | |||
12 | enum { | ||
13 | FE_PAIR_NONE, | ||
14 | FE_PAIR_SET, | ||
15 | FE_PAIR_DELTA, | ||
16 | FE_PAIR_ABSOLUTE | ||
17 | }; | ||
18 | |||
19 | /* VUID stream formats */ | ||
20 | #define VUID_NATIVE 0 /* Native byte stream format */ | ||
21 | #define VUID_FIRM_EVENT 1 /* send firm_event structures */ | ||
22 | |||
23 | /* ioctls */ | ||
24 | /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */ | ||
25 | #define VUIDSFORMAT _IOW('v', 1, int) | ||
26 | /* Retrieve input device byte stream format */ | ||
27 | #define VUIDGFORMAT _IOR('v', 2, int) | ||
28 | |||
29 | /* Possible tag values */ | ||
30 | /* mouse buttons: */ | ||
31 | #define MS_LEFT 0x7f20 | ||
32 | #define MS_MIDDLE 0x7f21 | ||
33 | #define MS_RIGHT 0x7f22 | ||
34 | /* motion: */ | ||
35 | #define LOC_X_DELTA 0x7f80 | ||
36 | #define LOC_Y_DELTA 0x7f81 | ||
37 | #define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */ | ||
38 | #define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */ | ||
39 | |||
40 | #define VKEY_UP 0 | ||
41 | #define VKEY_DOWN 1 | ||
diff --git a/include/asm-sparc64/audioio.h b/include/asm-sparc64/audioio.h deleted file mode 100644 index cf16173f521b..000000000000 --- a/include/asm-sparc64/audioio.h +++ /dev/null | |||
@@ -1,234 +0,0 @@ | |||
1 | /* | ||
2 | * include/asm-sparc/audioio.h | ||
3 | * | ||
4 | * Sparc Audio Midlayer | ||
5 | * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) | ||
6 | */ | ||
7 | |||
8 | #ifndef _AUDIOIO_H_ | ||
9 | #define _AUDIOIO_H_ | ||
10 | |||
11 | /* | ||
12 | * SunOS/Solaris /dev/audio interface | ||
13 | */ | ||
14 | |||
15 | #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/time.h> | ||
18 | #include <linux/ioctl.h> | ||
19 | #endif | ||
20 | |||
21 | /* | ||
22 | * This structure contains state information for audio device IO streams. | ||
23 | */ | ||
24 | typedef struct audio_prinfo { | ||
25 | /* | ||
26 | * The following values describe the audio data encoding. | ||
27 | */ | ||
28 | unsigned int sample_rate; /* samples per second */ | ||
29 | unsigned int channels; /* number of interleaved channels */ | ||
30 | unsigned int precision; /* bit-width of each sample */ | ||
31 | unsigned int encoding; /* data encoding method */ | ||
32 | |||
33 | /* | ||
34 | * The following values control audio device configuration | ||
35 | */ | ||
36 | unsigned int gain; /* gain level: 0 - 255 */ | ||
37 | unsigned int port; /* selected I/O port (see below) */ | ||
38 | unsigned int avail_ports; /* available I/O ports (see below) */ | ||
39 | unsigned int _xxx[2]; /* Reserved for future use */ | ||
40 | |||
41 | unsigned int buffer_size; /* I/O buffer size */ | ||
42 | |||
43 | /* | ||
44 | * The following values describe driver state | ||
45 | */ | ||
46 | unsigned int samples; /* number of samples converted */ | ||
47 | unsigned int eof; /* End Of File counter (play only) */ | ||
48 | |||
49 | unsigned char pause; /* non-zero for pause, zero to resume */ | ||
50 | unsigned char error; /* non-zero if overflow/underflow */ | ||
51 | unsigned char waiting; /* non-zero if a process wants access */ | ||
52 | unsigned char balance; /* stereo channel balance */ | ||
53 | |||
54 | unsigned short minordev; | ||
55 | |||
56 | /* | ||
57 | * The following values are read-only state flags | ||
58 | */ | ||
59 | unsigned char open; /* non-zero if open access permitted */ | ||
60 | unsigned char active; /* non-zero if I/O is active */ | ||
61 | } audio_prinfo_t; | ||
62 | |||
63 | |||
64 | /* | ||
65 | * This structure describes the current state of the audio device. | ||
66 | */ | ||
67 | typedef struct audio_info { | ||
68 | /* | ||
69 | * Per-stream information | ||
70 | */ | ||
71 | audio_prinfo_t play; /* output status information */ | ||
72 | audio_prinfo_t record; /* input status information */ | ||
73 | |||
74 | /* | ||
75 | * Per-unit/channel information | ||
76 | */ | ||
77 | unsigned int monitor_gain; /* input to output mix: 0 - 255 */ | ||
78 | unsigned char output_muted; /* non-zero if output is muted */ | ||
79 | unsigned char _xxx[3]; /* Reserved for future use */ | ||
80 | unsigned int _yyy[3]; /* Reserved for future use */ | ||
81 | } audio_info_t; | ||
82 | |||
83 | |||
84 | /* | ||
85 | * Audio encoding types | ||
86 | */ | ||
87 | #define AUDIO_ENCODING_NONE (0) /* no encoding assigned */ | ||
88 | #define AUDIO_ENCODING_ULAW (1) /* u-law encoding */ | ||
89 | #define AUDIO_ENCODING_ALAW (2) /* A-law encoding */ | ||
90 | #define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */ | ||
91 | #define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */ | ||
92 | #define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */ | ||
93 | #define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */ | ||
94 | #define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */ | ||
95 | |||
96 | /* | ||
97 | * These ranges apply to record, play, and monitor gain values | ||
98 | */ | ||
99 | #define AUDIO_MIN_GAIN (0) /* minimum gain value */ | ||
100 | #define AUDIO_MAX_GAIN (255) /* maximum gain value */ | ||
101 | |||
102 | /* | ||
103 | * These values apply to the balance field to adjust channel gain values | ||
104 | */ | ||
105 | #define AUDIO_LEFT_BALANCE (0) /* left channel only */ | ||
106 | #define AUDIO_MID_BALANCE (32) /* equal left/right channel */ | ||
107 | #define AUDIO_RIGHT_BALANCE (64) /* right channel only */ | ||
108 | #define AUDIO_BALANCE_SHIFT (3) | ||
109 | |||
110 | /* | ||
111 | * Generic minimum/maximum limits for number of channels, both modes | ||
112 | */ | ||
113 | #define AUDIO_MIN_PLAY_CHANNELS (1) | ||
114 | #define AUDIO_MAX_PLAY_CHANNELS (4) | ||
115 | #define AUDIO_MIN_REC_CHANNELS (1) | ||
116 | #define AUDIO_MAX_REC_CHANNELS (4) | ||
117 | |||
118 | /* | ||
119 | * Generic minimum/maximum limits for sample precision | ||
120 | */ | ||
121 | #define AUDIO_MIN_PLAY_PRECISION (8) | ||
122 | #define AUDIO_MAX_PLAY_PRECISION (32) | ||
123 | #define AUDIO_MIN_REC_PRECISION (8) | ||
124 | #define AUDIO_MAX_REC_PRECISION (32) | ||
125 | |||
126 | /* | ||
127 | * Define some convenient names for typical audio ports | ||
128 | */ | ||
129 | /* | ||
130 | * output ports (several may be enabled simultaneously) | ||
131 | */ | ||
132 | #define AUDIO_SPEAKER 0x01 /* output to built-in speaker */ | ||
133 | #define AUDIO_HEADPHONE 0x02 /* output to headphone jack */ | ||
134 | #define AUDIO_LINE_OUT 0x04 /* output to line out */ | ||
135 | |||
136 | /* | ||
137 | * input ports (usually only one at a time) | ||
138 | */ | ||
139 | #define AUDIO_MICROPHONE 0x01 /* input from microphone */ | ||
140 | #define AUDIO_LINE_IN 0x02 /* input from line in */ | ||
141 | #define AUDIO_CD 0x04 /* input from on-board CD inputs */ | ||
142 | #define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */ | ||
143 | #define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */ | ||
144 | |||
145 | |||
146 | /* | ||
147 | * This macro initializes an audio_info structure to 'harmless' values. | ||
148 | * Note that (~0) might not be a harmless value for a flag that was | ||
149 | * a signed int. | ||
150 | */ | ||
151 | #define AUDIO_INITINFO(i) { \ | ||
152 | unsigned int *__x__; \ | ||
153 | for (__x__ = (unsigned int *)(i); \ | ||
154 | (char *) __x__ < (((char *)(i)) + sizeof (audio_info_t)); \ | ||
155 | *__x__++ = ~0); \ | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * These allow testing for what the user wants to set | ||
160 | */ | ||
161 | #define AUD_INITVALUE (~0) | ||
162 | #define Modify(X) ((unsigned int)(X) != AUD_INITVALUE) | ||
163 | #define Modifys(X) ((X) != (unsigned short)AUD_INITVALUE) | ||
164 | #define Modifyc(X) ((X) != (unsigned char)AUD_INITVALUE) | ||
165 | |||
166 | /* | ||
167 | * Parameter for the AUDIO_GETDEV ioctl to determine current | ||
168 | * audio devices. | ||
169 | */ | ||
170 | #define MAX_AUDIO_DEV_LEN (16) | ||
171 | typedef struct audio_device { | ||
172 | char name[MAX_AUDIO_DEV_LEN]; | ||
173 | char version[MAX_AUDIO_DEV_LEN]; | ||
174 | char config[MAX_AUDIO_DEV_LEN]; | ||
175 | } audio_device_t; | ||
176 | |||
177 | |||
178 | /* | ||
179 | * Ioctl calls for the audio device. | ||
180 | */ | ||
181 | |||
182 | /* | ||
183 | * AUDIO_GETINFO retrieves the current state of the audio device. | ||
184 | * | ||
185 | * AUDIO_SETINFO copies all fields of the audio_info structure whose | ||
186 | * values are not set to the initialized value (-1) to the device state. | ||
187 | * It performs an implicit AUDIO_GETINFO to return the new state of the | ||
188 | * device. Note that the record.samples and play.samples fields are set | ||
189 | * to the last value before the AUDIO_SETINFO took effect. This allows | ||
190 | * an application to reset the counters while atomically retrieving the | ||
191 | * last value. | ||
192 | * | ||
193 | * AUDIO_DRAIN suspends the calling process until the write buffers are | ||
194 | * empty. | ||
195 | * | ||
196 | * AUDIO_GETDEV returns a structure of type audio_device_t which contains | ||
197 | * three strings. The string "name" is a short identifying string (for | ||
198 | * example, the SBus Fcode name string), the string "version" identifies | ||
199 | * the current version of the device, and the "config" string identifies | ||
200 | * the specific configuration of the audio stream. All fields are | ||
201 | * device-dependent -- see the device specific manual pages for details. | ||
202 | * | ||
203 | * AUDIO_GETDEV_SUNOS returns a number which is an audio device defined | ||
204 | * herein (making it not too portable) | ||
205 | * | ||
206 | * AUDIO_FLUSH stops all playback and recording, clears all queued buffers, | ||
207 | * resets error counters, and restarts recording and playback as appropriate | ||
208 | * for the current sampling mode. | ||
209 | */ | ||
210 | #define AUDIO_GETINFO _IOR('A', 1, audio_info_t) | ||
211 | #define AUDIO_SETINFO _IOWR('A', 2, audio_info_t) | ||
212 | #define AUDIO_DRAIN _IO('A', 3) | ||
213 | #define AUDIO_GETDEV _IOR('A', 4, audio_device_t) | ||
214 | #define AUDIO_GETDEV_SUNOS _IOR('A', 4, int) | ||
215 | #define AUDIO_FLUSH _IO('A', 5) | ||
216 | |||
217 | /* Define possible audio hardware configurations for | ||
218 | * old SunOS-style AUDIO_GETDEV ioctl */ | ||
219 | #define AUDIO_DEV_UNKNOWN (0) /* not defined */ | ||
220 | #define AUDIO_DEV_AMD (1) /* audioamd device */ | ||
221 | #define AUDIO_DEV_SPEAKERBOX (2) /* dbri device with speakerbox */ | ||
222 | #define AUDIO_DEV_CODEC (3) /* dbri device (internal speaker) */ | ||
223 | #define AUDIO_DEV_CS4231 (5) /* cs4231 device */ | ||
224 | |||
225 | /* | ||
226 | * The following ioctl sets the audio device into an internal loopback mode, | ||
227 | * if the hardware supports this. The argument is TRUE to set loopback, | ||
228 | * FALSE to reset to normal operation. If the hardware does not support | ||
229 | * internal loopback, the ioctl should fail with EINVAL. | ||
230 | * Causes ADC data to be digitally mixed in and sent to the DAC. | ||
231 | */ | ||
232 | #define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int) | ||
233 | |||
234 | #endif /* _AUDIOIO_H_ */ | ||
diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h index 543e4e500a72..7a408a030f52 100644 --- a/include/asm-sparc64/ebus.h +++ b/include/asm-sparc64/ebus.h | |||
@@ -79,6 +79,7 @@ extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, | |||
79 | size_t len); | 79 | size_t len); |
80 | extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); | 80 | extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); |
81 | extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); | 81 | extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); |
82 | extern unsigned int ebus_dma_addr(struct ebus_dma_info *p); | ||
82 | extern void ebus_dma_enable(struct ebus_dma_info *p, int on); | 83 | extern void ebus_dma_enable(struct ebus_dma_info *p, int on); |
83 | 84 | ||
84 | extern struct linux_ebus *ebus_chain; | 85 | extern struct linux_ebus *ebus_chain; |
diff --git a/include/asm-sparc64/kbio.h b/include/asm-sparc64/kbio.h deleted file mode 100644 index 3cf496bdf399..000000000000 --- a/include/asm-sparc64/kbio.h +++ /dev/null | |||
@@ -1,56 +0,0 @@ | |||
1 | #ifndef __LINUX_KBIO_H | ||
2 | #define __LINUX_KBIO_H | ||
3 | |||
4 | /* Return keyboard type */ | ||
5 | #define KIOCTYPE _IOR('k', 9, int) | ||
6 | /* Return Keyboard layout */ | ||
7 | #define KIOCLAYOUT _IOR('k', 20, int) | ||
8 | |||
9 | enum { | ||
10 | TR_NONE, | ||
11 | TR_ASCII, /* keyboard is in regular state */ | ||
12 | TR_EVENT, /* keystrokes sent as firm events */ | ||
13 | TR_UNTRANS_EVENT /* EVENT+up and down+no translation */ | ||
14 | }; | ||
15 | |||
16 | /* Return the current keyboard translation */ | ||
17 | #define KIOCGTRANS _IOR('k', 5, int) | ||
18 | /* Set the keyboard translation */ | ||
19 | #define KIOCTRANS _IOW('k', 0, int) | ||
20 | |||
21 | /* Send a keyboard command */ | ||
22 | #define KIOCCMD _IOW('k', 8, int) | ||
23 | |||
24 | /* Return if keystrokes are being sent to /dev/kbd */ | ||
25 | |||
26 | /* Set routing of keystrokes to /dev/kbd */ | ||
27 | #define KIOCSDIRECT _IOW('k', 10, int) | ||
28 | |||
29 | /* Set keyboard leds */ | ||
30 | #define KIOCSLED _IOW('k', 14, unsigned char) | ||
31 | |||
32 | /* Get keyboard leds */ | ||
33 | #define KIOCGLED _IOR('k', 15, unsigned char) | ||
34 | |||
35 | /* Used by KIOC[GS]RATE */ | ||
36 | struct kbd_rate { | ||
37 | unsigned char delay; /* Delay in Hz before first repeat. */ | ||
38 | unsigned char rate; /* In characters per second (0..50). */ | ||
39 | }; | ||
40 | |||
41 | /* Set keyboard rate */ | ||
42 | #define KIOCSRATE _IOW('k', 40, struct kbd_rate) | ||
43 | |||
44 | /* Get keyboard rate */ | ||
45 | #define KIOCGRATE _IOW('k', 41, struct kbd_rate) | ||
46 | |||
47 | /* Top bit records if the key is up or down */ | ||
48 | #define KBD_UP 0x80 | ||
49 | |||
50 | /* Usable information */ | ||
51 | #define KBD_KEYMASK 0x7f | ||
52 | |||
53 | /* All keys up */ | ||
54 | #define KBD_IDLE 0x75 | ||
55 | |||
56 | #endif /* __LINUX_KBIO_H */ | ||
diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h index 87c43c67866e..08ba72d7722c 100644 --- a/include/asm-sparc64/mmu_context.h +++ b/include/asm-sparc64/mmu_context.h | |||
@@ -87,37 +87,35 @@ extern void __flush_tlb_mm(unsigned long, unsigned long); | |||
87 | static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk) | 87 | static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk) |
88 | { | 88 | { |
89 | unsigned long ctx_valid; | 89 | unsigned long ctx_valid; |
90 | int cpu; | ||
90 | 91 | ||
92 | /* Note: page_table_lock is used here to serialize switch_mm | ||
93 | * and activate_mm, and their calls to get_new_mmu_context. | ||
94 | * This use of page_table_lock is unrelated to its other uses. | ||
95 | */ | ||
91 | spin_lock(&mm->page_table_lock); | 96 | spin_lock(&mm->page_table_lock); |
92 | if (CTX_VALID(mm->context)) | 97 | ctx_valid = CTX_VALID(mm->context); |
93 | ctx_valid = 1; | 98 | if (!ctx_valid) |
94 | else | 99 | get_new_mmu_context(mm); |
95 | ctx_valid = 0; | 100 | spin_unlock(&mm->page_table_lock); |
96 | 101 | ||
97 | if (!ctx_valid || (old_mm != mm)) { | 102 | if (!ctx_valid || (old_mm != mm)) { |
98 | if (!ctx_valid) | ||
99 | get_new_mmu_context(mm); | ||
100 | |||
101 | load_secondary_context(mm); | 103 | load_secondary_context(mm); |
102 | reload_tlbmiss_state(tsk, mm); | 104 | reload_tlbmiss_state(tsk, mm); |
103 | } | 105 | } |
104 | 106 | ||
105 | { | 107 | /* Even if (mm == old_mm) we _must_ check |
106 | int cpu = smp_processor_id(); | 108 | * the cpu_vm_mask. If we do not we could |
107 | 109 | * corrupt the TLB state because of how | |
108 | /* Even if (mm == old_mm) we _must_ check | 110 | * smp_flush_tlb_{page,range,mm} on sparc64 |
109 | * the cpu_vm_mask. If we do not we could | 111 | * and lazy tlb switches work. -DaveM |
110 | * corrupt the TLB state because of how | 112 | */ |
111 | * smp_flush_tlb_{page,range,mm} on sparc64 | 113 | cpu = smp_processor_id(); |
112 | * and lazy tlb switches work. -DaveM | 114 | if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) { |
113 | */ | 115 | cpu_set(cpu, mm->cpu_vm_mask); |
114 | if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) { | 116 | __flush_tlb_mm(CTX_HWBITS(mm->context), |
115 | cpu_set(cpu, mm->cpu_vm_mask); | 117 | SECONDARY_CONTEXT); |
116 | __flush_tlb_mm(CTX_HWBITS(mm->context), | ||
117 | SECONDARY_CONTEXT); | ||
118 | } | ||
119 | } | 118 | } |
120 | spin_unlock(&mm->page_table_lock); | ||
121 | } | 119 | } |
122 | 120 | ||
123 | #define deactivate_mm(tsk,mm) do { } while (0) | 121 | #define deactivate_mm(tsk,mm) do { } while (0) |
@@ -127,6 +125,10 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm | |||
127 | { | 125 | { |
128 | int cpu; | 126 | int cpu; |
129 | 127 | ||
128 | /* Note: page_table_lock is used here to serialize switch_mm | ||
129 | * and activate_mm, and their calls to get_new_mmu_context. | ||
130 | * This use of page_table_lock is unrelated to its other uses. | ||
131 | */ | ||
130 | spin_lock(&mm->page_table_lock); | 132 | spin_lock(&mm->page_table_lock); |
131 | if (!CTX_VALID(mm->context)) | 133 | if (!CTX_VALID(mm->context)) |
132 | get_new_mmu_context(mm); | 134 | get_new_mmu_context(mm); |
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h index 9777a9cca88a..ee26a071c677 100644 --- a/include/asm-sparc64/termios.h +++ b/include/asm-sparc64/termios.h | |||
@@ -38,15 +38,6 @@ struct sunos_ttysize { | |||
38 | int st_columns; /* Columns on the terminal */ | 38 | int st_columns; /* Columns on the terminal */ |
39 | }; | 39 | }; |
40 | 40 | ||
41 | /* Used for packet mode */ | ||
42 | #define TIOCPKT_DATA 0 | ||
43 | #define TIOCPKT_FLUSHREAD 1 | ||
44 | #define TIOCPKT_FLUSHWRITE 2 | ||
45 | #define TIOCPKT_STOP 4 | ||
46 | #define TIOCPKT_START 8 | ||
47 | #define TIOCPKT_NOSTOP 16 | ||
48 | #define TIOCPKT_DOSTOP 32 | ||
49 | |||
50 | struct winsize { | 41 | struct winsize { |
51 | unsigned short ws_row; | 42 | unsigned short ws_row; |
52 | unsigned short ws_col; | 43 | unsigned short ws_col; |
diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h index 66138d959df5..61c01882b562 100644 --- a/include/asm-sparc64/tlb.h +++ b/include/asm-sparc64/tlb.h | |||
@@ -58,11 +58,9 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned i | |||
58 | static inline void tlb_flush_mmu(struct mmu_gather *mp) | 58 | static inline void tlb_flush_mmu(struct mmu_gather *mp) |
59 | { | 59 | { |
60 | if (mp->need_flush) { | 60 | if (mp->need_flush) { |
61 | free_pages_and_swap_cache(mp->pages, mp->pages_nr); | ||
62 | mp->pages_nr = 0; | ||
61 | mp->need_flush = 0; | 63 | mp->need_flush = 0; |
62 | if (!tlb_fast_mode(mp)) { | ||
63 | free_pages_and_swap_cache(mp->pages, mp->pages_nr); | ||
64 | mp->pages_nr = 0; | ||
65 | } | ||
66 | } | 64 | } |
67 | 65 | ||
68 | } | 66 | } |
@@ -78,11 +76,9 @@ static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, un | |||
78 | { | 76 | { |
79 | tlb_flush_mmu(mp); | 77 | tlb_flush_mmu(mp); |
80 | 78 | ||
81 | if (mp->fullmm) { | 79 | if (mp->fullmm) |
82 | if (CTX_VALID(mp->mm->context)) | ||
83 | do_flush_tlb_mm(mp->mm); | ||
84 | mp->fullmm = 0; | 80 | mp->fullmm = 0; |
85 | } else | 81 | else |
86 | flush_tlb_pending(); | 82 | flush_tlb_pending(); |
87 | 83 | ||
88 | /* keep the page table cache within bounds */ | 84 | /* keep the page table cache within bounds */ |
@@ -93,11 +89,11 @@ static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, un | |||
93 | 89 | ||
94 | static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) | 90 | static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page) |
95 | { | 91 | { |
96 | mp->need_flush = 1; | ||
97 | if (tlb_fast_mode(mp)) { | 92 | if (tlb_fast_mode(mp)) { |
98 | free_page_and_swap_cache(page); | 93 | free_page_and_swap_cache(page); |
99 | return; | 94 | return; |
100 | } | 95 | } |
96 | mp->need_flush = 1; | ||
101 | mp->pages[mp->pages_nr++] = page; | 97 | mp->pages[mp->pages_nr++] = page; |
102 | if (mp->pages_nr >= FREE_PTE_NR) | 98 | if (mp->pages_nr >= FREE_PTE_NR) |
103 | tlb_flush_mmu(mp); | 99 | tlb_flush_mmu(mp); |
diff --git a/include/asm-sparc64/vuid_event.h b/include/asm-sparc64/vuid_event.h deleted file mode 100644 index 9ef4d17ad08f..000000000000 --- a/include/asm-sparc64/vuid_event.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* SunOS Virtual User Input Device (VUID) compatibility */ | ||
2 | |||
3 | typedef struct firm_event { | ||
4 | unsigned short id; /* tag for this event */ | ||
5 | unsigned char pair_type; /* unused by X11 */ | ||
6 | unsigned char pair; /* unused by X11 */ | ||
7 | int value; /* VKEY_UP, VKEY_DOWN or delta */ | ||
8 | struct timeval time; | ||
9 | } Firm_event; | ||
10 | |||
11 | enum { | ||
12 | FE_PAIR_NONE, | ||
13 | FE_PAIR_SET, | ||
14 | FE_PAIR_DELTA, | ||
15 | FE_PAIR_ABSOLUTE | ||
16 | }; | ||
17 | |||
18 | /* VUID stream formats */ | ||
19 | #define VUID_NATIVE 0 /* Native byte stream format */ | ||
20 | #define VUID_FIRM_EVENT 1 /* send firm_event structures */ | ||
21 | |||
22 | /* ioctls */ | ||
23 | /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */ | ||
24 | #define VUIDSFORMAT _IOW('v', 1, int) | ||
25 | /* Retrieve input device byte stream format */ | ||
26 | #define VUIDGFORMAT _IOR('v', 2, int) | ||
27 | |||
28 | /* Possible tag values */ | ||
29 | /* mouse buttons: */ | ||
30 | #define MS_LEFT 0x7f20 | ||
31 | #define MS_MIDDLE 0x7f21 | ||
32 | #define MS_RIGHT 0x7f22 | ||
33 | /* motion: */ | ||
34 | #define LOC_X_DELTA 0x7f80 | ||
35 | #define LOC_Y_DELTA 0x7f81 | ||
36 | #define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */ | ||
37 | #define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */ | ||
38 | |||
39 | #define VKEY_UP 0 | ||
40 | #define VKEY_DOWN 1 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index efac2c58ec7d..158710d22566 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -470,13 +470,6 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) | |||
470 | if (clone_flags & CLONE_VM) { | 470 | if (clone_flags & CLONE_VM) { |
471 | atomic_inc(&oldmm->mm_users); | 471 | atomic_inc(&oldmm->mm_users); |
472 | mm = oldmm; | 472 | mm = oldmm; |
473 | /* | ||
474 | * There are cases where the PTL is held to ensure no | ||
475 | * new threads start up in user mode using an mm, which | ||
476 | * allows optimizing out ipis; the tlb_gather_mmu code | ||
477 | * is an example. | ||
478 | */ | ||
479 | spin_unlock_wait(&oldmm->page_table_lock); | ||
480 | goto good_mm; | 473 | goto good_mm; |
481 | } | 474 | } |
482 | 475 | ||
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index f4361c518e46..1f8d27a6152e 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -61,13 +61,37 @@ MODULE_DESCRIPTION("Sun CS4231"); | |||
61 | MODULE_LICENSE("GPL"); | 61 | MODULE_LICENSE("GPL"); |
62 | MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); | 62 | MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); |
63 | 63 | ||
64 | typedef struct snd_cs4231 { | 64 | #ifdef SBUS_SUPPORT |
65 | spinlock_t lock; | 65 | typedef struct sbus_dma_info { |
66 | void __iomem *port; | 66 | spinlock_t lock; |
67 | int dir; | ||
68 | void __iomem *regs; | ||
69 | } sbus_dma_info_t; | ||
70 | #endif | ||
71 | |||
72 | typedef struct snd_cs4231 cs4231_t; | ||
73 | |||
74 | typedef struct cs4231_dma_control { | ||
75 | void (*prepare)(struct cs4231_dma_control *dma_cont, int dir); | ||
76 | void (*enable)(struct cs4231_dma_control *dma_cont, int on); | ||
77 | int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len); | ||
78 | unsigned int (*address)(struct cs4231_dma_control *dma_cont); | ||
79 | void (*reset)(cs4231_t *chip); | ||
80 | void (*preallocate)(cs4231_t *chip, snd_pcm_t *pcm); | ||
67 | #ifdef EBUS_SUPPORT | 81 | #ifdef EBUS_SUPPORT |
68 | struct ebus_dma_info eb2c; | 82 | struct ebus_dma_info ebus_info; |
69 | struct ebus_dma_info eb2p; | 83 | #endif |
84 | #ifdef SBUS_SUPPORT | ||
85 | struct sbus_dma_info sbus_info; | ||
70 | #endif | 86 | #endif |
87 | } cs4231_dma_control_t; | ||
88 | |||
89 | struct snd_cs4231 { | ||
90 | spinlock_t lock; | ||
91 | void __iomem *port; | ||
92 | |||
93 | cs4231_dma_control_t p_dma; | ||
94 | cs4231_dma_control_t c_dma; | ||
71 | 95 | ||
72 | u32 flags; | 96 | u32 flags; |
73 | #define CS4231_FLAG_EBUS 0x00000001 | 97 | #define CS4231_FLAG_EBUS 0x00000001 |
@@ -106,7 +130,7 @@ typedef struct snd_cs4231 { | |||
106 | unsigned int irq[2]; | 130 | unsigned int irq[2]; |
107 | unsigned int regs_size; | 131 | unsigned int regs_size; |
108 | struct snd_cs4231 *next; | 132 | struct snd_cs4231 *next; |
109 | } cs4231_t; | 133 | }; |
110 | 134 | ||
111 | static cs4231_t *cs4231_list; | 135 | static cs4231_t *cs4231_list; |
112 | 136 | ||
@@ -251,6 +275,15 @@ static cs4231_t *cs4231_list; | |||
251 | #define APCPNVA 0x38UL /* APC Play DMA Next Address */ | 275 | #define APCPNVA 0x38UL /* APC Play DMA Next Address */ |
252 | #define APCPNC 0x3cUL /* APC Play Next Count */ | 276 | #define APCPNC 0x3cUL /* APC Play Next Count */ |
253 | 277 | ||
278 | /* Defines for SBUS DMA-routines */ | ||
279 | |||
280 | #define APCVA 0x0UL /* APC DMA Address */ | ||
281 | #define APCC 0x4UL /* APC Count */ | ||
282 | #define APCNVA 0x8UL /* APC DMA Next Address */ | ||
283 | #define APCNC 0xcUL /* APC Next Count */ | ||
284 | #define APC_PLAY 0x30UL /* Play registers start at 0x30 */ | ||
285 | #define APC_RECORD 0x20UL /* Record registers start at 0x20 */ | ||
286 | |||
254 | /* APCCSR bits */ | 287 | /* APCCSR bits */ |
255 | 288 | ||
256 | #define APC_INT_PENDING 0x800000 /* Interrupt Pending */ | 289 | #define APC_INT_PENDING 0x800000 /* Interrupt Pending */ |
@@ -569,8 +602,7 @@ static void snd_cs4231_mce_down(cs4231_t *chip) | |||
569 | spin_unlock_irqrestore(&chip->lock, flags); | 602 | spin_unlock_irqrestore(&chip->lock, flags); |
570 | } | 603 | } |
571 | 604 | ||
572 | #ifdef EBUS_SUPPORT | 605 | static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, snd_pcm_substream_t *substream, unsigned int *periods_sent) |
573 | static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent) | ||
574 | { | 606 | { |
575 | snd_pcm_runtime_t *runtime = substream->runtime; | 607 | snd_pcm_runtime_t *runtime = substream->runtime; |
576 | 608 | ||
@@ -581,129 +613,41 @@ static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substre | |||
581 | if (period_size >= (1 << 24)) | 613 | if (period_size >= (1 << 24)) |
582 | BUG(); | 614 | BUG(); |
583 | 615 | ||
584 | if (ebus_dma_request(p, runtime->dma_addr + offset, period_size)) | 616 | if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size)) |
585 | return; | 617 | return; |
586 | (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; | 618 | (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; |
587 | } | 619 | } |
588 | } | 620 | } |
589 | #endif | ||
590 | |||
591 | #ifdef SBUS_SUPPORT | ||
592 | static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent) | ||
593 | { | ||
594 | cs4231_t *chip = snd_pcm_substream_chip(substream); | ||
595 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
596 | |||
597 | unsigned int period_size = snd_pcm_lib_period_bytes(substream); | ||
598 | unsigned int offset = period_size * (*periods_sent % runtime->periods); | ||
599 | |||
600 | if (runtime->period_size > 0xffff + 1) | ||
601 | BUG(); | ||
602 | |||
603 | switch (substream->stream) { | ||
604 | case SNDRV_PCM_STREAM_PLAYBACK: | ||
605 | sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA); | ||
606 | sbus_writel(period_size, chip->port + APCPNC); | ||
607 | break; | ||
608 | case SNDRV_PCM_STREAM_CAPTURE: | ||
609 | sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA); | ||
610 | sbus_writel(period_size, chip->port + APCCNC); | ||
611 | break; | ||
612 | } | ||
613 | |||
614 | (*periods_sent) = (*periods_sent + 1) % runtime->periods; | ||
615 | } | ||
616 | #endif | ||
617 | 621 | ||
618 | static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) | 622 | static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on) |
619 | { | 623 | { |
620 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 624 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
625 | cs4231_dma_control_t *dma_cont; | ||
621 | 626 | ||
622 | #ifdef EBUS_SUPPORT | 627 | if (what & CS4231_PLAYBACK_ENABLE) { |
623 | if (chip->flags & CS4231_FLAG_EBUS) { | 628 | dma_cont = &chip->p_dma; |
624 | if (what & CS4231_PLAYBACK_ENABLE) { | ||
625 | if (on) { | ||
626 | ebus_dma_prepare(&chip->eb2p, 0); | ||
627 | ebus_dma_enable(&chip->eb2p, 1); | ||
628 | snd_cs4231_ebus_advance_dma(&chip->eb2p, | ||
629 | chip->playback_substream, | ||
630 | &chip->p_periods_sent); | ||
631 | } else { | ||
632 | ebus_dma_enable(&chip->eb2p, 0); | ||
633 | } | ||
634 | } | ||
635 | if (what & CS4231_RECORD_ENABLE) { | ||
636 | if (on) { | ||
637 | ebus_dma_prepare(&chip->eb2c, 1); | ||
638 | ebus_dma_enable(&chip->eb2c, 1); | ||
639 | snd_cs4231_ebus_advance_dma(&chip->eb2c, | ||
640 | chip->capture_substream, | ||
641 | &chip->c_periods_sent); | ||
642 | } else { | ||
643 | ebus_dma_enable(&chip->eb2c, 0); | ||
644 | } | ||
645 | } | ||
646 | } else { | ||
647 | #endif | ||
648 | #ifdef SBUS_SUPPORT | ||
649 | u32 csr = sbus_readl(chip->port + APCCSR); | ||
650 | /* I don't know why, but on sbus the period counter must | ||
651 | * only start counting after the first period is sent. | ||
652 | * Therefore this dummy thing. | ||
653 | */ | ||
654 | unsigned int dummy = 0; | ||
655 | |||
656 | switch (what) { | ||
657 | case CS4231_PLAYBACK_ENABLE: | ||
658 | if (on) { | 629 | if (on) { |
659 | csr &= ~APC_XINT_PLAY; | 630 | dma_cont->prepare(dma_cont, 0); |
660 | sbus_writel(csr, chip->port + APCCSR); | 631 | dma_cont->enable(dma_cont, 1); |
661 | 632 | snd_cs4231_advance_dma(dma_cont, | |
662 | csr &= ~APC_PPAUSE; | 633 | chip->playback_substream, |
663 | sbus_writel(csr, chip->port + APCCSR); | 634 | &chip->p_periods_sent); |
664 | |||
665 | snd_cs4231_sbus_advance_dma(substream, &dummy); | ||
666 | |||
667 | csr |= APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA | | ||
668 | APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL | | ||
669 | APC_XINT_PENA | APC_PDMA_READY; | ||
670 | sbus_writel(csr, chip->port + APCCSR); | ||
671 | } else { | 635 | } else { |
672 | csr |= APC_PPAUSE; | 636 | dma_cont->enable(dma_cont, 0); |
673 | sbus_writel(csr, chip->port + APCCSR); | ||
674 | |||
675 | csr &= ~APC_PDMA_READY; | ||
676 | sbus_writel(csr, chip->port + APCCSR); | ||
677 | } | 637 | } |
678 | break; | 638 | } |
679 | case CS4231_RECORD_ENABLE: | 639 | if (what & CS4231_RECORD_ENABLE) { |
640 | dma_cont = &chip->c_dma; | ||
680 | if (on) { | 641 | if (on) { |
681 | csr &= ~APC_XINT_CAPT; | 642 | dma_cont->prepare(dma_cont, 1); |
682 | sbus_writel(csr, chip->port + APCCSR); | 643 | dma_cont->enable(dma_cont, 1); |
683 | 644 | snd_cs4231_advance_dma(dma_cont, | |
684 | csr &= ~APC_CPAUSE; | 645 | chip->capture_substream, |
685 | sbus_writel(csr, chip->port + APCCSR); | 646 | &chip->c_periods_sent); |
686 | |||
687 | snd_cs4231_sbus_advance_dma(substream, &dummy); | ||
688 | |||
689 | csr |= APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA | | ||
690 | APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL | | ||
691 | APC_CDMA_READY; | ||
692 | |||
693 | sbus_writel(csr, chip->port + APCCSR); | ||
694 | } else { | 647 | } else { |
695 | csr |= APC_CPAUSE; | 648 | dma_cont->enable(dma_cont, 0); |
696 | sbus_writel(csr, chip->port + APCCSR); | ||
697 | |||
698 | csr &= ~APC_CDMA_READY; | ||
699 | sbus_writel(csr, chip->port + APCCSR); | ||
700 | } | 649 | } |
701 | break; | ||
702 | } | ||
703 | #endif | ||
704 | #ifdef EBUS_SUPPORT | ||
705 | } | 650 | } |
706 | #endif | ||
707 | } | 651 | } |
708 | 652 | ||
709 | static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) | 653 | static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) |
@@ -1136,10 +1080,7 @@ static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream) | |||
1136 | if (runtime->period_size > 0xffff + 1) | 1080 | if (runtime->period_size > 0xffff + 1) |
1137 | BUG(); | 1081 | BUG(); |
1138 | 1082 | ||
1139 | snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 0x00ff); | ||
1140 | snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff); | ||
1141 | chip->p_periods_sent = 0; | 1083 | chip->p_periods_sent = 0; |
1142 | |||
1143 | spin_unlock_irqrestore(&chip->lock, flags); | 1084 | spin_unlock_irqrestore(&chip->lock, flags); |
1144 | 1085 | ||
1145 | return 0; | 1086 | return 0; |
@@ -1171,16 +1112,14 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream) | |||
1171 | static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream) | 1112 | static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream) |
1172 | { | 1113 | { |
1173 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1114 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1174 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
1175 | unsigned long flags; | 1115 | unsigned long flags; |
1176 | 1116 | ||
1177 | spin_lock_irqsave(&chip->lock, flags); | 1117 | spin_lock_irqsave(&chip->lock, flags); |
1178 | chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | | 1118 | chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | |
1179 | CS4231_RECORD_PIO); | 1119 | CS4231_RECORD_PIO); |
1180 | 1120 | ||
1181 | snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 0x00ff); | ||
1182 | snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff); | ||
1183 | 1121 | ||
1122 | chip->c_periods_sent = 0; | ||
1184 | spin_unlock_irqrestore(&chip->lock, flags); | 1123 | spin_unlock_irqrestore(&chip->lock, flags); |
1185 | 1124 | ||
1186 | return 0; | 1125 | return 0; |
@@ -1199,134 +1138,55 @@ static void snd_cs4231_overrange(cs4231_t *chip) | |||
1199 | chip->capture_substream->runtime->overrange++; | 1138 | chip->capture_substream->runtime->overrange++; |
1200 | } | 1139 | } |
1201 | 1140 | ||
1202 | static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip) | 1141 | static void snd_cs4231_play_callback(cs4231_t *cookie) |
1203 | { | ||
1204 | unsigned long flags; | ||
1205 | unsigned char status; | ||
1206 | |||
1207 | /*This is IRQ is not raised by the cs4231*/ | ||
1208 | if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ)) | ||
1209 | return IRQ_NONE; | ||
1210 | |||
1211 | status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); | ||
1212 | |||
1213 | if (status & CS4231_TIMER_IRQ) { | ||
1214 | if (chip->timer) | ||
1215 | snd_timer_interrupt(chip->timer, chip->timer->sticks); | ||
1216 | } | ||
1217 | |||
1218 | if (status & CS4231_RECORD_IRQ) | ||
1219 | snd_cs4231_overrange(chip); | ||
1220 | |||
1221 | /* ACK the CS4231 interrupt. */ | ||
1222 | spin_lock_irqsave(&chip->lock, flags); | ||
1223 | snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); | ||
1224 | spin_unlock_irqrestore(&chip->lock, flags); | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | #ifdef SBUS_SUPPORT | ||
1230 | static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1231 | { | ||
1232 | cs4231_t *chip = dev_id; | ||
1233 | |||
1234 | /* ACK the APC interrupt. */ | ||
1235 | u32 csr = sbus_readl(chip->port + APCCSR); | ||
1236 | |||
1237 | sbus_writel(csr, chip->port + APCCSR); | ||
1238 | |||
1239 | if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) && | ||
1240 | (csr & APC_PLAY_INT) && | ||
1241 | (csr & APC_XINT_PNVA) && | ||
1242 | !(csr & APC_XINT_EMPT)) { | ||
1243 | snd_cs4231_sbus_advance_dma(chip->playback_substream, | ||
1244 | &chip->p_periods_sent); | ||
1245 | snd_pcm_period_elapsed(chip->playback_substream); | ||
1246 | } | ||
1247 | |||
1248 | if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) && | ||
1249 | (csr & APC_CAPT_INT) && | ||
1250 | (csr & APC_XINT_CNVA)) { | ||
1251 | snd_cs4231_sbus_advance_dma(chip->capture_substream, | ||
1252 | &chip->c_periods_sent); | ||
1253 | snd_pcm_period_elapsed(chip->capture_substream); | ||
1254 | } | ||
1255 | |||
1256 | return snd_cs4231_generic_interrupt(chip); | ||
1257 | } | ||
1258 | #endif | ||
1259 | |||
1260 | #ifdef EBUS_SUPPORT | ||
1261 | static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie) | ||
1262 | { | 1142 | { |
1263 | cs4231_t *chip = cookie; | 1143 | cs4231_t *chip = cookie; |
1264 | 1144 | ||
1265 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) { | 1145 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) { |
1266 | snd_pcm_period_elapsed(chip->playback_substream); | 1146 | snd_pcm_period_elapsed(chip->playback_substream); |
1267 | snd_cs4231_ebus_advance_dma(p, chip->playback_substream, | 1147 | snd_cs4231_advance_dma(&chip->p_dma, chip->playback_substream, |
1268 | &chip->p_periods_sent); | 1148 | &chip->p_periods_sent); |
1269 | } | 1149 | } |
1270 | } | 1150 | } |
1271 | 1151 | ||
1272 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) | 1152 | static void snd_cs4231_capture_callback(cs4231_t *cookie) |
1273 | { | 1153 | { |
1274 | cs4231_t *chip = cookie; | 1154 | cs4231_t *chip = cookie; |
1275 | 1155 | ||
1276 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) { | 1156 | if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) { |
1277 | snd_pcm_period_elapsed(chip->capture_substream); | 1157 | snd_pcm_period_elapsed(chip->capture_substream); |
1278 | snd_cs4231_ebus_advance_dma(p, chip->capture_substream, | 1158 | snd_cs4231_advance_dma(&chip->c_dma, chip->capture_substream, |
1279 | &chip->c_periods_sent); | 1159 | &chip->c_periods_sent); |
1280 | } | 1160 | } |
1281 | } | 1161 | } |
1282 | #endif | ||
1283 | 1162 | ||
1284 | static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream) | 1163 | static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream) |
1285 | { | 1164 | { |
1286 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1165 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1287 | size_t ptr, residue, period_bytes; | 1166 | cs4231_dma_control_t *dma_cont = &chip->p_dma; |
1288 | 1167 | size_t ptr; | |
1168 | |||
1289 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) | 1169 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) |
1290 | return 0; | 1170 | return 0; |
1291 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1171 | ptr = dma_cont->address(dma_cont); |
1292 | ptr = period_bytes * chip->p_periods_sent; | 1172 | if (ptr != 0) |
1293 | #ifdef EBUS_SUPPORT | 1173 | ptr -= substream->runtime->dma_addr; |
1294 | if (chip->flags & CS4231_FLAG_EBUS) { | 1174 | |
1295 | residue = ebus_dma_residue(&chip->eb2p); | ||
1296 | } else { | ||
1297 | #endif | ||
1298 | #ifdef SBUS_SUPPORT | ||
1299 | residue = sbus_readl(chip->port + APCPC); | ||
1300 | #endif | ||
1301 | #ifdef EBUS_SUPPORT | ||
1302 | } | ||
1303 | #endif | ||
1304 | ptr += period_bytes - residue; | ||
1305 | |||
1306 | return bytes_to_frames(substream->runtime, ptr); | 1175 | return bytes_to_frames(substream->runtime, ptr); |
1307 | } | 1176 | } |
1308 | 1177 | ||
1309 | static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream) | 1178 | static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream) |
1310 | { | 1179 | { |
1311 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1180 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1312 | size_t ptr, residue, period_bytes; | 1181 | cs4231_dma_control_t *dma_cont = &chip->c_dma; |
1182 | size_t ptr; | ||
1313 | 1183 | ||
1314 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) | 1184 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) |
1315 | return 0; | 1185 | return 0; |
1316 | period_bytes = snd_pcm_lib_period_bytes(substream); | 1186 | ptr = dma_cont->address(dma_cont); |
1317 | ptr = period_bytes * chip->c_periods_sent; | 1187 | if (ptr != 0) |
1318 | #ifdef EBUS_SUPPORT | 1188 | ptr -= substream->runtime->dma_addr; |
1319 | if (chip->flags & CS4231_FLAG_EBUS) { | 1189 | |
1320 | residue = ebus_dma_residue(&chip->eb2c); | ||
1321 | } else { | ||
1322 | #endif | ||
1323 | #ifdef SBUS_SUPPORT | ||
1324 | residue = sbus_readl(chip->port + APCCC); | ||
1325 | #endif | ||
1326 | #ifdef EBUS_SUPPORT | ||
1327 | } | ||
1328 | #endif | ||
1329 | ptr += period_bytes - residue; | ||
1330 | return bytes_to_frames(substream->runtime, ptr); | 1190 | return bytes_to_frames(substream->runtime, ptr); |
1331 | } | 1191 | } |
1332 | 1192 | ||
@@ -1362,30 +1222,8 @@ static int snd_cs4231_probe(cs4231_t *chip) | |||
1362 | spin_lock_irqsave(&chip->lock, flags); | 1222 | spin_lock_irqsave(&chip->lock, flags); |
1363 | 1223 | ||
1364 | 1224 | ||
1365 | /* Reset DMA engine. */ | 1225 | /* Reset DMA engine (sbus only). */ |
1366 | #ifdef EBUS_SUPPORT | 1226 | chip->p_dma.reset(chip); |
1367 | if (chip->flags & CS4231_FLAG_EBUS) { | ||
1368 | /* Done by ebus_dma_register */ | ||
1369 | } else { | ||
1370 | #endif | ||
1371 | #ifdef SBUS_SUPPORT | ||
1372 | sbus_writel(APC_CHIP_RESET, chip->port + APCCSR); | ||
1373 | sbus_writel(0x00, chip->port + APCCSR); | ||
1374 | sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET, | ||
1375 | chip->port + APCCSR); | ||
1376 | |||
1377 | udelay(20); | ||
1378 | |||
1379 | sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET, | ||
1380 | chip->port + APCCSR); | ||
1381 | sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA | | ||
1382 | APC_XINT_PENA | | ||
1383 | APC_XINT_CENA), | ||
1384 | chip->port + APCCSR); | ||
1385 | #endif | ||
1386 | #ifdef EBUS_SUPPORT | ||
1387 | } | ||
1388 | #endif | ||
1389 | 1227 | ||
1390 | __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ | 1228 | __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ |
1391 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); | 1229 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); |
@@ -1505,8 +1343,8 @@ static int snd_cs4231_playback_close(snd_pcm_substream_t *substream) | |||
1505 | { | 1343 | { |
1506 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1344 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1507 | 1345 | ||
1508 | chip->playback_substream = NULL; | ||
1509 | snd_cs4231_close(chip, CS4231_MODE_PLAY); | 1346 | snd_cs4231_close(chip, CS4231_MODE_PLAY); |
1347 | chip->playback_substream = NULL; | ||
1510 | 1348 | ||
1511 | return 0; | 1349 | return 0; |
1512 | } | 1350 | } |
@@ -1515,8 +1353,8 @@ static int snd_cs4231_capture_close(snd_pcm_substream_t *substream) | |||
1515 | { | 1353 | { |
1516 | cs4231_t *chip = snd_pcm_substream_chip(substream); | 1354 | cs4231_t *chip = snd_pcm_substream_chip(substream); |
1517 | 1355 | ||
1518 | chip->capture_substream = NULL; | ||
1519 | snd_cs4231_close(chip, CS4231_MODE_RECORD); | 1356 | snd_cs4231_close(chip, CS4231_MODE_RECORD); |
1357 | chip->capture_substream = NULL; | ||
1520 | 1358 | ||
1521 | return 0; | 1359 | return 0; |
1522 | } | 1360 | } |
@@ -1571,21 +1409,7 @@ int snd_cs4231_pcm(cs4231_t *chip) | |||
1571 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; | 1409 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
1572 | strcpy(pcm->name, "CS4231"); | 1410 | strcpy(pcm->name, "CS4231"); |
1573 | 1411 | ||
1574 | #ifdef EBUS_SUPPORT | 1412 | chip->p_dma.preallocate(chip, pcm); |
1575 | if (chip->flags & CS4231_FLAG_EBUS) { | ||
1576 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
1577 | snd_dma_pci_data(chip->dev_u.pdev), | ||
1578 | 64*1024, 128*1024); | ||
1579 | } else { | ||
1580 | #endif | ||
1581 | #ifdef SBUS_SUPPORT | ||
1582 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, | ||
1583 | snd_dma_sbus_data(chip->dev_u.sdev), | ||
1584 | 64*1024, 128*1024); | ||
1585 | #endif | ||
1586 | #ifdef EBUS_SUPPORT | ||
1587 | } | ||
1588 | #endif | ||
1589 | 1413 | ||
1590 | chip->pcm = pcm; | 1414 | chip->pcm = pcm; |
1591 | 1415 | ||
@@ -1942,6 +1766,180 @@ out_err: | |||
1942 | } | 1766 | } |
1943 | 1767 | ||
1944 | #ifdef SBUS_SUPPORT | 1768 | #ifdef SBUS_SUPPORT |
1769 | |||
1770 | static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1771 | { | ||
1772 | unsigned long flags; | ||
1773 | unsigned char status; | ||
1774 | u32 csr; | ||
1775 | cs4231_t *chip = dev_id; | ||
1776 | |||
1777 | /*This is IRQ is not raised by the cs4231*/ | ||
1778 | if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ)) | ||
1779 | return IRQ_NONE; | ||
1780 | |||
1781 | /* ACK the APC interrupt. */ | ||
1782 | csr = sbus_readl(chip->port + APCCSR); | ||
1783 | |||
1784 | sbus_writel(csr, chip->port + APCCSR); | ||
1785 | |||
1786 | if ((csr & APC_PDMA_READY) && | ||
1787 | (csr & APC_PLAY_INT) && | ||
1788 | (csr & APC_XINT_PNVA) && | ||
1789 | !(csr & APC_XINT_EMPT)) | ||
1790 | snd_cs4231_play_callback(chip); | ||
1791 | |||
1792 | if ((csr & APC_CDMA_READY) && | ||
1793 | (csr & APC_CAPT_INT) && | ||
1794 | (csr & APC_XINT_CNVA) && | ||
1795 | !(csr & APC_XINT_EMPT)) | ||
1796 | snd_cs4231_capture_callback(chip); | ||
1797 | |||
1798 | status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); | ||
1799 | |||
1800 | if (status & CS4231_TIMER_IRQ) { | ||
1801 | if (chip->timer) | ||
1802 | snd_timer_interrupt(chip->timer, chip->timer->sticks); | ||
1803 | } | ||
1804 | |||
1805 | if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY)) | ||
1806 | snd_cs4231_overrange(chip); | ||
1807 | |||
1808 | /* ACK the CS4231 interrupt. */ | ||
1809 | spin_lock_irqsave(&chip->lock, flags); | ||
1810 | snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); | ||
1811 | spin_unlock_irqrestore(&chip->lock, flags); | ||
1812 | |||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1816 | /* | ||
1817 | * SBUS DMA routines | ||
1818 | */ | ||
1819 | |||
1820 | int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len) | ||
1821 | { | ||
1822 | unsigned long flags; | ||
1823 | u32 test, csr; | ||
1824 | int err; | ||
1825 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1826 | |||
1827 | if (len >= (1 << 24)) | ||
1828 | return -EINVAL; | ||
1829 | spin_lock_irqsave(&base->lock, flags); | ||
1830 | csr = sbus_readl(base->regs + APCCSR); | ||
1831 | err = -EINVAL; | ||
1832 | test = APC_CDMA_READY; | ||
1833 | if ( base->dir == APC_PLAY ) | ||
1834 | test = APC_PDMA_READY; | ||
1835 | if (!(csr & test)) | ||
1836 | goto out; | ||
1837 | err = -EBUSY; | ||
1838 | csr = sbus_readl(base->regs + APCCSR); | ||
1839 | test = APC_XINT_CNVA; | ||
1840 | if ( base->dir == APC_PLAY ) | ||
1841 | test = APC_XINT_PNVA; | ||
1842 | if (!(csr & test)) | ||
1843 | goto out; | ||
1844 | err = 0; | ||
1845 | sbus_writel(bus_addr, base->regs + base->dir + APCNVA); | ||
1846 | sbus_writel(len, base->regs + base->dir + APCNC); | ||
1847 | out: | ||
1848 | spin_unlock_irqrestore(&base->lock, flags); | ||
1849 | return err; | ||
1850 | } | ||
1851 | |||
1852 | void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d) | ||
1853 | { | ||
1854 | unsigned long flags; | ||
1855 | u32 csr, test; | ||
1856 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1857 | |||
1858 | spin_lock_irqsave(&base->lock, flags); | ||
1859 | csr = sbus_readl(base->regs + APCCSR); | ||
1860 | test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA | | ||
1861 | APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL | | ||
1862 | APC_XINT_PENA; | ||
1863 | if ( base->dir == APC_RECORD ) | ||
1864 | test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA | | ||
1865 | APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL; | ||
1866 | csr |= test; | ||
1867 | sbus_writel(csr, base->regs + APCCSR); | ||
1868 | spin_unlock_irqrestore(&base->lock, flags); | ||
1869 | } | ||
1870 | |||
1871 | void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on) | ||
1872 | { | ||
1873 | unsigned long flags; | ||
1874 | u32 csr, shift; | ||
1875 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1876 | |||
1877 | spin_lock_irqsave(&base->lock, flags); | ||
1878 | if (!on) { | ||
1879 | if (base->dir == APC_PLAY) { | ||
1880 | sbus_writel(0, base->regs + base->dir + APCNVA); | ||
1881 | sbus_writel(1, base->regs + base->dir + APCC); | ||
1882 | } | ||
1883 | else | ||
1884 | { | ||
1885 | sbus_writel(0, base->regs + base->dir + APCNC); | ||
1886 | sbus_writel(0, base->regs + base->dir + APCVA); | ||
1887 | } | ||
1888 | } | ||
1889 | udelay(600); | ||
1890 | csr = sbus_readl(base->regs + APCCSR); | ||
1891 | shift = 0; | ||
1892 | if ( base->dir == APC_PLAY ) | ||
1893 | shift = 1; | ||
1894 | if (on) | ||
1895 | csr &= ~(APC_CPAUSE << shift); | ||
1896 | else | ||
1897 | csr |= (APC_CPAUSE << shift); | ||
1898 | sbus_writel(csr, base->regs + APCCSR); | ||
1899 | if (on) | ||
1900 | csr |= (APC_CDMA_READY << shift); | ||
1901 | else | ||
1902 | csr &= ~(APC_CDMA_READY << shift); | ||
1903 | sbus_writel(csr, base->regs + APCCSR); | ||
1904 | |||
1905 | spin_unlock_irqrestore(&base->lock, flags); | ||
1906 | } | ||
1907 | |||
1908 | unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) | ||
1909 | { | ||
1910 | sbus_dma_info_t *base = &dma_cont->sbus_info; | ||
1911 | |||
1912 | return sbus_readl(base->regs + base->dir + APCVA); | ||
1913 | } | ||
1914 | |||
1915 | void sbus_dma_reset(cs4231_t *chip) | ||
1916 | { | ||
1917 | sbus_writel(APC_CHIP_RESET, chip->port + APCCSR); | ||
1918 | sbus_writel(0x00, chip->port + APCCSR); | ||
1919 | sbus_writel(sbus_readl(chip->port + APCCSR) | APC_CDC_RESET, | ||
1920 | chip->port + APCCSR); | ||
1921 | |||
1922 | udelay(20); | ||
1923 | |||
1924 | sbus_writel(sbus_readl(chip->port + APCCSR) & ~APC_CDC_RESET, | ||
1925 | chip->port + APCCSR); | ||
1926 | sbus_writel(sbus_readl(chip->port + APCCSR) | (APC_XINT_ENA | | ||
1927 | APC_XINT_PENA | | ||
1928 | APC_XINT_CENA), | ||
1929 | chip->port + APCCSR); | ||
1930 | } | ||
1931 | |||
1932 | void sbus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm) | ||
1933 | { | ||
1934 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, | ||
1935 | snd_dma_sbus_data(chip->dev_u.sdev), | ||
1936 | 64*1024, 128*1024); | ||
1937 | } | ||
1938 | |||
1939 | /* | ||
1940 | * Init and exit routines | ||
1941 | */ | ||
1942 | |||
1945 | static int snd_cs4231_sbus_free(cs4231_t *chip) | 1943 | static int snd_cs4231_sbus_free(cs4231_t *chip) |
1946 | { | 1944 | { |
1947 | if (chip->irq[0]) | 1945 | if (chip->irq[0]) |
@@ -1983,6 +1981,8 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, | |||
1983 | return -ENOMEM; | 1981 | return -ENOMEM; |
1984 | 1982 | ||
1985 | spin_lock_init(&chip->lock); | 1983 | spin_lock_init(&chip->lock); |
1984 | spin_lock_init(&chip->c_dma.sbus_info.lock); | ||
1985 | spin_lock_init(&chip->p_dma.sbus_info.lock); | ||
1986 | init_MUTEX(&chip->mce_mutex); | 1986 | init_MUTEX(&chip->mce_mutex); |
1987 | init_MUTEX(&chip->open_mutex); | 1987 | init_MUTEX(&chip->open_mutex); |
1988 | chip->card = card; | 1988 | chip->card = card; |
@@ -1998,6 +1998,25 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card, | |||
1998 | return -EIO; | 1998 | return -EIO; |
1999 | } | 1999 | } |
2000 | 2000 | ||
2001 | chip->c_dma.sbus_info.regs = chip->port; | ||
2002 | chip->p_dma.sbus_info.regs = chip->port; | ||
2003 | chip->c_dma.sbus_info.dir = APC_RECORD; | ||
2004 | chip->p_dma.sbus_info.dir = APC_PLAY; | ||
2005 | |||
2006 | chip->p_dma.prepare = sbus_dma_prepare; | ||
2007 | chip->p_dma.enable = sbus_dma_enable; | ||
2008 | chip->p_dma.request = sbus_dma_request; | ||
2009 | chip->p_dma.address = sbus_dma_addr; | ||
2010 | chip->p_dma.reset = sbus_dma_reset; | ||
2011 | chip->p_dma.preallocate = sbus_dma_preallocate; | ||
2012 | |||
2013 | chip->c_dma.prepare = sbus_dma_prepare; | ||
2014 | chip->c_dma.enable = sbus_dma_enable; | ||
2015 | chip->c_dma.request = sbus_dma_request; | ||
2016 | chip->c_dma.address = sbus_dma_addr; | ||
2017 | chip->c_dma.reset = sbus_dma_reset; | ||
2018 | chip->c_dma.preallocate = sbus_dma_preallocate; | ||
2019 | |||
2001 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, | 2020 | if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, |
2002 | SA_SHIRQ, "cs4231", chip)) { | 2021 | SA_SHIRQ, "cs4231", chip)) { |
2003 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n", | 2022 | snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n", |
@@ -2051,15 +2070,70 @@ static int cs4231_sbus_attach(struct sbus_dev *sdev) | |||
2051 | #endif | 2070 | #endif |
2052 | 2071 | ||
2053 | #ifdef EBUS_SUPPORT | 2072 | #ifdef EBUS_SUPPORT |
2073 | |||
2074 | static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie) | ||
2075 | { | ||
2076 | cs4231_t *chip = cookie; | ||
2077 | |||
2078 | snd_cs4231_play_callback(chip); | ||
2079 | } | ||
2080 | |||
2081 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) | ||
2082 | { | ||
2083 | cs4231_t *chip = cookie; | ||
2084 | |||
2085 | snd_cs4231_capture_callback(chip); | ||
2086 | } | ||
2087 | |||
2088 | /* | ||
2089 | * EBUS DMA wrappers | ||
2090 | */ | ||
2091 | |||
2092 | int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len) | ||
2093 | { | ||
2094 | return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len); | ||
2095 | } | ||
2096 | |||
2097 | void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on) | ||
2098 | { | ||
2099 | ebus_dma_enable(&dma_cont->ebus_info, on); | ||
2100 | } | ||
2101 | |||
2102 | void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir) | ||
2103 | { | ||
2104 | ebus_dma_prepare(&dma_cont->ebus_info, dir); | ||
2105 | } | ||
2106 | |||
2107 | unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont) | ||
2108 | { | ||
2109 | return ebus_dma_addr(&dma_cont->ebus_info); | ||
2110 | } | ||
2111 | |||
2112 | void _ebus_dma_reset(cs4231_t *chip) | ||
2113 | { | ||
2114 | return; | ||
2115 | } | ||
2116 | |||
2117 | void _ebus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm) | ||
2118 | { | ||
2119 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
2120 | snd_dma_pci_data(chip->dev_u.pdev), | ||
2121 | 64*1024, 128*1024); | ||
2122 | } | ||
2123 | |||
2124 | /* | ||
2125 | * Init and exit routines | ||
2126 | */ | ||
2127 | |||
2054 | static int snd_cs4231_ebus_free(cs4231_t *chip) | 2128 | static int snd_cs4231_ebus_free(cs4231_t *chip) |
2055 | { | 2129 | { |
2056 | if (chip->eb2c.regs) { | 2130 | if (chip->c_dma.ebus_info.regs) { |
2057 | ebus_dma_unregister(&chip->eb2c); | 2131 | ebus_dma_unregister(&chip->c_dma.ebus_info); |
2058 | iounmap(chip->eb2c.regs); | 2132 | iounmap(chip->c_dma.ebus_info.regs); |
2059 | } | 2133 | } |
2060 | if (chip->eb2p.regs) { | 2134 | if (chip->p_dma.ebus_info.regs) { |
2061 | ebus_dma_unregister(&chip->eb2p); | 2135 | ebus_dma_unregister(&chip->p_dma.ebus_info); |
2062 | iounmap(chip->eb2p.regs); | 2136 | iounmap(chip->p_dma.ebus_info.regs); |
2063 | } | 2137 | } |
2064 | 2138 | ||
2065 | if (chip->port) | 2139 | if (chip->port) |
@@ -2097,8 +2171,8 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card, | |||
2097 | return -ENOMEM; | 2171 | return -ENOMEM; |
2098 | 2172 | ||
2099 | spin_lock_init(&chip->lock); | 2173 | spin_lock_init(&chip->lock); |
2100 | spin_lock_init(&chip->eb2c.lock); | 2174 | spin_lock_init(&chip->c_dma.ebus_info.lock); |
2101 | spin_lock_init(&chip->eb2p.lock); | 2175 | spin_lock_init(&chip->p_dma.ebus_info.lock); |
2102 | init_MUTEX(&chip->mce_mutex); | 2176 | init_MUTEX(&chip->mce_mutex); |
2103 | init_MUTEX(&chip->open_mutex); | 2177 | init_MUTEX(&chip->open_mutex); |
2104 | chip->flags |= CS4231_FLAG_EBUS; | 2178 | chip->flags |= CS4231_FLAG_EBUS; |
@@ -2106,43 +2180,57 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card, | |||
2106 | chip->dev_u.pdev = edev->bus->self; | 2180 | chip->dev_u.pdev = edev->bus->self; |
2107 | memcpy(&chip->image, &snd_cs4231_original_image, | 2181 | memcpy(&chip->image, &snd_cs4231_original_image, |
2108 | sizeof(snd_cs4231_original_image)); | 2182 | sizeof(snd_cs4231_original_image)); |
2109 | strcpy(chip->eb2c.name, "cs4231(capture)"); | 2183 | strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)"); |
2110 | chip->eb2c.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; | 2184 | chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; |
2111 | chip->eb2c.callback = snd_cs4231_ebus_capture_callback; | 2185 | chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; |
2112 | chip->eb2c.client_cookie = chip; | 2186 | chip->c_dma.ebus_info.client_cookie = chip; |
2113 | chip->eb2c.irq = edev->irqs[0]; | 2187 | chip->c_dma.ebus_info.irq = edev->irqs[0]; |
2114 | strcpy(chip->eb2p.name, "cs4231(play)"); | 2188 | strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); |
2115 | chip->eb2p.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; | 2189 | chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; |
2116 | chip->eb2p.callback = snd_cs4231_ebus_play_callback; | 2190 | chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; |
2117 | chip->eb2p.client_cookie = chip; | 2191 | chip->p_dma.ebus_info.client_cookie = chip; |
2118 | chip->eb2p.irq = edev->irqs[1]; | 2192 | chip->p_dma.ebus_info.irq = edev->irqs[1]; |
2193 | |||
2194 | chip->p_dma.prepare = _ebus_dma_prepare; | ||
2195 | chip->p_dma.enable = _ebus_dma_enable; | ||
2196 | chip->p_dma.request = _ebus_dma_request; | ||
2197 | chip->p_dma.address = _ebus_dma_addr; | ||
2198 | chip->p_dma.reset = _ebus_dma_reset; | ||
2199 | chip->p_dma.preallocate = _ebus_dma_preallocate; | ||
2200 | |||
2201 | chip->c_dma.prepare = _ebus_dma_prepare; | ||
2202 | chip->c_dma.enable = _ebus_dma_enable; | ||
2203 | chip->c_dma.request = _ebus_dma_request; | ||
2204 | chip->c_dma.address = _ebus_dma_addr; | ||
2205 | chip->c_dma.reset = _ebus_dma_reset; | ||
2206 | chip->c_dma.preallocate = _ebus_dma_preallocate; | ||
2119 | 2207 | ||
2120 | chip->port = ioremap(edev->resource[0].start, 0x10); | 2208 | chip->port = ioremap(edev->resource[0].start, 0x10); |
2121 | chip->eb2p.regs = ioremap(edev->resource[1].start, 0x10); | 2209 | chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); |
2122 | chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10); | 2210 | chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); |
2123 | if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) { | 2211 | if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) { |
2124 | snd_cs4231_ebus_free(chip); | 2212 | snd_cs4231_ebus_free(chip); |
2125 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); | 2213 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); |
2126 | return -EIO; | 2214 | return -EIO; |
2127 | } | 2215 | } |
2128 | 2216 | ||
2129 | if (ebus_dma_register(&chip->eb2c)) { | 2217 | if (ebus_dma_register(&chip->c_dma.ebus_info)) { |
2130 | snd_cs4231_ebus_free(chip); | 2218 | snd_cs4231_ebus_free(chip); |
2131 | snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev); | 2219 | snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev); |
2132 | return -EBUSY; | 2220 | return -EBUSY; |
2133 | } | 2221 | } |
2134 | if (ebus_dma_irq_enable(&chip->eb2c, 1)) { | 2222 | if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) { |
2135 | snd_cs4231_ebus_free(chip); | 2223 | snd_cs4231_ebus_free(chip); |
2136 | snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); | 2224 | snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); |
2137 | return -EBUSY; | 2225 | return -EBUSY; |
2138 | } | 2226 | } |
2139 | 2227 | ||
2140 | if (ebus_dma_register(&chip->eb2p)) { | 2228 | if (ebus_dma_register(&chip->p_dma.ebus_info)) { |
2141 | snd_cs4231_ebus_free(chip); | 2229 | snd_cs4231_ebus_free(chip); |
2142 | snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev); | 2230 | snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev); |
2143 | return -EBUSY; | 2231 | return -EBUSY; |
2144 | } | 2232 | } |
2145 | if (ebus_dma_irq_enable(&chip->eb2p, 1)) { | 2233 | if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) { |
2146 | snd_cs4231_ebus_free(chip); | 2234 | snd_cs4231_ebus_free(chip); |
2147 | snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev); | 2235 | snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev); |
2148 | return -EBUSY; | 2236 | return -EBUSY; |