aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/power/video.txt2
-rw-r--r--arch/i386/Kconfig4
-rw-r--r--arch/i386/kernel/kprobes.c21
-rw-r--r--arch/i386/kernel/smpboot.c4
-rw-r--r--arch/s390/kernel/compat_signal.c2
-rw-r--r--arch/s390/kernel/compat_wrapper.S42
-rw-r--r--arch/s390/kernel/syscalls.S5
-rw-r--r--arch/s390/kernel/vmlinux.lds.S4
-rw-r--r--arch/s390/mm/extmem.c19
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/tipar.c2
-rw-r--r--drivers/pcmcia/i82365.c7
-rw-r--r--drivers/s390/block/dasd.c5
-rw-r--r--drivers/s390/block/dasd_devmap.c102
-rw-r--r--drivers/s390/block/dasd_eckd.c51
-rw-r--r--drivers/s390/block/dasd_eckd.h46
-rw-r--r--drivers/s390/block/dasd_int.h12
-rw-r--r--drivers/s390/char/tape_3590.c22
-rw-r--r--drivers/s390/char/tape_std.h1
-rw-r--r--drivers/s390/cio/chsc.c30
-rw-r--r--drivers/s390/cio/qdio.c36
-rw-r--r--drivers/s390/s390mach.c33
-rw-r--r--drivers/scsi/Kconfig4
-rw-r--r--drivers/scsi/advansys.c2
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/au1200fb.c1922
-rw-r--r--include/asm-i386/i387.h4
-rw-r--r--include/asm-s390/cache.h2
-rw-r--r--include/asm-s390/futex.h123
-rw-r--r--include/asm-xtensa/signal.h2
-rw-r--r--include/linux/signal.h4
-rw-r--r--kernel/irq/manage.c6
-rw-r--r--kernel/power/main.c2
-rw-r--r--mm/slab.c3
-rw-r--r--sound/oss/Kconfig14
35 files changed, 510 insertions, 2032 deletions
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
index d18a57d1a531..43a889f8f08d 100644
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -140,7 +140,7 @@ IBM TP T41p s3_bios (2), switch to X after resume
140IBM TP T42 s3_bios (2) 140IBM TP T42 s3_bios (2)
141IBM ThinkPad T42p (2373-GTG) s3_bios (2) 141IBM ThinkPad T42p (2373-GTG) s3_bios (2)
142IBM TP X20 ??? (*) 142IBM TP X20 ??? (*)
143IBM TP X30 s3_bios (2) 143IBM TP X30 s3_bios, s3_mode (4)
144IBM TP X31 / Type 2672-XXH none (1), use radeontool (http://fdd.com/software/radeon/) to turn off backlight. 144IBM TP X31 / Type 2672-XXH none (1), use radeontool (http://fdd.com/software/radeon/) to turn off backlight.
145IBM TP X32 none (1), but backlight is on and video is trashed after long suspend. s3_bios,s3_mode (4) works too. Perhaps that gets better results? 145IBM TP X32 none (1), but backlight is on and video is trashed after long suspend. s3_bios,s3_mode (4) works too. Perhaps that gets better results?
146IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4) 146IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4)
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 18ec9fe6deb6..c6fe99e57a05 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -467,7 +467,7 @@ endchoice
467 467
468choice 468choice
469 depends on EXPERIMENTAL && !X86_PAE 469 depends on EXPERIMENTAL && !X86_PAE
470 prompt "Memory split" 470 prompt "Memory split" if EMBEDDED
471 default VMSPLIT_3G 471 default VMSPLIT_3G
472 help 472 help
473 Select the desired split between kernel and user memory. 473 Select the desired split between kernel and user memory.
@@ -756,7 +756,7 @@ config PHYSICAL_START
756 756
757config HOTPLUG_CPU 757config HOTPLUG_CPU
758 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" 758 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
759 depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER && !X86_PC 759 depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
760 ---help--- 760 ---help---
761 Say Y here to experiment with turning CPUs off and on. CPUs 761 Say Y here to experiment with turning CPUs off and on. CPUs
762 can be controlled through /sys/devices/system/cpu. 762 can be controlled through /sys/devices/system/cpu.
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 043f5292e70a..38806f427849 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -242,10 +242,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
242 kcb->kprobe_status = KPROBE_REENTER; 242 kcb->kprobe_status = KPROBE_REENTER;
243 return 1; 243 return 1;
244 } else { 244 } else {
245 if (regs->eflags & VM_MASK) {
246 /* We are in virtual-8086 mode. Return 0 */
247 goto no_kprobe;
248 }
249 if (*addr != BREAKPOINT_INSTRUCTION) { 245 if (*addr != BREAKPOINT_INSTRUCTION) {
250 /* The breakpoint instruction was removed by 246 /* The breakpoint instruction was removed by
251 * another cpu right after we hit, no further 247 * another cpu right after we hit, no further
@@ -265,11 +261,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
265 261
266 p = get_kprobe(addr); 262 p = get_kprobe(addr);
267 if (!p) { 263 if (!p) {
268 if (regs->eflags & VM_MASK) {
269 /* We are in virtual-8086 mode. Return 0 */
270 goto no_kprobe;
271 }
272
273 if (*addr != BREAKPOINT_INSTRUCTION) { 264 if (*addr != BREAKPOINT_INSTRUCTION) {
274 /* 265 /*
275 * The breakpoint instruction was removed right 266 * The breakpoint instruction was removed right
@@ -452,10 +443,11 @@ static void __kprobes resume_execution(struct kprobe *p,
452 *tos &= ~(TF_MASK | IF_MASK); 443 *tos &= ~(TF_MASK | IF_MASK);
453 *tos |= kcb->kprobe_old_eflags; 444 *tos |= kcb->kprobe_old_eflags;
454 break; 445 break;
455 case 0xc3: /* ret/lret */ 446 case 0xc2: /* iret/ret/lret */
456 case 0xcb: 447 case 0xc3:
457 case 0xc2:
458 case 0xca: 448 case 0xca:
449 case 0xcb:
450 case 0xcf:
459 case 0xea: /* jmp absolute -- eip is correct */ 451 case 0xea: /* jmp absolute -- eip is correct */
460 /* eip is already adjusted, no more changes required */ 452 /* eip is already adjusted, no more changes required */
461 p->ainsn.boostable = 1; 453 p->ainsn.boostable = 1;
@@ -463,10 +455,13 @@ static void __kprobes resume_execution(struct kprobe *p,
463 case 0xe8: /* call relative - Fix return addr */ 455 case 0xe8: /* call relative - Fix return addr */
464 *tos = orig_eip + (*tos - copy_eip); 456 *tos = orig_eip + (*tos - copy_eip);
465 break; 457 break;
458 case 0x9a: /* call absolute -- same as call absolute, indirect */
459 *tos = orig_eip + (*tos - copy_eip);
460 goto no_change;
466 case 0xff: 461 case 0xff:
467 if ((p->ainsn.insn[1] & 0x30) == 0x10) { 462 if ((p->ainsn.insn[1] & 0x30) == 0x10) {
468 /* call absolute, indirect */
469 /* 463 /*
464 * call absolute, indirect
470 * Fix return addr; eip is correct. 465 * Fix return addr; eip is correct.
471 * But this is not boostable 466 * But this is not boostable
472 */ 467 */
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index a6969903f2d6..825b2b4ca721 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -313,7 +313,9 @@ static void __init synchronize_tsc_bp (void)
313 if (tsc_values[i] < avg) 313 if (tsc_values[i] < avg)
314 realdelta = -realdelta; 314 realdelta = -realdelta;
315 315
316 printk(KERN_INFO "CPU#%d had %ld usecs TSC skew, fixed it up.\n", i, realdelta); 316 if (realdelta > 0)
317 printk(KERN_INFO "CPU#%d had %ld usecs TSC "
318 "skew, fixed it up.\n", i, realdelta);
317 } 319 }
318 320
319 sum += delta; 321 sum += delta;
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 5291b5f8788d..b4c815d8ef75 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -430,7 +430,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
430 430
431 /* This is the X/Open sanctioned signal stack switching. */ 431 /* This is the X/Open sanctioned signal stack switching. */
432 if (ka->sa.sa_flags & SA_ONSTACK) { 432 if (ka->sa.sa_flags & SA_ONSTACK) {
433 if (! on_sig_stack(sp)) 433 if (! sas_ss_flags(sp))
434 sp = current->sas_ss_sp + current->sas_ss_size; 434 sp = current->sas_ss_sp + current->sas_ss_size;
435 } 435 }
436 436
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 199da68bd7be..ef5b9c44b86b 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1608,3 +1608,45 @@ compat_sys_ppoll_wrapper:
1608sys_unshare_wrapper: 1608sys_unshare_wrapper:
1609 llgfr %r2,%r2 # unsigned long 1609 llgfr %r2,%r2 # unsigned long
1610 jg sys_unshare 1610 jg sys_unshare
1611
1612 .globl compat_sys_set_robust_list_wrapper
1613compat_sys_set_robust_list_wrapper:
1614 llgtr %r2,%r2 # struct compat_robust_list_head *
1615 llgfr %r3,%r3 # size_t
1616 jg compat_sys_set_robust_list
1617
1618 .globl compat_sys_get_robust_list_wrapper
1619compat_sys_get_robust_list_wrapper:
1620 lgfr %r2,%r2 # int
1621 llgtr %r3,%r3 # compat_uptr_t_t *
1622 llgtr %r4,%r4 # compat_size_t *
1623 jg compat_sys_get_robust_list
1624
1625 .globl sys_splice_wrapper
1626sys_splice_wrapper:
1627 lgfr %r2,%r2 # int
1628 llgtr %r3,%r3 # loff_t *
1629 lgfr %r4,%r4 # int
1630 llgtr %r5,%r5 # loff_t *
1631 llgfr %r6,%r6 # size_t
1632 llgf %r0,164(%r15) # unsigned int
1633 stg %r0,160(%r15)
1634 jg sys_splice
1635
1636 .globl sys_sync_file_range_wrapper
1637sys_sync_file_range_wrapper:
1638 lgfr %r2,%r2 # int
1639 sllg %r3,%r3,32 # get high word of 64bit loff_t
1640 or %r3,%r4 # get low word of 64bit loff_t
1641 sllg %r4,%r5,32 # get high word of 64bit loff_t
1642 or %r4,%r6 # get low word of 64bit loff_t
1643 llgf %r5,164(%r15) # unsigned int
1644 jg sys_sync_file_range
1645
1646 .globl sys_tee_wrapper
1647sys_tee_wrapper:
1648 lgfr %r2,%r2 # int
1649 lgfr %r3,%r3 # int
1650 llgfr %r4,%r4 # size_t
1651 llgfr %r5,%r5 # unsigned int
1652 jg sys_tee
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 2f56654da821..fc2c0767202b 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -312,3 +312,8 @@ SYSCALL(sys_faccessat,sys_faccessat,sys_faccessat_wrapper) /* 300 */
312SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper) 312SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper)
313SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper) 313SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper)
314SYSCALL(sys_unshare,sys_unshare,sys_unshare_wrapper) 314SYSCALL(sys_unshare,sys_unshare,sys_unshare_wrapper)
315SYSCALL(sys_set_robust_list,sys_set_robust_list,compat_sys_set_robust_list_wrapper)
316SYSCALL(sys_get_robust_list,sys_get_robust_list,compat_sys_get_robust_list_wrapper)
317SYSCALL(sys_splice,sys_splice,sys_splice_wrapper)
318SYSCALL(sys_sync_file_range,sys_sync_file_range,sys_sync_file_range_wrapper)
319SYSCALL(sys_tee,sys_tee,sys_tee_wrapper)
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 9289face3027..9f34bb54c051 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -58,9 +58,11 @@ SECTIONS
58 . = ALIGN(4096); 58 . = ALIGN(4096);
59 .data.page_aligned : { *(.data.idt) } 59 .data.page_aligned : { *(.data.idt) }
60 60
61 . = ALIGN(32); 61 . = ALIGN(256);
62 .data.cacheline_aligned : { *(.data.cacheline_aligned) } 62 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
63 63
64 . = ALIGN(256);
65 .data.read_mostly : { *(.data.read_mostly) }
64 _edata = .; /* End of data section */ 66 _edata = .; /* End of data section */
65 67
66 . = ALIGN(8192); /* init_task */ 68 . = ALIGN(8192); /* init_task */
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index a9566bcab682..9b11e3e20903 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -192,6 +192,7 @@ query_segment_type (struct dcss_segment *seg)
192 diag_cc = dcss_diag (DCSS_SEGEXT, qin, &dummy, &vmrc); 192 diag_cc = dcss_diag (DCSS_SEGEXT, qin, &dummy, &vmrc);
193 193
194 if (diag_cc > 1) { 194 if (diag_cc > 1) {
195 PRINT_WARN ("segment_type: diag returned error %ld\n", vmrc);
195 rc = dcss_diag_translate_rc (vmrc); 196 rc = dcss_diag_translate_rc (vmrc);
196 goto out_free; 197 goto out_free;
197 } 198 }
@@ -553,7 +554,7 @@ segment_save(char *name)
553 int endpfn = 0; 554 int endpfn = 0;
554 char cmd1[160]; 555 char cmd1[160];
555 char cmd2[80]; 556 char cmd2[80];
556 int i; 557 int i, response;
557 558
558 if (!MACHINE_IS_VM) 559 if (!MACHINE_IS_VM)
559 return; 560 return;
@@ -576,8 +577,20 @@ segment_save(char *name)
576 segtype_string[seg->range[i].start & 0xff]); 577 segtype_string[seg->range[i].start & 0xff]);
577 } 578 }
578 sprintf(cmd2, "SAVESEG %s", name); 579 sprintf(cmd2, "SAVESEG %s", name);
579 cpcmd(cmd1, NULL, 0, NULL); 580 response = 0;
580 cpcmd(cmd2, NULL, 0, NULL); 581 cpcmd(cmd1, NULL, 0, &response);
582 if (response) {
583 PRINT_ERR("segment_save: DEFSEG failed with response code %i\n",
584 response);
585 goto out;
586 }
587 cpcmd(cmd2, NULL, 0, &response);
588 if (response) {
589 PRINT_ERR("segment_save: SAVESEG failed with response code %i\n",
590 response);
591 goto out;
592 }
593out:
581 spin_unlock(&dcss_lock); 594 spin_unlock(&dcss_lock);
582} 595}
583 596
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 8666171e187b..d3ba2f860ef0 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -271,7 +271,7 @@ static int mwave_ioctl(struct inode *inode, struct file *file,
271 ipcnum, 271 ipcnum,
272 pDrvData->IPCs[ipcnum].usIntCount); 272 pDrvData->IPCs[ipcnum].usIntCount);
273 273
274 if (ipcnum > ARRAY_SIZE(pDrvData->IPCs)) { 274 if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) {
275 PRINTK_ERROR(KERN_ERR_MWAVE 275 PRINTK_ERROR(KERN_ERR_MWAVE
276 "mwavedd::mwave_ioctl:" 276 "mwavedd::mwave_ioctl:"
277 " IOCTL_MW_REGISTER_IPC:" 277 " IOCTL_MW_REGISTER_IPC:"
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index eb2eb3e12d6a..079db5a935a1 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -515,7 +515,7 @@ tipar_init_module(void)
515 err = PTR_ERR(tipar_class); 515 err = PTR_ERR(tipar_class);
516 goto out_chrdev; 516 goto out_chrdev;
517 } 517 }
518 if (parport_register_driver(&tipar_driver) || tp_count == 0) { 518 if (parport_register_driver(&tipar_driver)) {
519 printk(KERN_ERR "tipar: unable to register with parport\n"); 519 printk(KERN_ERR "tipar: unable to register with parport\n");
520 err = -EIO; 520 err = -EIO;
521 goto out_class; 521 goto out_class;
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index bd0308e89815..a2f05f485156 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -509,7 +509,8 @@ static irqreturn_t i365_count_irq(int irq, void *dev, struct pt_regs *regs)
509static u_int __init test_irq(u_short sock, int irq) 509static u_int __init test_irq(u_short sock, int irq)
510{ 510{
511 debug(2, " testing ISA irq %d\n", irq); 511 debug(2, " testing ISA irq %d\n", irq);
512 if (request_irq(irq, i365_count_irq, 0, "scan", i365_count_irq) != 0) 512 if (request_irq(irq, i365_count_irq, SA_PROBEIRQ, "scan",
513 i365_count_irq) != 0)
513 return 1; 514 return 1;
514 irq_hits = 0; irq_sock = sock; 515 irq_hits = 0; irq_sock = sock;
515 msleep(10); 516 msleep(10);
@@ -561,7 +562,7 @@ static u_int __init isa_scan(u_short sock, u_int mask0)
561 } else { 562 } else {
562 /* Fallback: just find interrupts that aren't in use */ 563 /* Fallback: just find interrupts that aren't in use */
563 for (i = 0; i < 16; i++) 564 for (i = 0; i < 16; i++)
564 if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0)) 565 if ((mask0 & (1 << i)) && (_check_irq(i, SA_PROBEIRQ) == 0))
565 mask1 |= (1 << i); 566 mask1 |= (1 << i);
566 printk("default"); 567 printk("default");
567 /* If scan failed, default to polled status */ 568 /* If scan failed, default to polled status */
@@ -725,7 +726,7 @@ static void __init add_pcic(int ns, int type)
725 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12)); 726 u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
726 for (cs_irq = 15; cs_irq > 0; cs_irq--) 727 for (cs_irq = 15; cs_irq > 0; cs_irq--)
727 if ((cs_mask & (1 << cs_irq)) && 728 if ((cs_mask & (1 << cs_irq)) &&
728 (_check_irq(cs_irq, 0) == 0)) 729 (_check_irq(cs_irq, SA_PROBEIRQ) == 0))
729 break; 730 break;
730 if (cs_irq) { 731 if (cs_irq) {
731 grab_irq = 1; 732 grab_irq = 1;
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index a3bfebcf31ef..cfb1fff3787c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -315,6 +315,11 @@ dasd_increase_state(struct dasd_device *device)
315 rc = dasd_state_basic_to_ready(device); 315 rc = dasd_state_basic_to_ready(device);
316 316
317 if (!rc && 317 if (!rc &&
318 device->state == DASD_STATE_UNFMT &&
319 device->target > DASD_STATE_UNFMT)
320 rc = -EPERM;
321
322 if (!rc &&
318 device->state == DASD_STATE_READY && 323 device->state == DASD_STATE_READY &&
319 device->target >= DASD_STATE_ONLINE) 324 device->target >= DASD_STATE_ONLINE)
320 rc = dasd_state_ready_to_online(device); 325 rc = dasd_state_ready_to_online(device);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index c1c6f1381150..216bc4fba199 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -45,6 +45,7 @@ struct dasd_devmap {
45 unsigned int devindex; 45 unsigned int devindex;
46 unsigned short features; 46 unsigned short features;
47 struct dasd_device *device; 47 struct dasd_device *device;
48 struct dasd_uid uid;
48}; 49};
49 50
50/* 51/*
@@ -716,6 +717,68 @@ dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *bu
716 717
717static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); 718static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
718 719
720static ssize_t
721dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
722{
723 struct dasd_devmap *devmap;
724 int alias;
725
726 devmap = dasd_find_busid(dev->bus_id);
727 spin_lock(&dasd_devmap_lock);
728 if (!IS_ERR(devmap))
729 alias = devmap->uid.alias;
730 else
731 alias = 0;
732 spin_unlock(&dasd_devmap_lock);
733
734 return sprintf(buf, alias ? "1\n" : "0\n");
735}
736
737static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
738
739static ssize_t
740dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
741{
742 struct dasd_devmap *devmap;
743 char *vendor;
744
745 devmap = dasd_find_busid(dev->bus_id);
746 spin_lock(&dasd_devmap_lock);
747 if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
748 vendor = devmap->uid.vendor;
749 else
750 vendor = "";
751 spin_unlock(&dasd_devmap_lock);
752
753 return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
754}
755
756static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
757
758#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\
759 /* SSID */ 4 + 1 + /* unit addr */ 2 + 1)
760
761static ssize_t
762dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
763{
764 struct dasd_devmap *devmap;
765 char uid[UID_STRLEN];
766
767 devmap = dasd_find_busid(dev->bus_id);
768 spin_lock(&dasd_devmap_lock);
769 if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
770 snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x",
771 devmap->uid.vendor, devmap->uid.serial,
772 devmap->uid.ssid, devmap->uid.unit_addr);
773 else
774 uid[0] = 0;
775 spin_unlock(&dasd_devmap_lock);
776
777 return snprintf(buf, PAGE_SIZE, "%s\n", uid);
778}
779
780static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
781
719/* 782/*
720 * extended error-reporting 783 * extended error-reporting
721 */ 784 */
@@ -759,6 +822,9 @@ static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
759static struct attribute * dasd_attrs[] = { 822static struct attribute * dasd_attrs[] = {
760 &dev_attr_readonly.attr, 823 &dev_attr_readonly.attr,
761 &dev_attr_discipline.attr, 824 &dev_attr_discipline.attr,
825 &dev_attr_alias.attr,
826 &dev_attr_vendor.attr,
827 &dev_attr_uid.attr,
762 &dev_attr_use_diag.attr, 828 &dev_attr_use_diag.attr,
763 &dev_attr_eer_enabled.attr, 829 &dev_attr_eer_enabled.attr,
764 NULL, 830 NULL,
@@ -768,6 +834,42 @@ static struct attribute_group dasd_attr_group = {
768 .attrs = dasd_attrs, 834 .attrs = dasd_attrs,
769}; 835};
770 836
837
838/*
839 * Return copy of the device unique identifier.
840 */
841int
842dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
843{
844 struct dasd_devmap *devmap;
845
846 devmap = dasd_find_busid(cdev->dev.bus_id);
847 if (IS_ERR(devmap))
848 return PTR_ERR(devmap);
849 spin_lock(&dasd_devmap_lock);
850 *uid = devmap->uid;
851 spin_unlock(&dasd_devmap_lock);
852 return 0;
853}
854
855/*
856 * Register the given device unique identifier into devmap struct.
857 */
858int
859dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
860{
861 struct dasd_devmap *devmap;
862
863 devmap = dasd_find_busid(cdev->dev.bus_id);
864 if (IS_ERR(devmap))
865 return PTR_ERR(devmap);
866 spin_lock(&dasd_devmap_lock);
867 devmap->uid = *uid;
868 spin_unlock(&dasd_devmap_lock);
869 return 0;
870}
871EXPORT_SYMBOL(dasd_set_uid);
872
771/* 873/*
772 * Return value of the specified feature. 874 * Return value of the specified feature.
773 */ 875 */
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index ee09ef33d08d..7d5a6cee4bd8 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -446,6 +446,39 @@ dasd_eckd_cdl_reclen(int recid)
446 return LABEL_SIZE; 446 return LABEL_SIZE;
447} 447}
448 448
449/*
450 * Generate device unique id that specifies the physical device.
451 */
452static int
453dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid)
454{
455 struct dasd_eckd_private *private;
456 struct dasd_eckd_confdata *confdata;
457
458 private = (struct dasd_eckd_private *) device->private;
459 if (!private)
460 return -ENODEV;
461 confdata = &private->conf_data;
462 if (!confdata)
463 return -ENODEV;
464
465 memset(uid, 0, sizeof(struct dasd_uid));
466 strncpy(uid->vendor, confdata->ned1.HDA_manufacturer,
467 sizeof(uid->vendor) - 1);
468 EBCASC(uid->vendor, sizeof(uid->vendor) - 1);
469 strncpy(uid->serial, confdata->ned1.HDA_location,
470 sizeof(uid->serial) - 1);
471 EBCASC(uid->serial, sizeof(uid->serial) - 1);
472 uid->ssid = confdata->neq.subsystemID;
473 if (confdata->ned2.sneq.flags == 0x40) {
474 uid->alias = 1;
475 uid->unit_addr = confdata->ned2.sneq.base_unit_addr;
476 } else
477 uid->unit_addr = confdata->ned1.unit_addr;
478
479 return 0;
480}
481
449static int 482static int
450dasd_eckd_read_conf(struct dasd_device *device) 483dasd_eckd_read_conf(struct dasd_device *device)
451{ 484{
@@ -507,11 +540,15 @@ dasd_eckd_read_conf(struct dasd_device *device)
507 return 0; 540 return 0;
508} 541}
509 542
510 543/*
544 * Check device characteristics.
545 * If the device is accessible using ECKD discipline, the device is enabled.
546 */
511static int 547static int
512dasd_eckd_check_characteristics(struct dasd_device *device) 548dasd_eckd_check_characteristics(struct dasd_device *device)
513{ 549{
514 struct dasd_eckd_private *private; 550 struct dasd_eckd_private *private;
551 struct dasd_uid uid;
515 void *rdc_data; 552 void *rdc_data;
516 int rc; 553 int rc;
517 554
@@ -536,6 +573,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
536 573
537 /* Read Device Characteristics */ 574 /* Read Device Characteristics */
538 rdc_data = (void *) &(private->rdc_data); 575 rdc_data = (void *) &(private->rdc_data);
576 memset(rdc_data, 0, sizeof(rdc_data));
539 rc = read_dev_chars(device->cdev, &rdc_data, 64); 577 rc = read_dev_chars(device->cdev, &rdc_data, 64);
540 if (rc) { 578 if (rc) {
541 DEV_MESSAGE(KERN_WARNING, device, 579 DEV_MESSAGE(KERN_WARNING, device,
@@ -556,8 +594,17 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
556 594
557 /* Read Configuration Data */ 595 /* Read Configuration Data */
558 rc = dasd_eckd_read_conf (device); 596 rc = dasd_eckd_read_conf (device);
559 return rc; 597 if (rc)
598 return rc;
599
600 /* Generate device unique id and register in devmap */
601 rc = dasd_eckd_generate_uid(device, &uid);
602 if (rc)
603 return rc;
560 604
605 rc = dasd_set_uid(device->cdev, &uid);
606
607 return rc;
561} 608}
562 609
563static struct dasd_ccw_req * 610static struct dasd_ccw_req *
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index ad8524bb7bb3..d5734e976e1c 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -228,26 +228,36 @@ struct dasd_eckd_confdata {
228 unsigned char HDA_manufacturer[3]; 228 unsigned char HDA_manufacturer[3];
229 unsigned char HDA_location[2]; 229 unsigned char HDA_location[2];
230 unsigned char HDA_seqno[12]; 230 unsigned char HDA_seqno[12];
231 __u16 ID; 231 __u8 ID;
232 __u8 unit_addr;
232 } __attribute__ ((packed)) ned1; 233 } __attribute__ ((packed)) ned1;
233 struct { 234 union {
234 struct { 235 struct {
235 unsigned char identifier:2; 236 struct {
236 unsigned char token_id:1; 237 unsigned char identifier:2;
237 unsigned char sno_valid:1; 238 unsigned char token_id:1;
238 unsigned char subst_sno:1; 239 unsigned char sno_valid:1;
239 unsigned char recNED:1; 240 unsigned char subst_sno:1;
240 unsigned char emuNED:1; 241 unsigned char recNED:1;
241 unsigned char reserved:1; 242 unsigned char emuNED:1;
242 } __attribute__ ((packed)) flags; 243 unsigned char reserved:1;
243 __u8 descriptor; 244 } __attribute__ ((packed)) flags;
244 __u8 reserved[2]; 245 __u8 descriptor;
245 unsigned char dev_type[6]; 246 __u8 reserved[2];
246 unsigned char dev_model[3]; 247 unsigned char dev_type[6];
247 unsigned char DASD_manufacturer[3]; 248 unsigned char dev_model[3];
248 unsigned char DASD_location[2]; 249 unsigned char DASD_manufacturer[3];
249 unsigned char DASD_seqno[12]; 250 unsigned char DASD_location[2];
250 __u16 ID; 251 unsigned char DASD_seqno[12];
252 __u16 ID;
253 } __attribute__ ((packed)) ned;
254 struct {
255 unsigned char flags; /* byte 0 */
256 unsigned char res2[7]; /* byte 1- 7 */
257 unsigned char sua_flags; /* byte 8 */
258 __u8 base_unit_addr; /* byte 9 */
259 unsigned char res3[22]; /* byte 10-31 */
260 } __attribute__ ((packed)) sneq;
251 } __attribute__ ((packed)) ned2; 261 } __attribute__ ((packed)) ned2;
252 struct { 262 struct {
253 struct { 263 struct {
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 4293ba827523..d4b13e300a76 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -268,6 +268,16 @@ struct dasd_discipline {
268 268
269extern struct dasd_discipline *dasd_diag_discipline_pointer; 269extern struct dasd_discipline *dasd_diag_discipline_pointer;
270 270
271/*
272 * Unique identifier for dasd device.
273 */
274struct dasd_uid {
275 __u8 alias;
276 char vendor[4];
277 char serial[15];
278 __u16 ssid;
279 __u8 unit_addr;
280};
271 281
272/* 282/*
273 * Notification numbers for extended error reporting notifications: 283 * Notification numbers for extended error reporting notifications:
@@ -516,6 +526,8 @@ void dasd_devmap_exit(void);
516struct dasd_device *dasd_create_device(struct ccw_device *); 526struct dasd_device *dasd_create_device(struct ccw_device *);
517void dasd_delete_device(struct dasd_device *); 527void dasd_delete_device(struct dasd_device *);
518 528
529int dasd_get_uid(struct ccw_device *, struct dasd_uid *);
530int dasd_set_uid(struct ccw_device *, struct dasd_uid *);
519int dasd_get_feature(struct ccw_device *, int); 531int dasd_get_feature(struct ccw_device *, int);
520int dasd_set_feature(struct ccw_device *, int, int); 532int dasd_set_feature(struct ccw_device *, int, int);
521 533
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index c3915f60a3aa..d71ef1adea59 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -230,14 +230,16 @@ tape_3590_read_attmsg(struct tape_device *device)
230 * These functions are used to schedule follow-up actions from within an 230 * These functions are used to schedule follow-up actions from within an
231 * interrupt context (like unsolicited interrupts). 231 * interrupt context (like unsolicited interrupts).
232 */ 232 */
233struct work_handler_data {
234 struct tape_device *device;
235 enum tape_op op;
236 struct work_struct work;
237};
238
233static void 239static void
234tape_3590_work_handler(void *data) 240tape_3590_work_handler(void *data)
235{ 241{
236 struct { 242 struct work_handler_data *p = data;
237 struct tape_device *device;
238 enum tape_op op;
239 struct work_struct work;
240 } *p = data;
241 243
242 switch (p->op) { 244 switch (p->op) {
243 case TO_MSEN: 245 case TO_MSEN:
@@ -257,11 +259,7 @@ tape_3590_work_handler(void *data)
257static int 259static int
258tape_3590_schedule_work(struct tape_device *device, enum tape_op op) 260tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
259{ 261{
260 struct { 262 struct work_handler_data *p;
261 struct tape_device *device;
262 enum tape_op op;
263 struct work_struct work;
264 } *p;
265 263
266 if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL) 264 if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
267 return -ENOMEM; 265 return -ENOMEM;
@@ -316,7 +314,7 @@ tape_3590_bread(struct tape_device *device, struct request *req)
316 314
317 rq_for_each_bio(bio, req) { 315 rq_for_each_bio(bio, req) {
318 bio_for_each_segment(bv, bio, i) { 316 bio_for_each_segment(bv, bio, i) {
319 dst = kmap(bv->bv_page) + bv->bv_offset; 317 dst = page_address(bv->bv_page) + bv->bv_offset;
320 for (off = 0; off < bv->bv_len; 318 for (off = 0; off < bv->bv_len;
321 off += TAPEBLOCK_HSEC_SIZE) { 319 off += TAPEBLOCK_HSEC_SIZE) {
322 ccw->flags = CCW_FLAG_CC; 320 ccw->flags = CCW_FLAG_CC;
@@ -1168,6 +1166,7 @@ tape_3590_setup_device(struct tape_device *device)
1168static void 1166static void
1169tape_3590_cleanup_device(struct tape_device *device) 1167tape_3590_cleanup_device(struct tape_device *device)
1170{ 1168{
1169 flush_scheduled_work();
1171 tape_std_unassign(device); 1170 tape_std_unassign(device);
1172 1171
1173 kfree(device->discdata); 1172 kfree(device->discdata);
@@ -1234,6 +1233,7 @@ static struct tape_discipline tape_discipline_3590 = {
1234 1233
1235static struct ccw_device_id tape_3590_ids[] = { 1234static struct ccw_device_id tape_3590_ids[] = {
1236 {CCW_DEVICE_DEVTYPE(0x3590, 0, 0x3590, 0), .driver_info = tape_3590}, 1235 {CCW_DEVICE_DEVTYPE(0x3590, 0, 0x3590, 0), .driver_info = tape_3590},
1236 {CCW_DEVICE_DEVTYPE(0x3592, 0, 0x3592, 0), .driver_info = tape_3592},
1237 { /* end of list */ } 1237 { /* end of list */ }
1238}; 1238};
1239 1239
diff --git a/drivers/s390/char/tape_std.h b/drivers/s390/char/tape_std.h
index 2d311798edf4..1fc952359341 100644
--- a/drivers/s390/char/tape_std.h
+++ b/drivers/s390/char/tape_std.h
@@ -153,6 +153,7 @@ enum s390_tape_type {
153 tape_3480, 153 tape_3480,
154 tape_3490, 154 tape_3490,
155 tape_3590, 155 tape_3590,
156 tape_3592,
156}; 157};
157 158
158#endif // _TAPE_STD_H 159#endif // _TAPE_STD_H
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 6412b2c3edd3..72187e54dcac 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -242,28 +242,10 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
242 if (sch->vpm == mask) 242 if (sch->vpm == mask)
243 goto out_unreg; 243 goto out_unreg;
244 244
245 if ((sch->schib.scsw.actl & (SCSW_ACTL_CLEAR_PEND | 245 if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
246 SCSW_ACTL_HALT_PEND | 246 (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
247 SCSW_ACTL_START_PEND | 247 (sch->schib.pmcw.lpum == mask) &&
248 SCSW_ACTL_RESUME_PEND)) && 248 (sch->vpm == 0)) {
249 (sch->schib.pmcw.lpum == mask)) {
250 int cc = cio_cancel(sch);
251
252 if (cc == -ENODEV)
253 goto out_unreg;
254
255 if (cc == -EINVAL) {
256 cc = cio_clear(sch);
257 if (cc == -ENODEV)
258 goto out_unreg;
259 /* Call handler. */
260 if (sch->driver && sch->driver->termination)
261 sch->driver->termination(&sch->dev);
262 goto out_unlock;
263 }
264 } else if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
265 (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
266 (sch->schib.pmcw.lpum == mask)) {
267 int cc; 249 int cc;
268 250
269 cc = cio_clear(sch); 251 cc = cio_clear(sch);
@@ -653,13 +635,13 @@ __chp_add(struct subchannel_id schid, void *data)
653 if (sch->schib.pmcw.chpid[i] == chp->id) { 635 if (sch->schib.pmcw.chpid[i] == chp->id) {
654 if (stsch(sch->schid, &sch->schib) != 0) { 636 if (stsch(sch->schid, &sch->schib) != 0) {
655 /* Endgame. */ 637 /* Endgame. */
656 spin_unlock(&sch->lock); 638 spin_unlock_irq(&sch->lock);
657 return -ENXIO; 639 return -ENXIO;
658 } 640 }
659 break; 641 break;
660 } 642 }
661 if (i==8) { 643 if (i==8) {
662 spin_unlock(&sch->lock); 644 spin_unlock_irq(&sch->lock);
663 return 0; 645 return 0;
664 } 646 }
665 sch->lpm = ((sch->schib.pmcw.pim & 647 sch->lpm = ((sch->schib.pmcw.pim &
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 814f9258ce00..96f519281d92 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -38,6 +38,7 @@
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
40#include <linux/timer.h> 40#include <linux/timer.h>
41#include <linux/mempool.h>
41 42
42#include <asm/ccwdev.h> 43#include <asm/ccwdev.h>
43#include <asm/io.h> 44#include <asm/io.h>
@@ -80,6 +81,8 @@ static int indicator_used[INDICATORS_PER_CACHELINE];
80static __u32 * volatile indicators; 81static __u32 * volatile indicators;
81static __u32 volatile spare_indicator; 82static __u32 volatile spare_indicator;
82static atomic_t spare_indicator_usecount; 83static atomic_t spare_indicator_usecount;
84#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2
85static mempool_t *qdio_mempool_scssc;
83 86
84static debug_info_t *qdio_dbf_setup; 87static debug_info_t *qdio_dbf_setup;
85static debug_info_t *qdio_dbf_sbal; 88static debug_info_t *qdio_dbf_sbal;
@@ -1637,7 +1640,7 @@ next:
1637 1640
1638 } 1641 }
1639 kfree(irq_ptr->qdr); 1642 kfree(irq_ptr->qdr);
1640 kfree(irq_ptr); 1643 free_page((unsigned long) irq_ptr);
1641} 1644}
1642 1645
1643static void 1646static void
@@ -2304,7 +2307,7 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
2304 2307
2305 QDIO_DBF_TEXT0(0,setup,"getssqd"); 2308 QDIO_DBF_TEXT0(0,setup,"getssqd");
2306 qdioac = 0; 2309 qdioac = 0;
2307 ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2310 ssqd_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC);
2308 if (!ssqd_area) { 2311 if (!ssqd_area) {
2309 QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \ 2312 QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \
2310 "SIGAs for sch x%x.\n", irq_ptr->schid.sch_no); 2313 "SIGAs for sch x%x.\n", irq_ptr->schid.sch_no);
@@ -2364,7 +2367,7 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
2364out: 2367out:
2365 qdio_check_subchannel_qebsm(irq_ptr, qdioac, 2368 qdio_check_subchannel_qebsm(irq_ptr, qdioac,
2366 ssqd_area->sch_token); 2369 ssqd_area->sch_token);
2367 free_page ((unsigned long) ssqd_area); 2370 mempool_free(ssqd_area, qdio_mempool_scssc);
2368 irq_ptr->qdioac = qdioac; 2371 irq_ptr->qdioac = qdioac;
2369} 2372}
2370 2373
@@ -2458,7 +2461,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
2458 virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind); 2461 virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind);
2459 } 2462 }
2460 2463
2461 scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2464 scssc_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC);
2462 if (!scssc_area) { 2465 if (!scssc_area) {
2463 QDIO_PRINT_WARN("No memory for setting indicators on " \ 2466 QDIO_PRINT_WARN("No memory for setting indicators on " \
2464 "subchannel 0.%x.%x.\n", 2467 "subchannel 0.%x.%x.\n",
@@ -2514,7 +2517,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
2514 QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long)); 2517 QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long));
2515 result = 0; 2518 result = 0;
2516out: 2519out:
2517 free_page ((unsigned long) scssc_area); 2520 mempool_free(scssc_area, qdio_mempool_scssc);
2518 return result; 2521 return result;
2519 2522
2520} 2523}
@@ -2543,7 +2546,7 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target)
2543 if (!irq_ptr->is_thinint_irq) 2546 if (!irq_ptr->is_thinint_irq)
2544 return -ENODEV; 2547 return -ENODEV;
2545 2548
2546 scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2549 scsscf_area = mempool_alloc(qdio_mempool_scssc, GFP_ATOMIC);
2547 if (!scsscf_area) { 2550 if (!scsscf_area) {
2548 QDIO_PRINT_WARN("No memory for setting delay target on " \ 2551 QDIO_PRINT_WARN("No memory for setting delay target on " \
2549 "subchannel 0.%x.%x.\n", 2552 "subchannel 0.%x.%x.\n",
@@ -2581,7 +2584,7 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target)
2581 QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long)); 2584 QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long));
2582 result = 0; /* not critical */ 2585 result = 0; /* not critical */
2583out: 2586out:
2584 free_page ((unsigned long) scsscf_area); 2587 mempool_free(scsscf_area, qdio_mempool_scssc);
2585 return result; 2588 return result;
2586} 2589}
2587 2590
@@ -2980,7 +2983,7 @@ qdio_allocate(struct qdio_initialize *init_data)
2980 qdio_allocate_do_dbf(init_data); 2983 qdio_allocate_do_dbf(init_data);
2981 2984
2982 /* create irq */ 2985 /* create irq */
2983 irq_ptr = kzalloc(sizeof(struct qdio_irq), GFP_KERNEL | GFP_DMA); 2986 irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
2984 2987
2985 QDIO_DBF_TEXT0(0,setup,"irq_ptr:"); 2988 QDIO_DBF_TEXT0(0,setup,"irq_ptr:");
2986 QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*)); 2989 QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
@@ -2995,7 +2998,7 @@ qdio_allocate(struct qdio_initialize *init_data)
2995 /* QDR must be in DMA area since CCW data address is only 32 bit */ 2998 /* QDR must be in DMA area since CCW data address is only 32 bit */
2996 irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA); 2999 irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA);
2997 if (!(irq_ptr->qdr)) { 3000 if (!(irq_ptr->qdr)) {
2998 kfree(irq_ptr); 3001 free_page((unsigned long) irq_ptr);
2999 QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n"); 3002 QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
3000 return -ENOMEM; 3003 return -ENOMEM;
3001 } 3004 }
@@ -3780,6 +3783,16 @@ oom:
3780 return -ENOMEM; 3783 return -ENOMEM;
3781} 3784}
3782 3785
3786static void *qdio_mempool_alloc(gfp_t gfp_mask, void *size)
3787{
3788 return (void *) get_zeroed_page(gfp_mask|GFP_DMA);
3789}
3790
3791static void qdio_mempool_free(void *element, void *size)
3792{
3793 free_page((unsigned long) element);
3794}
3795
3783static int __init 3796static int __init
3784init_QDIO(void) 3797init_QDIO(void)
3785{ 3798{
@@ -3809,6 +3822,10 @@ init_QDIO(void)
3809 3822
3810 qdio_add_procfs_entry(); 3823 qdio_add_procfs_entry();
3811 3824
3825 qdio_mempool_scssc = mempool_create(QDIO_MEMPOOL_SCSSC_ELEMENTS,
3826 qdio_mempool_alloc,
3827 qdio_mempool_free, NULL);
3828
3812 if (tiqdio_check_chsc_availability()) 3829 if (tiqdio_check_chsc_availability())
3813 QDIO_PRINT_ERR("Not all CHSCs supported. Continuing.\n"); 3830 QDIO_PRINT_ERR("Not all CHSCs supported. Continuing.\n");
3814 3831
@@ -3824,6 +3841,7 @@ cleanup_QDIO(void)
3824 qdio_remove_procfs_entry(); 3841 qdio_remove_procfs_entry();
3825 qdio_release_qdio_memory(); 3842 qdio_release_qdio_memory();
3826 qdio_unregister_dbf_views(); 3843 qdio_unregister_dbf_views();
3844 mempool_destroy(qdio_mempool_scssc);
3827 3845
3828 printk("qdio: %s: module removed\n",version); 3846 printk("qdio: %s: module removed\n",version);
3829} 3847}
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 3bf466603512..5ae14803091f 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -362,12 +362,19 @@ s390_revalidate_registers(struct mci *mci)
362 return kill_task; 362 return kill_task;
363} 363}
364 364
365#define MAX_IPD_COUNT 29
366#define MAX_IPD_TIME (5 * 60 * 100 * 1000) /* 5 minutes */
367
365/* 368/*
366 * machine check handler. 369 * machine check handler.
367 */ 370 */
368void 371void
369s390_do_machine_check(struct pt_regs *regs) 372s390_do_machine_check(struct pt_regs *regs)
370{ 373{
374 static DEFINE_SPINLOCK(ipd_lock);
375 static unsigned long long last_ipd;
376 static int ipd_count;
377 unsigned long long tmp;
371 struct mci *mci; 378 struct mci *mci;
372 struct mcck_struct *mcck; 379 struct mcck_struct *mcck;
373 int umode; 380 int umode;
@@ -404,11 +411,27 @@ s390_do_machine_check(struct pt_regs *regs)
404 s390_handle_damage("processing backup machine " 411 s390_handle_damage("processing backup machine "
405 "check with damage."); 412 "check with damage.");
406 } 413 }
407 if (!umode) 414
408 s390_handle_damage("processing backup machine " 415 /*
409 "check in kernel mode."); 416 * Nullifying exigent condition, therefore we might
410 mcck->kill_task = 1; 417 * retry this instruction.
411 mcck->mcck_code = *(unsigned long long *) mci; 418 */
419
420 spin_lock(&ipd_lock);
421
422 tmp = get_clock();
423
424 if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
425 ipd_count++;
426 else
427 ipd_count = 1;
428
429 last_ipd = tmp;
430
431 if (ipd_count == MAX_IPD_COUNT)
432 s390_handle_damage("too many ipd retries.");
433
434 spin_unlock(&ipd_lock);
412 } 435 }
413 else { 436 else {
414 /* Processing damage -> stopping machine */ 437 /* Processing damage -> stopping machine */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 3e7302692dbe..a480a3742d47 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -446,7 +446,9 @@ config SCSI_DPT_I2O
446 446
447config SCSI_ADVANSYS 447config SCSI_ADVANSYS
448 tristate "AdvanSys SCSI support" 448 tristate "AdvanSys SCSI support"
449 depends on (ISA || EISA || PCI) && SCSI && BROKEN 449 depends on SCSI
450 depends on ISA || EISA || PCI
451 depends on BROKEN || X86_32
450 help 452 help
451 This is a driver for all SCSI host adapters manufactured by 453 This is a driver for all SCSI host adapters manufactured by
452 AdvanSys. It is documented in the kernel source in 454 AdvanSys. It is documented in the kernel source in
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 28b93057b607..2a419634b256 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -2051,7 +2051,7 @@ STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
2051#define ADV_VADDR_TO_U32 virt_to_bus 2051#define ADV_VADDR_TO_U32 virt_to_bus
2052#define ADV_U32_TO_VADDR bus_to_virt 2052#define ADV_U32_TO_VADDR bus_to_virt
2053 2053
2054#define AdvPortAddr ulong /* Virtual memory address size */ 2054#define AdvPortAddr void __iomem * /* Virtual memory address size */
2055 2055
2056/* 2056/*
2057 * Define Adv Library required memory access macros. 2057 * Define Adv Library required memory access macros.
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9060e7137441..4587087d777a 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -400,6 +400,8 @@ config FB_ASILIANT
400 select FB_CFB_FILLRECT 400 select FB_CFB_FILLRECT
401 select FB_CFB_COPYAREA 401 select FB_CFB_COPYAREA
402 select FB_CFB_IMAGEBLIT 402 select FB_CFB_IMAGEBLIT
403 help
404 This is the frame buffer device driver for the Asiliant 69030 chipset
403 405
404config FB_IMSTT 406config FB_IMSTT
405 bool "IMS Twin Turbo display support" 407 bool "IMS Twin Turbo display support"
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index b367de30b98c..600d3e0e08b7 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1920,1925 +1920,3 @@ module_exit(au1200fb_cleanup);
1920 1920
1921MODULE_DESCRIPTION(DRIVER_DESC); 1921MODULE_DESCRIPTION(DRIVER_DESC);
1922MODULE_LICENSE("GPL"); 1922MODULE_LICENSE("GPL");
1923/*
1924 * BRIEF MODULE DESCRIPTION
1925 * Au1200 LCD Driver.
1926 *
1927 * Copyright 2004-2005 AMD
1928 * Author: AMD
1929 *
1930 * Based on:
1931 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
1932 * Created 28 Dec 1997 by Geert Uytterhoeven
1933 *
1934 * This program is free software; you can redistribute it and/or modify it
1935 * under the terms of the GNU General Public License as published by the
1936 * Free Software Foundation; either version 2 of the License, or (at your
1937 * option) any later version.
1938 *
1939 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1940 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1941 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1942 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1943 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1944 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1945 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1946 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1947 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1948 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1949 *
1950 * You should have received a copy of the GNU General Public License along
1951 * with this program; if not, write to the Free Software Foundation, Inc.,
1952 * 675 Mass Ave, Cambridge, MA 02139, USA.
1953 */
1954
1955#include <linux/module.h>
1956#include <linux/platform_device.h>
1957#include <linux/kernel.h>
1958#include <linux/errno.h>
1959#include <linux/string.h>
1960#include <linux/mm.h>
1961#include <linux/fb.h>
1962#include <linux/init.h>
1963#include <linux/interrupt.h>
1964#include <linux/ctype.h>
1965#include <linux/dma-mapping.h>
1966
1967#include <asm/mach-au1x00/au1000.h>
1968#include "au1200fb.h"
1969
1970#ifdef CONFIG_PM
1971#include <asm/mach-au1x00/au1xxx_pm.h>
1972#endif
1973
1974#ifndef CONFIG_FB_AU1200_DEVS
1975#define CONFIG_FB_AU1200_DEVS 4
1976#endif
1977
1978#define DRIVER_NAME "au1200fb"
1979#define DRIVER_DESC "LCD controller driver for AU1200 processors"
1980
1981#define DEBUG 1
1982
1983#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
1984#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
1985#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
1986
1987#if DEBUG
1988#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
1989#else
1990#define print_dbg(f, arg...) do {} while (0)
1991#endif
1992
1993
1994#define AU1200_LCD_FB_IOCTL 0x46FF
1995
1996#define AU1200_LCD_SET_SCREEN 1
1997#define AU1200_LCD_GET_SCREEN 2
1998#define AU1200_LCD_SET_WINDOW 3
1999#define AU1200_LCD_GET_WINDOW 4
2000#define AU1200_LCD_SET_PANEL 5
2001#define AU1200_LCD_GET_PANEL 6
2002
2003#define SCREEN_SIZE (1<< 1)
2004#define SCREEN_BACKCOLOR (1<< 2)
2005#define SCREEN_BRIGHTNESS (1<< 3)
2006#define SCREEN_COLORKEY (1<< 4)
2007#define SCREEN_MASK (1<< 5)
2008
2009struct au1200_lcd_global_regs_t {
2010 unsigned int flags;
2011 unsigned int xsize;
2012 unsigned int ysize;
2013 unsigned int backcolor;
2014 unsigned int brightness;
2015 unsigned int colorkey;
2016 unsigned int mask;
2017 unsigned int panel_choice;
2018 char panel_desc[80];
2019
2020};
2021
2022#define WIN_POSITION (1<< 0)
2023#define WIN_ALPHA_COLOR (1<< 1)
2024#define WIN_ALPHA_MODE (1<< 2)
2025#define WIN_PRIORITY (1<< 3)
2026#define WIN_CHANNEL (1<< 4)
2027#define WIN_BUFFER_FORMAT (1<< 5)
2028#define WIN_COLOR_ORDER (1<< 6)
2029#define WIN_PIXEL_ORDER (1<< 7)
2030#define WIN_SIZE (1<< 8)
2031#define WIN_COLORKEY_MODE (1<< 9)
2032#define WIN_DOUBLE_BUFFER_MODE (1<< 10)
2033#define WIN_RAM_ARRAY_MODE (1<< 11)
2034#define WIN_BUFFER_SCALE (1<< 12)
2035#define WIN_ENABLE (1<< 13)
2036
2037struct au1200_lcd_window_regs_t {
2038 unsigned int flags;
2039 unsigned int xpos;
2040 unsigned int ypos;
2041 unsigned int alpha_color;
2042 unsigned int alpha_mode;
2043 unsigned int priority;
2044 unsigned int channel;
2045 unsigned int buffer_format;
2046 unsigned int color_order;
2047 unsigned int pixel_order;
2048 unsigned int xsize;
2049 unsigned int ysize;
2050 unsigned int colorkey_mode;
2051 unsigned int double_buffer_mode;
2052 unsigned int ram_array_mode;
2053 unsigned int xscale;
2054 unsigned int yscale;
2055 unsigned int enable;
2056};
2057
2058
2059struct au1200_lcd_iodata_t {
2060 unsigned int subcmd;
2061 struct au1200_lcd_global_regs_t global;
2062 struct au1200_lcd_window_regs_t window;
2063};
2064
2065#if defined(__BIG_ENDIAN)
2066#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
2067#else
2068#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
2069#endif
2070#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
2071
2072/* Private, per-framebuffer management information (independent of the panel itself) */
2073struct au1200fb_device {
2074 struct fb_info fb_info; /* FB driver info record */
2075
2076 int plane;
2077 unsigned char* fb_mem; /* FrameBuffer memory map */
2078 unsigned int fb_len;
2079 dma_addr_t fb_phys;
2080};
2081
2082static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
2083/********************************************************************/
2084
2085/* LCD controller restrictions */
2086#define AU1200_LCD_MAX_XRES 1280
2087#define AU1200_LCD_MAX_YRES 1024
2088#define AU1200_LCD_MAX_BPP 32
2089#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
2090#define AU1200_LCD_NBR_PALETTE_ENTRIES 256
2091
2092/* Default number of visible screen buffer to allocate */
2093#define AU1200FB_NBR_VIDEO_BUFFERS 1
2094
2095/********************************************************************/
2096
2097static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
2098static int window_index = 2; /* default is zero */
2099static int panel_index = 2; /* default is zero */
2100static struct window_settings *win;
2101static struct panel_settings *panel;
2102static int noblanking = 1;
2103static int nohwcursor = 0;
2104
2105struct window_settings {
2106 unsigned char name[64];
2107 uint32 mode_backcolor;
2108 uint32 mode_colorkey;
2109 uint32 mode_colorkeymsk;
2110 struct {
2111 int xres;
2112 int yres;
2113 int xpos;
2114 int ypos;
2115 uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
2116 uint32 mode_winenable;
2117 } w[4];
2118};
2119
2120#if defined(__BIG_ENDIAN)
2121#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
2122#else
2123#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
2124#endif
2125
2126extern int board_au1200fb_panel_init (void);
2127extern int board_au1200fb_panel_shutdown (void);
2128
2129#ifdef CONFIG_PM
2130int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
2131 au1xxx_request_t request, void *data);
2132au1xxx_power_dev_t *LCD_pm_dev;
2133#endif
2134
2135/*
2136 * Default window configurations
2137 */
2138static struct window_settings windows[] = {
2139 { /* Index 0 */
2140 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2141 /* mode_backcolor */ 0x006600ff,
2142 /* mode_colorkey,msk*/ 0, 0,
2143 {
2144 {
2145 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2146 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2147 LCD_WINCTRL1_PO_16BPP,
2148 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2149 },
2150 {
2151 /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
2152 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2153 LCD_WINCTRL1_PO_16BPP |
2154 LCD_WINCTRL1_PIPE,
2155 /* mode_winenable*/ LCD_WINENABLE_WEN1,
2156 },
2157 {
2158 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2159 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2160 LCD_WINCTRL1_PO_16BPP,
2161 /* mode_winenable*/ 0,
2162 },
2163 {
2164 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2165 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2166 LCD_WINCTRL1_PO_16BPP |
2167 LCD_WINCTRL1_PIPE,
2168 /* mode_winenable*/ 0,
2169 },
2170 },
2171 },
2172
2173 { /* Index 1 */
2174 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2175 /* mode_backcolor */ 0x006600ff,
2176 /* mode_colorkey,msk*/ 0, 0,
2177 {
2178 {
2179 /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
2180 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
2181 LCD_WINCTRL1_PO_00,
2182 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2183 },
2184 {
2185 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2186 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
2187 | LCD_WINCTRL1_PO_16BPP,
2188 /* mode_winenable*/ 0,
2189 },
2190 {
2191 /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
2192 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2193 LCD_WINCTRL1_PO_16BPP |
2194 LCD_WINCTRL1_PIPE,
2195 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
2196 },
2197 {
2198 /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
2199 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2200 LCD_WINCTRL1_PO_16BPP |
2201 LCD_WINCTRL1_PIPE,
2202 /* mode_winenable*/ 0,
2203 },
2204 },
2205 },
2206 { /* Index 2 */
2207 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2208 /* mode_backcolor */ 0x006600ff,
2209 /* mode_colorkey,msk*/ 0, 0,
2210 {
2211 {
2212 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2213 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2214 LCD_WINCTRL1_PO_16BPP,
2215 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2216 },
2217 {
2218 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2219 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2220 LCD_WINCTRL1_PO_16BPP,
2221 /* mode_winenable*/ 0,
2222 },
2223 {
2224 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2225 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
2226 LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
2227 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
2228 },
2229 {
2230 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2231 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2232 LCD_WINCTRL1_PO_16BPP |
2233 LCD_WINCTRL1_PIPE,
2234 /* mode_winenable*/ 0,
2235 },
2236 },
2237 },
2238 /* Need VGA 640 @ 24bpp, @ 32bpp */
2239 /* Need VGA 800 @ 24bpp, @ 32bpp */
2240 /* Need VGA 1024 @ 24bpp, @ 32bpp */
2241};
2242
2243/*
2244 * Controller configurations for various panels.
2245 */
2246
2247struct panel_settings
2248{
2249 const char name[25]; /* Full name <vendor>_<model> */
2250
2251 struct fb_monspecs monspecs; /* FB monitor specs */
2252
2253 /* panel timings */
2254 uint32 mode_screen;
2255 uint32 mode_horztiming;
2256 uint32 mode_verttiming;
2257 uint32 mode_clkcontrol;
2258 uint32 mode_pwmdiv;
2259 uint32 mode_pwmhi;
2260 uint32 mode_outmask;
2261 uint32 mode_fifoctrl;
2262 uint32 mode_toyclksrc;
2263 uint32 mode_backlight;
2264 uint32 mode_auxpll;
2265 int (*device_init)(void);
2266 int (*device_shutdown)(void);
2267#define Xres min_xres
2268#define Yres min_yres
2269 u32 min_xres; /* Minimum horizontal resolution */
2270 u32 max_xres; /* Maximum horizontal resolution */
2271 u32 min_yres; /* Minimum vertical resolution */
2272 u32 max_yres; /* Maximum vertical resolution */
2273};
2274
2275/********************************************************************/
2276/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
2277
2278/* List of panels known to work with the AU1200 LCD controller.
2279 * To add a new panel, enter the same specifications as the
2280 * Generic_TFT one, and MAKE SURE that it doesn't conflicts
2281 * with the controller restrictions. Restrictions are:
2282 *
2283 * STN color panels: max_bpp <= 12
2284 * STN mono panels: max_bpp <= 4
2285 * TFT panels: max_bpp <= 16
2286 * max_xres <= 800
2287 * max_yres <= 600
2288 */
2289static struct panel_settings known_lcd_panels[] =
2290{
2291 [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
2292 .name = "QVGA_320x240",
2293 .monspecs = {
2294 .modedb = NULL,
2295 .modedb_len = 0,
2296 .hfmin = 30000,
2297 .hfmax = 70000,
2298 .vfmin = 60,
2299 .vfmax = 60,
2300 .dclkmin = 6000000,
2301 .dclkmax = 28000000,
2302 .input = FB_DISP_RGB,
2303 },
2304 .mode_screen = LCD_SCREEN_SX_N(320) |
2305 LCD_SCREEN_SY_N(240),
2306 .mode_horztiming = 0x00c4623b,
2307 .mode_verttiming = 0x00502814,
2308 .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
2309 .mode_pwmdiv = 0x00000000,
2310 .mode_pwmhi = 0x00000000,
2311 .mode_outmask = 0x00FFFFFF,
2312 .mode_fifoctrl = 0x2f2f2f2f,
2313 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2314 .mode_backlight = 0x00000000,
2315 .mode_auxpll = 8, /* 96MHz AUXPLL */
2316 .device_init = NULL,
2317 .device_shutdown = NULL,
2318 320, 320,
2319 240, 240,
2320 },
2321
2322 [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
2323 .name = "VGA_640x480",
2324 .monspecs = {
2325 .modedb = NULL,
2326 .modedb_len = 0,
2327 .hfmin = 30000,
2328 .hfmax = 70000,
2329 .vfmin = 60,
2330 .vfmax = 60,
2331 .dclkmin = 6000000,
2332 .dclkmax = 28000000,
2333 .input = FB_DISP_RGB,
2334 },
2335 .mode_screen = 0x13f9df80,
2336 .mode_horztiming = 0x003c5859,
2337 .mode_verttiming = 0x00741201,
2338 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
2339 .mode_pwmdiv = 0x00000000,
2340 .mode_pwmhi = 0x00000000,
2341 .mode_outmask = 0x00FFFFFF,
2342 .mode_fifoctrl = 0x2f2f2f2f,
2343 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2344 .mode_backlight = 0x00000000,
2345 .mode_auxpll = 8, /* 96MHz AUXPLL */
2346 .device_init = NULL,
2347 .device_shutdown = NULL,
2348 640, 480,
2349 640, 480,
2350 },
2351
2352 [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
2353 .name = "SVGA_800x600",
2354 .monspecs = {
2355 .modedb = NULL,
2356 .modedb_len = 0,
2357 .hfmin = 30000,
2358 .hfmax = 70000,
2359 .vfmin = 60,
2360 .vfmax = 60,
2361 .dclkmin = 6000000,
2362 .dclkmax = 28000000,
2363 .input = FB_DISP_RGB,
2364 },
2365 .mode_screen = 0x18fa5780,
2366 .mode_horztiming = 0x00dc7e77,
2367 .mode_verttiming = 0x00584805,
2368 .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
2369 .mode_pwmdiv = 0x00000000,
2370 .mode_pwmhi = 0x00000000,
2371 .mode_outmask = 0x00FFFFFF,
2372 .mode_fifoctrl = 0x2f2f2f2f,
2373 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2374 .mode_backlight = 0x00000000,
2375 .mode_auxpll = 8, /* 96MHz AUXPLL */
2376 .device_init = NULL,
2377 .device_shutdown = NULL,
2378 800, 800,
2379 600, 600,
2380 },
2381
2382 [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
2383 .name = "XVGA_1024x768",
2384 .monspecs = {
2385 .modedb = NULL,
2386 .modedb_len = 0,
2387 .hfmin = 30000,
2388 .hfmax = 70000,
2389 .vfmin = 60,
2390 .vfmax = 60,
2391 .dclkmin = 6000000,
2392 .dclkmax = 28000000,
2393 .input = FB_DISP_RGB,
2394 },
2395 .mode_screen = 0x1ffaff80,
2396 .mode_horztiming = 0x007d0e57,
2397 .mode_verttiming = 0x00740a01,
2398 .mode_clkcontrol = 0x000A0000, /* /1 */
2399 .mode_pwmdiv = 0x00000000,
2400 .mode_pwmhi = 0x00000000,
2401 .mode_outmask = 0x00FFFFFF,
2402 .mode_fifoctrl = 0x2f2f2f2f,
2403 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2404 .mode_backlight = 0x00000000,
2405 .mode_auxpll = 6, /* 72MHz AUXPLL */
2406 .device_init = NULL,
2407 .device_shutdown = NULL,
2408 1024, 1024,
2409 768, 768,
2410 },
2411
2412 [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
2413 .name = "XVGA_1280x1024",
2414 .monspecs = {
2415 .modedb = NULL,
2416 .modedb_len = 0,
2417 .hfmin = 30000,
2418 .hfmax = 70000,
2419 .vfmin = 60,
2420 .vfmax = 60,
2421 .dclkmin = 6000000,
2422 .dclkmax = 28000000,
2423 .input = FB_DISP_RGB,
2424 },
2425 .mode_screen = 0x27fbff80,
2426 .mode_horztiming = 0x00cdb2c7,
2427 .mode_verttiming = 0x00600002,
2428 .mode_clkcontrol = 0x000A0000, /* /1 */
2429 .mode_pwmdiv = 0x00000000,
2430 .mode_pwmhi = 0x00000000,
2431 .mode_outmask = 0x00FFFFFF,
2432 .mode_fifoctrl = 0x2f2f2f2f,
2433 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2434 .mode_backlight = 0x00000000,
2435 .mode_auxpll = 10, /* 120MHz AUXPLL */
2436 .device_init = NULL,
2437 .device_shutdown = NULL,
2438 1280, 1280,
2439 1024, 1024,
2440 },
2441
2442 [5] = { /* Samsung 1024x768 TFT */
2443 .name = "Samsung_1024x768_TFT",
2444 .monspecs = {
2445 .modedb = NULL,
2446 .modedb_len = 0,
2447 .hfmin = 30000,
2448 .hfmax = 70000,
2449 .vfmin = 60,
2450 .vfmax = 60,
2451 .dclkmin = 6000000,
2452 .dclkmax = 28000000,
2453 .input = FB_DISP_RGB,
2454 },
2455 .mode_screen = 0x1ffaff80,
2456 .mode_horztiming = 0x018cc677,
2457 .mode_verttiming = 0x00241217,
2458 .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
2459 .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
2460 .mode_pwmhi = 0x03400000, /* SCB 0x0 */
2461 .mode_outmask = 0x00FFFFFF,
2462 .mode_fifoctrl = 0x2f2f2f2f,
2463 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2464 .mode_backlight = 0x00000000,
2465 .mode_auxpll = 8, /* 96MHz AUXPLL */
2466 .device_init = board_au1200fb_panel_init,
2467 .device_shutdown = board_au1200fb_panel_shutdown,
2468 1024, 1024,
2469 768, 768,
2470 },
2471
2472 [6] = { /* Toshiba 640x480 TFT */
2473 .name = "Toshiba_640x480_TFT",
2474 .monspecs = {
2475 .modedb = NULL,
2476 .modedb_len = 0,
2477 .hfmin = 30000,
2478 .hfmax = 70000,
2479 .vfmin = 60,
2480 .vfmax = 60,
2481 .dclkmin = 6000000,
2482 .dclkmax = 28000000,
2483 .input = FB_DISP_RGB,
2484 },
2485 .mode_screen = LCD_SCREEN_SX_N(640) |
2486 LCD_SCREEN_SY_N(480),
2487 .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
2488 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
2489 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
2490 LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
2491 .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
2492 .mode_pwmdiv = 0x8000063f,
2493 .mode_pwmhi = 0x03400000,
2494 .mode_outmask = 0x00fcfcfc,
2495 .mode_fifoctrl = 0x2f2f2f2f,
2496 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2497 .mode_backlight = 0x00000000,
2498 .mode_auxpll = 8, /* 96MHz AUXPLL */
2499 .device_init = board_au1200fb_panel_init,
2500 .device_shutdown = board_au1200fb_panel_shutdown,
2501 640, 480,
2502 640, 480,
2503 },
2504
2505 [7] = { /* Sharp 320x240 TFT */
2506 .name = "Sharp_320x240_TFT",
2507 .monspecs = {
2508 .modedb = NULL,
2509 .modedb_len = 0,
2510 .hfmin = 12500,
2511 .hfmax = 20000,
2512 .vfmin = 38,
2513 .vfmax = 81,
2514 .dclkmin = 4500000,
2515 .dclkmax = 6800000,
2516 .input = FB_DISP_RGB,
2517 },
2518 .mode_screen = LCD_SCREEN_SX_N(320) |
2519 LCD_SCREEN_SY_N(240),
2520 .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
2521 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
2522 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
2523 LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
2524 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
2525 .mode_pwmdiv = 0x8000063f,
2526 .mode_pwmhi = 0x03400000,
2527 .mode_outmask = 0x00fcfcfc,
2528 .mode_fifoctrl = 0x2f2f2f2f,
2529 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2530 .mode_backlight = 0x00000000,
2531 .mode_auxpll = 8, /* 96MHz AUXPLL */
2532 .device_init = board_au1200fb_panel_init,
2533 .device_shutdown = board_au1200fb_panel_shutdown,
2534 320, 320,
2535 240, 240,
2536 },
2537
2538 [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
2539 .name = "Toppoly_TD070WGCB2",
2540 .monspecs = {
2541 .modedb = NULL,
2542 .modedb_len = 0,
2543 .hfmin = 30000,
2544 .hfmax = 70000,
2545 .vfmin = 60,
2546 .vfmax = 60,
2547 .dclkmin = 6000000,
2548 .dclkmax = 28000000,
2549 .input = FB_DISP_RGB,
2550 },
2551 .mode_screen = LCD_SCREEN_SX_N(856) |
2552 LCD_SCREEN_SY_N(480),
2553 .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
2554 LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
2555 .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
2556 LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
2557 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
2558 .mode_pwmdiv = 0x8000063f,
2559 .mode_pwmhi = 0x03400000,
2560 .mode_outmask = 0x00fcfcfc,
2561 .mode_fifoctrl = 0x2f2f2f2f,
2562 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2563 .mode_backlight = 0x00000000,
2564 .mode_auxpll = 8, /* 96MHz AUXPLL */
2565 .device_init = board_au1200fb_panel_init,
2566 .device_shutdown = board_au1200fb_panel_shutdown,
2567 856, 856,
2568 480, 480,
2569 },
2570};
2571
2572#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
2573
2574/********************************************************************/
2575
2576#ifdef CONFIG_PM
2577static int set_brightness(unsigned int brightness)
2578{
2579 unsigned int hi1, divider;
2580
2581 /* limit brightness pwm duty to >= 30/1600 */
2582 if (brightness < 30) {
2583 brightness = 30;
2584 }
2585 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
2586 hi1 = (lcd->pwmhi >> 16) + 1;
2587 hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
2588 lcd->pwmhi &= 0xFFFF;
2589 lcd->pwmhi |= (hi1 << 16);
2590
2591 return brightness;
2592}
2593#endif /* CONFIG_PM */
2594
2595static int winbpp (unsigned int winctrl1)
2596{
2597 int bits = 0;
2598
2599 /* how many bits are needed for each pixel format */
2600 switch (winctrl1 & LCD_WINCTRL1_FRM) {
2601 case LCD_WINCTRL1_FRM_1BPP:
2602 bits = 1;
2603 break;
2604 case LCD_WINCTRL1_FRM_2BPP:
2605 bits = 2;
2606 break;
2607 case LCD_WINCTRL1_FRM_4BPP:
2608 bits = 4;
2609 break;
2610 case LCD_WINCTRL1_FRM_8BPP:
2611 bits = 8;
2612 break;
2613 case LCD_WINCTRL1_FRM_12BPP:
2614 case LCD_WINCTRL1_FRM_16BPP655:
2615 case LCD_WINCTRL1_FRM_16BPP565:
2616 case LCD_WINCTRL1_FRM_16BPP556:
2617 case LCD_WINCTRL1_FRM_16BPPI1555:
2618 case LCD_WINCTRL1_FRM_16BPPI5551:
2619 case LCD_WINCTRL1_FRM_16BPPA1555:
2620 case LCD_WINCTRL1_FRM_16BPPA5551:
2621 bits = 16;
2622 break;
2623 case LCD_WINCTRL1_FRM_24BPP:
2624 case LCD_WINCTRL1_FRM_32BPP:
2625 bits = 32;
2626 break;
2627 }
2628
2629 return bits;
2630}
2631
2632static int fbinfo2index (struct fb_info *fb_info)
2633{
2634 int i;
2635
2636 for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
2637 if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
2638 return i;
2639 }
2640 printk("au1200fb: ERROR: fbinfo2index failed!\n");
2641 return -1;
2642}
2643
2644static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
2645 int xpos, int ypos)
2646{
2647 uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
2648 int xsz, ysz;
2649
2650 /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
2651
2652 winctrl0 = lcd->window[plane].winctrl0;
2653 winctrl1 = lcd->window[plane].winctrl1;
2654 winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
2655 winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
2656
2657 /* Check for off-screen adjustments */
2658 xsz = win->w[plane].xres;
2659 ysz = win->w[plane].yres;
2660 if ((xpos + win->w[plane].xres) > panel->Xres) {
2661 /* Off-screen to the right */
2662 xsz = panel->Xres - xpos; /* off by 1 ??? */
2663 /*printk("off screen right\n");*/
2664 }
2665
2666 if ((ypos + win->w[plane].yres) > panel->Yres) {
2667 /* Off-screen to the bottom */
2668 ysz = panel->Yres - ypos; /* off by 1 ??? */
2669 /*printk("off screen bottom\n");*/
2670 }
2671
2672 if (xpos < 0) {
2673 /* Off-screen to the left */
2674 xsz = win->w[plane].xres + xpos;
2675 fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
2676 xpos = 0;
2677 /*printk("off screen left\n");*/
2678 }
2679
2680 if (ypos < 0) {
2681 /* Off-screen to the top */
2682 ysz = win->w[plane].yres + ypos;
2683 /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
2684 ypos = 0;
2685 /*printk("off screen top\n");*/
2686 }
2687
2688 /* record settings */
2689 win->w[plane].xpos = xpos;
2690 win->w[plane].ypos = ypos;
2691
2692 xsz -= 1;
2693 ysz -= 1;
2694 winctrl0 |= (xpos << 21);
2695 winctrl0 |= (ypos << 10);
2696 winctrl1 |= (xsz << 11);
2697 winctrl1 |= (ysz << 0);
2698
2699 /* Disable the window while making changes, then restore WINEN */
2700 winenable = lcd->winenable & (1 << plane);
2701 au_sync();
2702 lcd->winenable &= ~(1 << plane);
2703 lcd->window[plane].winctrl0 = winctrl0;
2704 lcd->window[plane].winctrl1 = winctrl1;
2705 lcd->window[plane].winbuf0 =
2706 lcd->window[plane].winbuf1 = fbdev->fb_phys;
2707 lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
2708 lcd->winenable |= winenable;
2709 au_sync();
2710
2711 return 0;
2712}
2713
2714static void au1200_setpanel (struct panel_settings *newpanel)
2715{
2716 /*
2717 * Perform global setup/init of LCD controller
2718 */
2719 uint32 winenable;
2720
2721 /* Make sure all windows disabled */
2722 winenable = lcd->winenable;
2723 lcd->winenable = 0;
2724 au_sync();
2725 /*
2726 * Ensure everything is disabled before reconfiguring
2727 */
2728 if (lcd->screen & LCD_SCREEN_SEN) {
2729 /* Wait for vertical sync period */
2730 lcd->intstatus = LCD_INT_SS;
2731 while ((lcd->intstatus & LCD_INT_SS) == 0) {
2732 au_sync();
2733 }
2734
2735 lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
2736
2737 do {
2738 lcd->intstatus = lcd->intstatus; /*clear interrupts*/
2739 au_sync();
2740 /*wait for controller to shut down*/
2741 } while ((lcd->intstatus & LCD_INT_SD) == 0);
2742
2743 /* Call shutdown of current panel (if up) */
2744 /* this must occur last, because if an external clock is driving
2745 the controller, the clock cannot be turned off before first
2746 shutting down the controller.
2747 */
2748 if (panel->device_shutdown != NULL)
2749 panel->device_shutdown();
2750 }
2751
2752 /* Newpanel == NULL indicates a shutdown operation only */
2753 if (newpanel == NULL)
2754 return;
2755
2756 panel = newpanel;
2757
2758 printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
2759
2760 /*
2761 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
2762 */
2763 if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
2764 {
2765 uint32 sys_clksrc;
2766 au_writel(panel->mode_auxpll, SYS_AUXPLL);
2767 sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;
2768 sys_clksrc |= panel->mode_toyclksrc;
2769 au_writel(sys_clksrc, SYS_CLKSRC);
2770 }
2771
2772 /*
2773 * Configure panel timings
2774 */
2775 lcd->screen = panel->mode_screen;
2776 lcd->horztiming = panel->mode_horztiming;
2777 lcd->verttiming = panel->mode_verttiming;
2778 lcd->clkcontrol = panel->mode_clkcontrol;
2779 lcd->pwmdiv = panel->mode_pwmdiv;
2780 lcd->pwmhi = panel->mode_pwmhi;
2781 lcd->outmask = panel->mode_outmask;
2782 lcd->fifoctrl = panel->mode_fifoctrl;
2783 au_sync();
2784
2785 /* fixme: Check window settings to make sure still valid
2786 * for new geometry */
2787#if 0
2788 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
2789 au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
2790 au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
2791 au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
2792#endif
2793 lcd->winenable = winenable;
2794
2795 /*
2796 * Re-enable screen now that it is configured
2797 */
2798 lcd->screen |= LCD_SCREEN_SEN;
2799 au_sync();
2800
2801 /* Call init of panel */
2802 if (panel->device_init != NULL) panel->device_init();
2803
2804 /* FIX!!!! not appropriate on panel change!!! Global setup/init */
2805 lcd->intenable = 0;
2806 lcd->intstatus = ~0;
2807 lcd->backcolor = win->mode_backcolor;
2808
2809 /* Setup Color Key - FIX!!! */
2810 lcd->colorkey = win->mode_colorkey;
2811 lcd->colorkeymsk = win->mode_colorkeymsk;
2812
2813 /* Setup HWCursor - FIX!!! Need to support this eventually */
2814 lcd->hwc.cursorctrl = 0;
2815 lcd->hwc.cursorpos = 0;
2816 lcd->hwc.cursorcolor0 = 0;
2817 lcd->hwc.cursorcolor1 = 0;
2818 lcd->hwc.cursorcolor2 = 0;
2819 lcd->hwc.cursorcolor3 = 0;
2820
2821
2822#if 0
2823#define D(X) printk("%25s: %08X\n", #X, X)
2824 D(lcd->screen);
2825 D(lcd->horztiming);
2826 D(lcd->verttiming);
2827 D(lcd->clkcontrol);
2828 D(lcd->pwmdiv);
2829 D(lcd->pwmhi);
2830 D(lcd->outmask);
2831 D(lcd->fifoctrl);
2832 D(lcd->window[0].winctrl0);
2833 D(lcd->window[0].winctrl1);
2834 D(lcd->window[0].winctrl2);
2835 D(lcd->window[0].winbuf0);
2836 D(lcd->window[0].winbuf1);
2837 D(lcd->window[0].winbufctrl);
2838 D(lcd->window[1].winctrl0);
2839 D(lcd->window[1].winctrl1);
2840 D(lcd->window[1].winctrl2);
2841 D(lcd->window[1].winbuf0);
2842 D(lcd->window[1].winbuf1);
2843 D(lcd->window[1].winbufctrl);
2844 D(lcd->window[2].winctrl0);
2845 D(lcd->window[2].winctrl1);
2846 D(lcd->window[2].winctrl2);
2847 D(lcd->window[2].winbuf0);
2848 D(lcd->window[2].winbuf1);
2849 D(lcd->window[2].winbufctrl);
2850 D(lcd->window[3].winctrl0);
2851 D(lcd->window[3].winctrl1);
2852 D(lcd->window[3].winctrl2);
2853 D(lcd->window[3].winbuf0);
2854 D(lcd->window[3].winbuf1);
2855 D(lcd->window[3].winbufctrl);
2856 D(lcd->winenable);
2857 D(lcd->intenable);
2858 D(lcd->intstatus);
2859 D(lcd->backcolor);
2860 D(lcd->winenable);
2861 D(lcd->colorkey);
2862 D(lcd->colorkeymsk);
2863 D(lcd->hwc.cursorctrl);
2864 D(lcd->hwc.cursorpos);
2865 D(lcd->hwc.cursorcolor0);
2866 D(lcd->hwc.cursorcolor1);
2867 D(lcd->hwc.cursorcolor2);
2868 D(lcd->hwc.cursorcolor3);
2869#endif
2870}
2871
2872static void au1200_setmode(struct au1200fb_device *fbdev)
2873{
2874 int plane = fbdev->plane;
2875 /* Window/plane setup */
2876 lcd->window[plane].winctrl1 = ( 0
2877 | LCD_WINCTRL1_PRI_N(plane)
2878 | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
2879 ) ;
2880
2881 au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
2882
2883 lcd->window[plane].winctrl2 = ( 0
2884 | LCD_WINCTRL2_CKMODE_00
2885 | LCD_WINCTRL2_DBM
2886 | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
2887 | LCD_WINCTRL2_SCX_1
2888 | LCD_WINCTRL2_SCY_1
2889 ) ;
2890 lcd->winenable |= win->w[plane].mode_winenable;
2891 au_sync();
2892}
2893
2894
2895/* Inline helpers */
2896
2897/*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
2898/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
2899
2900#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
2901
2902/* Bitfields format supported by the controller. */
2903static struct fb_bitfield rgb_bitfields[][4] = {
2904 /* Red, Green, Blue, Transp */
2905 [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
2906 { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2907
2908 [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
2909 { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2910
2911 [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
2912 { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
2913
2914 [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
2915 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2916
2917 [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
2918 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
2919
2920 [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
2921 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
2922
2923 [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
2924 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
2925
2926 [LCD_WINCTRL1_FRM_24BPP >> 25] =
2927 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
2928
2929 [LCD_WINCTRL1_FRM_32BPP >> 25] =
2930 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
2931};
2932
2933/*-------------------------------------------------------------------------*/
2934
2935/* Helpers */
2936
2937static void au1200fb_update_fbinfo(struct fb_info *fbi)
2938{
2939 /* FIX!!!! This also needs to take the window pixel format into account!!! */
2940
2941 /* Update var-dependent FB info */
2942 if (panel_is_color(panel)) {
2943 if (fbi->var.bits_per_pixel <= 8) {
2944 /* palettized */
2945 fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
2946 fbi->fix.line_length = fbi->var.xres_virtual /
2947 (8/fbi->var.bits_per_pixel);
2948 } else {
2949 /* non-palettized */
2950 fbi->fix.visual = FB_VISUAL_TRUECOLOR;
2951 fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
2952 }
2953 } else {
2954 /* mono FIX!!! mono 8 and 4 bits */
2955 fbi->fix.visual = FB_VISUAL_MONO10;
2956 fbi->fix.line_length = fbi->var.xres_virtual / 8;
2957 }
2958
2959 fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
2960 print_dbg("line length: %d\n", fbi->fix.line_length);
2961 print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
2962}
2963
2964/*-------------------------------------------------------------------------*/
2965
2966/* AU1200 framebuffer driver */
2967
2968/* fb_check_var
2969 * Validate var settings with hardware restrictions and modify it if necessary
2970 */
2971static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
2972 struct fb_info *fbi)
2973{
2974 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
2975 u32 pixclock;
2976 int screen_size, plane;
2977
2978 plane = fbdev->plane;
2979
2980 /* Make sure that the mode respect all LCD controller and
2981 * panel restrictions. */
2982 var->xres = win->w[plane].xres;
2983 var->yres = win->w[plane].yres;
2984
2985 /* No need for virtual resolution support */
2986 var->xres_virtual = var->xres;
2987 var->yres_virtual = var->yres;
2988
2989 var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
2990
2991 screen_size = var->xres_virtual * var->yres_virtual;
2992 if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
2993 else screen_size /= (8/var->bits_per_pixel);
2994
2995 if (fbdev->fb_len < screen_size)
2996 return -EINVAL; /* Virtual screen is to big, abort */
2997
2998 /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
2999 /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
3000 * clock can only be obtain by dividing this value by an even integer.
3001 * Fallback to a slower pixel clock if necessary. */
3002 pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
3003 pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2));
3004
3005 if (AU1200_LCD_MAX_CLK % pixclock) {
3006 int diff = AU1200_LCD_MAX_CLK % pixclock;
3007 pixclock -= diff;
3008 }
3009
3010 var->pixclock = KHZ2PICOS(pixclock/1000);
3011#if 0
3012 if (!panel_is_active(panel)) {
3013 int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
3014
3015 if (!panel_is_color(panel)
3016 && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
3017 /* STN 8bit mono panel support is up to 6MHz pixclock */
3018 var->pixclock = KHZ2PICOS(6000);
3019 } else if (!pcd) {
3020 /* Other STN panel support is up to 12MHz */
3021 var->pixclock = KHZ2PICOS(12000);
3022 }
3023 }
3024#endif
3025 /* Set bitfield accordingly */
3026 switch (var->bits_per_pixel) {
3027 case 16:
3028 {
3029 /* 16bpp True color.
3030 * These must be set to MATCH WINCTRL[FORM] */
3031 int idx;
3032 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3033 var->red = rgb_bitfields[idx][0];
3034 var->green = rgb_bitfields[idx][1];
3035 var->blue = rgb_bitfields[idx][2];
3036 var->transp = rgb_bitfields[idx][3];
3037 break;
3038 }
3039
3040 case 32:
3041 {
3042 /* 32bpp True color.
3043 * These must be set to MATCH WINCTRL[FORM] */
3044 int idx;
3045 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3046 var->red = rgb_bitfields[idx][0];
3047 var->green = rgb_bitfields[idx][1];
3048 var->blue = rgb_bitfields[idx][2];
3049 var->transp = rgb_bitfields[idx][3];
3050 break;
3051 }
3052 default:
3053 print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
3054 return -EINVAL;
3055 }
3056
3057 return 0;
3058}
3059
3060/* fb_set_par
3061 * Set hardware with var settings. This will enable the controller with a
3062 * specific mode, normally validated with the fb_check_var method
3063 */
3064static int au1200fb_fb_set_par(struct fb_info *fbi)
3065{
3066 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
3067
3068 au1200fb_update_fbinfo(fbi);
3069 au1200_setmode(fbdev);
3070
3071 return 0;
3072}
3073
3074/* fb_setcolreg
3075 * Set color in LCD palette.
3076 */
3077static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
3078 unsigned blue, unsigned transp, struct fb_info *fbi)
3079{
3080 volatile u32 *palette = lcd->palette;
3081 u32 value;
3082
3083 if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
3084 return -EINVAL;
3085
3086 if (fbi->var.grayscale) {
3087 /* Convert color to grayscale */
3088 red = green = blue =
3089 (19595 * red + 38470 * green + 7471 * blue) >> 16;
3090 }
3091
3092 if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
3093 /* Place color in the pseudopalette */
3094 if (regno > 16)
3095 return -EINVAL;
3096
3097 palette = (u32*) fbi->pseudo_palette;
3098
3099 red >>= (16 - fbi->var.red.length);
3100 green >>= (16 - fbi->var.green.length);
3101 blue >>= (16 - fbi->var.blue.length);
3102
3103 value = (red << fbi->var.red.offset) |
3104 (green << fbi->var.green.offset)|
3105 (blue << fbi->var.blue.offset);
3106 value &= 0xFFFF;
3107
3108 } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
3109 /* COLOR TFT PALLETTIZED (use RGB 565) */
3110 value = (red & 0xF800)|((green >> 5) &
3111 0x07E0)|((blue >> 11) & 0x001F);
3112 value &= 0xFFFF;
3113
3114 } else if (0 /*panel_is_color(fbdev->panel)*/) {
3115 /* COLOR STN MODE */
3116 value = 0x1234;
3117 value &= 0xFFF;
3118 } else {
3119 /* MONOCHROME MODE */
3120 value = (green >> 12) & 0x000F;
3121 value &= 0xF;
3122 }
3123
3124 palette[regno] = value;
3125
3126 return 0;
3127}
3128
3129/* fb_blank
3130 * Blank the screen. Depending on the mode, the screen will be
3131 * activated with the backlight color, or desactivated
3132 */
3133static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
3134{
3135 /* Short-circuit screen blanking */
3136 if (noblanking)
3137 return 0;
3138
3139 switch (blank_mode) {
3140
3141 case FB_BLANK_UNBLANK:
3142 case FB_BLANK_NORMAL:
3143 /* printk("turn on panel\n"); */
3144 au1200_setpanel(panel);
3145 break;
3146 case FB_BLANK_VSYNC_SUSPEND:
3147 case FB_BLANK_HSYNC_SUSPEND:
3148 case FB_BLANK_POWERDOWN:
3149 /* printk("turn off panel\n"); */
3150 au1200_setpanel(NULL);
3151 break;
3152 default:
3153 break;
3154
3155 }
3156
3157 /* FB_BLANK_NORMAL is a soft blank */
3158 return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
3159}
3160
3161/* fb_mmap
3162 * Map video memory in user space. We don't use the generic fb_mmap
3163 * method mainly to allow the use of the TLB streaming flag (CCA=6)
3164 */
3165static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
3166
3167{
3168 unsigned int len;
3169 unsigned long start=0, off;
3170 struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
3171
3172#ifdef CONFIG_PM
3173 au1xxx_pm_access(LCD_pm_dev);
3174#endif
3175
3176 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
3177 return -EINVAL;
3178 }
3179
3180 start = fbdev->fb_phys & PAGE_MASK;
3181 len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
3182
3183 off = vma->vm_pgoff << PAGE_SHIFT;
3184
3185 if ((vma->vm_end - vma->vm_start + off) > len) {
3186 return -EINVAL;
3187 }
3188
3189 off += start;
3190 vma->vm_pgoff = off >> PAGE_SHIFT;
3191
3192 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
3193 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
3194
3195 vma->vm_flags |= VM_IO;
3196
3197 return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
3198 vma->vm_end - vma->vm_start,
3199 vma->vm_page_prot);
3200
3201 return 0;
3202}
3203
3204static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
3205{
3206
3207 unsigned int hi1, divider;
3208
3209 /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
3210
3211 if (pdata->flags & SCREEN_BACKCOLOR)
3212 lcd->backcolor = pdata->backcolor;
3213
3214 if (pdata->flags & SCREEN_BRIGHTNESS) {
3215
3216 // limit brightness pwm duty to >= 30/1600
3217 if (pdata->brightness < 30) {
3218 pdata->brightness = 30;
3219 }
3220 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
3221 hi1 = (lcd->pwmhi >> 16) + 1;
3222 hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
3223 lcd->pwmhi &= 0xFFFF;
3224 lcd->pwmhi |= (hi1 << 16);
3225 }
3226
3227 if (pdata->flags & SCREEN_COLORKEY)
3228 lcd->colorkey = pdata->colorkey;
3229
3230 if (pdata->flags & SCREEN_MASK)
3231 lcd->colorkeymsk = pdata->mask;
3232 au_sync();
3233}
3234
3235static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
3236{
3237 unsigned int hi1, divider;
3238
3239 pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
3240 pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
3241
3242 pdata->backcolor = lcd->backcolor;
3243 pdata->colorkey = lcd->colorkey;
3244 pdata->mask = lcd->colorkeymsk;
3245
3246 // brightness
3247 hi1 = (lcd->pwmhi >> 16) + 1;
3248 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
3249 pdata->brightness = ((hi1 << 8) / divider) - 1;
3250 au_sync();
3251}
3252
3253static void set_window(unsigned int plane,
3254 struct au1200_lcd_window_regs_t *pdata)
3255{
3256 unsigned int val, bpp;
3257
3258 /* Window control register 0 */
3259 if (pdata->flags & WIN_POSITION) {
3260 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
3261 LCD_WINCTRL0_OY);
3262 val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
3263 val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
3264 lcd->window[plane].winctrl0 = val;
3265 }
3266 if (pdata->flags & WIN_ALPHA_COLOR) {
3267 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
3268 val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
3269 lcd->window[plane].winctrl0 = val;
3270 }
3271 if (pdata->flags & WIN_ALPHA_MODE) {
3272 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
3273 val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
3274 lcd->window[plane].winctrl0 = val;
3275 }
3276
3277 /* Window control register 1 */
3278 if (pdata->flags & WIN_PRIORITY) {
3279 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
3280 val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
3281 lcd->window[plane].winctrl1 = val;
3282 }
3283 if (pdata->flags & WIN_CHANNEL) {
3284 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
3285 val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
3286 lcd->window[plane].winctrl1 = val;
3287 }
3288 if (pdata->flags & WIN_BUFFER_FORMAT) {
3289 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
3290 val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
3291 lcd->window[plane].winctrl1 = val;
3292 }
3293 if (pdata->flags & WIN_COLOR_ORDER) {
3294 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
3295 val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
3296 lcd->window[plane].winctrl1 = val;
3297 }
3298 if (pdata->flags & WIN_PIXEL_ORDER) {
3299 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
3300 val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
3301 lcd->window[plane].winctrl1 = val;
3302 }
3303 if (pdata->flags & WIN_SIZE) {
3304 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
3305 LCD_WINCTRL1_SZY);
3306 val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
3307 val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
3308 lcd->window[plane].winctrl1 = val;
3309 /* program buffer line width */
3310 bpp = winbpp(val) / 8;
3311 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
3312 val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
3313 lcd->window[plane].winctrl2 = val;
3314 }
3315
3316 /* Window control register 2 */
3317 if (pdata->flags & WIN_COLORKEY_MODE) {
3318 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
3319 val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
3320 lcd->window[plane].winctrl2 = val;
3321 }
3322 if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
3323 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
3324 val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
3325 lcd->window[plane].winctrl2 = val;
3326 }
3327 if (pdata->flags & WIN_RAM_ARRAY_MODE) {
3328 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
3329 val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
3330 lcd->window[plane].winctrl2 = val;
3331 }
3332
3333 /* Buffer line width programmed with WIN_SIZE */
3334
3335 if (pdata->flags & WIN_BUFFER_SCALE) {
3336 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
3337 LCD_WINCTRL2_SCY);
3338 val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
3339 val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
3340 lcd->window[plane].winctrl2 = val;
3341 }
3342
3343 if (pdata->flags & WIN_ENABLE) {
3344 val = lcd->winenable;
3345 val &= ~(1<<plane);
3346 val |= (pdata->enable & 1) << plane;
3347 lcd->winenable = val;
3348 }
3349 au_sync();
3350}
3351
3352static void get_window(unsigned int plane,
3353 struct au1200_lcd_window_regs_t *pdata)
3354{
3355 /* Window control register 0 */
3356 pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
3357 pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
3358 pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
3359 pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
3360
3361 /* Window control register 1 */
3362 pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
3363 pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
3364 pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3365 pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
3366 pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
3367 pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
3368 pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
3369
3370 /* Window control register 2 */
3371 pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
3372 pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
3373 pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
3374
3375 pdata->enable = (lcd->winenable >> plane) & 1;
3376 au_sync();
3377}
3378
3379static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
3380 unsigned long arg)
3381{
3382 int plane;
3383 int val;
3384
3385#ifdef CONFIG_PM
3386 au1xxx_pm_access(LCD_pm_dev);
3387#endif
3388
3389 plane = fbinfo2index(info);
3390 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
3391
3392 if (cmd == AU1200_LCD_FB_IOCTL) {
3393 struct au1200_lcd_iodata_t iodata;
3394
3395 if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
3396 return -EFAULT;
3397
3398 print_dbg("FB IOCTL called\n");
3399
3400 switch (iodata.subcmd) {
3401 case AU1200_LCD_SET_SCREEN:
3402 print_dbg("AU1200_LCD_SET_SCREEN\n");
3403 set_global(cmd, &iodata.global);
3404 break;
3405
3406 case AU1200_LCD_GET_SCREEN:
3407 print_dbg("AU1200_LCD_GET_SCREEN\n");
3408 get_global(cmd, &iodata.global);
3409 break;
3410
3411 case AU1200_LCD_SET_WINDOW:
3412 print_dbg("AU1200_LCD_SET_WINDOW\n");
3413 set_window(plane, &iodata.window);
3414 break;
3415
3416 case AU1200_LCD_GET_WINDOW:
3417 print_dbg("AU1200_LCD_GET_WINDOW\n");
3418 get_window(plane, &iodata.window);
3419 break;
3420
3421 case AU1200_LCD_SET_PANEL:
3422 print_dbg("AU1200_LCD_SET_PANEL\n");
3423 if ((iodata.global.panel_choice >= 0) &&
3424 (iodata.global.panel_choice <
3425 NUM_PANELS))
3426 {
3427 struct panel_settings *newpanel;
3428 panel_index = iodata.global.panel_choice;
3429 newpanel = &known_lcd_panels[panel_index];
3430 au1200_setpanel(newpanel);
3431 }
3432 break;
3433
3434 case AU1200_LCD_GET_PANEL:
3435 print_dbg("AU1200_LCD_GET_PANEL\n");
3436 iodata.global.panel_choice = panel_index;
3437 break;
3438
3439 default:
3440 return -EINVAL;
3441 }
3442
3443 val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
3444 if (val) {
3445 print_dbg("error: could not copy %d bytes\n", val);
3446 return -EFAULT;
3447 }
3448 }
3449
3450 return 0;
3451}
3452
3453
3454static struct fb_ops au1200fb_fb_ops = {
3455 .owner = THIS_MODULE,
3456 .fb_check_var = au1200fb_fb_check_var,
3457 .fb_set_par = au1200fb_fb_set_par,
3458 .fb_setcolreg = au1200fb_fb_setcolreg,
3459 .fb_blank = au1200fb_fb_blank,
3460 .fb_fillrect = cfb_fillrect,
3461 .fb_copyarea = cfb_copyarea,
3462 .fb_imageblit = cfb_imageblit,
3463 .fb_sync = NULL,
3464 .fb_ioctl = au1200fb_ioctl,
3465 .fb_mmap = au1200fb_fb_mmap,
3466};
3467
3468/*-------------------------------------------------------------------------*/
3469
3470static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs)
3471{
3472 /* Nothing to do for now, just clear any pending interrupt */
3473 lcd->intstatus = lcd->intstatus;
3474 au_sync();
3475
3476 return IRQ_HANDLED;
3477}
3478
3479/*-------------------------------------------------------------------------*/
3480
3481/* AU1200 LCD device probe helpers */
3482
3483static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
3484{
3485 struct fb_info *fbi = &fbdev->fb_info;
3486 int bpp;
3487
3488 memset(fbi, 0, sizeof(struct fb_info));
3489 fbi->fbops = &au1200fb_fb_ops;
3490
3491 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
3492
3493 /* Copy monitor specs from panel data */
3494 /* fixme: we're setting up LCD controller windows, so these dont give a
3495 damn as to what the monitor specs are (the panel itself does, but that
3496 isnt done here...so maybe need a generic catchall monitor setting??? */
3497 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
3498
3499 /* We first try the user mode passed in argument. If that failed,
3500 * or if no one has been specified, we default to the first mode of the
3501 * panel list. Note that after this call, var data will be set */
3502 if (!fb_find_mode(&fbi->var,
3503 fbi,
3504 NULL, /* drv_info.opt_mode, */
3505 fbi->monspecs.modedb,
3506 fbi->monspecs.modedb_len,
3507 fbi->monspecs.modedb,
3508 bpp)) {
3509
3510 print_err("Cannot find valid mode for panel %s", panel->name);
3511 return -EFAULT;
3512 }
3513
3514 fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
3515 if (!fbi->pseudo_palette) {
3516 return -ENOMEM;
3517 }
3518 memset(fbi->pseudo_palette, 0, sizeof(u32) * 16);
3519
3520 if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
3521 print_err("Fail to allocate colormap (%d entries)",
3522 AU1200_LCD_NBR_PALETTE_ENTRIES);
3523 kfree(fbi->pseudo_palette);
3524 return -EFAULT;
3525 }
3526
3527 strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
3528 fbi->fix.smem_start = fbdev->fb_phys;
3529 fbi->fix.smem_len = fbdev->fb_len;
3530 fbi->fix.type = FB_TYPE_PACKED_PIXELS;
3531 fbi->fix.xpanstep = 0;
3532 fbi->fix.ypanstep = 0;
3533 fbi->fix.mmio_start = 0;
3534 fbi->fix.mmio_len = 0;
3535 fbi->fix.accel = FB_ACCEL_NONE;
3536
3537 fbi->screen_base = (char __iomem *) fbdev->fb_mem;
3538
3539 au1200fb_update_fbinfo(fbi);
3540
3541 return 0;
3542}
3543
3544/*-------------------------------------------------------------------------*/
3545
3546/* AU1200 LCD controller device driver */
3547
3548static int au1200fb_drv_probe(struct device *dev)
3549{
3550 struct au1200fb_device *fbdev;
3551 unsigned long page;
3552 int bpp, plane, ret;
3553
3554 if (!dev)
3555 return -EINVAL;
3556
3557 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
3558 bpp = winbpp(win->w[plane].mode_winctrl1);
3559 if (win->w[plane].xres == 0)
3560 win->w[plane].xres = panel->Xres;
3561 if (win->w[plane].yres == 0)
3562 win->w[plane].yres = panel->Yres;
3563
3564 fbdev = &_au1200fb_devices[plane];
3565 memset(fbdev, 0, sizeof(struct au1200fb_device));
3566 fbdev->plane = plane;
3567
3568 /* Allocate the framebuffer to the maximum screen size */
3569 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
3570
3571 fbdev->fb_mem = dma_alloc_noncoherent(dev,
3572 PAGE_ALIGN(fbdev->fb_len),
3573 &fbdev->fb_phys, GFP_KERNEL);
3574 if (!fbdev->fb_mem) {
3575 print_err("fail to allocate frambuffer (size: %dK))",
3576 fbdev->fb_len / 1024);
3577 return -ENOMEM;
3578 }
3579
3580 /*
3581 * Set page reserved so that mmap will work. This is necessary
3582 * since we'll be remapping normal memory.
3583 */
3584 for (page = (unsigned long)fbdev->fb_phys;
3585 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
3586 fbdev->fb_len);
3587 page += PAGE_SIZE) {
3588 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
3589 }
3590 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
3591 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
3592
3593 /* Init FB data */
3594 if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
3595 goto failed;
3596
3597 /* Register new framebuffer */
3598 if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
3599 print_err("cannot register new framebuffer");
3600 goto failed;
3601 }
3602
3603 au1200fb_fb_set_par(&fbdev->fb_info);
3604
3605#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
3606 if (plane == 0)
3607 if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
3608 /* Start display and show logo on boot */
3609 fb_set_cmap(&fbdev->fb_info.cmap,
3610 &fbdev->fb_info);
3611
3612 fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
3613 }
3614#endif
3615 }
3616
3617 /* Now hook interrupt too */
3618 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
3619 SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) {
3620 print_err("fail to request interrupt line %d (err: %d)",
3621 AU1200_LCD_INT, ret);
3622 goto failed;
3623 }
3624
3625 return 0;
3626
3627failed:
3628 /* NOTE: This only does the current plane/window that failed; others are still active */
3629 if (fbdev->fb_mem)
3630 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
3631 fbdev->fb_mem, fbdev->fb_phys);
3632 if (fbdev->fb_info.cmap.len != 0)
3633 fb_dealloc_cmap(&fbdev->fb_info.cmap);
3634 if (fbdev->fb_info.pseudo_palette)
3635 kfree(fbdev->fb_info.pseudo_palette);
3636 if (plane == 0)
3637 free_irq(AU1200_LCD_INT, (void*)dev);
3638 return ret;
3639}
3640
3641static int au1200fb_drv_remove(struct device *dev)
3642{
3643 struct au1200fb_device *fbdev;
3644 int plane;
3645
3646 if (!dev)
3647 return -ENODEV;
3648
3649 /* Turn off the panel */
3650 au1200_setpanel(NULL);
3651
3652 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
3653 {
3654 fbdev = &_au1200fb_devices[plane];
3655
3656 /* Clean up all probe data */
3657 unregister_framebuffer(&fbdev->fb_info);
3658 if (fbdev->fb_mem)
3659 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
3660 fbdev->fb_mem, fbdev->fb_phys);
3661 if (fbdev->fb_info.cmap.len != 0)
3662 fb_dealloc_cmap(&fbdev->fb_info.cmap);
3663 if (fbdev->fb_info.pseudo_palette)
3664 kfree(fbdev->fb_info.pseudo_palette);
3665 }
3666
3667 free_irq(AU1200_LCD_INT, (void *)dev);
3668
3669 return 0;
3670}
3671
3672#ifdef CONFIG_PM
3673static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
3674{
3675 /* TODO */
3676 return 0;
3677}
3678
3679static int au1200fb_drv_resume(struct device *dev, u32 level)
3680{
3681 /* TODO */
3682 return 0;
3683}
3684#endif /* CONFIG_PM */
3685
3686static struct device_driver au1200fb_driver = {
3687 .name = "au1200-lcd",
3688 .bus = &platform_bus_type,
3689 .probe = au1200fb_drv_probe,
3690 .remove = au1200fb_drv_remove,
3691#ifdef CONFIG_PM
3692 .suspend = au1200fb_drv_suspend,
3693 .resume = au1200fb_drv_resume,
3694#endif
3695};
3696
3697/*-------------------------------------------------------------------------*/
3698
3699/* Kernel driver */
3700
3701static void au1200fb_setup(void)
3702{
3703 char* options = NULL;
3704 char* this_opt;
3705 int num_panels = ARRAY_SIZE(known_lcd_panels);
3706 int panel_idx = -1;
3707
3708 fb_get_options(DRIVER_NAME, &options);
3709
3710 if (options) {
3711 while ((this_opt = strsep(&options,",")) != NULL) {
3712 /* Panel option - can be panel name,
3713 * "bs" for board-switch, or number/index */
3714 if (!strncmp(this_opt, "panel:", 6)) {
3715 int i;
3716 long int li;
3717 char *endptr;
3718 this_opt += 6;
3719 /* First check for index, which allows
3720 * to short circuit this mess */
3721 li = simple_strtol(this_opt, &endptr, 0);
3722 if (*endptr == '\0') {
3723 panel_idx = (int)li;
3724 }
3725 else if (strcmp(this_opt, "bs") == 0) {
3726 extern int board_au1200fb_panel(void);
3727 panel_idx = board_au1200fb_panel();
3728 }
3729
3730 else
3731 for (i = 0; i < num_panels; i++) {
3732 if (!strcmp(this_opt, known_lcd_panels[i].name)) {
3733 panel_idx = i;
3734 break;
3735 }
3736 }
3737
3738 if ((panel_idx < 0) || (panel_idx >= num_panels)) {
3739 print_warn("Panel %s not supported!", this_opt);
3740 }
3741 else
3742 panel_index = panel_idx;
3743 }
3744
3745 else if (strncmp(this_opt, "nohwcursor", 10) == 0) {
3746 nohwcursor = 1;
3747 }
3748
3749 /* Unsupported option */
3750 else {
3751 print_warn("Unsupported option \"%s\"", this_opt);
3752 }
3753 }
3754 }
3755}
3756
3757#ifdef CONFIG_PM
3758static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
3759 au1xxx_request_t request, void *data) {
3760 int retval = -1;
3761 unsigned int d = 0;
3762 unsigned int brightness = 0;
3763
3764 if (request == AU1XXX_PM_SLEEP) {
3765 board_au1200fb_panel_shutdown();
3766 }
3767 else if (request == AU1XXX_PM_WAKEUP) {
3768 if(dev->prev_state == SLEEP_STATE)
3769 {
3770 int plane;
3771 au1200_setpanel(panel);
3772 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
3773 struct au1200fb_device *fbdev;
3774 fbdev = &_au1200fb_devices[plane];
3775 au1200fb_fb_set_par(&fbdev->fb_info);
3776 }
3777 }
3778
3779 d = *((unsigned int*)data);
3780 if(d <=10) brightness = 26;
3781 else if(d<=20) brightness = 51;
3782 else if(d<=30) brightness = 77;
3783 else if(d<=40) brightness = 102;
3784 else if(d<=50) brightness = 128;
3785 else if(d<=60) brightness = 153;
3786 else if(d<=70) brightness = 179;
3787 else if(d<=80) brightness = 204;
3788 else if(d<=90) brightness = 230;
3789 else brightness = 255;
3790 set_brightness(brightness);
3791 } else if (request == AU1XXX_PM_GETSTATUS) {
3792 return dev->cur_state;
3793 } else if (request == AU1XXX_PM_ACCESS) {
3794 if (dev->cur_state != SLEEP_STATE)
3795 return retval;
3796 else {
3797 au1200_setpanel(panel);
3798 }
3799 } else if (request == AU1XXX_PM_IDLE) {
3800 } else if (request == AU1XXX_PM_CLEANUP) {
3801 }
3802
3803 return retval;
3804}
3805#endif
3806
3807static int __init au1200fb_init(void)
3808{
3809 print_info("" DRIVER_DESC "");
3810
3811 /* Setup driver with options */
3812 au1200fb_setup();
3813
3814 /* Point to the panel selected */
3815 panel = &known_lcd_panels[panel_index];
3816 win = &windows[window_index];
3817
3818 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
3819 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
3820
3821 /* Kickstart the panel, the framebuffers/windows come soon enough */
3822 au1200_setpanel(panel);
3823
3824 #ifdef CONFIG_PM
3825 LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
3826 if ( LCD_pm_dev == NULL)
3827 printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
3828 else
3829 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
3830 #endif
3831
3832 return driver_register(&au1200fb_driver);
3833}
3834
3835static void __exit au1200fb_cleanup(void)
3836{
3837 driver_unregister(&au1200fb_driver);
3838}
3839
3840module_init(au1200fb_init);
3841module_exit(au1200fb_cleanup);
3842
3843MODULE_DESCRIPTION(DRIVER_DESC);
3844MODULE_LICENSE("GPL");
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 7b1f01191e70..bc1d6edae1ed 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -58,13 +58,13 @@ static inline void __save_init_fpu( struct task_struct *tsk )
58 alternative_input( 58 alternative_input(
59 "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, 59 "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
60 "fxsave %[fx]\n" 60 "fxsave %[fx]\n"
61 "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", 61 "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
62 X86_FEATURE_FXSR, 62 X86_FEATURE_FXSR,
63 [fx] "m" (tsk->thread.i387.fxsave), 63 [fx] "m" (tsk->thread.i387.fxsave),
64 [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); 64 [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
65 /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception 65 /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
66 is pending. Clear the x87 state here by setting it to fixed 66 is pending. Clear the x87 state here by setting it to fixed
67 values. __per_cpu_offset[0] is a random variable that should be in L1 */ 67 values. safe_address is a random variable that should be in L1 */
68 alternative_input( 68 alternative_input(
69 GENERIC_NOP8 GENERIC_NOP2, 69 GENERIC_NOP8 GENERIC_NOP2,
70 "emms\n\t" /* clear stack tags */ 70 "emms\n\t" /* clear stack tags */
diff --git a/include/asm-s390/cache.h b/include/asm-s390/cache.h
index e20cdd9074db..cdf431b061bb 100644
--- a/include/asm-s390/cache.h
+++ b/include/asm-s390/cache.h
@@ -16,4 +16,6 @@
16 16
17#define ARCH_KMALLOC_MINALIGN 8 17#define ARCH_KMALLOC_MINALIGN 8
18 18
19#define __read_mostly __attribute__((__section__(".data.read_mostly")))
20
19#endif 21#endif
diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h
index 6a332a9f099c..40c25e166a9b 100644
--- a/include/asm-s390/futex.h
+++ b/include/asm-s390/futex.h
@@ -1,6 +1,121 @@
1#ifndef _ASM_FUTEX_H 1#ifndef _ASM_S390_FUTEX_H
2#define _ASM_FUTEX_H 2#define _ASM_S390_FUTEX_H
3 3
4#include <asm-generic/futex.h> 4#ifdef __KERNEL__
5 5
6#endif 6#include <linux/futex.h>
7#include <asm/errno.h>
8#include <asm/uaccess.h>
9
10#ifndef __s390x__
11#define __futex_atomic_fixup \
12 ".section __ex_table,\"a\"\n" \
13 " .align 4\n" \
14 " .long 0b,2b,1b,2b\n" \
15 ".previous"
16#else /* __s390x__ */
17#define __futex_atomic_fixup \
18 ".section __ex_table,\"a\"\n" \
19 " .align 8\n" \
20 " .quad 0b,2b,1b,2b\n" \
21 ".previous"
22#endif /* __s390x__ */
23
24#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
25 asm volatile(" l %1,0(%6)\n" \
26 "0: " insn \
27 " cs %1,%2,0(%6)\n" \
28 "1: jl 0b\n" \
29 " lhi %0,0\n" \
30 "2:\n" \
31 __futex_atomic_fixup \
32 : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
33 "=m" (*uaddr) \
34 : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
35 "m" (*uaddr) : "cc" );
36
37static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
38{
39 int op = (encoded_op >> 28) & 7;
40 int cmp = (encoded_op >> 24) & 15;
41 int oparg = (encoded_op << 8) >> 20;
42 int cmparg = (encoded_op << 20) >> 20;
43 int oldval = 0, newval, ret;
44 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
45 oparg = 1 << oparg;
46
47 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
48 return -EFAULT;
49
50 inc_preempt_count();
51
52 switch (op) {
53 case FUTEX_OP_SET:
54 __futex_atomic_op("lr %2,%5\n",
55 ret, oldval, newval, uaddr, oparg);
56 break;
57 case FUTEX_OP_ADD:
58 __futex_atomic_op("lr %2,%1\nar %2,%5\n",
59 ret, oldval, newval, uaddr, oparg);
60 break;
61 case FUTEX_OP_OR:
62 __futex_atomic_op("lr %2,%1\nor %2,%5\n",
63 ret, oldval, newval, uaddr, oparg);
64 break;
65 case FUTEX_OP_ANDN:
66 __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
67 ret, oldval, newval, uaddr, oparg);
68 break;
69 case FUTEX_OP_XOR:
70 __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
71 ret, oldval, newval, uaddr, oparg);
72 break;
73 default:
74 ret = -ENOSYS;
75 }
76
77 dec_preempt_count();
78
79 if (!ret) {
80 switch (cmp) {
81 case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
82 case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
83 case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
84 case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
85 case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
86 case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
87 default: ret = -ENOSYS;
88 }
89 }
90 return ret;
91}
92
93static inline int
94futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
95{
96 int ret;
97
98 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
99 return -EFAULT;
100 asm volatile(" cs %1,%4,0(%5)\n"
101 "0: lr %0,%1\n"
102 "1:\n"
103#ifndef __s390x__
104 ".section __ex_table,\"a\"\n"
105 " .align 4\n"
106 " .long 0b,1b\n"
107 ".previous"
108#else /* __s390x__ */
109 ".section __ex_table,\"a\"\n"
110 " .align 8\n"
111 " .quad 0b,1b\n"
112 ".previous"
113#endif /* __s390x__ */
114 : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
115 : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
116 : "cc", "memory" );
117 return oldval;
118}
119
120#endif /* __KERNEL__ */
121#endif /* _ASM_S390_FUTEX_H */
diff --git a/include/asm-xtensa/signal.h b/include/asm-xtensa/signal.h
index 5d6fc9cdf58d..a99c9aec64ec 100644
--- a/include/asm-xtensa/signal.h
+++ b/include/asm-xtensa/signal.h
@@ -118,9 +118,9 @@ typedef struct {
118 * SA_INTERRUPT is also used by the irq handling routines. 118 * SA_INTERRUPT is also used by the irq handling routines.
119 * SA_SHIRQ is for shared interrupt support on PCI and EISA. 119 * SA_SHIRQ is for shared interrupt support on PCI and EISA.
120 */ 120 */
121#define SA_PROBE SA_ONESHOT
122#define SA_SAMPLE_RANDOM SA_RESTART 121#define SA_SAMPLE_RANDOM SA_RESTART
123#define SA_SHIRQ 0x04000000 122#define SA_SHIRQ 0x04000000
123#define SA_PROBEIRQ 0x08000000
124#endif 124#endif
125 125
126#define SIG_BLOCK 0 /* for blocking signals */ 126#define SIG_BLOCK 0 /* for blocking signals */
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 162a8fd10b29..70739f51a09f 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -14,10 +14,12 @@
14 * 14 *
15 * SA_INTERRUPT is also used by the irq handling routines. 15 * SA_INTERRUPT is also used by the irq handling routines.
16 * SA_SHIRQ is for shared interrupt support on PCI and EISA. 16 * SA_SHIRQ is for shared interrupt support on PCI and EISA.
17 * SA_PROBEIRQ is set by callers when they expect sharing mismatches to occur
17 */ 18 */
18#define SA_PROBE SA_ONESHOT
19#define SA_SAMPLE_RANDOM SA_RESTART 19#define SA_SAMPLE_RANDOM SA_RESTART
20#define SA_SHIRQ 0x04000000 20#define SA_SHIRQ 0x04000000
21#define SA_PROBEIRQ 0x08000000
22
21/* 23/*
22 * As above, these correspond to the IORESOURCE_IRQ_* defines in 24 * As above, these correspond to the IORESOURCE_IRQ_* defines in
23 * linux/ioport.h to select the interrupt line behaviour. When 25 * linux/ioport.h to select the interrupt line behaviour. When
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index ac766ad573e8..1279e3499534 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -246,8 +246,10 @@ int setup_irq(unsigned int irq, struct irqaction * new)
246 246
247mismatch: 247mismatch:
248 spin_unlock_irqrestore(&desc->lock, flags); 248 spin_unlock_irqrestore(&desc->lock, flags);
249 printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__); 249 if (!(new->flags & SA_PROBEIRQ)) {
250 dump_stack(); 250 printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__);
251 dump_stack();
252 }
251 return -EBUSY; 253 return -EBUSY;
252} 254}
253 255
diff --git a/kernel/power/main.c b/kernel/power/main.c
index ee371f50ccaa..a6d9ef46009e 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -272,7 +272,7 @@ static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n
272 if (*s && !strncmp(buf, *s, len)) 272 if (*s && !strncmp(buf, *s, len))
273 break; 273 break;
274 } 274 }
275 if (*s) 275 if (state < PM_SUSPEND_MAX && *s)
276 error = enter_state(state); 276 error = enter_state(state);
277 else 277 else
278 error = -EINVAL; 278 error = -EINVAL;
diff --git a/mm/slab.c b/mm/slab.c
index af5c5237e11a..c32af7e7581e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -979,7 +979,8 @@ static void __drain_alien_cache(struct kmem_cache *cachep,
979 * That way we could avoid the overhead of putting the objects 979 * That way we could avoid the overhead of putting the objects
980 * into the free lists and getting them back later. 980 * into the free lists and getting them back later.
981 */ 981 */
982 transfer_objects(rl3->shared, ac, ac->limit); 982 if (rl3->shared)
983 transfer_objects(rl3->shared, ac, ac->limit);
983 984
984 free_block(cachep, ac->entry, ac->avail, node); 985 free_block(cachep, ac->entry, ac->avail, node);
985 ac->avail = 0; 986 ac->avail = 0;
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 6275266dde2e..558c6ed443be 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -478,6 +478,20 @@ config SOUND_ACI_MIXER
478 478
479 This driver is also available as a module and will be called aci. 479 This driver is also available as a module and will be called aci.
480 480
481config SOUND_CS4232
482 tristate "Crystal CS4232 based (PnP) cards"
483 depends on SOUND_OSS
484 help
485 Say Y here if you have a card based on the Crystal CS4232 chip set,
486 which uses its own Plug and Play protocol.
487
488 If you compile the driver into the kernel, you have to add
489 "cs4232=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel
490 command line.
491
492 See <file:Documentation/sound/oss/CS4232> for more information on
493 configuring this card.
494
481config SOUND_VMIDI 495config SOUND_VMIDI
482 tristate "Loopback MIDI device support" 496 tristate "Loopback MIDI device support"
483 depends on SOUND_OSS 497 depends on SOUND_OSS