aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig7
-rw-r--r--drivers/char/Makefile3
-rw-r--r--drivers/char/apm-emulation.c672
-rw-r--r--drivers/char/drm/drmP.h36
-rw-r--r--drivers/char/drm/drm_bufs.c19
-rw-r--r--drivers/char/drm/drm_memory.c94
-rw-r--r--drivers/char/drm/drm_memory.h20
-rw-r--r--drivers/char/drm/drm_memory_debug.h70
-rw-r--r--drivers/char/drm/drm_mm.c183
-rw-r--r--drivers/char/drm/drm_pciids.h4
-rw-r--r--drivers/char/drm/drm_proc.c4
-rw-r--r--drivers/char/drm/drm_sman.c3
-rw-r--r--drivers/char/drm/drm_vm.c16
-rw-r--r--drivers/char/drm/i810_dma.c34
-rw-r--r--drivers/char/drm/i810_drv.h2
-rw-r--r--drivers/char/drm/i830_dma.c32
-rw-r--r--drivers/char/drm/i830_drv.h2
-rw-r--r--drivers/char/drm/via_dma.c9
-rw-r--r--drivers/char/drm/via_dmablit.c2
-rw-r--r--drivers/char/drm/via_drv.h11
-rw-r--r--drivers/char/drm/via_irq.c16
-rw-r--r--drivers/char/drm/via_map.c3
-rw-r--r--drivers/char/drm/via_verifier.c50
-rw-r--r--drivers/char/drm/via_verifier.h1
-rw-r--r--drivers/char/hvc_beat.c134
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c18
-rw-r--r--drivers/char/sysrq.c20
-rw-r--r--drivers/char/tpm/tpm_bios.c8
-rw-r--r--drivers/char/watchdog/booke_wdt.c20
-rw-r--r--drivers/char/watchdog/machzwd.c2
30 files changed, 1154 insertions, 341 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 9e43e39dc35c..d08bb4ee1307 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -610,6 +610,13 @@ config HVC_RTAS
610 help 610 help
611 IBM Console device driver which makes use of RTAS 611 IBM Console device driver which makes use of RTAS
612 612
613config HVC_BEAT
614 bool "Toshiba's Beat Hypervisor Console support"
615 depends on PPC_CELLEB
616 select HVC_DRIVER
617 help
618 Toshiba's Cell Reference Set Beat Console device driver
619
613config HVCS 620config HVCS
614 tristate "IBM Hypervisor Virtual Console Server support" 621 tristate "IBM Hypervisor Virtual Console Server support"
615 depends on PPC_PSERIES 622 depends on PPC_PSERIES
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index fc110637ced6..ae8567cc529c 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_RIO) += rio/ generic_serial.o
45obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o 45obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
46obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o 46obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
47obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o 47obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
48obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
48obj-$(CONFIG_HVC_DRIVER) += hvc_console.o 49obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
49obj-$(CONFIG_RAW_DRIVER) += raw.o 50obj-$(CONFIG_RAW_DRIVER) += raw.o
50obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 51obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
@@ -59,6 +60,8 @@ obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
59obj-$(CONFIG_PRINTER) += lp.o 60obj-$(CONFIG_PRINTER) += lp.o
60obj-$(CONFIG_TIPAR) += tipar.o 61obj-$(CONFIG_TIPAR) += tipar.o
61 62
63obj-$(CONFIG_APM_EMULATION) += apm-emulation.o
64
62obj-$(CONFIG_DTLK) += dtlk.o 65obj-$(CONFIG_DTLK) += dtlk.o
63obj-$(CONFIG_R3964) += n_r3964.o 66obj-$(CONFIG_R3964) += n_r3964.o
64obj-$(CONFIG_APPLICOM) += applicom.o 67obj-$(CONFIG_APPLICOM) += applicom.o
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
new file mode 100644
index 000000000000..179c7a3b6e75
--- /dev/null
+++ b/drivers/char/apm-emulation.c
@@ -0,0 +1,672 @@
1/*
2 * bios-less APM driver for ARM Linux
3 * Jamey Hicks <jamey@crl.dec.com>
4 * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com)
5 *
6 * APM 1.2 Reference:
7 * Intel Corporation, Microsoft Corporation. Advanced Power Management
8 * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
9 *
10 * [This document is available from Microsoft at:
11 * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
12 */
13#include <linux/module.h>
14#include <linux/poll.h>
15#include <linux/slab.h>
16#include <linux/proc_fs.h>
17#include <linux/miscdevice.h>
18#include <linux/apm_bios.h>
19#include <linux/capability.h>
20#include <linux/sched.h>
21#include <linux/pm.h>
22#include <linux/apm-emulation.h>
23#include <linux/device.h>
24#include <linux/kernel.h>
25#include <linux/list.h>
26#include <linux/init.h>
27#include <linux/completion.h>
28#include <linux/kthread.h>
29#include <linux/delay.h>
30
31#include <asm/system.h>
32
33/*
34 * The apm_bios device is one of the misc char devices.
35 * This is its minor number.
36 */
37#define APM_MINOR_DEV 134
38
39/*
40 * See Documentation/Config.help for the configuration options.
41 *
42 * Various options can be changed at boot time as follows:
43 * (We allow underscores for compatibility with the modules code)
44 * apm=on/off enable/disable APM
45 */
46
47/*
48 * Maximum number of events stored
49 */
50#define APM_MAX_EVENTS 16
51
52struct apm_queue {
53 unsigned int event_head;
54 unsigned int event_tail;
55 apm_event_t events[APM_MAX_EVENTS];
56};
57
58/*
59 * The per-file APM data
60 */
61struct apm_user {
62 struct list_head list;
63
64 unsigned int suser: 1;
65 unsigned int writer: 1;
66 unsigned int reader: 1;
67
68 int suspend_result;
69 unsigned int suspend_state;
70#define SUSPEND_NONE 0 /* no suspend pending */
71#define SUSPEND_PENDING 1 /* suspend pending read */
72#define SUSPEND_READ 2 /* suspend read, pending ack */
73#define SUSPEND_ACKED 3 /* suspend acked */
74#define SUSPEND_WAIT 4 /* waiting for suspend */
75#define SUSPEND_DONE 5 /* suspend completed */
76
77 struct apm_queue queue;
78};
79
80/*
81 * Local variables
82 */
83static int suspends_pending;
84static int apm_disabled;
85static struct task_struct *kapmd_tsk;
86
87static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
88static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
89
90/*
91 * This is a list of everyone who has opened /dev/apm_bios
92 */
93static DECLARE_RWSEM(user_list_lock);
94static LIST_HEAD(apm_user_list);
95
96/*
97 * kapmd info. kapmd provides us a process context to handle
98 * "APM" events within - specifically necessary if we're going
99 * to be suspending the system.
100 */
101static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
102static DEFINE_SPINLOCK(kapmd_queue_lock);
103static struct apm_queue kapmd_queue;
104
105static DEFINE_MUTEX(state_lock);
106
107static const char driver_version[] = "1.13"; /* no spaces */
108
109
110
111/*
112 * Compatibility cruft until the IPAQ people move over to the new
113 * interface.
114 */
115static void __apm_get_power_status(struct apm_power_info *info)
116{
117}
118
119/*
120 * This allows machines to provide their own "apm get power status" function.
121 */
122void (*apm_get_power_status)(struct apm_power_info *) = __apm_get_power_status;
123EXPORT_SYMBOL(apm_get_power_status);
124
125
126/*
127 * APM event queue management.
128 */
129static inline int queue_empty(struct apm_queue *q)
130{
131 return q->event_head == q->event_tail;
132}
133
134static inline apm_event_t queue_get_event(struct apm_queue *q)
135{
136 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
137 return q->events[q->event_tail];
138}
139
140static void queue_add_event(struct apm_queue *q, apm_event_t event)
141{
142 q->event_head = (q->event_head + 1) % APM_MAX_EVENTS;
143 if (q->event_head == q->event_tail) {
144 static int notified;
145
146 if (notified++ == 0)
147 printk(KERN_ERR "apm: an event queue overflowed\n");
148 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
149 }
150 q->events[q->event_head] = event;
151}
152
153static void queue_event(apm_event_t event)
154{
155 struct apm_user *as;
156
157 down_read(&user_list_lock);
158 list_for_each_entry(as, &apm_user_list, list) {
159 if (as->reader)
160 queue_add_event(&as->queue, event);
161 }
162 up_read(&user_list_lock);
163 wake_up_interruptible(&apm_waitqueue);
164}
165
166/*
167 * queue_suspend_event - queue an APM suspend event.
168 *
169 * Check that we're in a state where we can suspend. If not,
170 * return -EBUSY. Otherwise, queue an event to all "writer"
171 * users. If there are no "writer" users, return '1' to
172 * indicate that we can immediately suspend.
173 */
174static int queue_suspend_event(apm_event_t event, struct apm_user *sender)
175{
176 struct apm_user *as;
177 int ret = 1;
178
179 mutex_lock(&state_lock);
180 down_read(&user_list_lock);
181
182 /*
183 * If a thread is still processing, we can't suspend, so reject
184 * the request.
185 */
186 list_for_each_entry(as, &apm_user_list, list) {
187 if (as != sender && as->reader && as->writer && as->suser &&
188 as->suspend_state != SUSPEND_NONE) {
189 ret = -EBUSY;
190 goto out;
191 }
192 }
193
194 list_for_each_entry(as, &apm_user_list, list) {
195 if (as != sender && as->reader && as->writer && as->suser) {
196 as->suspend_state = SUSPEND_PENDING;
197 suspends_pending++;
198 queue_add_event(&as->queue, event);
199 ret = 0;
200 }
201 }
202 out:
203 up_read(&user_list_lock);
204 mutex_unlock(&state_lock);
205 wake_up_interruptible(&apm_waitqueue);
206 return ret;
207}
208
209static void apm_suspend(void)
210{
211 struct apm_user *as;
212 int err = pm_suspend(PM_SUSPEND_MEM);
213
214 /*
215 * Anyone on the APM queues will think we're still suspended.
216 * Send a message so everyone knows we're now awake again.
217 */
218 queue_event(APM_NORMAL_RESUME);
219
220 /*
221 * Finally, wake up anyone who is sleeping on the suspend.
222 */
223 mutex_lock(&state_lock);
224 down_read(&user_list_lock);
225 list_for_each_entry(as, &apm_user_list, list) {
226 if (as->suspend_state == SUSPEND_WAIT ||
227 as->suspend_state == SUSPEND_ACKED) {
228 as->suspend_result = err;
229 as->suspend_state = SUSPEND_DONE;
230 }
231 }
232 up_read(&user_list_lock);
233 mutex_unlock(&state_lock);
234
235 wake_up(&apm_suspend_waitqueue);
236}
237
238static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
239{
240 struct apm_user *as = fp->private_data;
241 apm_event_t event;
242 int i = count, ret = 0;
243
244 if (count < sizeof(apm_event_t))
245 return -EINVAL;
246
247 if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK)
248 return -EAGAIN;
249
250 wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue));
251
252 while ((i >= sizeof(event)) && !queue_empty(&as->queue)) {
253 event = queue_get_event(&as->queue);
254
255 ret = -EFAULT;
256 if (copy_to_user(buf, &event, sizeof(event)))
257 break;
258
259 mutex_lock(&state_lock);
260 if (as->suspend_state == SUSPEND_PENDING &&
261 (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND))
262 as->suspend_state = SUSPEND_READ;
263 mutex_unlock(&state_lock);
264
265 buf += sizeof(event);
266 i -= sizeof(event);
267 }
268
269 if (i < count)
270 ret = count - i;
271
272 return ret;
273}
274
275static unsigned int apm_poll(struct file *fp, poll_table * wait)
276{
277 struct apm_user *as = fp->private_data;
278
279 poll_wait(fp, &apm_waitqueue, wait);
280 return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM;
281}
282
283/*
284 * apm_ioctl - handle APM ioctl
285 *
286 * APM_IOC_SUSPEND
287 * This IOCTL is overloaded, and performs two functions. It is used to:
288 * - initiate a suspend
289 * - acknowledge a suspend read from /dev/apm_bios.
290 * Only when everyone who has opened /dev/apm_bios with write permission
291 * has acknowledge does the actual suspend happen.
292 */
293static int
294apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
295{
296 struct apm_user *as = filp->private_data;
297 unsigned long flags;
298 int err = -EINVAL;
299
300 if (!as->suser || !as->writer)
301 return -EPERM;
302
303 switch (cmd) {
304 case APM_IOC_SUSPEND:
305 mutex_lock(&state_lock);
306
307 as->suspend_result = -EINTR;
308
309 if (as->suspend_state == SUSPEND_READ) {
310 int pending;
311
312 /*
313 * If we read a suspend command from /dev/apm_bios,
314 * then the corresponding APM_IOC_SUSPEND ioctl is
315 * interpreted as an acknowledge.
316 */
317 as->suspend_state = SUSPEND_ACKED;
318 suspends_pending--;
319 pending = suspends_pending == 0;
320 mutex_unlock(&state_lock);
321
322 /*
323 * If there are no further acknowledges required,
324 * suspend the system.
325 */
326 if (pending)
327 apm_suspend();
328
329 /*
330 * Wait for the suspend/resume to complete. If there
331 * are pending acknowledges, we wait here for them.
332 *
333 * Note: we need to ensure that the PM subsystem does
334 * not kick us out of the wait when it suspends the
335 * threads.
336 */
337 flags = current->flags;
338 current->flags |= PF_NOFREEZE;
339
340 wait_event(apm_suspend_waitqueue,
341 as->suspend_state == SUSPEND_DONE);
342 } else {
343 as->suspend_state = SUSPEND_WAIT;
344 mutex_unlock(&state_lock);
345
346 /*
347 * Otherwise it is a request to suspend the system.
348 * Queue an event for all readers, and expect an
349 * acknowledge from all writers who haven't already
350 * acknowledged.
351 */
352 err = queue_suspend_event(APM_USER_SUSPEND, as);
353 if (err < 0) {
354 /*
355 * Avoid taking the lock here - this
356 * should be fine.
357 */
358 as->suspend_state = SUSPEND_NONE;
359 break;
360 }
361
362 if (err > 0)
363 apm_suspend();
364
365 /*
366 * Wait for the suspend/resume to complete. If there
367 * are pending acknowledges, we wait here for them.
368 *
369 * Note: we need to ensure that the PM subsystem does
370 * not kick us out of the wait when it suspends the
371 * threads.
372 */
373 flags = current->flags;
374 current->flags |= PF_NOFREEZE;
375
376 wait_event_interruptible(apm_suspend_waitqueue,
377 as->suspend_state == SUSPEND_DONE);
378 }
379
380 current->flags = flags;
381
382 mutex_lock(&state_lock);
383 err = as->suspend_result;
384 as->suspend_state = SUSPEND_NONE;
385 mutex_unlock(&state_lock);
386 break;
387 }
388
389 return err;
390}
391
392static int apm_release(struct inode * inode, struct file * filp)
393{
394 struct apm_user *as = filp->private_data;
395 int pending = 0;
396
397 filp->private_data = NULL;
398
399 down_write(&user_list_lock);
400 list_del(&as->list);
401 up_write(&user_list_lock);
402
403 /*
404 * We are now unhooked from the chain. As far as new
405 * events are concerned, we no longer exist. However, we
406 * need to balance suspends_pending, which means the
407 * possibility of sleeping.
408 */
409 mutex_lock(&state_lock);
410 if (as->suspend_state != SUSPEND_NONE) {
411 suspends_pending -= 1;
412 pending = suspends_pending == 0;
413 }
414 mutex_unlock(&state_lock);
415 if (pending)
416 apm_suspend();
417
418 kfree(as);
419 return 0;
420}
421
422static int apm_open(struct inode * inode, struct file * filp)
423{
424 struct apm_user *as;
425
426 as = kzalloc(sizeof(*as), GFP_KERNEL);
427 if (as) {
428 /*
429 * XXX - this is a tiny bit broken, when we consider BSD
430 * process accounting. If the device is opened by root, we
431 * instantly flag that we used superuser privs. Who knows,
432 * we might close the device immediately without doing a
433 * privileged operation -- cevans
434 */
435 as->suser = capable(CAP_SYS_ADMIN);
436 as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
437 as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
438
439 down_write(&user_list_lock);
440 list_add(&as->list, &apm_user_list);
441 up_write(&user_list_lock);
442
443 filp->private_data = as;
444 }
445
446 return as ? 0 : -ENOMEM;
447}
448
449static struct file_operations apm_bios_fops = {
450 .owner = THIS_MODULE,
451 .read = apm_read,
452 .poll = apm_poll,
453 .ioctl = apm_ioctl,
454 .open = apm_open,
455 .release = apm_release,
456};
457
458static struct miscdevice apm_device = {
459 .minor = APM_MINOR_DEV,
460 .name = "apm_bios",
461 .fops = &apm_bios_fops
462};
463
464
465#ifdef CONFIG_PROC_FS
466/*
467 * Arguments, with symbols from linux/apm_bios.h.
468 *
469 * 0) Linux driver version (this will change if format changes)
470 * 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
471 * 2) APM flags from APM Installation Check (0x00):
472 * bit 0: APM_16_BIT_SUPPORT
473 * bit 1: APM_32_BIT_SUPPORT
474 * bit 2: APM_IDLE_SLOWS_CLOCK
475 * bit 3: APM_BIOS_DISABLED
476 * bit 4: APM_BIOS_DISENGAGED
477 * 3) AC line status
478 * 0x00: Off-line
479 * 0x01: On-line
480 * 0x02: On backup power (BIOS >= 1.1 only)
481 * 0xff: Unknown
482 * 4) Battery status
483 * 0x00: High
484 * 0x01: Low
485 * 0x02: Critical
486 * 0x03: Charging
487 * 0x04: Selected battery not present (BIOS >= 1.2 only)
488 * 0xff: Unknown
489 * 5) Battery flag
490 * bit 0: High
491 * bit 1: Low
492 * bit 2: Critical
493 * bit 3: Charging
494 * bit 7: No system battery
495 * 0xff: Unknown
496 * 6) Remaining battery life (percentage of charge):
497 * 0-100: valid
498 * -1: Unknown
499 * 7) Remaining battery life (time units):
500 * Number of remaining minutes or seconds
501 * -1: Unknown
502 * 8) min = minutes; sec = seconds
503 */
504static int apm_get_info(char *buf, char **start, off_t fpos, int length)
505{
506 struct apm_power_info info;
507 char *units;
508 int ret;
509
510 info.ac_line_status = 0xff;
511 info.battery_status = 0xff;
512 info.battery_flag = 0xff;
513 info.battery_life = -1;
514 info.time = -1;
515 info.units = -1;
516
517 if (apm_get_power_status)
518 apm_get_power_status(&info);
519
520 switch (info.units) {
521 default: units = "?"; break;
522 case 0: units = "min"; break;
523 case 1: units = "sec"; break;
524 }
525
526 ret = sprintf(buf, "%s 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
527 driver_version, APM_32_BIT_SUPPORT,
528 info.ac_line_status, info.battery_status,
529 info.battery_flag, info.battery_life,
530 info.time, units);
531
532 return ret;
533}
534#endif
535
536static int kapmd(void *arg)
537{
538 do {
539 apm_event_t event;
540 int ret;
541
542 wait_event_interruptible(kapmd_wait,
543 !queue_empty(&kapmd_queue) || kthread_should_stop());
544
545 if (kthread_should_stop())
546 break;
547
548 spin_lock_irq(&kapmd_queue_lock);
549 event = 0;
550 if (!queue_empty(&kapmd_queue))
551 event = queue_get_event(&kapmd_queue);
552 spin_unlock_irq(&kapmd_queue_lock);
553
554 switch (event) {
555 case 0:
556 break;
557
558 case APM_LOW_BATTERY:
559 case APM_POWER_STATUS_CHANGE:
560 queue_event(event);
561 break;
562
563 case APM_USER_SUSPEND:
564 case APM_SYS_SUSPEND:
565 ret = queue_suspend_event(event, NULL);
566 if (ret < 0) {
567 /*
568 * We were busy. Try again in 50ms.
569 */
570 queue_add_event(&kapmd_queue, event);
571 msleep(50);
572 }
573 if (ret > 0)
574 apm_suspend();
575 break;
576
577 case APM_CRITICAL_SUSPEND:
578 apm_suspend();
579 break;
580 }
581 } while (1);
582
583 return 0;
584}
585
586static int __init apm_init(void)
587{
588 int ret;
589
590 if (apm_disabled) {
591 printk(KERN_NOTICE "apm: disabled on user request.\n");
592 return -ENODEV;
593 }
594
595 kapmd_tsk = kthread_create(kapmd, NULL, "kapmd");
596 if (IS_ERR(kapmd_tsk)) {
597 ret = PTR_ERR(kapmd_tsk);
598 kapmd_tsk = NULL;
599 return ret;
600 }
601 kapmd_tsk->flags |= PF_NOFREEZE;
602 wake_up_process(kapmd_tsk);
603
604#ifdef CONFIG_PROC_FS
605 create_proc_info_entry("apm", 0, NULL, apm_get_info);
606#endif
607
608 ret = misc_register(&apm_device);
609 if (ret != 0) {
610 remove_proc_entry("apm", NULL);
611 kthread_stop(kapmd_tsk);
612 }
613
614 return ret;
615}
616
617static void __exit apm_exit(void)
618{
619 misc_deregister(&apm_device);
620 remove_proc_entry("apm", NULL);
621
622 kthread_stop(kapmd_tsk);
623}
624
625module_init(apm_init);
626module_exit(apm_exit);
627
628MODULE_AUTHOR("Stephen Rothwell");
629MODULE_DESCRIPTION("Advanced Power Management");
630MODULE_LICENSE("GPL");
631
632#ifndef MODULE
633static int __init apm_setup(char *str)
634{
635 while ((str != NULL) && (*str != '\0')) {
636 if (strncmp(str, "off", 3) == 0)
637 apm_disabled = 1;
638 if (strncmp(str, "on", 2) == 0)
639 apm_disabled = 0;
640 str = strchr(str, ',');
641 if (str != NULL)
642 str += strspn(str, ", \t");
643 }
644 return 1;
645}
646
647__setup("apm=", apm_setup);
648#endif
649
650/**
651 * apm_queue_event - queue an APM event for kapmd
652 * @event: APM event
653 *
654 * Queue an APM event for kapmd to process and ultimately take the
655 * appropriate action. Only a subset of events are handled:
656 * %APM_LOW_BATTERY
657 * %APM_POWER_STATUS_CHANGE
658 * %APM_USER_SUSPEND
659 * %APM_SYS_SUSPEND
660 * %APM_CRITICAL_SUSPEND
661 */
662void apm_queue_event(apm_event_t event)
663{
664 unsigned long flags;
665
666 spin_lock_irqsave(&kapmd_queue_lock, flags);
667 queue_add_event(&kapmd_queue, event);
668 spin_unlock_irqrestore(&kapmd_queue_lock, flags);
669
670 wake_up_interruptible(&kapmd_wait);
671}
672EXPORT_SYMBOL(apm_queue_event);
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 6dcdceb81203..85d99e21e188 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -532,11 +532,13 @@ typedef struct drm_mm_node {
532 int free; 532 int free;
533 unsigned long start; 533 unsigned long start;
534 unsigned long size; 534 unsigned long size;
535 struct drm_mm *mm;
535 void *private; 536 void *private;
536} drm_mm_node_t; 537} drm_mm_node_t;
537 538
538typedef struct drm_mm { 539typedef struct drm_mm {
539 drm_mm_node_t root_node; 540 struct list_head fl_entry;
541 struct list_head ml_entry;
540} drm_mm_t; 542} drm_mm_t;
541 543
542/** 544/**
@@ -843,9 +845,6 @@ extern void drm_mem_init(void);
843extern int drm_mem_info(char *buf, char **start, off_t offset, 845extern int drm_mem_info(char *buf, char **start, off_t offset,
844 int request, int *eof, void *data); 846 int request, int *eof, void *data);
845extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); 847extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
846extern void *drm_ioremap(unsigned long offset, unsigned long size,
847 drm_device_t * dev);
848extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev);
849 848
850extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); 849extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type);
851extern int drm_free_agp(DRM_AGP_MEM * handle, int pages); 850extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
@@ -1053,33 +1052,18 @@ extern void drm_sysfs_device_remove(struct class_device *class_dev);
1053extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, 1052extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
1054 unsigned long size, 1053 unsigned long size,
1055 unsigned alignment); 1054 unsigned alignment);
1056extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur); 1055void drm_mm_put_block(drm_mm_node_t * cur);
1057extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, 1056extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size,
1058 unsigned alignment, int best_match); 1057 unsigned alignment, int best_match);
1059extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); 1058extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size);
1060extern void drm_mm_takedown(drm_mm_t *mm); 1059extern void drm_mm_takedown(drm_mm_t *mm);
1060extern int drm_mm_clean(drm_mm_t *mm);
1061extern unsigned long drm_mm_tail_space(drm_mm_t *mm);
1062extern int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size);
1063extern int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size);
1061 1064
1062/* Inline replacements for DRM_IOREMAP macros */ 1065extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
1063static __inline__ void drm_core_ioremap(struct drm_map *map, 1066extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
1064 struct drm_device *dev)
1065{
1066 map->handle = drm_ioremap(map->offset, map->size, dev);
1067}
1068
1069#if 0
1070static __inline__ void drm_core_ioremap_nocache(struct drm_map *map,
1071 struct drm_device *dev)
1072{
1073 map->handle = drm_ioremap_nocache(map->offset, map->size, dev);
1074}
1075#endif /* 0 */
1076
1077static __inline__ void drm_core_ioremapfree(struct drm_map *map,
1078 struct drm_device *dev)
1079{
1080 if (map->handle && map->size)
1081 drm_ioremapfree(map->handle, map->size, dev);
1082}
1083 1067
1084static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, 1068static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
1085 unsigned int token) 1069 unsigned int token)
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 9f65f5697ba8..a6828cc14e58 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -79,14 +79,14 @@ static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
79 79
80 if (!use_hashed_handle) { 80 if (!use_hashed_handle) {
81 int ret; 81 int ret;
82 hash->key = user_token; 82 hash->key = user_token >> PAGE_SHIFT;
83 ret = drm_ht_insert_item(&dev->map_hash, hash); 83 ret = drm_ht_insert_item(&dev->map_hash, hash);
84 if (ret != -EINVAL) 84 if (ret != -EINVAL)
85 return ret; 85 return ret;
86 } 86 }
87 return drm_ht_just_insert_please(&dev->map_hash, hash, 87 return drm_ht_just_insert_please(&dev->map_hash, hash,
88 user_token, 32 - PAGE_SHIFT - 3, 88 user_token, 32 - PAGE_SHIFT - 3,
89 PAGE_SHIFT, DRM_MAP_HASH_OFFSET); 89 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);
90} 90}
91 91
92/** 92/**
@@ -178,11 +178,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
178 } 178 }
179 } 179 }
180 if (map->type == _DRM_REGISTERS) 180 if (map->type == _DRM_REGISTERS)
181 map->handle = drm_ioremap(map->offset, map->size, dev); 181 map->handle = ioremap(map->offset, map->size);
182 break; 182 break;
183 183
184 case _DRM_SHM: 184 case _DRM_SHM:
185 map->handle = vmalloc_32(map->size); 185 map->handle = vmalloc_user(map->size);
186 DRM_DEBUG("%lu %d %p\n", 186 DRM_DEBUG("%lu %d %p\n",
187 map->size, drm_order(map->size), map->handle); 187 map->size, drm_order(map->size), map->handle);
188 if (!map->handle) { 188 if (!map->handle) {
@@ -238,7 +238,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
238 list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); 238 list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
239 if (!list) { 239 if (!list) {
240 if (map->type == _DRM_REGISTERS) 240 if (map->type == _DRM_REGISTERS)
241 drm_ioremapfree(map->handle, map->size, dev); 241 iounmap(map->handle);
242 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 242 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
243 return -EINVAL; 243 return -EINVAL;
244 } 244 }
@@ -255,14 +255,14 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
255 ret = drm_map_handle(dev, &list->hash, user_token, 0); 255 ret = drm_map_handle(dev, &list->hash, user_token, 0);
256 if (ret) { 256 if (ret) {
257 if (map->type == _DRM_REGISTERS) 257 if (map->type == _DRM_REGISTERS)
258 drm_ioremapfree(map->handle, map->size, dev); 258 iounmap(map->handle);
259 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 259 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
260 drm_free(list, sizeof(*list), DRM_MEM_MAPS); 260 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
261 mutex_unlock(&dev->struct_mutex); 261 mutex_unlock(&dev->struct_mutex);
262 return ret; 262 return ret;
263 } 263 }
264 264
265 list->user_token = list->hash.key; 265 list->user_token = list->hash.key << PAGE_SHIFT;
266 mutex_unlock(&dev->struct_mutex); 266 mutex_unlock(&dev->struct_mutex);
267 267
268 *maplist = list; 268 *maplist = list;
@@ -347,7 +347,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
347 347
348 if (r_list->map == map) { 348 if (r_list->map == map) {
349 list_del(list); 349 list_del(list);
350 drm_ht_remove_key(&dev->map_hash, r_list->user_token); 350 drm_ht_remove_key(&dev->map_hash,
351 r_list->user_token >> PAGE_SHIFT);
351 drm_free(list, sizeof(*list), DRM_MEM_MAPS); 352 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
352 break; 353 break;
353 } 354 }
@@ -362,7 +363,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
362 363
363 switch (map->type) { 364 switch (map->type) {
364 case _DRM_REGISTERS: 365 case _DRM_REGISTERS:
365 drm_ioremapfree(map->handle, map->size, dev); 366 iounmap(map->handle);
366 /* FALLTHROUGH */ 367 /* FALLTHROUGH */
367 case _DRM_FRAME_BUFFER: 368 case _DRM_FRAME_BUFFER:
368 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) { 369 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index 5681cae1d404..92a867082376 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -79,28 +79,6 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
79} 79}
80 80
81#if __OS_HAS_AGP 81#if __OS_HAS_AGP
82/*
83 * Find the drm_map that covers the range [offset, offset+size).
84 */
85static drm_map_t *drm_lookup_map(unsigned long offset,
86 unsigned long size, drm_device_t * dev)
87{
88 struct list_head *list;
89 drm_map_list_t *r_list;
90 drm_map_t *map;
91
92 list_for_each(list, &dev->maplist->head) {
93 r_list = (drm_map_list_t *) list;
94 map = r_list->map;
95 if (!map)
96 continue;
97 if (map->offset <= offset
98 && (offset + size) <= (map->offset + map->size))
99 return map;
100 }
101 return NULL;
102}
103
104static void *agp_remap(unsigned long offset, unsigned long size, 82static void *agp_remap(unsigned long offset, unsigned long size,
105 drm_device_t * dev) 83 drm_device_t * dev)
106{ 84{
@@ -169,13 +147,6 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
169} 147}
170 148
171#else /* __OS_HAS_AGP */ 149#else /* __OS_HAS_AGP */
172
173static inline drm_map_t *drm_lookup_map(unsigned long offset,
174 unsigned long size, drm_device_t * dev)
175{
176 return NULL;
177}
178
179static inline void *agp_remap(unsigned long offset, unsigned long size, 150static inline void *agp_remap(unsigned long offset, unsigned long size,
180 drm_device_t * dev) 151 drm_device_t * dev)
181{ 152{
@@ -184,57 +155,28 @@ static inline void *agp_remap(unsigned long offset, unsigned long size,
184 155
185#endif /* agp */ 156#endif /* agp */
186 157
187void *drm_ioremap(unsigned long offset, unsigned long size, 158#endif /* debug_memory */
188 drm_device_t * dev)
189{
190 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
191 drm_map_t *map = drm_lookup_map(offset, size, dev);
192
193 if (map && map->type == _DRM_AGP)
194 return agp_remap(offset, size, dev);
195 }
196 return ioremap(offset, size);
197}
198EXPORT_SYMBOL(drm_ioremap);
199 159
200#if 0 160void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
201void *drm_ioremap_nocache(unsigned long offset,
202 unsigned long size, drm_device_t * dev)
203{ 161{
204 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { 162 if (drm_core_has_AGP(dev) &&
205 drm_map_t *map = drm_lookup_map(offset, size, dev); 163 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
206 164 map->handle = agp_remap(map->offset, map->size, dev);
207 if (map && map->type == _DRM_AGP) 165 else
208 return agp_remap(offset, size, dev); 166 map->handle = ioremap(map->offset, map->size);
209 }
210 return ioremap_nocache(offset, size);
211} 167}
212#endif /* 0 */ 168EXPORT_SYMBOL(drm_core_ioremap);
213 169
214void drm_ioremapfree(void *pt, unsigned long size, 170void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
215 drm_device_t * dev)
216{ 171{
217 /* 172 if (!map->handle || !map->size)
218 * This is a bit ugly. It would be much cleaner if the DRM API would use separate 173 return;
219 * routines for handling mappings in the AGP space. Hopefully this can be done in 174
220 * a future revision of the interface... 175 if (drm_core_has_AGP(dev) &&
221 */ 176 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
222 if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture 177 vunmap(map->handle);
223 && ((unsigned long)pt >= VMALLOC_START 178 else
224 && (unsigned long)pt < VMALLOC_END)) { 179 iounmap(map->handle);
225 unsigned long offset;
226 drm_map_t *map;
227
228 offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
229 map = drm_lookup_map(offset, size, dev);
230 if (map && map->type == _DRM_AGP) {
231 vunmap(pt);
232 return;
233 }
234 }
235
236 iounmap(pt);
237} 180}
238EXPORT_SYMBOL(drm_ioremapfree); 181EXPORT_SYMBOL(drm_core_ioremapfree);
239 182
240#endif /* debug_memory */
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
index f1b97aff10cf..63e425b5ea82 100644
--- a/drivers/char/drm/drm_memory.h
+++ b/drivers/char/drm/drm_memory.h
@@ -56,26 +56,6 @@
56# endif 56# endif
57#endif 57#endif
58 58
59static inline unsigned long drm_follow_page(void *vaddr)
60{
61 pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
62 pud_t *pud = pud_offset(pgd, (unsigned long)vaddr);
63 pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr);
64 pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr);
65 return pte_pfn(*ptep) << PAGE_SHIFT;
66}
67
68#else /* __OS_HAS_AGP */ 59#else /* __OS_HAS_AGP */
69 60
70static inline unsigned long drm_follow_page(void *vaddr)
71{
72 return 0;
73}
74
75#endif 61#endif
76
77void *drm_ioremap(unsigned long offset, unsigned long size,
78 drm_device_t * dev);
79
80void drm_ioremapfree(void *pt, unsigned long size,
81 drm_device_t * dev);
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index 74581af806e1..6463271deea8 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -205,76 +205,6 @@ void drm_free (void *pt, size_t size, int area) {
205 } 205 }
206} 206}
207 207
208void *drm_ioremap (unsigned long offset, unsigned long size,
209 drm_device_t * dev) {
210 void *pt;
211
212 if (!size) {
213 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
214 "Mapping 0 bytes at 0x%08lx\n", offset);
215 return NULL;
216 }
217
218 if (!(pt = drm_ioremap(offset, size, dev))) {
219 spin_lock(&drm_mem_lock);
220 ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
221 spin_unlock(&drm_mem_lock);
222 return NULL;
223 }
224 spin_lock(&drm_mem_lock);
225 ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
226 drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
227 spin_unlock(&drm_mem_lock);
228 return pt;
229}
230
231#if 0
232void *drm_ioremap_nocache (unsigned long offset, unsigned long size,
233 drm_device_t * dev) {
234 void *pt;
235
236 if (!size) {
237 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
238 "Mapping 0 bytes at 0x%08lx\n", offset);
239 return NULL;
240 }
241
242 if (!(pt = drm_ioremap_nocache(offset, size, dev))) {
243 spin_lock(&drm_mem_lock);
244 ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
245 spin_unlock(&drm_mem_lock);
246 return NULL;
247 }
248 spin_lock(&drm_mem_lock);
249 ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
250 drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
251 spin_unlock(&drm_mem_lock);
252 return pt;
253}
254#endif /* 0 */
255
256void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) {
257 int alloc_count;
258 int free_count;
259
260 if (!pt)
261 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
262 "Attempt to free NULL pointer\n");
263 else
264 drm_ioremapfree(pt, size, dev);
265
266 spin_lock(&drm_mem_lock);
267 drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
268 free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
269 alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
270 spin_unlock(&drm_mem_lock);
271 if (free_count > alloc_count) {
272 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
273 "Excess frees: %d frees, %d allocs\n",
274 free_count, alloc_count);
275 }
276}
277
278#if __OS_HAS_AGP 208#if __OS_HAS_AGP
279 209
280DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { 210DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) {
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c
index 617526bd5b0c..9b46b85027d0 100644
--- a/drivers/char/drm/drm_mm.c
+++ b/drivers/char/drm/drm_mm.c
@@ -42,36 +42,131 @@
42 */ 42 */
43 43
44#include "drmP.h" 44#include "drmP.h"
45#include <linux/slab.h>
46
47unsigned long drm_mm_tail_space(drm_mm_t *mm)
48{
49 struct list_head *tail_node;
50 drm_mm_node_t *entry;
51
52 tail_node = mm->ml_entry.prev;
53 entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
54 if (!entry->free)
55 return 0;
56
57 return entry->size;
58}
59
60int drm_mm_remove_space_from_tail(drm_mm_t *mm, unsigned long size)
61{
62 struct list_head *tail_node;
63 drm_mm_node_t *entry;
64
65 tail_node = mm->ml_entry.prev;
66 entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
67 if (!entry->free)
68 return -ENOMEM;
69
70 if (entry->size <= size)
71 return -ENOMEM;
72
73 entry->size -= size;
74 return 0;
75}
76
77
78static int drm_mm_create_tail_node(drm_mm_t *mm,
79 unsigned long start,
80 unsigned long size)
81{
82 drm_mm_node_t *child;
83
84 child = (drm_mm_node_t *)
85 drm_alloc(sizeof(*child), DRM_MEM_MM);
86 if (!child)
87 return -ENOMEM;
88
89 child->free = 1;
90 child->size = size;
91 child->start = start;
92 child->mm = mm;
93
94 list_add_tail(&child->ml_entry, &mm->ml_entry);
95 list_add_tail(&child->fl_entry, &mm->fl_entry);
96
97 return 0;
98}
99
100
101int drm_mm_add_space_to_tail(drm_mm_t *mm, unsigned long size)
102{
103 struct list_head *tail_node;
104 drm_mm_node_t *entry;
105
106 tail_node = mm->ml_entry.prev;
107 entry = list_entry(tail_node, drm_mm_node_t, ml_entry);
108 if (!entry->free) {
109 return drm_mm_create_tail_node(mm, entry->start + entry->size, size);
110 }
111 entry->size += size;
112 return 0;
113}
114
115static drm_mm_node_t *drm_mm_split_at_start(drm_mm_node_t *parent,
116 unsigned long size)
117{
118 drm_mm_node_t *child;
119
120 child = (drm_mm_node_t *)
121 drm_alloc(sizeof(*child), DRM_MEM_MM);
122 if (!child)
123 return NULL;
124
125 INIT_LIST_HEAD(&child->fl_entry);
126
127 child->free = 0;
128 child->size = size;
129 child->start = parent->start;
130 child->mm = parent->mm;
131
132 list_add_tail(&child->ml_entry, &parent->ml_entry);
133 INIT_LIST_HEAD(&child->fl_entry);
134
135 parent->size -= size;
136 parent->start += size;
137 return child;
138}
139
140
45 141
46drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, 142drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
47 unsigned long size, unsigned alignment) 143 unsigned long size, unsigned alignment)
48{ 144{
49 145
146 drm_mm_node_t *align_splitoff = NULL;
50 drm_mm_node_t *child; 147 drm_mm_node_t *child;
148 unsigned tmp = 0;
51 149
52 if (alignment) 150 if (alignment)
53 size += alignment - 1; 151 tmp = parent->start % alignment;
152
153 if (tmp) {
154 align_splitoff = drm_mm_split_at_start(parent, alignment - tmp);
155 if (!align_splitoff)
156 return NULL;
157 }
54 158
55 if (parent->size == size) { 159 if (parent->size == size) {
56 list_del_init(&parent->fl_entry); 160 list_del_init(&parent->fl_entry);
57 parent->free = 0; 161 parent->free = 0;
58 return parent; 162 return parent;
59 } else { 163 } else {
60 child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); 164 child = drm_mm_split_at_start(parent, size);
61 if (!child) 165 }
62 return NULL;
63
64 INIT_LIST_HEAD(&child->ml_entry);
65 INIT_LIST_HEAD(&child->fl_entry);
66 166
67 child->free = 0; 167 if (align_splitoff)
68 child->size = size; 168 drm_mm_put_block(align_splitoff);
69 child->start = parent->start;
70 169
71 list_add_tail(&child->ml_entry, &parent->ml_entry);
72 parent->size -= size;
73 parent->start += size;
74 }
75 return child; 170 return child;
76} 171}
77 172
@@ -80,12 +175,12 @@ drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent,
80 * Otherwise add to the free stack. 175 * Otherwise add to the free stack.
81 */ 176 */
82 177
83void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) 178void drm_mm_put_block(drm_mm_node_t * cur)
84{ 179{
85 180
86 drm_mm_node_t *list_root = &mm->root_node; 181 drm_mm_t *mm = cur->mm;
87 struct list_head *cur_head = &cur->ml_entry; 182 struct list_head *cur_head = &cur->ml_entry;
88 struct list_head *root_head = &list_root->ml_entry; 183 struct list_head *root_head = &mm->ml_entry;
89 drm_mm_node_t *prev_node = NULL; 184 drm_mm_node_t *prev_node = NULL;
90 drm_mm_node_t *next_node; 185 drm_mm_node_t *next_node;
91 186
@@ -116,7 +211,7 @@ void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur)
116 } 211 }
117 if (!merged) { 212 if (!merged) {
118 cur->free = 1; 213 cur->free = 1;
119 list_add(&cur->fl_entry, &list_root->fl_entry); 214 list_add(&cur->fl_entry, &mm->fl_entry);
120 } else { 215 } else {
121 list_del(&cur->ml_entry); 216 list_del(&cur->ml_entry);
122 drm_free(cur, sizeof(*cur), DRM_MEM_MM); 217 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
@@ -128,20 +223,30 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
128 unsigned alignment, int best_match) 223 unsigned alignment, int best_match)
129{ 224{
130 struct list_head *list; 225 struct list_head *list;
131 const struct list_head *free_stack = &mm->root_node.fl_entry; 226 const struct list_head *free_stack = &mm->fl_entry;
132 drm_mm_node_t *entry; 227 drm_mm_node_t *entry;
133 drm_mm_node_t *best; 228 drm_mm_node_t *best;
134 unsigned long best_size; 229 unsigned long best_size;
230 unsigned wasted;
135 231
136 best = NULL; 232 best = NULL;
137 best_size = ~0UL; 233 best_size = ~0UL;
138 234
139 if (alignment)
140 size += alignment - 1;
141
142 list_for_each(list, free_stack) { 235 list_for_each(list, free_stack) {
143 entry = list_entry(list, drm_mm_node_t, fl_entry); 236 entry = list_entry(list, drm_mm_node_t, fl_entry);
144 if (entry->size >= size) { 237 wasted = 0;
238
239 if (entry->size < size)
240 continue;
241
242 if (alignment) {
243 register unsigned tmp = entry->start % alignment;
244 if (tmp)
245 wasted += alignment - tmp;
246 }
247
248
249 if (entry->size >= size + wasted) {
145 if (!best_match) 250 if (!best_match)
146 return entry; 251 return entry;
147 if (size < best_size) { 252 if (size < best_size) {
@@ -154,40 +259,32 @@ drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm,
154 return best; 259 return best;
155} 260}
156 261
157int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) 262int drm_mm_clean(drm_mm_t * mm)
158{ 263{
159 drm_mm_node_t *child; 264 struct list_head *head = &mm->ml_entry;
160
161 INIT_LIST_HEAD(&mm->root_node.ml_entry);
162 INIT_LIST_HEAD(&mm->root_node.fl_entry);
163 child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM);
164 if (!child)
165 return -ENOMEM;
166
167 INIT_LIST_HEAD(&child->ml_entry);
168 INIT_LIST_HEAD(&child->fl_entry);
169 265
170 child->start = start; 266 return (head->next->next == head);
171 child->size = size; 267}
172 child->free = 1;
173 268
174 list_add(&child->fl_entry, &mm->root_node.fl_entry); 269int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size)
175 list_add(&child->ml_entry, &mm->root_node.ml_entry); 270{
271 INIT_LIST_HEAD(&mm->ml_entry);
272 INIT_LIST_HEAD(&mm->fl_entry);
176 273
177 return 0; 274 return drm_mm_create_tail_node(mm, start, size);
178} 275}
179 276
180EXPORT_SYMBOL(drm_mm_init); 277EXPORT_SYMBOL(drm_mm_init);
181 278
182void drm_mm_takedown(drm_mm_t * mm) 279void drm_mm_takedown(drm_mm_t * mm)
183{ 280{
184 struct list_head *bnode = mm->root_node.fl_entry.next; 281 struct list_head *bnode = mm->fl_entry.next;
185 drm_mm_node_t *entry; 282 drm_mm_node_t *entry;
186 283
187 entry = list_entry(bnode, drm_mm_node_t, fl_entry); 284 entry = list_entry(bnode, drm_mm_node_t, fl_entry);
188 285
189 if (entry->ml_entry.next != &mm->root_node.ml_entry || 286 if (entry->ml_entry.next != &mm->ml_entry ||
190 entry->fl_entry.next != &mm->root_node.fl_entry) { 287 entry->fl_entry.next != &mm->fl_entry) {
191 DRM_ERROR("Memory manager not clean. Delaying takedown\n"); 288 DRM_ERROR("Memory manager not clean. Delaying takedown\n");
192 return; 289 return;
193 } 290 }
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 09398d5fbd3f..ad54b845978b 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -226,12 +226,14 @@
226 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 226 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
227 {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ 227 {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
228 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 228 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
229 {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
229 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 230 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
230 {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 231 {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
231 {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 232 {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
232 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 233 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
233 {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 234 {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
234 {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ 235 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
236 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
235 {0, 0, 0} 237 {0, 0, 0}
236 238
237#define i810_PCI_IDS \ 239#define i810_PCI_IDS \
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 62d5fe15f046..7fd0da712142 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -500,7 +500,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
500 for (pt = dev->vmalist; pt; pt = pt->next) { 500 for (pt = dev->vmalist; pt; pt = pt->next) {
501 if (!(vma = pt->vma)) 501 if (!(vma = pt->vma))
502 continue; 502 continue;
503 DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx", 503 DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
504 pt->pid, 504 pt->pid,
505 vma->vm_start, 505 vma->vm_start,
506 vma->vm_end, 506 vma->vm_end,
@@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
510 vma->vm_flags & VM_MAYSHARE ? 's' : 'p', 510 vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
511 vma->vm_flags & VM_LOCKED ? 'l' : '-', 511 vma->vm_flags & VM_LOCKED ? 'l' : '-',
512 vma->vm_flags & VM_IO ? 'i' : '-', 512 vma->vm_flags & VM_IO ? 'i' : '-',
513 vma->vm_pgoff << PAGE_SHIFT); 513 vma->vm_pgoff);
514 514
515#if defined(__i386__) 515#if defined(__i386__)
516 pgprot = pgprot_val(vma->vm_page_prot); 516 pgprot = pgprot_val(vma->vm_page_prot);
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c
index 19c81d2e13d0..e15db6d6bea9 100644
--- a/drivers/char/drm/drm_sman.c
+++ b/drivers/char/drm/drm_sman.c
@@ -101,10 +101,9 @@ static void *drm_sman_mm_allocate(void *private, unsigned long size,
101 101
102static void drm_sman_mm_free(void *private, void *ref) 102static void drm_sman_mm_free(void *private, void *ref)
103{ 103{
104 drm_mm_t *mm = (drm_mm_t *) private;
105 drm_mm_node_t *node = (drm_mm_node_t *) ref; 104 drm_mm_node_t *node = (drm_mm_node_t *) ref;
106 105
107 drm_mm_put_block(mm, node); 106 drm_mm_put_block(node);
108} 107}
109 108
110static void drm_sman_mm_destroy(void *private) 109static void drm_sman_mm_destroy(void *private)
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index b9cfc077f6bc..54a632848955 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -70,7 +70,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
70 if (!dev->agp || !dev->agp->cant_use_aperture) 70 if (!dev->agp || !dev->agp->cant_use_aperture)
71 goto vm_nopage_error; 71 goto vm_nopage_error;
72 72
73 if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) 73 if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
74 goto vm_nopage_error; 74 goto vm_nopage_error;
75 75
76 r_list = drm_hash_entry(hash, drm_map_list_t, hash); 76 r_list = drm_hash_entry(hash, drm_map_list_t, hash);
@@ -227,7 +227,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
227 map->size); 227 map->size);
228 DRM_DEBUG("mtrr_del = %d\n", retcode); 228 DRM_DEBUG("mtrr_del = %d\n", retcode);
229 } 229 }
230 drm_ioremapfree(map->handle, map->size, dev); 230 iounmap(map->handle);
231 break; 231 break;
232 case _DRM_SHM: 232 case _DRM_SHM:
233 vfree(map->handle); 233 vfree(map->handle);
@@ -463,8 +463,8 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
463 lock_kernel(); 463 lock_kernel();
464 dev = priv->head->dev; 464 dev = priv->head->dev;
465 dma = dev->dma; 465 dma = dev->dma;
466 DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", 466 DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
467 vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); 467 vma->vm_start, vma->vm_end, vma->vm_pgoff);
468 468
469 /* Length must match exact page count */ 469 /* Length must match exact page count */
470 if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { 470 if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
@@ -537,8 +537,8 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
537 unsigned long offset = 0; 537 unsigned long offset = 0;
538 drm_hash_item_t *hash; 538 drm_hash_item_t *hash;
539 539
540 DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", 540 DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
541 vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); 541 vma->vm_start, vma->vm_end, vma->vm_pgoff);
542 542
543 if (!priv->authenticated) 543 if (!priv->authenticated)
544 return -EACCES; 544 return -EACCES;
@@ -547,7 +547,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
547 * the AGP mapped at physical address 0 547 * the AGP mapped at physical address 0
548 * --BenH. 548 * --BenH.
549 */ 549 */
550 if (!(vma->vm_pgoff << PAGE_SHIFT) 550 if (!vma->vm_pgoff
551#if __OS_HAS_AGP 551#if __OS_HAS_AGP
552 && (!dev->agp 552 && (!dev->agp
553 || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) 553 || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
@@ -555,7 +555,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
555 ) 555 )
556 return drm_mmap_dma(filp, vma); 556 return drm_mmap_dma(filp, vma);
557 557
558 if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) { 558 if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) {
559 DRM_ERROR("Could not find map\n"); 559 DRM_ERROR("Could not find map\n");
560 return -EINVAL; 560 return -EINVAL;
561 } 561 }
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index fa2de70f7401..60cb4e45a75e 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -219,8 +219,7 @@ static int i810_dma_cleanup(drm_device_t * dev)
219 (drm_i810_private_t *) dev->dev_private; 219 (drm_i810_private_t *) dev->dev_private;
220 220
221 if (dev_priv->ring.virtual_start) { 221 if (dev_priv->ring.virtual_start) {
222 drm_ioremapfree((void *)dev_priv->ring.virtual_start, 222 drm_core_ioremapfree(&dev_priv->ring.map, dev);
223 dev_priv->ring.Size, dev);
224 } 223 }
225 if (dev_priv->hw_status_page) { 224 if (dev_priv->hw_status_page) {
226 pci_free_consistent(dev->pdev, PAGE_SIZE, 225 pci_free_consistent(dev->pdev, PAGE_SIZE,
@@ -236,9 +235,9 @@ static int i810_dma_cleanup(drm_device_t * dev)
236 for (i = 0; i < dma->buf_count; i++) { 235 for (i = 0; i < dma->buf_count; i++) {
237 drm_buf_t *buf = dma->buflist[i]; 236 drm_buf_t *buf = dma->buflist[i];
238 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 237 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
238
239 if (buf_priv->kernel_virtual && buf->total) 239 if (buf_priv->kernel_virtual && buf->total)
240 drm_ioremapfree(buf_priv->kernel_virtual, 240 drm_core_ioremapfree(&buf_priv->map, dev);
241 buf->total, dev);
242 } 241 }
243 } 242 }
244 return 0; 243 return 0;
@@ -311,8 +310,15 @@ static int i810_freelist_init(drm_device_t * dev, drm_i810_private_t * dev_priv)
311 310
312 *buf_priv->in_use = I810_BUF_FREE; 311 *buf_priv->in_use = I810_BUF_FREE;
313 312
314 buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 313 buf_priv->map.offset = buf->bus_address;
315 buf->total, dev); 314 buf_priv->map.size = buf->total;
315 buf_priv->map.type = _DRM_AGP;
316 buf_priv->map.flags = 0;
317 buf_priv->map.mtrr = 0;
318
319 drm_core_ioremap(&buf_priv->map, dev);
320 buf_priv->kernel_virtual = buf_priv->map.handle;
321
316 } 322 }
317 return 0; 323 return 0;
318} 324}
@@ -363,18 +369,24 @@ static int i810_dma_initialize(drm_device_t * dev,
363 dev_priv->ring.End = init->ring_end; 369 dev_priv->ring.End = init->ring_end;
364 dev_priv->ring.Size = init->ring_size; 370 dev_priv->ring.Size = init->ring_size;
365 371
366 dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 372 dev_priv->ring.map.offset = dev->agp->base + init->ring_start;
367 init->ring_start, 373 dev_priv->ring.map.size = init->ring_size;
368 init->ring_size, dev); 374 dev_priv->ring.map.type = _DRM_AGP;
375 dev_priv->ring.map.flags = 0;
376 dev_priv->ring.map.mtrr = 0;
369 377
370 if (dev_priv->ring.virtual_start == NULL) { 378 drm_core_ioremap(&dev_priv->ring.map, dev);
379
380 if (dev_priv->ring.map.handle == NULL) {
371 dev->dev_private = (void *)dev_priv; 381 dev->dev_private = (void *)dev_priv;
372 i810_dma_cleanup(dev); 382 i810_dma_cleanup(dev);
373 DRM_ERROR("can not ioremap virtual address for" 383 DRM_ERROR("can not ioremap virtual address for"
374 " ring buffer\n"); 384 " ring buffer\n");
375 return -ENOMEM; 385 return DRM_ERR(ENOMEM);
376 } 386 }
377 387
388 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
389
378 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 390 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
379 391
380 dev_priv->w = init->w; 392 dev_priv->w = init->w;
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index e8cf3ff606f0..e6df49f4928a 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -61,6 +61,7 @@ typedef struct drm_i810_buf_priv {
61 int currently_mapped; 61 int currently_mapped;
62 void *virtual; 62 void *virtual;
63 void *kernel_virtual; 63 void *kernel_virtual;
64 drm_local_map_t map;
64} drm_i810_buf_priv_t; 65} drm_i810_buf_priv_t;
65 66
66typedef struct _drm_i810_ring_buffer { 67typedef struct _drm_i810_ring_buffer {
@@ -72,6 +73,7 @@ typedef struct _drm_i810_ring_buffer {
72 int head; 73 int head;
73 int tail; 74 int tail;
74 int space; 75 int space;
76 drm_local_map_t map;
75} drm_i810_ring_buffer_t; 77} drm_i810_ring_buffer_t;
76 78
77typedef struct drm_i810_private { 79typedef struct drm_i810_private {
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 4f0e5746ab33..95224455ec0c 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -223,8 +223,7 @@ static int i830_dma_cleanup(drm_device_t * dev)
223 (drm_i830_private_t *) dev->dev_private; 223 (drm_i830_private_t *) dev->dev_private;
224 224
225 if (dev_priv->ring.virtual_start) { 225 if (dev_priv->ring.virtual_start) {
226 drm_ioremapfree((void *)dev_priv->ring.virtual_start, 226 drm_core_ioremapfree(&dev_priv->ring.map, dev);
227 dev_priv->ring.Size, dev);
228 } 227 }
229 if (dev_priv->hw_status_page) { 228 if (dev_priv->hw_status_page) {
230 pci_free_consistent(dev->pdev, PAGE_SIZE, 229 pci_free_consistent(dev->pdev, PAGE_SIZE,
@@ -242,8 +241,7 @@ static int i830_dma_cleanup(drm_device_t * dev)
242 drm_buf_t *buf = dma->buflist[i]; 241 drm_buf_t *buf = dma->buflist[i];
243 drm_i830_buf_priv_t *buf_priv = buf->dev_private; 242 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
244 if (buf_priv->kernel_virtual && buf->total) 243 if (buf_priv->kernel_virtual && buf->total)
245 drm_ioremapfree(buf_priv->kernel_virtual, 244 drm_core_ioremapfree(&buf_priv->map, dev);
246 buf->total, dev);
247 } 245 }
248 } 246 }
249 return 0; 247 return 0;
@@ -320,8 +318,14 @@ static int i830_freelist_init(drm_device_t * dev, drm_i830_private_t * dev_priv)
320 318
321 *buf_priv->in_use = I830_BUF_FREE; 319 *buf_priv->in_use = I830_BUF_FREE;
322 320
323 buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 321 buf_priv->map.offset = buf->bus_address;
324 buf->total, dev); 322 buf_priv->map.size = buf->total;
323 buf_priv->map.type = _DRM_AGP;
324 buf_priv->map.flags = 0;
325 buf_priv->map.mtrr = 0;
326
327 drm_core_ioremap(&buf_priv->map, dev);
328 buf_priv->kernel_virtual = buf_priv->map.handle;
325 } 329 }
326 return 0; 330 return 0;
327} 331}
@@ -373,18 +377,24 @@ static int i830_dma_initialize(drm_device_t * dev,
373 dev_priv->ring.End = init->ring_end; 377 dev_priv->ring.End = init->ring_end;
374 dev_priv->ring.Size = init->ring_size; 378 dev_priv->ring.Size = init->ring_size;
375 379
376 dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 380 dev_priv->ring.map.offset = dev->agp->base + init->ring_start;
377 init->ring_start, 381 dev_priv->ring.map.size = init->ring_size;
378 init->ring_size, dev); 382 dev_priv->ring.map.type = _DRM_AGP;
383 dev_priv->ring.map.flags = 0;
384 dev_priv->ring.map.mtrr = 0;
385
386 drm_core_ioremap(&dev_priv->ring.map, dev);
379 387
380 if (dev_priv->ring.virtual_start == NULL) { 388 if (dev_priv->ring.map.handle == NULL) {
381 dev->dev_private = (void *)dev_priv; 389 dev->dev_private = (void *)dev_priv;
382 i830_dma_cleanup(dev); 390 i830_dma_cleanup(dev);
383 DRM_ERROR("can not ioremap virtual address for" 391 DRM_ERROR("can not ioremap virtual address for"
384 " ring buffer\n"); 392 " ring buffer\n");
385 return -ENOMEM; 393 return DRM_ERR(ENOMEM);
386 } 394 }
387 395
396 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
397
388 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 398 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
389 399
390 dev_priv->w = init->w; 400 dev_priv->w = init->w;
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index 85bc5be6f916..e91f94afb4bb 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -68,6 +68,7 @@ typedef struct drm_i830_buf_priv {
68 int currently_mapped; 68 int currently_mapped;
69 void __user *virtual; 69 void __user *virtual;
70 void *kernel_virtual; 70 void *kernel_virtual;
71 drm_local_map_t map;
71} drm_i830_buf_priv_t; 72} drm_i830_buf_priv_t;
72 73
73typedef struct _drm_i830_ring_buffer { 74typedef struct _drm_i830_ring_buffer {
@@ -79,6 +80,7 @@ typedef struct _drm_i830_ring_buffer {
79 int head; 80 int head;
80 int tail; 81 int tail;
81 int space; 82 int space;
83 drm_local_map_t map;
82} drm_i830_ring_buffer_t; 84} drm_i830_ring_buffer_t;
83 85
84typedef struct drm_i830_private { 86typedef struct drm_i830_private {
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
index a691ae74129d..c0539c6299cf 100644
--- a/drivers/char/drm/via_dma.c
+++ b/drivers/char/drm/via_dma.c
@@ -190,6 +190,11 @@ static int via_initialize(drm_device_t * dev,
190 return DRM_ERR(EFAULT); 190 return DRM_ERR(EFAULT);
191 } 191 }
192 192
193 if (dev_priv->chipset == VIA_DX9_0) {
194 DRM_ERROR("AGP DMA is not supported on this chip\n");
195 return DRM_ERR(EINVAL);
196 }
197
193 dev_priv->ring.map.offset = dev->agp->base + init->offset; 198 dev_priv->ring.map.offset = dev->agp->base + init->offset;
194 dev_priv->ring.map.size = init->size; 199 dev_priv->ring.map.size = init->size;
195 dev_priv->ring.map.type = 0; 200 dev_priv->ring.map.type = 0;
@@ -480,6 +485,7 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
480 VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); 485 VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
481 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); 486 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
482 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); 487 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
488 VIA_READ(VIA_REG_TRANSPACE);
483 } 489 }
484 } 490 }
485 return paused; 491 return paused;
@@ -557,8 +563,9 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
557 563
558 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); 564 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
559 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); 565 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
560 566 DRM_WRITEMEMORYBARRIER();
561 VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); 567 VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
568 VIA_READ(VIA_REG_TRANSPACE);
562} 569}
563 570
564static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) 571static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index 806f9ce5f47b..2054d5773717 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -218,7 +218,9 @@ via_fire_dmablit(drm_device_t *dev, drm_via_sg_info_t *vsg, int engine)
218 VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE); 218 VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE);
219 VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0); 219 VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0);
220 VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start); 220 VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start);
221 DRM_WRITEMEMORYBARRIER();
221 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS); 222 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS);
223 VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04);
222} 224}
223 225
224/* 226/*
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index d21b5b75da0f..8b8778d4a423 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -29,10 +29,10 @@
29 29
30#define DRIVER_NAME "via" 30#define DRIVER_NAME "via"
31#define DRIVER_DESC "VIA Unichrome / Pro" 31#define DRIVER_DESC "VIA Unichrome / Pro"
32#define DRIVER_DATE "20060529" 32#define DRIVER_DATE "20061227"
33 33
34#define DRIVER_MAJOR 2 34#define DRIVER_MAJOR 2
35#define DRIVER_MINOR 10 35#define DRIVER_MINOR 11
36#define DRIVER_PATCHLEVEL 0 36#define DRIVER_PATCHLEVEL 0
37 37
38#include "via_verifier.h" 38#include "via_verifier.h"
@@ -79,7 +79,7 @@ typedef struct drm_via_private {
79 char pci_buf[VIA_PCI_BUF_SIZE]; 79 char pci_buf[VIA_PCI_BUF_SIZE];
80 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; 80 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
81 uint32_t num_fire_offsets; 81 uint32_t num_fire_offsets;
82 int pro_group_a; 82 int chipset;
83 drm_via_irq_t via_irqs[VIA_NUM_IRQS]; 83 drm_via_irq_t via_irqs[VIA_NUM_IRQS];
84 unsigned num_irqs; 84 unsigned num_irqs;
85 maskarray_t *irq_masks; 85 maskarray_t *irq_masks;
@@ -96,8 +96,9 @@ typedef struct drm_via_private {
96} drm_via_private_t; 96} drm_via_private_t;
97 97
98enum via_family { 98enum via_family {
99 VIA_OTHER = 0, 99 VIA_OTHER = 0, /* Baseline */
100 VIA_PRO_GROUP_A, 100 VIA_PRO_GROUP_A, /* Another video engine and DMA commands */
101 VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */
101}; 102};
102 103
103/* VIA MMIO register access */ 104/* VIA MMIO register access */
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
index c33d068cde19..1ac5941ad237 100644
--- a/drivers/char/drm/via_irq.c
+++ b/drivers/char/drm/via_irq.c
@@ -258,12 +258,16 @@ void via_driver_irq_preinstall(drm_device_t * dev)
258 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; 258 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
259 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; 259 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
260 260
261 dev_priv->irq_masks = (dev_priv->pro_group_a) ? 261 if (dev_priv->chipset == VIA_PRO_GROUP_A ||
262 via_pro_group_a_irqs : via_unichrome_irqs; 262 dev_priv->chipset == VIA_DX9_0) {
263 dev_priv->num_irqs = (dev_priv->pro_group_a) ? 263 dev_priv->irq_masks = via_pro_group_a_irqs;
264 via_num_pro_group_a : via_num_unichrome; 264 dev_priv->num_irqs = via_num_pro_group_a;
265 dev_priv->irq_map = (dev_priv->pro_group_a) ? 265 dev_priv->irq_map = via_irqmap_pro_group_a;
266 via_irqmap_pro_group_a : via_irqmap_unichrome; 266 } else {
267 dev_priv->irq_masks = via_unichrome_irqs;
268 dev_priv->num_irqs = via_num_unichrome;
269 dev_priv->irq_map = via_irqmap_unichrome;
270 }
267 271
268 for (i = 0; i < dev_priv->num_irqs; ++i) { 272 for (i = 0; i < dev_priv->num_irqs; ++i) {
269 atomic_set(&cur_irq->irq_received, 0); 273 atomic_set(&cur_irq->irq_received, 0);
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
index 782011e0a58d..4e3fc072aa3b 100644
--- a/drivers/char/drm/via_map.c
+++ b/drivers/char/drm/via_map.c
@@ -106,8 +106,7 @@ int via_driver_load(drm_device_t *dev, unsigned long chipset)
106 106
107 dev->dev_private = (void *)dev_priv; 107 dev->dev_private = (void *)dev_priv;
108 108
109 if (chipset == VIA_PRO_GROUP_A) 109 dev_priv->chipset = chipset;
110 dev_priv->pro_group_a = 1;
111 110
112 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); 111 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
113 if (ret) { 112 if (ret) {
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
index 70c897c88766..2e7e08078287 100644
--- a/drivers/char/drm/via_verifier.c
+++ b/drivers/char/drm/via_verifier.c
@@ -306,6 +306,7 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
306 unsigned long lo = ~0, hi = 0, tmp; 306 unsigned long lo = ~0, hi = 0, tmp;
307 uint32_t *addr, *pitch, *height, tex; 307 uint32_t *addr, *pitch, *height, tex;
308 unsigned i; 308 unsigned i;
309 int npot;
309 310
310 if (end > 9) 311 if (end > 9)
311 end = 9; 312 end = 9;
@@ -316,12 +317,15 @@ static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
316 &(cur_seq->t_addr[tex = cur_seq->texture][start]); 317 &(cur_seq->t_addr[tex = cur_seq->texture][start]);
317 pitch = &(cur_seq->pitch[tex][start]); 318 pitch = &(cur_seq->pitch[tex][start]);
318 height = &(cur_seq->height[tex][start]); 319 height = &(cur_seq->height[tex][start]);
319 320 npot = cur_seq->tex_npot[tex];
320 for (i = start; i <= end; ++i) { 321 for (i = start; i <= end; ++i) {
321 tmp = *addr++; 322 tmp = *addr++;
322 if (tmp < lo) 323 if (tmp < lo)
323 lo = tmp; 324 lo = tmp;
324 tmp += (*height++ << *pitch++); 325 if (i == 0 && npot)
326 tmp += (*height++ * *pitch++);
327 else
328 tmp += (*height++ << *pitch++);
325 if (tmp > hi) 329 if (tmp > hi)
326 hi = tmp; 330 hi = tmp;
327 } 331 }
@@ -443,13 +447,21 @@ investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
443 return 0; 447 return 0;
444 case check_texture_addr3: 448 case check_texture_addr3:
445 cur_seq->unfinished = tex_address; 449 cur_seq->unfinished = tex_address;
446 tmp = ((cmd >> 24) - 0x2B); 450 tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit);
447 cur_seq->pitch[cur_seq->texture][tmp] = 451 if (tmp == 0 &&
448 (cmd & 0x00F00000) >> 20; 452 (cmd & HC_HTXnEnPit_MASK)) {
449 if (!tmp && (cmd & 0x000FFFFF)) { 453 cur_seq->pitch[cur_seq->texture][tmp] =
450 DRM_ERROR 454 (cmd & HC_HTXnLnPit_MASK);
451 ("Unimplemented texture level 0 pitch mode.\n"); 455 cur_seq->tex_npot[cur_seq->texture] = 1;
452 return 2; 456 } else {
457 cur_seq->pitch[cur_seq->texture][tmp] =
458 (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT;
459 cur_seq->tex_npot[cur_seq->texture] = 0;
460 if (cmd & 0x000FFFFF) {
461 DRM_ERROR
462 ("Unimplemented texture level 0 pitch mode.\n");
463 return 2;
464 }
453 } 465 }
454 return 0; 466 return 0;
455 case check_texture_addr4: 467 case check_texture_addr4:
@@ -961,7 +973,13 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size,
961 uint32_t cmd; 973 uint32_t cmd;
962 const uint32_t *buf_end = buf + (size >> 2); 974 const uint32_t *buf_end = buf + (size >> 2);
963 verifier_state_t state = state_command; 975 verifier_state_t state = state_command;
964 int pro_group_a = dev_priv->pro_group_a; 976 int cme_video;
977 int supported_3d;
978
979 cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A ||
980 dev_priv->chipset == VIA_DX9_0);
981
982 supported_3d = dev_priv->chipset != VIA_DX9_0;
965 983
966 hc_state->dev = dev; 984 hc_state->dev = dev;
967 hc_state->unfinished = no_sequence; 985 hc_state->unfinished = no_sequence;
@@ -986,17 +1004,21 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size,
986 state = via_check_vheader6(&buf, buf_end); 1004 state = via_check_vheader6(&buf, buf_end);
987 break; 1005 break;
988 case state_command: 1006 case state_command:
989 if (HALCYON_HEADER2 == (cmd = *buf)) 1007 if ((HALCYON_HEADER2 == (cmd = *buf)) &&
1008 supported_3d)
990 state = state_header2; 1009 state = state_header2;
991 else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 1010 else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
992 state = state_header1; 1011 state = state_header1;
993 else if (pro_group_a 1012 else if (cme_video
994 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5) 1013 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
995 state = state_vheader5; 1014 state = state_vheader5;
996 else if (pro_group_a 1015 else if (cme_video
997 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6) 1016 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
998 state = state_vheader6; 1017 state = state_vheader6;
999 else { 1018 else if ((cmd == HALCYON_HEADER2) && !supported_3d) {
1019 DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n");
1020 state = state_error;
1021 } else {
1000 DRM_ERROR 1022 DRM_ERROR
1001 ("Invalid / Unimplemented DMA HEADER command. 0x%x\n", 1023 ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
1002 cmd); 1024 cmd);
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
index 256590fcc22a..b77f59df0278 100644
--- a/drivers/char/drm/via_verifier.h
+++ b/drivers/char/drm/via_verifier.h
@@ -43,6 +43,7 @@ typedef struct {
43 uint32_t tex_level_lo[2]; 43 uint32_t tex_level_lo[2];
44 uint32_t tex_level_hi[2]; 44 uint32_t tex_level_hi[2];
45 uint32_t tex_palette_size[2]; 45 uint32_t tex_palette_size[2];
46 uint32_t tex_npot[2];
46 drm_via_sequence_t unfinished; 47 drm_via_sequence_t unfinished;
47 int agp_texture; 48 int agp_texture;
48 int multitex; 49 int multitex;
diff --git a/drivers/char/hvc_beat.c b/drivers/char/hvc_beat.c
new file mode 100644
index 000000000000..6f019f19be71
--- /dev/null
+++ b/drivers/char/hvc_beat.c
@@ -0,0 +1,134 @@
1/*
2 * Beat hypervisor console driver
3 *
4 * (C) Copyright 2006 TOSHIBA CORPORATION
5 *
6 * This code is based on drivers/char/hvc_rtas.c:
7 * (C) Copyright IBM Corporation 2001-2005
8 * (C) Copyright Red Hat, Inc. 2005
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/err.h>
28#include <linux/string.h>
29#include <linux/console.h>
30#include <asm/prom.h>
31#include <asm/hvconsole.h>
32#include <asm/firmware.h>
33
34#include "hvc_console.h"
35
36extern int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *);
37extern int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t);
38
39struct hvc_struct *hvc_beat_dev = NULL;
40
41/* bug: only one queue is available regardless of vtermno */
42static int hvc_beat_get_chars(uint32_t vtermno, char *buf, int cnt)
43{
44 static unsigned char q[sizeof(unsigned long) * 2]
45 __attribute__((aligned(sizeof(unsigned long))));
46 static int qlen = 0;
47 unsigned long got;
48
49again:
50 if (qlen) {
51 if (qlen > cnt) {
52 memcpy(buf, q, cnt);
53 qlen -= cnt;
54 memmove(q + cnt, q, qlen);
55 return cnt;
56 } else { /* qlen <= cnt */
57 int r;
58
59 memcpy(buf, q, qlen);
60 r = qlen;
61 qlen = 0;
62 return r;
63 }
64 }
65 if (beat_get_term_char(vtermno, &got,
66 ((unsigned long *)q), ((unsigned long *)q) + 1) == 0) {
67 qlen = got;
68 goto again;
69 }
70 return 0;
71}
72
73static int hvc_beat_put_chars(uint32_t vtermno, const char *buf, int cnt)
74{
75 unsigned long kb[2];
76 int rest, nlen;
77
78 for (rest = cnt; rest > 0; rest -= nlen) {
79 nlen = (rest > 16) ? 16 : rest;
80 memcpy(kb, buf, nlen);
81 beat_put_term_char(vtermno, rest, kb[0], kb[1]);
82 rest -= nlen;
83 }
84 return cnt;
85}
86
87static struct hv_ops hvc_beat_get_put_ops = {
88 .get_chars = hvc_beat_get_chars,
89 .put_chars = hvc_beat_put_chars,
90};
91
92static int hvc_beat_useit = 1;
93
94static int hvc_beat_config(char *p)
95{
96 hvc_beat_useit = simple_strtoul(p, NULL, 0);
97 return 0;
98}
99
100static int hvc_beat_console_init(void)
101{
102 if (hvc_beat_useit && machine_is_compatible("Beat")) {
103 hvc_instantiate(0, 0, &hvc_beat_get_put_ops);
104 }
105 return 0;
106}
107
108/* temp */
109static int hvc_beat_init(void)
110{
111 struct hvc_struct *hp;
112
113 if (!firmware_has_feature(FW_FEATURE_BEAT))
114 return -ENODEV;
115
116 hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16);
117 if (IS_ERR(hp))
118 return PTR_ERR(hp);
119 hvc_beat_dev = hp;
120 return 0;
121}
122
123static void __exit hvc_beat_exit(void)
124{
125 if (hvc_beat_dev)
126 hvc_remove(hvc_beat_dev);
127}
128
129module_init(hvc_beat_init);
130module_exit(hvc_beat_exit);
131
132__setup("hvc_beat=", hvc_beat_config);
133
134console_initcall(hvc_beat_console_init);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index f1afd26a509f..a7b33d2f5991 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1802,7 +1802,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi)
1802 return -ENODEV; 1802 return -ENODEV;
1803 } 1803 }
1804 1804
1805 if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) 1805 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
1806 addr_space = IPMI_MEM_ADDR_SPACE; 1806 addr_space = IPMI_MEM_ADDR_SPACE;
1807 else 1807 else
1808 addr_space = IPMI_IO_ADDR_SPACE; 1808 addr_space = IPMI_IO_ADDR_SPACE;
@@ -1848,19 +1848,19 @@ static __devinit int try_init_acpi(struct SPMITable *spmi)
1848 info->irq_setup = NULL; 1848 info->irq_setup = NULL;
1849 } 1849 }
1850 1850
1851 if (spmi->addr.register_bit_width) { 1851 if (spmi->addr.bit_width) {
1852 /* A (hopefully) properly formed register bit width. */ 1852 /* A (hopefully) properly formed register bit width. */
1853 info->io.regspacing = spmi->addr.register_bit_width / 8; 1853 info->io.regspacing = spmi->addr.bit_width / 8;
1854 } else { 1854 } else {
1855 info->io.regspacing = DEFAULT_REGSPACING; 1855 info->io.regspacing = DEFAULT_REGSPACING;
1856 } 1856 }
1857 info->io.regsize = info->io.regspacing; 1857 info->io.regsize = info->io.regspacing;
1858 info->io.regshift = spmi->addr.register_bit_offset; 1858 info->io.regshift = spmi->addr.bit_offset;
1859 1859
1860 if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 1860 if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
1861 info->io_setup = mem_setup; 1861 info->io_setup = mem_setup;
1862 info->io.addr_type = IPMI_IO_ADDR_SPACE; 1862 info->io.addr_type = IPMI_IO_ADDR_SPACE;
1863 } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 1863 } else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
1864 info->io_setup = port_setup; 1864 info->io_setup = port_setup;
1865 info->io.addr_type = IPMI_MEM_ADDR_SPACE; 1865 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
1866 } else { 1866 } else {
@@ -1888,10 +1888,8 @@ static __devinit void acpi_find_bmc(void)
1888 return; 1888 return;
1889 1889
1890 for (i = 0; ; i++) { 1890 for (i = 0; ; i++) {
1891 status = acpi_get_firmware_table("SPMI", i+1, 1891 status = acpi_get_table(ACPI_SIG_SPMI, i+1,
1892 ACPI_LOGICAL_ADDRESSING, 1892 (struct acpi_table_header **)&spmi);
1893 (struct acpi_table_header **)
1894 &spmi);
1895 if (status != AE_OK) 1893 if (status != AE_OK)
1896 return; 1894 return;
1897 1895
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 13935235e066..7fd3cd5ddf21 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -215,7 +215,7 @@ static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty)
215} 215}
216static struct sysrq_key_op sysrq_showstate_blocked_op = { 216static struct sysrq_key_op sysrq_showstate_blocked_op = {
217 .handler = sysrq_handle_showstate_blocked, 217 .handler = sysrq_handle_showstate_blocked,
218 .help_msg = "showBlockedTasks", 218 .help_msg = "shoW-blocked-tasks",
219 .action_msg = "Show Blocked State", 219 .action_msg = "Show Blocked State",
220 .enable_mask = SYSRQ_ENABLE_DUMP, 220 .enable_mask = SYSRQ_ENABLE_DUMP,
221}; 221};
@@ -315,15 +315,16 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
315 &sysrq_loglevel_op, /* 9 */ 315 &sysrq_loglevel_op, /* 9 */
316 316
317 /* 317 /*
318 * Don't use for system provided sysrqs, it is handled specially on 318 * a: Don't use for system provided sysrqs, it is handled specially on
319 * sparc and will never arrive 319 * sparc and will never arrive.
320 */ 320 */
321 NULL, /* a */ 321 NULL, /* a */
322 &sysrq_reboot_op, /* b */ 322 &sysrq_reboot_op, /* b */
323 &sysrq_crashdump_op, /* c */ 323 &sysrq_crashdump_op, /* c & ibm_emac driver debug */
324 &sysrq_showlocks_op, /* d */ 324 &sysrq_showlocks_op, /* d */
325 &sysrq_term_op, /* e */ 325 &sysrq_term_op, /* e */
326 &sysrq_moom_op, /* f */ 326 &sysrq_moom_op, /* f */
327 /* g: May be registered by ppc for kgdb */
327 NULL, /* g */ 328 NULL, /* g */
328 NULL, /* h */ 329 NULL, /* h */
329 &sysrq_kill_op, /* i */ 330 &sysrq_kill_op, /* i */
@@ -332,18 +333,19 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
332 NULL, /* l */ 333 NULL, /* l */
333 &sysrq_showmem_op, /* m */ 334 &sysrq_showmem_op, /* m */
334 &sysrq_unrt_op, /* n */ 335 &sysrq_unrt_op, /* n */
335 /* This will often be registered as 'Off' at init time */ 336 /* o: This will often be registered as 'Off' at init time */
336 NULL, /* o */ 337 NULL, /* o */
337 &sysrq_showregs_op, /* p */ 338 &sysrq_showregs_op, /* p */
338 NULL, /* q */ 339 NULL, /* q */
339 &sysrq_unraw_op, /* r */ 340 &sysrq_unraw_op, /* r */
340 &sysrq_sync_op, /* s */ 341 &sysrq_sync_op, /* s */
341 &sysrq_showstate_op, /* t */ 342 &sysrq_showstate_op, /* t */
342 &sysrq_mountro_op, /* u */ 343 &sysrq_mountro_op, /* u */
343 /* May be assigned at init time by SMP VOYAGER */ 344 /* v: May be registered at init time by SMP VOYAGER */
344 NULL, /* v */ 345 NULL, /* v */
345 NULL, /* w */ 346 &sysrq_showstate_blocked_op, /* w */
346 &sysrq_showstate_blocked_op, /* x */ 347 /* x: May be registered on ppc/powerpc for xmon */
348 NULL, /* x */
347 NULL, /* y */ 349 NULL, /* y */
348 NULL /* z */ 350 NULL /* z */
349}; 351};
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index a611972024e6..7fca5f470beb 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -372,10 +372,8 @@ static int read_log(struct tpm_bios_log *log)
372 } 372 }
373 373
374 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ 374 /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
375 status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1, 375 status = acpi_get_table(ACPI_SIG_TCPA, 1,
376 ACPI_LOGICAL_ADDRESSING, 376 (struct acpi_table_header **)&buff);
377 (struct acpi_table_header **)
378 &buff);
379 377
380 if (ACPI_FAILURE(status)) { 378 if (ACPI_FAILURE(status)) {
381 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", 379 printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
@@ -409,7 +407,7 @@ static int read_log(struct tpm_bios_log *log)
409 407
410 log->bios_event_log_end = log->bios_event_log + len; 408 log->bios_event_log_end = log->bios_event_log + len;
411 409
412 acpi_os_map_memory(start, len, (void *) &virt); 410 virt = acpi_os_map_memory(start, len);
413 411
414 memcpy(log->bios_event_log, virt, len); 412 memcpy(log->bios_event_log, virt, len);
415 413
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index 488902231cc2..0e23f29f71ab 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -35,7 +35,7 @@
35#ifdef CONFIG_FSL_BOOKE 35#ifdef CONFIG_FSL_BOOKE
36#define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */ 36#define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */
37#else 37#else
38#define WDT_PERIOD_DEFAULT 4 /* Refer to the PPC40x and PPC4xx manuals */ 38#define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */
39#endif /* for timing information */ 39#endif /* for timing information */
40 40
41u32 booke_wdt_enabled = 0; 41u32 booke_wdt_enabled = 0;
@@ -48,12 +48,22 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
48#endif 48#endif
49 49
50/* 50/*
51 * booke_wdt_ping:
52 */
53static __inline__ void booke_wdt_ping(void)
54{
55 mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
56}
57
58/*
51 * booke_wdt_enable: 59 * booke_wdt_enable:
52 */ 60 */
53static __inline__ void booke_wdt_enable(void) 61static __inline__ void booke_wdt_enable(void)
54{ 62{
55 u32 val; 63 u32 val;
56 64
65 /* clear status before enabling watchdog */
66 booke_wdt_ping();
57 val = mfspr(SPRN_TCR); 67 val = mfspr(SPRN_TCR);
58 val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); 68 val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
59 69
@@ -61,14 +71,6 @@ static __inline__ void booke_wdt_enable(void)
61} 71}
62 72
63/* 73/*
64 * booke_wdt_ping:
65 */
66static __inline__ void booke_wdt_ping(void)
67{
68 mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
69}
70
71/*
72 * booke_wdt_write: 74 * booke_wdt_write:
73 */ 75 */
74static ssize_t booke_wdt_write (struct file *file, const char __user *buf, 76static ssize_t booke_wdt_write (struct file *file, const char __user *buf,
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 276577d08fba..4d730fdbd528 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -325,7 +325,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
325 return put_user(0, p); 325 return put_user(0, p);
326 326
327 case WDIOC_KEEPALIVE: 327 case WDIOC_KEEPALIVE:
328 zf_ping(0); 328 zf_ping(NULL);
329 break; 329 break;
330 330
331 default: 331 default: