aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt19
-rw-r--r--Documentation/leds-class.txt71
-rw-r--r--Documentation/memory-barriers.txt1913
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c2
-rw-r--r--arch/alpha/kernel/core_marvel.c2
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/common/sharpsl_pm.c10
-rw-r--r--arch/arm/kernel/process.c1
-rw-r--r--arch/arm/mach-pxa/corgi.c11
-rw-r--r--arch/arm/mach-pxa/spitz.c11
-rw-r--r--arch/arm/mach-pxa/tosa.c9
-rw-r--r--arch/arm26/kernel/armksyms.c2
-rw-r--r--arch/frv/kernel/frv_ksyms.c2
-rw-r--r--arch/h8300/kernel/h8300_ksyms.c2
-rw-r--r--arch/i386/kernel/apic.c22
-rw-r--r--arch/i386/kernel/cpu/mcheck/mce.c4
-rw-r--r--arch/i386/kernel/io_apic.c2
-rw-r--r--arch/i386/kernel/process.c1
-rw-r--r--arch/i386/kernel/syscall_table.S1
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/i386/kernel/vsyscall-sigreturn.S2
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c1
-rw-r--r--arch/m68knommu/kernel/m68k_ksyms.c2
-rw-r--r--arch/mips/kernel/process.c1
-rw-r--r--arch/powerpc/kernel/crash_dump.c4
-rw-r--r--arch/powerpc/kernel/process.c1
-rw-r--r--arch/powerpc/kernel/vdso32/sigtramp.S2
-rw-r--r--arch/powerpc/kernel/vdso64/sigtramp.S2
-rw-r--r--arch/s390/kernel/smp.c6
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/setup.c2
-rw-r--r--arch/um/Kconfig3
-rw-r--r--arch/um/Makefile7
-rw-r--r--arch/um/Makefile-x86_642
-rw-r--r--arch/um/drivers/daemon_kern.c13
-rw-r--r--arch/um/drivers/harddog_kern.c8
-rw-r--r--arch/um/drivers/hostaudio_kern.c10
-rw-r--r--arch/um/drivers/mcast_kern.c13
-rw-r--r--arch/um/drivers/mconsole_kern.c140
-rw-r--r--arch/um/drivers/pcap_kern.c13
-rw-r--r--arch/um/drivers/slip_kern.c13
-rw-r--r--arch/um/drivers/slirp_kern.c15
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/include/kern_util.h6
-rw-r--r--arch/um/include/line.h18
-rw-r--r--arch/um/include/mem_user.h1
-rw-r--r--arch/um/include/os.h10
-rw-r--r--arch/um/include/sysdep-i386/checksum.h5
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h5
-rw-r--r--arch/um/include/sysdep-i386/tls.h32
-rw-r--r--arch/um/include/sysdep-x86_64/tls.h29
-rw-r--r--arch/um/include/user_util.h5
-rw-r--r--arch/um/kernel/exec_kern.c16
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/um/kernel/process_kern.c26
-rw-r--r--arch/um/kernel/ptrace.c44
-rw-r--r--arch/um/kernel/skas/process_kern.c11
-rw-r--r--arch/um/kernel/syscall_kern.c4
-rw-r--r--arch/um/kernel/trap_kern.c8
-rw-r--r--arch/um/kernel/tt/process_kern.c10
-rw-r--r--arch/um/os-Linux/Makefile7
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c13
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c13
-rw-r--r--arch/um/os-Linux/mem.c27
-rw-r--r--arch/um/os-Linux/process.c44
-rw-r--r--arch/um/os-Linux/start_up.c20
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile2
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c33
-rw-r--r--arch/um/os-Linux/tls.c76
-rw-r--r--arch/um/scripts/Makefile.rules26
-rw-r--r--arch/um/scripts/Makefile.unmap22
-rw-r--r--arch/um/sys-i386/Makefile23
-rw-r--r--arch/um/sys-i386/ptrace.c45
-rw-r--r--arch/um/sys-i386/ptrace_user.c10
-rw-r--r--arch/um/sys-i386/signal.c48
-rw-r--r--arch/um/sys-i386/sys_call_table.S2
-rw-r--r--arch/um/sys-i386/syscalls.c16
-rw-r--r--arch/um/sys-i386/tls.c384
-rw-r--r--arch/um/sys-x86_64/Makefile34
-rw-r--r--arch/um/sys-x86_64/tls.c14
-rw-r--r--arch/x86_64/ia32/vsyscall-sigreturn.S23
-rw-r--r--arch/x86_64/kernel/apic.c14
-rw-r--r--arch/x86_64/kernel/early_printk.c2
-rw-r--r--arch/x86_64/kernel/mce.c4
-rw-r--r--arch/x86_64/kernel/pmtimer.c2
-rw-r--r--arch/x86_64/kernel/setup.c2
-rw-r--r--arch/x86_64/kernel/setup64.c4
-rw-r--r--arch/x86_64/kernel/smpboot.c2
-rw-r--r--arch/x86_64/kernel/time.c4
-rw-r--r--arch/x86_64/kernel/traps.c4
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c2
-rw-r--r--arch/x86_64/mm/fault.c2
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c2
-rw-r--r--block/Kconfig8
-rw-r--r--block/elevator.c2
-rw-r--r--block/genhd.c103
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/ec.c4
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c18
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c8
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c80
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c85
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c61
-rw-r--r--drivers/char/istallion.c32
-rw-r--r--drivers/char/stallion.c46
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/vt.c4
-rw-r--r--drivers/edac/Kconfig2
-rw-r--r--drivers/ide/ide-disk.c3
-rw-r--r--drivers/ide/ide-taskfile.c8
-rw-r--r--drivers/isdn/sc/ioctl.c9
-rw-r--r--drivers/leds/Kconfig77
-rw-r--r--drivers/leds/Makefile16
-rw-r--r--drivers/leds/led-class.c167
-rw-r--r--drivers/leds/led-core.c25
-rw-r--r--drivers/leds/led-triggers.c239
-rw-r--r--drivers/leds/leds-corgi.c121
-rw-r--r--drivers/leds/leds-ixp4xx-gpio.c215
-rw-r--r--drivers/leds/leds-locomo.c95
-rw-r--r--drivers/leds/leds-spitz.c125
-rw-r--r--drivers/leds/leds-tosa.c131
-rw-r--r--drivers/leds/leds.h44
-rw-r--r--drivers/leds/ledtrig-ide-disk.c62
-rw-r--r--drivers/leds/ledtrig-timer.c170
-rw-r--r--drivers/md/md.c8
-rw-r--r--drivers/md/raid1.c13
-rw-r--r--drivers/md/raid6main.c2
-rw-r--r--drivers/media/video/cpia_pp.c2
-rw-r--r--drivers/mtd/chips/amd_flash.c4
-rw-r--r--drivers/mtd/chips/jedec_probe.c19
-rw-r--r--drivers/mtd/chips/sharp.c7
-rw-r--r--drivers/mtd/cmdlinepart.c7
-rw-r--r--drivers/mtd/devices/blkmtd.c13
-rw-r--r--drivers/mtd/devices/block2mtd.c13
-rw-r--r--drivers/mtd/devices/doc2000.c37
-rw-r--r--drivers/mtd/devices/lart.c10
-rw-r--r--drivers/mtd/devices/m25p80.c2
-rw-r--r--drivers/mtd/devices/ms02-nv.c2
-rw-r--r--drivers/mtd/inftlcore.c7
-rw-r--r--drivers/mtd/maps/alchemy-flash.c4
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c2
-rw-r--r--drivers/mtd/maps/dbox2-flash.c2
-rw-r--r--drivers/mtd/maps/dilnetpc.c4
-rw-r--r--drivers/mtd/maps/dmv182.c2
-rw-r--r--drivers/mtd/maps/h720x-flash.c2
-rw-r--r--drivers/mtd/maps/netsc520.c4
-rw-r--r--drivers/mtd/maps/nettel.c3
-rw-r--r--drivers/mtd/maps/ocotea.c6
-rw-r--r--drivers/mtd/maps/pci.c3
-rw-r--r--drivers/mtd/maps/pcmciamtd.c2
-rw-r--r--drivers/mtd/maps/redwood.c3
-rw-r--r--drivers/mtd/maps/sbc8240.c8
-rw-r--r--drivers/mtd/maps/sc520cdp.c2
-rw-r--r--drivers/mtd/maps/scx200_docflash.c2
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c4
-rw-r--r--drivers/mtd/maps/ts5500_flash.c2
-rw-r--r--drivers/mtd/maps/uclinux.c2
-rw-r--r--drivers/mtd/maps/vmax301.c2
-rw-r--r--drivers/mtd/mtd_blkdevs.c32
-rw-r--r--drivers/mtd/mtdblock.c14
-rw-r--r--drivers/mtd/mtdcore.c45
-rw-r--r--drivers/mtd/nand/Kconfig17
-rw-r--r--drivers/mtd/nand/au1550nd.c4
-rw-r--r--drivers/mtd/nand/nand_base.c26
-rw-r--r--drivers/mtd/redboot.c6
-rw-r--r--drivers/net/3c59x.c33
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/netconsole.c2
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c2
-rw-r--r--drivers/net/tokenring/Kconfig2
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/pcmcia/vrc4171_card.c12
-rw-r--r--drivers/pcmcia/vrc4173_cardu.c8
-rw-r--r--drivers/scsi/ahci.c4
-rw-r--r--drivers/scsi/ata_piix.c4
-rw-r--r--drivers/scsi/ibmmca.c2
-rw-r--r--drivers/scsi/libata-core.c28
-rw-r--r--drivers/scsi/libata-scsi.c8
-rw-r--r--drivers/scsi/libata.h2
-rw-r--r--drivers/serial/jsm/jsm_tty.c29
-rw-r--r--drivers/video/Kconfig12
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/backlight/Kconfig4
-rw-r--r--drivers/video/backlight/backlight.c84
-rw-r--r--drivers/video/backlight/corgi_bl.c124
-rw-r--r--drivers/video/backlight/hp680_bl.c139
-rw-r--r--drivers/video/cfbimgblt.c2
-rw-r--r--drivers/video/console/fbcon.c11
-rw-r--r--drivers/video/console/sticore.c4
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/pxafb.c8
-rw-r--r--drivers/video/radeonfb.c3167
-rw-r--r--drivers/video/stifb.c4
-rw-r--r--drivers/video/w100fb.c162
-rw-r--r--drivers/video/w100fb.h748
-rw-r--r--fs/Makefile2
-rw-r--r--fs/char_dev.c87
-rw-r--r--fs/dcache.c50
-rw-r--r--fs/hppfs/hppfs_kern.c14
-rw-r--r--fs/locks.c45
-rw-r--r--fs/msdos/namei.c15
-rw-r--r--fs/namei.c3
-rw-r--r--fs/proc/base.c13
-rw-r--r--fs/proc/proc_misc.c163
-rw-r--r--fs/select.c8
-rw-r--r--fs/sync.c164
-rw-r--r--fs/vfat/namei.c18
-rw-r--r--include/asm-arm/arch-pxa/sharpsl.h2
-rw-r--r--include/asm-generic/local.h13
-rw-r--r--include/asm-generic/mutex-dec.h30
-rw-r--r--include/asm-generic/mutex-xchg.h33
-rw-r--r--include/asm-i386/apicdef.h1
-rw-r--r--include/asm-i386/floppy.h34
-rw-r--r--include/asm-i386/local.h6
-rw-r--r--include/asm-i386/unistd.h3
-rw-r--r--include/asm-powerpc/system.h5
-rw-r--r--include/asm-s390/percpu.h2
-rw-r--r--include/asm-um/desc.h12
-rw-r--r--include/asm-um/host_ldt-i386.h34
-rw-r--r--include/asm-um/host_ldt-x86_64.h (renamed from include/asm-um/ldt-x86_64.h)39
-rw-r--r--include/asm-um/ldt-i386.h69
-rw-r--r--include/asm-um/ldt.h41
-rw-r--r--include/asm-um/processor-i386.h35
-rw-r--r--include/asm-um/processor-x86_64.h9
-rw-r--r--include/asm-um/ptrace-generic.h16
-rw-r--r--include/asm-um/ptrace-i386.h41
-rw-r--r--include/asm-um/ptrace-x86_64.h35
-rw-r--r--include/asm-um/segment.h6
-rw-r--r--include/asm-um/thread_info.h16
-rw-r--r--include/asm-um/uaccess.h2
-rw-r--r--include/asm-x86_64/local.h10
-rw-r--r--include/linux/backlight.h25
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/fadvise.h6
-rw-r--r--include/linux/fb.h2
-rw-r--r--include/linux/fs.h22
-rw-r--r--include/linux/hrtimer.h16
-rw-r--r--include/linux/ipmi_smi.h16
-rw-r--r--include/linux/leds.h111
-rw-r--r--include/linux/migrate.h5
-rw-r--r--include/linux/mtd/blktrans.h4
-rw-r--r--include/linux/mtd/doc2000.h4
-rw-r--r--include/linux/mtd/inftl.h5
-rw-r--r--include/linux/namei.h1
-rw-r--r--include/linux/netdevice.h55
-rw-r--r--include/linux/pagemap.h4
-rw-r--r--include/linux/pid.h96
-rw-r--r--include/linux/sched.h18
-rw-r--r--include/linux/skbuff.h29
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/timer.h8
-rw-r--r--include/linux/tiocl.h1
-rw-r--r--include/net/tcp.h3
-rw-r--r--kernel/acct.c12
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/cpuset.c69
-rw-r--r--kernel/exit.c7
-rw-r--r--kernel/fork.c28
-rw-r--r--kernel/futex.c4
-rw-r--r--kernel/futex_compat.c4
-rw-r--r--kernel/hrtimer.c49
-rw-r--r--kernel/module.c1
-rw-r--r--kernel/pid.c212
-rw-r--r--kernel/power/process.c3
-rw-r--r--kernel/sched.c84
-rw-r--r--kernel/signal.c1
-rw-r--r--kernel/sys.c19
-rw-r--r--kernel/timer.c92
-rw-r--r--mm/fadvise.c20
-rw-r--r--mm/hugetlb.c6
-rw-r--r--mm/memory.c2
-rw-r--r--mm/swapfile.c14
-rw-r--r--net/core/dev.c64
-rw-r--r--net/core/sock.c16
-rw-r--r--net/dccp/feat.c6
-rw-r--r--net/decnet/dn_dev.c2
279 files changed, 7174 insertions, 5493 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 495858b236b6..59d0c74c79c9 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -127,13 +127,6 @@ Who: Christoph Hellwig <hch@lst.de>
127 127
128--------------------------- 128---------------------------
129 129
130What: EXPORT_SYMBOL(lookup_hash)
131When: January 2006
132Why: Too low-level interface. Use lookup_one_len or lookup_create instead.
133Who: Christoph Hellwig <hch@lst.de>
134
135---------------------------
136
137What: CONFIG_FORCED_INLINING 130What: CONFIG_FORCED_INLINING
138When: June 2006 131When: June 2006
139Why: Config option is there to see if gcc is good enough. (in january 132Why: Config option is there to see if gcc is good enough. (in january
@@ -241,3 +234,15 @@ Why: The USB subsystem has changed a lot over time, and it has been
241Who: Greg Kroah-Hartman <gregkh@suse.de> 234Who: Greg Kroah-Hartman <gregkh@suse.de>
242 235
243--------------------------- 236---------------------------
237
238What: find_trylock_page
239When: January 2007
240Why: The interface no longer has any callers left in the kernel. It
241 is an odd interface (compared with other find_*_page functions), in
242 that it does not take a refcount to the page, only the page lock.
243 It should be replaced with find_get_page or find_lock_page if possible.
244 This feature removal can be reevaluated if users of the interface
245 cannot cleanly use something else.
246Who: Nick Piggin <npiggin@suse.de>
247
248---------------------------
diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt
new file mode 100644
index 000000000000..8c35c0426110
--- /dev/null
+++ b/Documentation/leds-class.txt
@@ -0,0 +1,71 @@
1LED handling under Linux
2========================
3
4If you're reading this and thinking about keyboard leds, these are
5handled by the input subsystem and the led class is *not* needed.
6
7In its simplest form, the LED class just allows control of LEDs from
8userspace. LEDs appear in /sys/class/leds/. The brightness file will
9set the brightness of the LED (taking a value 0-255). Most LEDs don't
10have hardware brightness support so will just be turned on for non-zero
11brightness settings.
12
13The class also introduces the optional concept of an LED trigger. A trigger
14is a kernel based source of led events. Triggers can either be simple or
15complex. A simple trigger isn't configurable and is designed to slot into
16existing subsystems with minimal additional code. Examples are the ide-disk,
17nand-disk and sharpsl-charge triggers. With led triggers disabled, the code
18optimises away.
19
20Complex triggers whilst available to all LEDs have LED specific
21parameters and work on a per LED basis. The timer trigger is an example.
22
23You can change triggers in a similar manner to the way an IO scheduler
24is chosen (via /sys/class/leds/<device>/trigger). Trigger specific
25parameters can appear in /sys/class/leds/<device> once a given trigger is
26selected.
27
28
29Design Philosophy
30=================
31
32The underlying design philosophy is simplicity. LEDs are simple devices
33and the aim is to keep a small amount of code giving as much functionality
34as possible. Please keep this in mind when suggesting enhancements.
35
36
37LED Device Naming
38=================
39
40Is currently of the form:
41
42"devicename:colour"
43
44There have been calls for LED properties such as colour to be exported as
45individual led class attributes. As a solution which doesn't incur as much
46overhead, I suggest these become part of the device name. The naming scheme
47above leaves scope for further attributes should they be needed.
48
49
50Known Issues
51============
52
53The LED Trigger core cannot be a module as the simple trigger functions
54would cause nightmare dependency issues. I see this as a minor issue
55compared to the benefits the simple trigger functionality brings. The
56rest of the LED subsystem can be modular.
57
58Some leds can be programmed to flash in hardware. As this isn't a generic
59LED device property, this should be exported as a device specific sysfs
60attribute rather than part of the class if this functionality is required.
61
62
63Future Development
64==================
65
66At the moment, a trigger can't be created specifically for a single LED.
67There are a number of cases where a trigger might only be mappable to a
68particular LED (ACPI?). The addition of triggers provided by the LED driver
69should cover this option and be possible to add without breaking the
70current interface.
71
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
new file mode 100644
index 000000000000..f8550310a6d5
--- /dev/null
+++ b/Documentation/memory-barriers.txt
@@ -0,0 +1,1913 @@
1 ============================
2 LINUX KERNEL MEMORY BARRIERS
3 ============================
4
5By: David Howells <dhowells@redhat.com>
6
7Contents:
8
9 (*) Abstract memory access model.
10
11 - Device operations.
12 - Guarantees.
13
14 (*) What are memory barriers?
15
16 - Varieties of memory barrier.
17 - What may not be assumed about memory barriers?
18 - Data dependency barriers.
19 - Control dependencies.
20 - SMP barrier pairing.
21 - Examples of memory barrier sequences.
22
23 (*) Explicit kernel barriers.
24
25 - Compiler barrier.
26 - The CPU memory barriers.
27 - MMIO write barrier.
28
29 (*) Implicit kernel memory barriers.
30
31 - Locking functions.
32 - Interrupt disabling functions.
33 - Miscellaneous functions.
34
35 (*) Inter-CPU locking barrier effects.
36
37 - Locks vs memory accesses.
38 - Locks vs I/O accesses.
39
40 (*) Where are memory barriers needed?
41
42 - Interprocessor interaction.
43 - Atomic operations.
44 - Accessing devices.
45 - Interrupts.
46
47 (*) Kernel I/O barrier effects.
48
49 (*) Assumed minimum execution ordering model.
50
51 (*) The effects of the cpu cache.
52
53 - Cache coherency.
54 - Cache coherency vs DMA.
55 - Cache coherency vs MMIO.
56
57 (*) The things CPUs get up to.
58
59 - And then there's the Alpha.
60
61 (*) References.
62
63
64============================
65ABSTRACT MEMORY ACCESS MODEL
66============================
67
68Consider the following abstract model of the system:
69
70 : :
71 : :
72 : :
73 +-------+ : +--------+ : +-------+
74 | | : | | : | |
75 | | : | | : | |
76 | CPU 1 |<----->| Memory |<----->| CPU 2 |
77 | | : | | : | |
78 | | : | | : | |
79 +-------+ : +--------+ : +-------+
80 ^ : ^ : ^
81 | : | : |
82 | : | : |
83 | : v : |
84 | : +--------+ : |
85 | : | | : |
86 | : | | : |
87 +---------->| Device |<----------+
88 : | | :
89 : | | :
90 : +--------+ :
91 : :
92
93Each CPU executes a program that generates memory access operations. In the
94abstract CPU, memory operation ordering is very relaxed, and a CPU may actually
95perform the memory operations in any order it likes, provided program causality
96appears to be maintained. Similarly, the compiler may also arrange the
97instructions it emits in any order it likes, provided it doesn't affect the
98apparent operation of the program.
99
100So in the above diagram, the effects of the memory operations performed by a
101CPU are perceived by the rest of the system as the operations cross the
102interface between the CPU and rest of the system (the dotted lines).
103
104
105For example, consider the following sequence of events:
106
107 CPU 1 CPU 2
108 =============== ===============
109 { A == 1; B == 2 }
110 A = 3; x = A;
111 B = 4; y = B;
112
113The set of accesses as seen by the memory system in the middle can be arranged
114in 24 different combinations:
115
116 STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4
117 STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3
118 STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4
119 STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4
120 STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3
121 STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4
122 STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4
123 STORE B=4, ...
124 ...
125
126and can thus result in four different combinations of values:
127
128 x == 1, y == 2
129 x == 1, y == 4
130 x == 3, y == 2
131 x == 3, y == 4
132
133
134Furthermore, the stores committed by a CPU to the memory system may not be
135perceived by the loads made by another CPU in the same order as the stores were
136committed.
137
138
139As a further example, consider this sequence of events:
140
141 CPU 1 CPU 2
142 =============== ===============
143 { A == 1, B == 2, C = 3, P == &A, Q == &C }
144 B = 4; Q = P;
145 P = &B D = *Q;
146
147There is an obvious data dependency here, as the value loaded into D depends on
148the address retrieved from P by CPU 2. At the end of the sequence, any of the
149following results are possible:
150
151 (Q == &A) and (D == 1)
152 (Q == &B) and (D == 2)
153 (Q == &B) and (D == 4)
154
155Note that CPU 2 will never try and load C into D because the CPU will load P
156into Q before issuing the load of *Q.
157
158
159DEVICE OPERATIONS
160-----------------
161
162Some devices present their control interfaces as collections of memory
163locations, but the order in which the control registers are accessed is very
164important. For instance, imagine an ethernet card with a set of internal
165registers that are accessed through an address port register (A) and a data
166port register (D). To read internal register 5, the following code might then
167be used:
168
169 *A = 5;
170 x = *D;
171
172but this might show up as either of the following two sequences:
173
174 STORE *A = 5, x = LOAD *D
175 x = LOAD *D, STORE *A = 5
176
177the second of which will almost certainly result in a malfunction, since it set
178the address _after_ attempting to read the register.
179
180
181GUARANTEES
182----------
183
184There are some minimal guarantees that may be expected of a CPU:
185
186 (*) On any given CPU, dependent memory accesses will be issued in order, with
187 respect to itself. This means that for:
188
189 Q = P; D = *Q;
190
191 the CPU will issue the following memory operations:
192
193 Q = LOAD P, D = LOAD *Q
194
195 and always in that order.
196
197 (*) Overlapping loads and stores within a particular CPU will appear to be
198 ordered within that CPU. This means that for:
199
200 a = *X; *X = b;
201
202 the CPU will only issue the following sequence of memory operations:
203
204 a = LOAD *X, STORE *X = b
205
206 And for:
207
208 *X = c; d = *X;
209
210 the CPU will only issue:
211
212 STORE *X = c, d = LOAD *X
213
214 (Loads and stores overlap if they are targetted at overlapping pieces of
215 memory).
216
217And there are a number of things that _must_ or _must_not_ be assumed:
218
219 (*) It _must_not_ be assumed that independent loads and stores will be issued
220 in the order given. This means that for:
221
222 X = *A; Y = *B; *D = Z;
223
224 we may get any of the following sequences:
225
226 X = LOAD *A, Y = LOAD *B, STORE *D = Z
227 X = LOAD *A, STORE *D = Z, Y = LOAD *B
228 Y = LOAD *B, X = LOAD *A, STORE *D = Z
229 Y = LOAD *B, STORE *D = Z, X = LOAD *A
230 STORE *D = Z, X = LOAD *A, Y = LOAD *B
231 STORE *D = Z, Y = LOAD *B, X = LOAD *A
232
233 (*) It _must_ be assumed that overlapping memory accesses may be merged or
234 discarded. This means that for:
235
236 X = *A; Y = *(A + 4);
237
238 we may get any one of the following sequences:
239
240 X = LOAD *A; Y = LOAD *(A + 4);
241 Y = LOAD *(A + 4); X = LOAD *A;
242 {X, Y} = LOAD {*A, *(A + 4) };
243
244 And for:
245
246 *A = X; Y = *A;
247
248 we may get either of:
249
250 STORE *A = X; Y = LOAD *A;
251 STORE *A = Y;
252
253
254=========================
255WHAT ARE MEMORY BARRIERS?
256=========================
257
258As can be seen above, independent memory operations are effectively performed
259in random order, but this can be a problem for CPU-CPU interaction and for I/O.
260What is required is some way of intervening to instruct the compiler and the
261CPU to restrict the order.
262
263Memory barriers are such interventions. They impose a perceived partial
264ordering between the memory operations specified on either side of the barrier.
265They request that the sequence of memory events generated appears to other
266parts of the system as if the barrier is effective on that CPU.
267
268
269VARIETIES OF MEMORY BARRIER
270---------------------------
271
272Memory barriers come in four basic varieties:
273
274 (1) Write (or store) memory barriers.
275
276 A write memory barrier gives a guarantee that all the STORE operations
277 specified before the barrier will appear to happen before all the STORE
278 operations specified after the barrier with respect to the other
279 components of the system.
280
281 A write barrier is a partial ordering on stores only; it is not required
282 to have any effect on loads.
283
284 A CPU can be viewed as as commiting a sequence of store operations to the
285 memory system as time progresses. All stores before a write barrier will
286 occur in the sequence _before_ all the stores after the write barrier.
287
288 [!] Note that write barriers should normally be paired with read or data
289 dependency barriers; see the "SMP barrier pairing" subsection.
290
291
292 (2) Data dependency barriers.
293
294 A data dependency barrier is a weaker form of read barrier. In the case
295 where two loads are performed such that the second depends on the result
296 of the first (eg: the first load retrieves the address to which the second
297 load will be directed), a data dependency barrier would be required to
298 make sure that the target of the second load is updated before the address
299 obtained by the first load is accessed.
300
301 A data dependency barrier is a partial ordering on interdependent loads
302 only; it is not required to have any effect on stores, independent loads
303 or overlapping loads.
304
305 As mentioned in (1), the other CPUs in the system can be viewed as
306 committing sequences of stores to the memory system that the CPU being
307 considered can then perceive. A data dependency barrier issued by the CPU
308 under consideration guarantees that for any load preceding it, if that
309 load touches one of a sequence of stores from another CPU, then by the
310 time the barrier completes, the effects of all the stores prior to that
311 touched by the load will be perceptible to any loads issued after the data
312 dependency barrier.
313
314 See the "Examples of memory barrier sequences" subsection for diagrams
315 showing the ordering constraints.
316
317 [!] Note that the first load really has to have a _data_ dependency and
318 not a control dependency. If the address for the second load is dependent
319 on the first load, but the dependency is through a conditional rather than
320 actually loading the address itself, then it's a _control_ dependency and
321 a full read barrier or better is required. See the "Control dependencies"
322 subsection for more information.
323
324 [!] Note that data dependency barriers should normally be paired with
325 write barriers; see the "SMP barrier pairing" subsection.
326
327
328 (3) Read (or load) memory barriers.
329
330 A read barrier is a data dependency barrier plus a guarantee that all the
331 LOAD operations specified before the barrier will appear to happen before
332 all the LOAD operations specified after the barrier with respect to the
333 other components of the system.
334
335 A read barrier is a partial ordering on loads only; it is not required to
336 have any effect on stores.
337
338 Read memory barriers imply data dependency barriers, and so can substitute
339 for them.
340
341 [!] Note that read barriers should normally be paired with write barriers;
342 see the "SMP barrier pairing" subsection.
343
344
345 (4) General memory barriers.
346
347 A general memory barrier is a combination of both a read memory barrier
348 and a write memory barrier. It is a partial ordering over both loads and
349 stores.
350
351 General memory barriers imply both read and write memory barriers, and so
352 can substitute for either.
353
354
355And a couple of implicit varieties:
356
357 (5) LOCK operations.
358
359 This acts as a one-way permeable barrier. It guarantees that all memory
360 operations after the LOCK operation will appear to happen after the LOCK
361 operation with respect to the other components of the system.
362
363 Memory operations that occur before a LOCK operation may appear to happen
364 after it completes.
365
366 A LOCK operation should almost always be paired with an UNLOCK operation.
367
368
369 (6) UNLOCK operations.
370
371 This also acts as a one-way permeable barrier. It guarantees that all
372 memory operations before the UNLOCK operation will appear to happen before
373 the UNLOCK operation with respect to the other components of the system.
374
375 Memory operations that occur after an UNLOCK operation may appear to
376 happen before it completes.
377
378 LOCK and UNLOCK operations are guaranteed to appear with respect to each
379 other strictly in the order specified.
380
381 The use of LOCK and UNLOCK operations generally precludes the need for
382 other sorts of memory barrier (but note the exceptions mentioned in the
383 subsection "MMIO write barrier").
384
385
386Memory barriers are only required where there's a possibility of interaction
387between two CPUs or between a CPU and a device. If it can be guaranteed that
388there won't be any such interaction in any particular piece of code, then
389memory barriers are unnecessary in that piece of code.
390
391
392Note that these are the _minimum_ guarantees. Different architectures may give
393more substantial guarantees, but they may _not_ be relied upon outside of arch
394specific code.
395
396
397WHAT MAY NOT BE ASSUMED ABOUT MEMORY BARRIERS?
398----------------------------------------------
399
400There are certain things that the Linux kernel memory barriers do not guarantee:
401
402 (*) There is no guarantee that any of the memory accesses specified before a
403 memory barrier will be _complete_ by the completion of a memory barrier
404 instruction; the barrier can be considered to draw a line in that CPU's
405 access queue that accesses of the appropriate type may not cross.
406
407 (*) There is no guarantee that issuing a memory barrier on one CPU will have
408 any direct effect on another CPU or any other hardware in the system. The
409 indirect effect will be the order in which the second CPU sees the effects
410 of the first CPU's accesses occur, but see the next point:
411
412 (*) There is no guarantee that the a CPU will see the correct order of effects
413 from a second CPU's accesses, even _if_ the second CPU uses a memory
414 barrier, unless the first CPU _also_ uses a matching memory barrier (see
415 the subsection on "SMP Barrier Pairing").
416
417 (*) There is no guarantee that some intervening piece of off-the-CPU
418 hardware[*] will not reorder the memory accesses. CPU cache coherency
419 mechanisms should propagate the indirect effects of a memory barrier
420 between CPUs, but might not do so in order.
421
422 [*] For information on bus mastering DMA and coherency please read:
423
424 Documentation/pci.txt
425 Documentation/DMA-mapping.txt
426 Documentation/DMA-API.txt
427
428
429DATA DEPENDENCY BARRIERS
430------------------------
431
432The usage requirements of data dependency barriers are a little subtle, and
433it's not always obvious that they're needed. To illustrate, consider the
434following sequence of events:
435
436 CPU 1 CPU 2
437 =============== ===============
438 { A == 1, B == 2, C = 3, P == &A, Q == &C }
439 B = 4;
440 <write barrier>
441 P = &B
442 Q = P;
443 D = *Q;
444
445There's a clear data dependency here, and it would seem that by the end of the
446sequence, Q must be either &A or &B, and that:
447
448 (Q == &A) implies (D == 1)
449 (Q == &B) implies (D == 4)
450
451But! CPU 2's perception of P may be updated _before_ its perception of B, thus
452leading to the following situation:
453
454 (Q == &B) and (D == 2) ????
455
456Whilst this may seem like a failure of coherency or causality maintenance, it
457isn't, and this behaviour can be observed on certain real CPUs (such as the DEC
458Alpha).
459
460To deal with this, a data dependency barrier must be inserted between the
461address load and the data load:
462
463 CPU 1 CPU 2
464 =============== ===============
465 { A == 1, B == 2, C = 3, P == &A, Q == &C }
466 B = 4;
467 <write barrier>
468 P = &B
469 Q = P;
470 <data dependency barrier>
471 D = *Q;
472
473This enforces the occurrence of one of the two implications, and prevents the
474third possibility from arising.
475
476[!] Note that this extremely counterintuitive situation arises most easily on
477machines with split caches, so that, for example, one cache bank processes
478even-numbered cache lines and the other bank processes odd-numbered cache
479lines. The pointer P might be stored in an odd-numbered cache line, and the
480variable B might be stored in an even-numbered cache line. Then, if the
481even-numbered bank of the reading CPU's cache is extremely busy while the
482odd-numbered bank is idle, one can see the new value of the pointer P (&B),
483but the old value of the variable B (1).
484
485
486Another example of where data dependency barriers might by required is where a
487number is read from memory and then used to calculate the index for an array
488access:
489
490 CPU 1 CPU 2
491 =============== ===============
492 { M[0] == 1, M[1] == 2, M[3] = 3, P == 0, Q == 3 }
493 M[1] = 4;
494 <write barrier>
495 P = 1
496 Q = P;
497 <data dependency barrier>
498 D = M[Q];
499
500
501The data dependency barrier is very important to the RCU system, for example.
502See rcu_dereference() in include/linux/rcupdate.h. This permits the current
503target of an RCU'd pointer to be replaced with a new modified target, without
504the replacement target appearing to be incompletely initialised.
505
506See also the subsection on "Cache Coherency" for a more thorough example.
507
508
509CONTROL DEPENDENCIES
510--------------------
511
512A control dependency requires a full read memory barrier, not simply a data
513dependency barrier to make it work correctly. Consider the following bit of
514code:
515
516 q = &a;
517 if (p)
518 q = &b;
519 <data dependency barrier>
520 x = *q;
521
522This will not have the desired effect because there is no actual data
523dependency, but rather a control dependency that the CPU may short-circuit by
524attempting to predict the outcome in advance. In such a case what's actually
525required is:
526
527 q = &a;
528 if (p)
529 q = &b;
530 <read barrier>
531 x = *q;
532
533
534SMP BARRIER PAIRING
535-------------------
536
537When dealing with CPU-CPU interactions, certain types of memory barrier should
538always be paired. A lack of appropriate pairing is almost certainly an error.
539
540A write barrier should always be paired with a data dependency barrier or read
541barrier, though a general barrier would also be viable. Similarly a read
542barrier or a data dependency barrier should always be paired with at least an
543write barrier, though, again, a general barrier is viable:
544
545 CPU 1 CPU 2
546 =============== ===============
547 a = 1;
548 <write barrier>
549 b = 2; x = a;
550 <read barrier>
551 y = b;
552
553Or:
554
555 CPU 1 CPU 2
556 =============== ===============================
557 a = 1;
558 <write barrier>
559 b = &a; x = b;
560 <data dependency barrier>
561 y = *x;
562
563Basically, the read barrier always has to be there, even though it can be of
564the "weaker" type.
565
566
567EXAMPLES OF MEMORY BARRIER SEQUENCES
568------------------------------------
569
570Firstly, write barriers act as a partial orderings on store operations.
571Consider the following sequence of events:
572
573 CPU 1
574 =======================
575 STORE A = 1
576 STORE B = 2
577 STORE C = 3
578 <write barrier>
579 STORE D = 4
580 STORE E = 5
581
582This sequence of events is committed to the memory coherence system in an order
583that the rest of the system might perceive as the unordered set of { STORE A,
584STORE B, STORE C } all occuring before the unordered set of { STORE D, STORE E
585}:
586
587 +-------+ : :
588 | | +------+
589 | |------>| C=3 | } /\
590 | | : +------+ }----- \ -----> Events perceptible
591 | | : | A=1 | } \/ to rest of system
592 | | : +------+ }
593 | CPU 1 | : | B=2 | }
594 | | +------+ }
595 | | wwwwwwwwwwwwwwww } <--- At this point the write barrier
596 | | +------+ } requires all stores prior to the
597 | | : | E=5 | } barrier to be committed before
598 | | : +------+ } further stores may be take place.
599 | |------>| D=4 | }
600 | | +------+
601 +-------+ : :
602 |
603 | Sequence in which stores committed to memory system
604 | by CPU 1
605 V
606
607
608Secondly, data dependency barriers act as a partial orderings on data-dependent
609loads. Consider the following sequence of events:
610
611 CPU 1 CPU 2
612 ======================= =======================
613 STORE A = 1
614 STORE B = 2
615 <write barrier>
616 STORE C = &B LOAD X
617 STORE D = 4 LOAD C (gets &B)
618 LOAD *C (reads B)
619
620Without intervention, CPU 2 may perceive the events on CPU 1 in some
621effectively random order, despite the write barrier issued by CPU 1:
622
623 +-------+ : : : :
624 | | +------+ +-------+ | Sequence of update
625 | |------>| B=2 |----- --->| Y->8 | | of perception on
626 | | : +------+ \ +-------+ | CPU 2
627 | CPU 1 | : | A=1 | \ --->| C->&Y | V
628 | | +------+ | +-------+
629 | | wwwwwwwwwwwwwwww | : :
630 | | +------+ | : :
631 | | : | C=&B |--- | : : +-------+
632 | | : +------+ \ | +-------+ | |
633 | |------>| D=4 | ----------->| C->&B |------>| |
634 | | +------+ | +-------+ | |
635 +-------+ : : | : : | |
636 | : : | |
637 | : : | CPU 2 |
638 | +-------+ | |
639 Apparently incorrect ---> | | B->7 |------>| |
640 perception of B (!) | +-------+ | |
641 | : : | |
642 | +-------+ | |
643 The load of X holds ---> \ | X->9 |------>| |
644 up the maintenance \ +-------+ | |
645 of coherence of B ----->| B->2 | +-------+
646 +-------+
647 : :
648
649
650In the above example, CPU 2 perceives that B is 7, despite the load of *C
651(which would be B) coming after the the LOAD of C.
652
653If, however, a data dependency barrier were to be placed between the load of C
654and the load of *C (ie: B) on CPU 2, then the following will occur:
655
656 +-------+ : : : :
657 | | +------+ +-------+
658 | |------>| B=2 |----- --->| Y->8 |
659 | | : +------+ \ +-------+
660 | CPU 1 | : | A=1 | \ --->| C->&Y |
661 | | +------+ | +-------+
662 | | wwwwwwwwwwwwwwww | : :
663 | | +------+ | : :
664 | | : | C=&B |--- | : : +-------+
665 | | : +------+ \ | +-------+ | |
666 | |------>| D=4 | ----------->| C->&B |------>| |
667 | | +------+ | +-------+ | |
668 +-------+ : : | : : | |
669 | : : | |
670 | : : | CPU 2 |
671 | +-------+ | |
672 \ | X->9 |------>| |
673 \ +-------+ | |
674 ----->| B->2 | | |
675 +-------+ | |
676 Makes sure all effects ---> ddddddddddddddddd | |
677 prior to the store of C +-------+ | |
678 are perceptible to | B->2 |------>| |
679 successive loads +-------+ | |
680 : : +-------+
681
682
683And thirdly, a read barrier acts as a partial order on loads. Consider the
684following sequence of events:
685
686 CPU 1 CPU 2
687 ======================= =======================
688 STORE A=1
689 STORE B=2
690 STORE C=3
691 <write barrier>
692 STORE D=4
693 STORE E=5
694 LOAD A
695 LOAD B
696 LOAD C
697 LOAD D
698 LOAD E
699
700Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in
701some effectively random order, despite the write barrier issued by CPU 1:
702
703 +-------+ : :
704 | | +------+
705 | |------>| C=3 | }
706 | | : +------+ }
707 | | : | A=1 | }
708 | | : +------+ }
709 | CPU 1 | : | B=2 | }---
710 | | +------+ } \
711 | | wwwwwwwwwwwww} \
712 | | +------+ } \ : : +-------+
713 | | : | E=5 | } \ +-------+ | |
714 | | : +------+ } \ { | C->3 |------>| |
715 | |------>| D=4 | } \ { +-------+ : | |
716 | | +------+ \ { | E->5 | : | |
717 +-------+ : : \ { +-------+ : | |
718 Transfer -->{ | A->1 | : | CPU 2 |
719 from CPU 1 { +-------+ : | |
720 to CPU 2 { | D->4 | : | |
721 { +-------+ : | |
722 { | B->2 |------>| |
723 +-------+ | |
724 : : +-------+
725
726
727If, however, a read barrier were to be placed between the load of C and the
728load of D on CPU 2, then the partial ordering imposed by CPU 1 will be
729perceived correctly by CPU 2.
730
731 +-------+ : :
732 | | +------+
733 | |------>| C=3 | }
734 | | : +------+ }
735 | | : | A=1 | }---
736 | | : +------+ } \
737 | CPU 1 | : | B=2 | } \
738 | | +------+ \
739 | | wwwwwwwwwwwwwwww \
740 | | +------+ \ : : +-------+
741 | | : | E=5 | } \ +-------+ | |
742 | | : +------+ }--- \ { | C->3 |------>| |
743 | |------>| D=4 | } \ \ { +-------+ : | |
744 | | +------+ \ -->{ | B->2 | : | |
745 +-------+ : : \ { +-------+ : | |
746 \ { | A->1 | : | CPU 2 |
747 \ +-------+ | |
748 At this point the read ----> \ rrrrrrrrrrrrrrrrr | |
749 barrier causes all effects \ +-------+ | |
750 prior to the storage of C \ { | E->5 | : | |
751 to be perceptible to CPU 2 -->{ +-------+ : | |
752 { | D->4 |------>| |
753 +-------+ | |
754 : : +-------+
755
756
757========================
758EXPLICIT KERNEL BARRIERS
759========================
760
761The Linux kernel has a variety of different barriers that act at different
762levels:
763
764 (*) Compiler barrier.
765
766 (*) CPU memory barriers.
767
768 (*) MMIO write barrier.
769
770
771COMPILER BARRIER
772----------------
773
774The Linux kernel has an explicit compiler barrier function that prevents the
775compiler from moving the memory accesses either side of it to the other side:
776
777 barrier();
778
779This a general barrier - lesser varieties of compiler barrier do not exist.
780
781The compiler barrier has no direct effect on the CPU, which may then reorder
782things however it wishes.
783
784
785CPU MEMORY BARRIERS
786-------------------
787
788The Linux kernel has eight basic CPU memory barriers:
789
790 TYPE MANDATORY SMP CONDITIONAL
791 =============== ======================= ===========================
792 GENERAL mb() smp_mb()
793 WRITE wmb() smp_wmb()
794 READ rmb() smp_rmb()
795 DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends()
796
797
798All CPU memory barriers unconditionally imply compiler barriers.
799
800SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
801systems because it is assumed that a CPU will be appear to be self-consistent,
802and will order overlapping accesses correctly with respect to itself.
803
804[!] Note that SMP memory barriers _must_ be used to control the ordering of
805references to shared memory on SMP systems, though the use of locking instead
806is sufficient.
807
808Mandatory barriers should not be used to control SMP effects, since mandatory
809barriers unnecessarily impose overhead on UP systems. They may, however, be
810used to control MMIO effects on accesses through relaxed memory I/O windows.
811These are required even on non-SMP systems as they affect the order in which
812memory operations appear to a device by prohibiting both the compiler and the
813CPU from reordering them.
814
815
816There are some more advanced barrier functions:
817
818 (*) set_mb(var, value)
819 (*) set_wmb(var, value)
820
821 These assign the value to the variable and then insert at least a write
822 barrier after it, depending on the function. They aren't guaranteed to
823 insert anything more than a compiler barrier in a UP compilation.
824
825
826 (*) smp_mb__before_atomic_dec();
827 (*) smp_mb__after_atomic_dec();
828 (*) smp_mb__before_atomic_inc();
829 (*) smp_mb__after_atomic_inc();
830
831 These are for use with atomic add, subtract, increment and decrement
832 functions, especially when used for reference counting. These functions
833 do not imply memory barriers.
834
835 As an example, consider a piece of code that marks an object as being dead
836 and then decrements the object's reference count:
837
838 obj->dead = 1;
839 smp_mb__before_atomic_dec();
840 atomic_dec(&obj->ref_count);
841
842 This makes sure that the death mark on the object is perceived to be set
843 *before* the reference counter is decremented.
844
845 See Documentation/atomic_ops.txt for more information. See the "Atomic
846 operations" subsection for information on where to use these.
847
848
849 (*) smp_mb__before_clear_bit(void);
850 (*) smp_mb__after_clear_bit(void);
851
852 These are for use similar to the atomic inc/dec barriers. These are
853 typically used for bitwise unlocking operations, so care must be taken as
854 there are no implicit memory barriers here either.
855
856 Consider implementing an unlock operation of some nature by clearing a
857 locking bit. The clear_bit() would then need to be barriered like this:
858
859 smp_mb__before_clear_bit();
860 clear_bit( ... );
861
862 This prevents memory operations before the clear leaking to after it. See
863 the subsection on "Locking Functions" with reference to UNLOCK operation
864 implications.
865
866 See Documentation/atomic_ops.txt for more information. See the "Atomic
867 operations" subsection for information on where to use these.
868
869
870MMIO WRITE BARRIER
871------------------
872
873The Linux kernel also has a special barrier for use with memory-mapped I/O
874writes:
875
876 mmiowb();
877
878This is a variation on the mandatory write barrier that causes writes to weakly
879ordered I/O regions to be partially ordered. Its effects may go beyond the
880CPU->Hardware interface and actually affect the hardware at some level.
881
882See the subsection "Locks vs I/O accesses" for more information.
883
884
885===============================
886IMPLICIT KERNEL MEMORY BARRIERS
887===============================
888
889Some of the other functions in the linux kernel imply memory barriers, amongst
890which are locking, scheduling and memory allocation functions.
891
892This specification is a _minimum_ guarantee; any particular architecture may
893provide more substantial guarantees, but these may not be relied upon outside
894of arch specific code.
895
896
897LOCKING FUNCTIONS
898-----------------
899
900The Linux kernel has a number of locking constructs:
901
902 (*) spin locks
903 (*) R/W spin locks
904 (*) mutexes
905 (*) semaphores
906 (*) R/W semaphores
907 (*) RCU
908
909In all cases there are variants on "LOCK" operations and "UNLOCK" operations
910for each construct. These operations all imply certain barriers:
911
912 (1) LOCK operation implication:
913
914 Memory operations issued after the LOCK will be completed after the LOCK
915 operation has completed.
916
917 Memory operations issued before the LOCK may be completed after the LOCK
918 operation has completed.
919
920 (2) UNLOCK operation implication:
921
922 Memory operations issued before the UNLOCK will be completed before the
923 UNLOCK operation has completed.
924
925 Memory operations issued after the UNLOCK may be completed before the
926 UNLOCK operation has completed.
927
928 (3) LOCK vs LOCK implication:
929
930 All LOCK operations issued before another LOCK operation will be completed
931 before that LOCK operation.
932
933 (4) LOCK vs UNLOCK implication:
934
935 All LOCK operations issued before an UNLOCK operation will be completed
936 before the UNLOCK operation.
937
938 All UNLOCK operations issued before a LOCK operation will be completed
939 before the LOCK operation.
940
941 (5) Failed conditional LOCK implication:
942
943 Certain variants of the LOCK operation may fail, either due to being
944 unable to get the lock immediately, or due to receiving an unblocked
945 signal whilst asleep waiting for the lock to become available. Failed
946 locks do not imply any sort of barrier.
947
948Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is
949equivalent to a full barrier, but a LOCK followed by an UNLOCK is not.
950
951[!] Note: one of the consequence of LOCKs and UNLOCKs being only one-way
952 barriers is that the effects instructions outside of a critical section may
953 seep into the inside of the critical section.
954
955Locks and semaphores may not provide any guarantee of ordering on UP compiled
956systems, and so cannot be counted on in such a situation to actually achieve
957anything at all - especially with respect to I/O accesses - unless combined
958with interrupt disabling operations.
959
960See also the section on "Inter-CPU locking barrier effects".
961
962
963As an example, consider the following:
964
965 *A = a;
966 *B = b;
967 LOCK
968 *C = c;
969 *D = d;
970 UNLOCK
971 *E = e;
972 *F = f;
973
974The following sequence of events is acceptable:
975
976 LOCK, {*F,*A}, *E, {*C,*D}, *B, UNLOCK
977
978 [+] Note that {*F,*A} indicates a combined access.
979
980But none of the following are:
981
982 {*F,*A}, *B, LOCK, *C, *D, UNLOCK, *E
983 *A, *B, *C, LOCK, *D, UNLOCK, *E, *F
984 *A, *B, LOCK, *C, UNLOCK, *D, *E, *F
985 *B, LOCK, *C, *D, UNLOCK, {*F,*A}, *E
986
987
988
989INTERRUPT DISABLING FUNCTIONS
990-----------------------------
991
992Functions that disable interrupts (LOCK equivalent) and enable interrupts
993(UNLOCK equivalent) will act as compiler barriers only. So if memory or I/O
994barriers are required in such a situation, they must be provided from some
995other means.
996
997
998MISCELLANEOUS FUNCTIONS
999-----------------------
1000
1001Other functions that imply barriers:
1002
1003 (*) schedule() and similar imply full memory barriers.
1004
1005 (*) Memory allocation and release functions imply full memory barriers.
1006
1007
1008=================================
1009INTER-CPU LOCKING BARRIER EFFECTS
1010=================================
1011
1012On SMP systems locking primitives give a more substantial form of barrier: one
1013that does affect memory access ordering on other CPUs, within the context of
1014conflict on any particular lock.
1015
1016
1017LOCKS VS MEMORY ACCESSES
1018------------------------
1019
1020Consider the following: the system has a pair of spinlocks (N) and (Q), and
1021three CPUs; then should the following sequence of events occur:
1022
1023 CPU 1 CPU 2
1024 =============================== ===============================
1025 *A = a; *E = e;
1026 LOCK M LOCK Q
1027 *B = b; *F = f;
1028 *C = c; *G = g;
1029 UNLOCK M UNLOCK Q
1030 *D = d; *H = h;
1031
1032Then there is no guarantee as to what order CPU #3 will see the accesses to *A
1033through *H occur in, other than the constraints imposed by the separate locks
1034on the separate CPUs. It might, for example, see:
1035
1036 *E, LOCK M, LOCK Q, *G, *C, *F, *A, *B, UNLOCK Q, *D, *H, UNLOCK M
1037
1038But it won't see any of:
1039
1040 *B, *C or *D preceding LOCK M
1041 *A, *B or *C following UNLOCK M
1042 *F, *G or *H preceding LOCK Q
1043 *E, *F or *G following UNLOCK Q
1044
1045
1046However, if the following occurs:
1047
1048 CPU 1 CPU 2
1049 =============================== ===============================
1050 *A = a;
1051 LOCK M [1]
1052 *B = b;
1053 *C = c;
1054 UNLOCK M [1]
1055 *D = d; *E = e;
1056 LOCK M [2]
1057 *F = f;
1058 *G = g;
1059 UNLOCK M [2]
1060 *H = h;
1061
1062CPU #3 might see:
1063
1064 *E, LOCK M [1], *C, *B, *A, UNLOCK M [1],
1065 LOCK M [2], *H, *F, *G, UNLOCK M [2], *D
1066
1067But assuming CPU #1 gets the lock first, it won't see any of:
1068
1069 *B, *C, *D, *F, *G or *H preceding LOCK M [1]
1070 *A, *B or *C following UNLOCK M [1]
1071 *F, *G or *H preceding LOCK M [2]
1072 *A, *B, *C, *E, *F or *G following UNLOCK M [2]
1073
1074
1075LOCKS VS I/O ACCESSES
1076---------------------
1077
1078Under certain circumstances (especially involving NUMA), I/O accesses within
1079two spinlocked sections on two different CPUs may be seen as interleaved by the
1080PCI bridge, because the PCI bridge does not necessarily participate in the
1081cache-coherence protocol, and is therefore incapable of issuing the required
1082read memory barriers.
1083
1084For example:
1085
1086 CPU 1 CPU 2
1087 =============================== ===============================
1088 spin_lock(Q)
1089 writel(0, ADDR)
1090 writel(1, DATA);
1091 spin_unlock(Q);
1092 spin_lock(Q);
1093 writel(4, ADDR);
1094 writel(5, DATA);
1095 spin_unlock(Q);
1096
1097may be seen by the PCI bridge as follows:
1098
1099 STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5
1100
1101which would probably cause the hardware to malfunction.
1102
1103
1104What is necessary here is to intervene with an mmiowb() before dropping the
1105spinlock, for example:
1106
1107 CPU 1 CPU 2
1108 =============================== ===============================
1109 spin_lock(Q)
1110 writel(0, ADDR)
1111 writel(1, DATA);
1112 mmiowb();
1113 spin_unlock(Q);
1114 spin_lock(Q);
1115 writel(4, ADDR);
1116 writel(5, DATA);
1117 mmiowb();
1118 spin_unlock(Q);
1119
1120this will ensure that the two stores issued on CPU #1 appear at the PCI bridge
1121before either of the stores issued on CPU #2.
1122
1123
1124Furthermore, following a store by a load to the same device obviates the need
1125for an mmiowb(), because the load forces the store to complete before the load
1126is performed:
1127
1128 CPU 1 CPU 2
1129 =============================== ===============================
1130 spin_lock(Q)
1131 writel(0, ADDR)
1132 a = readl(DATA);
1133 spin_unlock(Q);
1134 spin_lock(Q);
1135 writel(4, ADDR);
1136 b = readl(DATA);
1137 spin_unlock(Q);
1138
1139
1140See Documentation/DocBook/deviceiobook.tmpl for more information.
1141
1142
1143=================================
1144WHERE ARE MEMORY BARRIERS NEEDED?
1145=================================
1146
1147Under normal operation, memory operation reordering is generally not going to
1148be a problem as a single-threaded linear piece of code will still appear to
1149work correctly, even if it's in an SMP kernel. There are, however, three
1150circumstances in which reordering definitely _could_ be a problem:
1151
1152 (*) Interprocessor interaction.
1153
1154 (*) Atomic operations.
1155
1156 (*) Accessing devices (I/O).
1157
1158 (*) Interrupts.
1159
1160
1161INTERPROCESSOR INTERACTION
1162--------------------------
1163
1164When there's a system with more than one processor, more than one CPU in the
1165system may be working on the same data set at the same time. This can cause
1166synchronisation problems, and the usual way of dealing with them is to use
1167locks. Locks, however, are quite expensive, and so it may be preferable to
1168operate without the use of a lock if at all possible. In such a case
1169operations that affect both CPUs may have to be carefully ordered to prevent
1170a malfunction.
1171
1172Consider, for example, the R/W semaphore slow path. Here a waiting process is
1173queued on the semaphore, by virtue of it having a piece of its stack linked to
1174the semaphore's list of waiting processes:
1175
1176 struct rw_semaphore {
1177 ...
1178 spinlock_t lock;
1179 struct list_head waiters;
1180 };
1181
1182 struct rwsem_waiter {
1183 struct list_head list;
1184 struct task_struct *task;
1185 };
1186
1187To wake up a particular waiter, the up_read() or up_write() functions have to:
1188
1189 (1) read the next pointer from this waiter's record to know as to where the
1190 next waiter record is;
1191
1192 (4) read the pointer to the waiter's task structure;
1193
1194 (3) clear the task pointer to tell the waiter it has been given the semaphore;
1195
1196 (4) call wake_up_process() on the task; and
1197
1198 (5) release the reference held on the waiter's task struct.
1199
1200In otherwords, it has to perform this sequence of events:
1201
1202 LOAD waiter->list.next;
1203 LOAD waiter->task;
1204 STORE waiter->task;
1205 CALL wakeup
1206 RELEASE task
1207
1208and if any of these steps occur out of order, then the whole thing may
1209malfunction.
1210
1211Once it has queued itself and dropped the semaphore lock, the waiter does not
1212get the lock again; it instead just waits for its task pointer to be cleared
1213before proceeding. Since the record is on the waiter's stack, this means that
1214if the task pointer is cleared _before_ the next pointer in the list is read,
1215another CPU might start processing the waiter and might clobber the waiter's
1216stack before the up*() function has a chance to read the next pointer.
1217
1218Consider then what might happen to the above sequence of events:
1219
1220 CPU 1 CPU 2
1221 =============================== ===============================
1222 down_xxx()
1223 Queue waiter
1224 Sleep
1225 up_yyy()
1226 LOAD waiter->task;
1227 STORE waiter->task;
1228 Woken up by other event
1229 <preempt>
1230 Resume processing
1231 down_xxx() returns
1232 call foo()
1233 foo() clobbers *waiter
1234 </preempt>
1235 LOAD waiter->list.next;
1236 --- OOPS ---
1237
1238This could be dealt with using the semaphore lock, but then the down_xxx()
1239function has to needlessly get the spinlock again after being woken up.
1240
1241The way to deal with this is to insert a general SMP memory barrier:
1242
1243 LOAD waiter->list.next;
1244 LOAD waiter->task;
1245 smp_mb();
1246 STORE waiter->task;
1247 CALL wakeup
1248 RELEASE task
1249
1250In this case, the barrier makes a guarantee that all memory accesses before the
1251barrier will appear to happen before all the memory accesses after the barrier
1252with respect to the other CPUs on the system. It does _not_ guarantee that all
1253the memory accesses before the barrier will be complete by the time the barrier
1254instruction itself is complete.
1255
1256On a UP system - where this wouldn't be a problem - the smp_mb() is just a
1257compiler barrier, thus making sure the compiler emits the instructions in the
1258right order without actually intervening in the CPU. Since there there's only
1259one CPU, that CPU's dependency ordering logic will take care of everything
1260else.
1261
1262
1263ATOMIC OPERATIONS
1264-----------------
1265
1266Though they are technically interprocessor interaction considerations, atomic
1267operations are noted specially as they do _not_ generally imply memory
1268barriers. The possible offenders include:
1269
1270 xchg();
1271 cmpxchg();
1272 test_and_set_bit();
1273 test_and_clear_bit();
1274 test_and_change_bit();
1275 atomic_cmpxchg();
1276 atomic_inc_return();
1277 atomic_dec_return();
1278 atomic_add_return();
1279 atomic_sub_return();
1280 atomic_inc_and_test();
1281 atomic_dec_and_test();
1282 atomic_sub_and_test();
1283 atomic_add_negative();
1284 atomic_add_unless();
1285
1286These may be used for such things as implementing LOCK operations or controlling
1287the lifetime of objects by decreasing their reference counts. In such cases
1288they need preceding memory barriers.
1289
1290The following may also be possible offenders as they may be used as UNLOCK
1291operations.
1292
1293 set_bit();
1294 clear_bit();
1295 change_bit();
1296 atomic_set();
1297
1298
1299The following are a little tricky:
1300
1301 atomic_add();
1302 atomic_sub();
1303 atomic_inc();
1304 atomic_dec();
1305
1306If they're used for statistics generation, then they probably don't need memory
1307barriers, unless there's a coupling between statistical data.
1308
1309If they're used for reference counting on an object to control its lifetime,
1310they probably don't need memory barriers because either the reference count
1311will be adjusted inside a locked section, or the caller will already hold
1312sufficient references to make the lock, and thus a memory barrier unnecessary.
1313
1314If they're used for constructing a lock of some description, then they probably
1315do need memory barriers as a lock primitive generally has to do things in a
1316specific order.
1317
1318
1319Basically, each usage case has to be carefully considered as to whether memory
1320barriers are needed or not. The simplest rule is probably: if the atomic
1321operation is protected by a lock, then it does not require a barrier unless
1322there's another operation within the critical section with respect to which an
1323ordering must be maintained.
1324
1325See Documentation/atomic_ops.txt for more information.
1326
1327
1328ACCESSING DEVICES
1329-----------------
1330
1331Many devices can be memory mapped, and so appear to the CPU as if they're just
1332a set of memory locations. To control such a device, the driver usually has to
1333make the right memory accesses in exactly the right order.
1334
1335However, having a clever CPU or a clever compiler creates a potential problem
1336in that the carefully sequenced accesses in the driver code won't reach the
1337device in the requisite order if the CPU or the compiler thinks it is more
1338efficient to reorder, combine or merge accesses - something that would cause
1339the device to malfunction.
1340
1341Inside of the Linux kernel, I/O should be done through the appropriate accessor
1342routines - such as inb() or writel() - which know how to make such accesses
1343appropriately sequential. Whilst this, for the most part, renders the explicit
1344use of memory barriers unnecessary, there are a couple of situations where they
1345might be needed:
1346
1347 (1) On some systems, I/O stores are not strongly ordered across all CPUs, and
1348 so for _all_ general drivers locks should be used and mmiowb() must be
1349 issued prior to unlocking the critical section.
1350
1351 (2) If the accessor functions are used to refer to an I/O memory window with
1352 relaxed memory access properties, then _mandatory_ memory barriers are
1353 required to enforce ordering.
1354
1355See Documentation/DocBook/deviceiobook.tmpl for more information.
1356
1357
1358INTERRUPTS
1359----------
1360
1361A driver may be interrupted by its own interrupt service routine, and thus the
1362two parts of the driver may interfere with each other's attempts to control or
1363access the device.
1364
1365This may be alleviated - at least in part - by disabling local interrupts (a
1366form of locking), such that the critical operations are all contained within
1367the interrupt-disabled section in the driver. Whilst the driver's interrupt
1368routine is executing, the driver's core may not run on the same CPU, and its
1369interrupt is not permitted to happen again until the current interrupt has been
1370handled, thus the interrupt handler does not need to lock against that.
1371
1372However, consider a driver that was talking to an ethernet card that sports an
1373address register and a data register. If that driver's core talks to the card
1374under interrupt-disablement and then the driver's interrupt handler is invoked:
1375
1376 LOCAL IRQ DISABLE
1377 writew(ADDR, 3);
1378 writew(DATA, y);
1379 LOCAL IRQ ENABLE
1380 <interrupt>
1381 writew(ADDR, 4);
1382 q = readw(DATA);
1383 </interrupt>
1384
1385The store to the data register might happen after the second store to the
1386address register if ordering rules are sufficiently relaxed:
1387
1388 STORE *ADDR = 3, STORE *ADDR = 4, STORE *DATA = y, q = LOAD *DATA
1389
1390
1391If ordering rules are relaxed, it must be assumed that accesses done inside an
1392interrupt disabled section may leak outside of it and may interleave with
1393accesses performed in an interrupt - and vice versa - unless implicit or
1394explicit barriers are used.
1395
1396Normally this won't be a problem because the I/O accesses done inside such
1397sections will include synchronous load operations on strictly ordered I/O
1398registers that form implicit I/O barriers. If this isn't sufficient then an
1399mmiowb() may need to be used explicitly.
1400
1401
1402A similar situation may occur between an interrupt routine and two routines
1403running on separate CPUs that communicate with each other. If such a case is
1404likely, then interrupt-disabling locks should be used to guarantee ordering.
1405
1406
1407==========================
1408KERNEL I/O BARRIER EFFECTS
1409==========================
1410
1411When accessing I/O memory, drivers should use the appropriate accessor
1412functions:
1413
1414 (*) inX(), outX():
1415
1416 These are intended to talk to I/O space rather than memory space, but
1417 that's primarily a CPU-specific concept. The i386 and x86_64 processors do
1418 indeed have special I/O space access cycles and instructions, but many
1419 CPUs don't have such a concept.
1420
1421 The PCI bus, amongst others, defines an I/O space concept - which on such
1422 CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O
1423 space. However, it may also mapped as a virtual I/O space in the CPU's
1424 memory map, particularly on those CPUs that don't support alternate
1425 I/O spaces.
1426
1427 Accesses to this space may be fully synchronous (as on i386), but
1428 intermediary bridges (such as the PCI host bridge) may not fully honour
1429 that.
1430
1431 They are guaranteed to be fully ordered with respect to each other.
1432
1433 They are not guaranteed to be fully ordered with respect to other types of
1434 memory and I/O operation.
1435
1436 (*) readX(), writeX():
1437
1438 Whether these are guaranteed to be fully ordered and uncombined with
1439 respect to each other on the issuing CPU depends on the characteristics
1440 defined for the memory window through which they're accessing. On later
1441 i386 architecture machines, for example, this is controlled by way of the
1442 MTRR registers.
1443
1444 Ordinarily, these will be guaranteed to be fully ordered and uncombined,,
1445 provided they're not accessing a prefetchable device.
1446
1447 However, intermediary hardware (such as a PCI bridge) may indulge in
1448 deferral if it so wishes; to flush a store, a load from the same location
1449 is preferred[*], but a load from the same device or from configuration
1450 space should suffice for PCI.
1451
1452 [*] NOTE! attempting to load from the same location as was written to may
1453 cause a malfunction - consider the 16550 Rx/Tx serial registers for
1454 example.
1455
1456 Used with prefetchable I/O memory, an mmiowb() barrier may be required to
1457 force stores to be ordered.
1458
1459 Please refer to the PCI specification for more information on interactions
1460 between PCI transactions.
1461
1462 (*) readX_relaxed()
1463
1464 These are similar to readX(), but are not guaranteed to be ordered in any
1465 way. Be aware that there is no I/O read barrier available.
1466
1467 (*) ioreadX(), iowriteX()
1468
1469 These will perform as appropriate for the type of access they're actually
1470 doing, be it inX()/outX() or readX()/writeX().
1471
1472
1473========================================
1474ASSUMED MINIMUM EXECUTION ORDERING MODEL
1475========================================
1476
1477It has to be assumed that the conceptual CPU is weakly-ordered but that it will
1478maintain the appearance of program causality with respect to itself. Some CPUs
1479(such as i386 or x86_64) are more constrained than others (such as powerpc or
1480frv), and so the most relaxed case (namely DEC Alpha) must be assumed outside
1481of arch-specific code.
1482
1483This means that it must be considered that the CPU will execute its instruction
1484stream in any order it feels like - or even in parallel - provided that if an
1485instruction in the stream depends on the an earlier instruction, then that
1486earlier instruction must be sufficiently complete[*] before the later
1487instruction may proceed; in other words: provided that the appearance of
1488causality is maintained.
1489
1490 [*] Some instructions have more than one effect - such as changing the
1491 condition codes, changing registers or changing memory - and different
1492 instructions may depend on different effects.
1493
1494A CPU may also discard any instruction sequence that winds up having no
1495ultimate effect. For example, if two adjacent instructions both load an
1496immediate value into the same register, the first may be discarded.
1497
1498
1499Similarly, it has to be assumed that compiler might reorder the instruction
1500stream in any way it sees fit, again provided the appearance of causality is
1501maintained.
1502
1503
1504============================
1505THE EFFECTS OF THE CPU CACHE
1506============================
1507
1508The way cached memory operations are perceived across the system is affected to
1509a certain extent by the caches that lie between CPUs and memory, and by the
1510memory coherence system that maintains the consistency of state in the system.
1511
1512As far as the way a CPU interacts with another part of the system through the
1513caches goes, the memory system has to include the CPU's caches, and memory
1514barriers for the most part act at the interface between the CPU and its cache
1515(memory barriers logically act on the dotted line in the following diagram):
1516
1517 <--- CPU ---> : <----------- Memory ----------->
1518 :
1519 +--------+ +--------+ : +--------+ +-----------+
1520 | | | | : | | | | +--------+
1521 | CPU | | Memory | : | CPU | | | | |
1522 | Core |--->| Access |----->| Cache |<-->| | | |
1523 | | | Queue | : | | | |--->| Memory |
1524 | | | | : | | | | | |
1525 +--------+ +--------+ : +--------+ | | | |
1526 : | Cache | +--------+
1527 : | Coherency |
1528 : | Mechanism | +--------+
1529 +--------+ +--------+ : +--------+ | | | |
1530 | | | | : | | | | | |
1531 | CPU | | Memory | : | CPU | | |--->| Device |
1532 | Core |--->| Access |----->| Cache |<-->| | | |
1533 | | | Queue | : | | | | | |
1534 | | | | : | | | | +--------+
1535 +--------+ +--------+ : +--------+ +-----------+
1536 :
1537 :
1538
1539Although any particular load or store may not actually appear outside of the
1540CPU that issued it since it may have been satisfied within the CPU's own cache,
1541it will still appear as if the full memory access had taken place as far as the
1542other CPUs are concerned since the cache coherency mechanisms will migrate the
1543cacheline over to the accessing CPU and propagate the effects upon conflict.
1544
1545The CPU core may execute instructions in any order it deems fit, provided the
1546expected program causality appears to be maintained. Some of the instructions
1547generate load and store operations which then go into the queue of memory
1548accesses to be performed. The core may place these in the queue in any order
1549it wishes, and continue execution until it is forced to wait for an instruction
1550to complete.
1551
1552What memory barriers are concerned with is controlling the order in which
1553accesses cross from the CPU side of things to the memory side of things, and
1554the order in which the effects are perceived to happen by the other observers
1555in the system.
1556
1557[!] Memory barriers are _not_ needed within a given CPU, as CPUs always see
1558their own loads and stores as if they had happened in program order.
1559
1560[!] MMIO or other device accesses may bypass the cache system. This depends on
1561the properties of the memory window through which devices are accessed and/or
1562the use of any special device communication instructions the CPU may have.
1563
1564
1565CACHE COHERENCY
1566---------------
1567
1568Life isn't quite as simple as it may appear above, however: for while the
1569caches are expected to be coherent, there's no guarantee that that coherency
1570will be ordered. This means that whilst changes made on one CPU will
1571eventually become visible on all CPUs, there's no guarantee that they will
1572become apparent in the same order on those other CPUs.
1573
1574
1575Consider dealing with a system that has pair of CPUs (1 & 2), each of which has
1576a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D):
1577
1578 :
1579 : +--------+
1580 : +---------+ | |
1581 +--------+ : +--->| Cache A |<------->| |
1582 | | : | +---------+ | |
1583 | CPU 1 |<---+ | |
1584 | | : | +---------+ | |
1585 +--------+ : +--->| Cache B |<------->| |
1586 : +---------+ | |
1587 : | Memory |
1588 : +---------+ | System |
1589 +--------+ : +--->| Cache C |<------->| |
1590 | | : | +---------+ | |
1591 | CPU 2 |<---+ | |
1592 | | : | +---------+ | |
1593 +--------+ : +--->| Cache D |<------->| |
1594 : +---------+ | |
1595 : +--------+
1596 :
1597
1598Imagine the system has the following properties:
1599
1600 (*) an odd-numbered cache line may be in cache A, cache C or it may still be
1601 resident in memory;
1602
1603 (*) an even-numbered cache line may be in cache B, cache D or it may still be
1604 resident in memory;
1605
1606 (*) whilst the CPU core is interrogating one cache, the other cache may be
1607 making use of the bus to access the rest of the system - perhaps to
1608 displace a dirty cacheline or to do a speculative load;
1609
1610 (*) each cache has a queue of operations that need to be applied to that cache
1611 to maintain coherency with the rest of the system;
1612
1613 (*) the coherency queue is not flushed by normal loads to lines already
1614 present in the cache, even though the contents of the queue may
1615 potentially effect those loads.
1616
1617Imagine, then, that two writes are made on the first CPU, with a write barrier
1618between them to guarantee that they will appear to reach that CPU's caches in
1619the requisite order:
1620
1621 CPU 1 CPU 2 COMMENT
1622 =============== =============== =======================================
1623 u == 0, v == 1 and p == &u, q == &u
1624 v = 2;
1625 smp_wmb(); Make sure change to v visible before
1626 change to p
1627 <A:modify v=2> v is now in cache A exclusively
1628 p = &v;
1629 <B:modify p=&v> p is now in cache B exclusively
1630
1631The write memory barrier forces the other CPUs in the system to perceive that
1632the local CPU's caches have apparently been updated in the correct order. But
1633now imagine that the second CPU that wants to read those values:
1634
1635 CPU 1 CPU 2 COMMENT
1636 =============== =============== =======================================
1637 ...
1638 q = p;
1639 x = *q;
1640
1641The above pair of reads may then fail to happen in expected order, as the
1642cacheline holding p may get updated in one of the second CPU's caches whilst
1643the update to the cacheline holding v is delayed in the other of the second
1644CPU's caches by some other cache event:
1645
1646 CPU 1 CPU 2 COMMENT
1647 =============== =============== =======================================
1648 u == 0, v == 1 and p == &u, q == &u
1649 v = 2;
1650 smp_wmb();
1651 <A:modify v=2> <C:busy>
1652 <C:queue v=2>
1653 p = &b; q = p;
1654 <D:request p>
1655 <B:modify p=&v> <D:commit p=&v>
1656 <D:read p>
1657 x = *q;
1658 <C:read *q> Reads from v before v updated in cache
1659 <C:unbusy>
1660 <C:commit v=2>
1661
1662Basically, whilst both cachelines will be updated on CPU 2 eventually, there's
1663no guarantee that, without intervention, the order of update will be the same
1664as that committed on CPU 1.
1665
1666
1667To intervene, we need to interpolate a data dependency barrier or a read
1668barrier between the loads. This will force the cache to commit its coherency
1669queue before processing any further requests:
1670
1671 CPU 1 CPU 2 COMMENT
1672 =============== =============== =======================================
1673 u == 0, v == 1 and p == &u, q == &u
1674 v = 2;
1675 smp_wmb();
1676 <A:modify v=2> <C:busy>
1677 <C:queue v=2>
1678 p = &b; q = p;
1679 <D:request p>
1680 <B:modify p=&v> <D:commit p=&v>
1681 <D:read p>
1682 smp_read_barrier_depends()
1683 <C:unbusy>
1684 <C:commit v=2>
1685 x = *q;
1686 <C:read *q> Reads from v after v updated in cache
1687
1688
1689This sort of problem can be encountered on DEC Alpha processors as they have a
1690split cache that improves performance by making better use of the data bus.
1691Whilst most CPUs do imply a data dependency barrier on the read when a memory
1692access depends on a read, not all do, so it may not be relied on.
1693
1694Other CPUs may also have split caches, but must coordinate between the various
1695cachelets for normal memory accesss. The semantics of the Alpha removes the
1696need for coordination in absence of memory barriers.
1697
1698
1699CACHE COHERENCY VS DMA
1700----------------------
1701
1702Not all systems maintain cache coherency with respect to devices doing DMA. In
1703such cases, a device attempting DMA may obtain stale data from RAM because
1704dirty cache lines may be resident in the caches of various CPUs, and may not
1705have been written back to RAM yet. To deal with this, the appropriate part of
1706the kernel must flush the overlapping bits of cache on each CPU (and maybe
1707invalidate them as well).
1708
1709In addition, the data DMA'd to RAM by a device may be overwritten by dirty
1710cache lines being written back to RAM from a CPU's cache after the device has
1711installed its own data, or cache lines simply present in a CPUs cache may
1712simply obscure the fact that RAM has been updated, until at such time as the
1713cacheline is discarded from the CPU's cache and reloaded. To deal with this,
1714the appropriate part of the kernel must invalidate the overlapping bits of the
1715cache on each CPU.
1716
1717See Documentation/cachetlb.txt for more information on cache management.
1718
1719
1720CACHE COHERENCY VS MMIO
1721-----------------------
1722
1723Memory mapped I/O usually takes place through memory locations that are part of
1724a window in the CPU's memory space that have different properties assigned than
1725the usual RAM directed window.
1726
1727Amongst these properties is usually the fact that such accesses bypass the
1728caching entirely and go directly to the device buses. This means MMIO accesses
1729may, in effect, overtake accesses to cached memory that were emitted earlier.
1730A memory barrier isn't sufficient in such a case, but rather the cache must be
1731flushed between the cached memory write and the MMIO access if the two are in
1732any way dependent.
1733
1734
1735=========================
1736THE THINGS CPUS GET UP TO
1737=========================
1738
1739A programmer might take it for granted that the CPU will perform memory
1740operations in exactly the order specified, so that if a CPU is, for example,
1741given the following piece of code to execute:
1742
1743 a = *A;
1744 *B = b;
1745 c = *C;
1746 d = *D;
1747 *E = e;
1748
1749They would then expect that the CPU will complete the memory operation for each
1750instruction before moving on to the next one, leading to a definite sequence of
1751operations as seen by external observers in the system:
1752
1753 LOAD *A, STORE *B, LOAD *C, LOAD *D, STORE *E.
1754
1755
1756Reality is, of course, much messier. With many CPUs and compilers, the above
1757assumption doesn't hold because:
1758
1759 (*) loads are more likely to need to be completed immediately to permit
1760 execution progress, whereas stores can often be deferred without a
1761 problem;
1762
1763 (*) loads may be done speculatively, and the result discarded should it prove
1764 to have been unnecessary;
1765
1766 (*) loads may be done speculatively, leading to the result having being
1767 fetched at the wrong time in the expected sequence of events;
1768
1769 (*) the order of the memory accesses may be rearranged to promote better use
1770 of the CPU buses and caches;
1771
1772 (*) loads and stores may be combined to improve performance when talking to
1773 memory or I/O hardware that can do batched accesses of adjacent locations,
1774 thus cutting down on transaction setup costs (memory and PCI devices may
1775 both be able to do this); and
1776
1777 (*) the CPU's data cache may affect the ordering, and whilst cache-coherency
1778 mechanisms may alleviate this - once the store has actually hit the cache
1779 - there's no guarantee that the coherency management will be propagated in
1780 order to other CPUs.
1781
1782So what another CPU, say, might actually observe from the above piece of code
1783is:
1784
1785 LOAD *A, ..., LOAD {*C,*D}, STORE *E, STORE *B
1786
1787 (Where "LOAD {*C,*D}" is a combined load)
1788
1789
1790However, it is guaranteed that a CPU will be self-consistent: it will see its
1791_own_ accesses appear to be correctly ordered, without the need for a memory
1792barrier. For instance with the following code:
1793
1794 U = *A;
1795 *A = V;
1796 *A = W;
1797 X = *A;
1798 *A = Y;
1799 Z = *A;
1800
1801and assuming no intervention by an external influence, it can be assumed that
1802the final result will appear to be:
1803
1804 U == the original value of *A
1805 X == W
1806 Z == Y
1807 *A == Y
1808
1809The code above may cause the CPU to generate the full sequence of memory
1810accesses:
1811
1812 U=LOAD *A, STORE *A=V, STORE *A=W, X=LOAD *A, STORE *A=Y, Z=LOAD *A
1813
1814in that order, but, without intervention, the sequence may have almost any
1815combination of elements combined or discarded, provided the program's view of
1816the world remains consistent.
1817
1818The compiler may also combine, discard or defer elements of the sequence before
1819the CPU even sees them.
1820
1821For instance:
1822
1823 *A = V;
1824 *A = W;
1825
1826may be reduced to:
1827
1828 *A = W;
1829
1830since, without a write barrier, it can be assumed that the effect of the
1831storage of V to *A is lost. Similarly:
1832
1833 *A = Y;
1834 Z = *A;
1835
1836may, without a memory barrier, be reduced to:
1837
1838 *A = Y;
1839 Z = Y;
1840
1841and the LOAD operation never appear outside of the CPU.
1842
1843
1844AND THEN THERE'S THE ALPHA
1845--------------------------
1846
1847The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that,
1848some versions of the Alpha CPU have a split data cache, permitting them to have
1849two semantically related cache lines updating at separate times. This is where
1850the data dependency barrier really becomes necessary as this synchronises both
1851caches with the memory coherence system, thus making it seem like pointer
1852changes vs new data occur in the right order.
1853
1854The Alpha defines the Linux's kernel's memory barrier model.
1855
1856See the subsection on "Cache Coherency" above.
1857
1858
1859==========
1860REFERENCES
1861==========
1862
1863Alpha AXP Architecture Reference Manual, Second Edition (Sites & Witek,
1864Digital Press)
1865 Chapter 5.2: Physical Address Space Characteristics
1866 Chapter 5.4: Caches and Write Buffers
1867 Chapter 5.5: Data Sharing
1868 Chapter 5.6: Read/Write Ordering
1869
1870AMD64 Architecture Programmer's Manual Volume 2: System Programming
1871 Chapter 7.1: Memory-Access Ordering
1872 Chapter 7.4: Buffering and Combining Memory Writes
1873
1874IA-32 Intel Architecture Software Developer's Manual, Volume 3:
1875System Programming Guide
1876 Chapter 7.1: Locked Atomic Operations
1877 Chapter 7.2: Memory Ordering
1878 Chapter 7.4: Serializing Instructions
1879
1880The SPARC Architecture Manual, Version 9
1881 Chapter 8: Memory Models
1882 Appendix D: Formal Specification of the Memory Models
1883 Appendix J: Programming with the Memory Models
1884
1885UltraSPARC Programmer Reference Manual
1886 Chapter 5: Memory Accesses and Cacheability
1887 Chapter 15: Sparc-V9 Memory Models
1888
1889UltraSPARC III Cu User's Manual
1890 Chapter 9: Memory Models
1891
1892UltraSPARC IIIi Processor User's Manual
1893 Chapter 8: Memory Models
1894
1895UltraSPARC Architecture 2005
1896 Chapter 9: Memory
1897 Appendix D: Formal Specifications of the Memory Models
1898
1899UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005
1900 Chapter 8: Memory Models
1901 Appendix F: Caches and Cache Coherency
1902
1903Solaris Internals, Core Kernel Architecture, p63-68:
1904 Chapter 3.3: Hardware Considerations for Locks and
1905 Synchronization
1906
1907Unix Systems for Modern Architectures, Symmetric Multiprocessing and Caching
1908for Kernel Programmers:
1909 Chapter 13: Other Memory Models
1910
1911Intel Itanium Architecture Software Developer's Manual: Volume 1:
1912 Section 2.6: Speculation
1913 Section 4.4: Memory Access
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 1898ea79d0e2..9d6186d50245 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -216,8 +216,6 @@ EXPORT_SYMBOL(memcpy);
216EXPORT_SYMBOL(memset); 216EXPORT_SYMBOL(memset);
217EXPORT_SYMBOL(memchr); 217EXPORT_SYMBOL(memchr);
218 218
219EXPORT_SYMBOL(get_wchan);
220
221#ifdef CONFIG_ALPHA_IRONGATE 219#ifdef CONFIG_ALPHA_IRONGATE
222EXPORT_SYMBOL(irongate_ioremap); 220EXPORT_SYMBOL(irongate_ioremap);
223EXPORT_SYMBOL(irongate_iounmap); 221EXPORT_SYMBOL(irongate_iounmap);
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index 44866cb26a80..7f6a98455e74 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -435,7 +435,7 @@ marvel_specify_io7(char *str)
435 str = pchar; 435 str = pchar;
436 } while(*str); 436 } while(*str);
437 437
438 return 0; 438 return 1;
439} 439}
440__setup("io7=", marvel_specify_io7); 440__setup("io7=", marvel_specify_io7);
441 441
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba46d779ede7..e91db542eb01 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -839,6 +839,8 @@ source "drivers/misc/Kconfig"
839 839
840source "drivers/mfd/Kconfig" 840source "drivers/mfd/Kconfig"
841 841
842source "drivers/leds/Kconfig"
843
842source "drivers/media/Kconfig" 844source "drivers/media/Kconfig"
843 845
844source "drivers/video/Kconfig" 846source "drivers/video/Kconfig"
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 978d32e82d39..3cd8c9ee4510 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/leds.h>
25 26
26#include <asm/hardware.h> 27#include <asm/hardware.h>
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
@@ -75,6 +76,7 @@ static void sharpsl_battery_thread(void *private_);
75struct sharpsl_pm_status sharpsl_pm; 76struct sharpsl_pm_status sharpsl_pm;
76DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); 77DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
77DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); 78DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
79DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
78 80
79 81
80static int get_percentage(int voltage) 82static int get_percentage(int voltage)
@@ -190,10 +192,10 @@ void sharpsl_pm_led(int val)
190 dev_err(sharpsl_pm.dev, "Charging Error!\n"); 192 dev_err(sharpsl_pm.dev, "Charging Error!\n");
191 } else if (val == SHARPSL_LED_ON) { 193 } else if (val == SHARPSL_LED_ON) {
192 dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); 194 dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
193 195 led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
194 } else { 196 } else {
195 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); 197 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
196 198 led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
197 } 199 }
198} 200}
199 201
@@ -786,6 +788,8 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
786 init_timer(&sharpsl_pm.chrg_full_timer); 788 init_timer(&sharpsl_pm.chrg_full_timer);
787 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; 789 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
788 790
791 led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
792
789 sharpsl_pm.machinfo->init(); 793 sharpsl_pm.machinfo->init();
790 794
791 device_create_file(&pdev->dev, &dev_attr_battery_percentage); 795 device_create_file(&pdev->dev, &dev_attr_battery_percentage);
@@ -807,6 +811,8 @@ static int sharpsl_pm_remove(struct platform_device *pdev)
807 device_remove_file(&pdev->dev, &dev_attr_battery_percentage); 811 device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
808 device_remove_file(&pdev->dev, &dev_attr_battery_voltage); 812 device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
809 813
814 led_trigger_unregister_simple(sharpsl_charge_led_trigger);
815
810 sharpsl_pm.machinfo->exit(); 816 sharpsl_pm.machinfo->exit();
811 817
812 del_timer_sync(&sharpsl_pm.chrg_full_timer); 818 del_timer_sync(&sharpsl_pm.chrg_full_timer);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 489c069e5c3e..1ff75cee4b0d 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -474,4 +474,3 @@ unsigned long get_wchan(struct task_struct *p)
474 } while (count ++ < 16); 474 } while (count ++ < 16);
475 return 0; 475 return 0;
476} 476}
477EXPORT_SYMBOL(get_wchan);
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 68923b1d2b62..d6d726036361 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -141,6 +141,8 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
141 */ 141 */
142static struct corgibl_machinfo corgi_bl_machinfo = { 142static struct corgibl_machinfo corgi_bl_machinfo = {
143 .max_intensity = 0x2f, 143 .max_intensity = 0x2f,
144 .default_intensity = 0x1f,
145 .limit_mask = 0x0b,
144 .set_bl_intensity = corgi_bl_set_intensity, 146 .set_bl_intensity = corgi_bl_set_intensity,
145}; 147};
146 148
@@ -164,6 +166,14 @@ static struct platform_device corgikbd_device = {
164 166
165 167
166/* 168/*
169 * Corgi LEDs
170 */
171static struct platform_device corgiled_device = {
172 .name = "corgi-led",
173 .id = -1,
174};
175
176/*
167 * Corgi Touch Screen Device 177 * Corgi Touch Screen Device
168 */ 178 */
169static struct resource corgits_resources[] = { 179static struct resource corgits_resources[] = {
@@ -297,6 +307,7 @@ static struct platform_device *devices[] __initdata = {
297 &corgikbd_device, 307 &corgikbd_device,
298 &corgibl_device, 308 &corgibl_device,
299 &corgits_device, 309 &corgits_device,
310 &corgiled_device,
300}; 311};
301 312
302static void __init corgi_init(void) 313static void __init corgi_init(void)
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 0dbb079ecd25..19b372df544a 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -220,6 +220,8 @@ struct corgissp_machinfo spitz_ssp_machinfo = {
220 * Spitz Backlight Device 220 * Spitz Backlight Device
221 */ 221 */
222static struct corgibl_machinfo spitz_bl_machinfo = { 222static struct corgibl_machinfo spitz_bl_machinfo = {
223 .default_intensity = 0x1f,
224 .limit_mask = 0x0b,
223 .max_intensity = 0x2f, 225 .max_intensity = 0x2f,
224}; 226};
225 227
@@ -242,6 +244,14 @@ static struct platform_device spitzkbd_device = {
242 244
243 245
244/* 246/*
247 * Spitz LEDs
248 */
249static struct platform_device spitzled_device = {
250 .name = "spitz-led",
251 .id = -1,
252};
253
254/*
245 * Spitz Touch Screen Device 255 * Spitz Touch Screen Device
246 */ 256 */
247static struct resource spitzts_resources[] = { 257static struct resource spitzts_resources[] = {
@@ -418,6 +428,7 @@ static struct platform_device *devices[] __initdata = {
418 &spitzkbd_device, 428 &spitzkbd_device,
419 &spitzts_device, 429 &spitzts_device,
420 &spitzbl_device, 430 &spitzbl_device,
431 &spitzled_device,
421}; 432};
422 433
423static void __init common_init(void) 434static void __init common_init(void)
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 66ec71756d0f..76c0e7f0a219 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -251,10 +251,19 @@ static struct platform_device tosakbd_device = {
251 .id = -1, 251 .id = -1,
252}; 252};
253 253
254/*
255 * Tosa LEDs
256 */
257static struct platform_device tosaled_device = {
258 .name = "tosa-led",
259 .id = -1,
260};
261
254static struct platform_device *devices[] __initdata = { 262static struct platform_device *devices[] __initdata = {
255 &tosascoop_device, 263 &tosascoop_device,
256 &tosascoop_jc_device, 264 &tosascoop_jc_device,
257 &tosakbd_device, 265 &tosakbd_device,
266 &tosaled_device,
258}; 267};
259 268
260static void __init tosa_init(void) 269static void __init tosa_init(void)
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
index 811a6376c624..a6a1b3373444 100644
--- a/arch/arm26/kernel/armksyms.c
+++ b/arch/arm26/kernel/armksyms.c
@@ -212,8 +212,6 @@ EXPORT_SYMBOL(sys_open);
212EXPORT_SYMBOL(sys_exit); 212EXPORT_SYMBOL(sys_exit);
213EXPORT_SYMBOL(sys_wait4); 213EXPORT_SYMBOL(sys_wait4);
214 214
215EXPORT_SYMBOL(get_wchan);
216
217#ifdef CONFIG_PREEMPT 215#ifdef CONFIG_PREEMPT
218EXPORT_SYMBOL(kernel_flag); 216EXPORT_SYMBOL(kernel_flag);
219#endif 217#endif
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index aa6b7d0a2109..07c8ffa0dd39 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -79,8 +79,6 @@ EXPORT_SYMBOL(memmove);
79EXPORT_SYMBOL(__outsl_ns); 79EXPORT_SYMBOL(__outsl_ns);
80EXPORT_SYMBOL(__insl_ns); 80EXPORT_SYMBOL(__insl_ns);
81 81
82EXPORT_SYMBOL(get_wchan);
83
84#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS 82#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
85EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask); 83EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask);
86EXPORT_SYMBOL(atomic_test_and_OR_mask); 84EXPORT_SYMBOL(atomic_test_and_OR_mask);
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
index 69d6ad32d56c..b6cd78c972bb 100644
--- a/arch/h8300/kernel/h8300_ksyms.c
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -55,8 +55,6 @@ EXPORT_SYMBOL(memcmp);
55EXPORT_SYMBOL(memscan); 55EXPORT_SYMBOL(memscan);
56EXPORT_SYMBOL(memmove); 56EXPORT_SYMBOL(memmove);
57 57
58EXPORT_SYMBOL(get_wchan);
59
60/* 58/*
61 * libgcc functions - functions that are used internally by the 59 * libgcc functions - functions that are used internally by the
62 * compiler... (prototypes are not correct though, but that 60 * compiler... (prototypes are not correct though, but that
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index eb5279d23b7f..6273bf74c203 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -415,6 +415,7 @@ void __init init_bsp_APIC(void)
415void __devinit setup_local_APIC(void) 415void __devinit setup_local_APIC(void)
416{ 416{
417 unsigned long oldvalue, value, ver, maxlvt; 417 unsigned long oldvalue, value, ver, maxlvt;
418 int i, j;
418 419
419 /* Pound the ESR really hard over the head with a big hammer - mbligh */ 420 /* Pound the ESR really hard over the head with a big hammer - mbligh */
420 if (esr_disable) { 421 if (esr_disable) {
@@ -452,6 +453,25 @@ void __devinit setup_local_APIC(void)
452 apic_write_around(APIC_TASKPRI, value); 453 apic_write_around(APIC_TASKPRI, value);
453 454
454 /* 455 /*
456 * After a crash, we no longer service the interrupts and a pending
457 * interrupt from previous kernel might still have ISR bit set.
458 *
459 * Most probably by now CPU has serviced that pending interrupt and
460 * it might not have done the ack_APIC_irq() because it thought,
461 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
462 * does not clear the ISR bit and cpu thinks it has already serivced
463 * the interrupt. Hence a vector might get locked. It was noticed
464 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
465 */
466 for (i = APIC_ISR_NR - 1; i >= 0; i--) {
467 value = apic_read(APIC_ISR + i*0x10);
468 for (j = 31; j >= 0; j--) {
469 if (value & (1<<j))
470 ack_APIC_irq();
471 }
472 }
473
474 /*
455 * Now that we are all set up, enable the APIC 475 * Now that we are all set up, enable the APIC
456 */ 476 */
457 value = apic_read(APIC_SPIV); 477 value = apic_read(APIC_SPIV);
@@ -732,7 +752,7 @@ static int __init apic_set_verbosity(char *str)
732 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 752 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
733 " use apic=verbose or apic=debug\n", str); 753 " use apic=verbose or apic=debug\n", str);
734 754
735 return 0; 755 return 1;
736} 756}
737 757
738__setup("apic=", apic_set_verbosity); 758__setup("apic=", apic_set_verbosity);
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index 6170af3c271a..afa0888f9a1e 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -64,13 +64,13 @@ void mcheck_init(struct cpuinfo_x86 *c)
64static int __init mcheck_disable(char *str) 64static int __init mcheck_disable(char *str)
65{ 65{
66 mce_disabled = 1; 66 mce_disabled = 1;
67 return 0; 67 return 1;
68} 68}
69 69
70static int __init mcheck_enable(char *str) 70static int __init mcheck_enable(char *str)
71{ 71{
72 mce_disabled = -1; 72 mce_disabled = -1;
73 return 0; 73 return 1;
74} 74}
75 75
76__setup("nomce", mcheck_disable); 76__setup("nomce", mcheck_disable);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 3b329af4afc5..f8f132aa5472 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -644,7 +644,7 @@ failed:
644int __init irqbalance_disable(char *str) 644int __init irqbalance_disable(char *str)
645{ 645{
646 irqbalance_disabled = 1; 646 irqbalance_disabled = 1;
647 return 0; 647 return 1;
648} 648}
649 649
650__setup("noirqbalance", irqbalance_disable); 650__setup("noirqbalance", irqbalance_disable);
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 24b3e745478b..6259afea46d1 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -781,7 +781,6 @@ unsigned long get_wchan(struct task_struct *p)
781 } while (count++ < 16); 781 } while (count++ < 16);
782 return 0; 782 return 0;
783} 783}
784EXPORT_SYMBOL(get_wchan);
785 784
786/* 785/*
787 * sys_alloc_thread_area: get a yet unused TLS descriptor index. 786 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index ce3ef4fa0551..4f58b9c0efe3 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -313,3 +313,4 @@ ENTRY(sys_call_table)
313 .long sys_set_robust_list 313 .long sys_set_robust_list
314 .long sys_get_robust_list 314 .long sys_get_robust_list
315 .long sys_splice 315 .long sys_splice
316 .long sys_sync_file_range
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 6b63a5aa1e46..e38527994590 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -1193,6 +1193,6 @@ void __init trap_init(void)
1193static int __init kstack_setup(char *s) 1193static int __init kstack_setup(char *s)
1194{ 1194{
1195 kstack_depth_to_print = simple_strtoul(s, NULL, 0); 1195 kstack_depth_to_print = simple_strtoul(s, NULL, 0);
1196 return 0; 1196 return 1;
1197} 1197}
1198__setup("kstack=", kstack_setup); 1198__setup("kstack=", kstack_setup);
diff --git a/arch/i386/kernel/vsyscall-sigreturn.S b/arch/i386/kernel/vsyscall-sigreturn.S
index fadb5bc3c374..a92262f41659 100644
--- a/arch/i386/kernel/vsyscall-sigreturn.S
+++ b/arch/i386/kernel/vsyscall-sigreturn.S
@@ -44,7 +44,7 @@ __kernel_rt_sigreturn:
44.LSTARTCIEDLSI1: 44.LSTARTCIEDLSI1:
45 .long 0 /* CIE ID */ 45 .long 0 /* CIE ID */
46 .byte 1 /* Version number */ 46 .byte 1 /* Version number */
47 .string "zR" /* NUL-terminated augmentation string */ 47 .string "zRS" /* NUL-terminated augmentation string */
48 .uleb128 1 /* Code alignment factor */ 48 .uleb128 1 /* Code alignment factor */
49 .sleb128 -4 /* Data alignment factor */ 49 .sleb128 -4 /* Data alignment factor */
50 .byte 8 /* Return address register column */ 50 .byte 8 /* Return address register column */
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index 3d7f2000b714..c3319514a85e 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -79,4 +79,3 @@ EXPORT_SYMBOL(__down_failed_interruptible);
79EXPORT_SYMBOL(__down_failed_trylock); 79EXPORT_SYMBOL(__down_failed_trylock);
80EXPORT_SYMBOL(__up_wakeup); 80EXPORT_SYMBOL(__up_wakeup);
81 81
82EXPORT_SYMBOL(get_wchan);
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
index d844c755945a..f9b4ea16c099 100644
--- a/arch/m68knommu/kernel/m68k_ksyms.c
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -57,8 +57,6 @@ EXPORT_SYMBOL(__down_failed_interruptible);
57EXPORT_SYMBOL(__down_failed_trylock); 57EXPORT_SYMBOL(__down_failed_trylock);
58EXPORT_SYMBOL(__up_wakeup); 58EXPORT_SYMBOL(__up_wakeup);
59 59
60EXPORT_SYMBOL(get_wchan);
61
62/* 60/*
63 * libgcc functions - functions that are used internally by the 61 * libgcc functions - functions that are used internally by the
64 * compiler... (prototypes are not correct though, but that 62 * compiler... (prototypes are not correct though, but that
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index a8f435d82940..c66db5e5ab62 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -419,4 +419,3 @@ unsigned long get_wchan(struct task_struct *p)
419 return pc; 419 return pc;
420} 420}
421 421
422EXPORT_SYMBOL(get_wchan);
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 211d72653ea6..764d07329716 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -61,7 +61,7 @@ static int __init parse_elfcorehdr(char *p)
61 if (p) 61 if (p)
62 elfcorehdr_addr = memparse(p, &p); 62 elfcorehdr_addr = memparse(p, &p);
63 63
64 return 0; 64 return 1;
65} 65}
66__setup("elfcorehdr=", parse_elfcorehdr); 66__setup("elfcorehdr=", parse_elfcorehdr);
67#endif 67#endif
@@ -71,7 +71,7 @@ static int __init parse_savemaxmem(char *p)
71 if (p) 71 if (p)
72 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1; 72 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
73 73
74 return 0; 74 return 1;
75} 75}
76__setup("savemaxmem=", parse_savemaxmem); 76__setup("savemaxmem=", parse_savemaxmem);
77 77
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 706090c99f47..2dd47d2dd998 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -834,7 +834,6 @@ unsigned long get_wchan(struct task_struct *p)
834 } while (count++ < 16); 834 } while (count++ < 16);
835 return 0; 835 return 0;
836} 836}
837EXPORT_SYMBOL(get_wchan);
838 837
839static int kstack_depth_to_print = 64; 838static int kstack_depth_to_print = 64;
840 839
diff --git a/arch/powerpc/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S
index e04642781917..0c6a37b29dde 100644
--- a/arch/powerpc/kernel/vdso32/sigtramp.S
+++ b/arch/powerpc/kernel/vdso32/sigtramp.S
@@ -261,7 +261,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt32)
261.Lcie_start: 261.Lcie_start:
262 .long 0 /* CIE ID */ 262 .long 0 /* CIE ID */
263 .byte 1 /* Version number */ 263 .byte 1 /* Version number */
264 .string "zR" /* NUL-terminated augmentation string */ 264 .string "zRS" /* NUL-terminated augmentation string */
265 .uleb128 4 /* Code alignment factor */ 265 .uleb128 4 /* Code alignment factor */
266 .sleb128 -4 /* Data alignment factor */ 266 .sleb128 -4 /* Data alignment factor */
267 .byte 67 /* Return address register column, ap */ 267 .byte 67 /* Return address register column, ap */
diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S
index 31b604ab56de..7479edb101b8 100644
--- a/arch/powerpc/kernel/vdso64/sigtramp.S
+++ b/arch/powerpc/kernel/vdso64/sigtramp.S
@@ -263,7 +263,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
263.Lcie_start: 263.Lcie_start:
264 .long 0 /* CIE ID */ 264 .long 0 /* CIE ID */
265 .byte 1 /* Version number */ 265 .byte 1 /* Version number */
266 .string "zR" /* NUL-terminated augmentation string */ 266 .string "zRS" /* NUL-terminated augmentation string */
267 .uleb128 4 /* Code alignment factor */ 267 .uleb128 4 /* Code alignment factor */
268 .sleb128 -8 /* Data alignment factor */ 268 .sleb128 -8 /* Data alignment factor */
269 .byte 67 /* Return address register column, ap */ 269 .byte 67 /* Return address register column, ap */
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 2b8841f85534..343120c9223d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -801,7 +801,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
801 */ 801 */
802 print_cpu_info(&S390_lowcore.cpu_data); 802 print_cpu_info(&S390_lowcore.cpu_data);
803 803
804 for_each_cpu(i) { 804 for_each_possible_cpu(i) {
805 lowcore_ptr[i] = (struct _lowcore *) 805 lowcore_ptr[i] = (struct _lowcore *)
806 __get_free_pages(GFP_KERNEL|GFP_DMA, 806 __get_free_pages(GFP_KERNEL|GFP_DMA,
807 sizeof(void*) == 8 ? 1 : 0); 807 sizeof(void*) == 8 ? 1 : 0);
@@ -831,7 +831,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
831#endif 831#endif
832 set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); 832 set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]);
833 833
834 for_each_cpu(cpu) 834 for_each_possible_cpu(cpu)
835 if (cpu != smp_processor_id()) 835 if (cpu != smp_processor_id())
836 smp_create_idle(cpu); 836 smp_create_idle(cpu);
837} 837}
@@ -868,7 +868,7 @@ static int __init topology_init(void)
868 int cpu; 868 int cpu;
869 int ret; 869 int ret;
870 870
871 for_each_cpu(cpu) { 871 for_each_possible_cpu(cpu) {
872 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); 872 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
873 if (ret) 873 if (ret)
874 printk(KERN_WARNING "topology_init: register_cpu %d " 874 printk(KERN_WARNING "topology_init: register_cpu %d "
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index cf94e8ef17c5..868e68b28880 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -30,7 +30,7 @@ static int x##_disabled __initdata = 0; \
30static int __init x##_setup(char *opts) \ 30static int __init x##_setup(char *opts) \
31{ \ 31{ \
32 x##_disabled = 1; \ 32 x##_disabled = 1; \
33 return 0; \ 33 return 1; \
34} \ 34} \
35__setup("no" __stringify(x), x##_setup); 35__setup("no" __stringify(x), x##_setup);
36 36
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 7ee4ca203616..bb229ef030f3 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -401,7 +401,7 @@ static int __init topology_init(void)
401{ 401{
402 int cpu_id; 402 int cpu_id;
403 403
404 for_each_cpu(cpu_id) 404 for_each_possible_cpu(cpu_id)
405 register_cpu(&cpu[cpu_id], cpu_id, NULL); 405 register_cpu(&cpu[cpu_id], cpu_id, NULL);
406 406
407 return 0; 407 return 0;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 5982fe2753e0..05fbb20636cb 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -22,6 +22,9 @@ config SBUS
22config PCI 22config PCI
23 bool 23 bool
24 24
25config PCMCIA
26 bool
27
25config GENERIC_CALIBRATE_DELAY 28config GENERIC_CALIBRATE_DELAY
26 bool 29 bool
27 default y 30 default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 8d14c7a831be..24790bed2054 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -20,7 +20,7 @@ core-y += $(ARCH_DIR)/kernel/ \
20 20
21# Have to precede the include because the included Makefiles reference them. 21# Have to precede the include because the included Makefiles reference them.
22SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ 22SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
23 module.h vm-flags.h elf.h ldt.h 23 module.h vm-flags.h elf.h host_ldt.h
24SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) 24SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
25 25
26# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes 26# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
@@ -129,7 +129,7 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
129 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ 129 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
130 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \ 130 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
131 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \ 131 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \
132 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o 132 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o
133 133
134#The wrappers will select whether using "malloc" or the kernel allocator. 134#The wrappers will select whether using "malloc" or the kernel allocator.
135LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 135LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
@@ -150,8 +150,7 @@ CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
150 $(ARCH_DIR)/include/user_constants.h \ 150 $(ARCH_DIR)/include/user_constants.h \
151 $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch 151 $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
152 152
153MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \ 153MRPROPER_FILES += $(ARCH_SYMLINKS)
154 $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
155 154
156archclean: 155archclean:
157 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ 156 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 38df311e75dc..dfd88b652fbe 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1,7 +1,7 @@
1# Copyright 2003 - 2004 Pathscale, Inc 1# Copyright 2003 - 2004 Pathscale, Inc
2# Released under the GPL 2# Released under the GPL
3 3
4libs-y += arch/um/sys-x86_64/ 4core-y += arch/um/sys-x86_64/
5START := 0x60000000 5START := 0x60000000
6 6
7#We #undef __x86_64__ for kernelspace, not for userspace where 7#We #undef __x86_64__ for kernelspace, not for userspace where
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index a61b7b46bc02..53d09ed78b42 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -95,18 +95,7 @@ static struct transport daemon_transport = {
95static int register_daemon(void) 95static int register_daemon(void)
96{ 96{
97 register_transport(&daemon_transport); 97 register_transport(&daemon_transport);
98 return(1); 98 return 0;
99} 99}
100 100
101__initcall(register_daemon); 101__initcall(register_daemon);
102
103/*
104 * Overrides for Emacs so that we follow Linus's tabbing style.
105 * Emacs will notice this stuff at the end of the file and automatically
106 * adjust the settings for this buffer only. This must remain at the end
107 * of the file.
108 * ---------------------------------------------------------------------------
109 * Local variables:
110 * c-file-style: "linux"
111 * End:
112 */
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 49acb2badf32..d18a974735e6 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -104,7 +104,7 @@ static int harddog_release(struct inode *inode, struct file *file)
104 104
105extern int ping_watchdog(int fd); 105extern int ping_watchdog(int fd);
106 106
107static ssize_t harddog_write(struct file *file, const char *data, size_t len, 107static ssize_t harddog_write(struct file *file, const char __user *data, size_t len,
108 loff_t *ppos) 108 loff_t *ppos)
109{ 109{
110 /* 110 /*
@@ -118,6 +118,7 @@ static ssize_t harddog_write(struct file *file, const char *data, size_t len,
118static int harddog_ioctl(struct inode *inode, struct file *file, 118static int harddog_ioctl(struct inode *inode, struct file *file,
119 unsigned int cmd, unsigned long arg) 119 unsigned int cmd, unsigned long arg)
120{ 120{
121 void __user *argp= (void __user *)arg;
121 static struct watchdog_info ident = { 122 static struct watchdog_info ident = {
122 WDIOC_SETTIMEOUT, 123 WDIOC_SETTIMEOUT,
123 0, 124 0,
@@ -127,13 +128,12 @@ static int harddog_ioctl(struct inode *inode, struct file *file,
127 default: 128 default:
128 return -ENOTTY; 129 return -ENOTTY;
129 case WDIOC_GETSUPPORT: 130 case WDIOC_GETSUPPORT:
130 if(copy_to_user((struct harddog_info *)arg, &ident, 131 if(copy_to_user(argp, &ident, sizeof(ident)))
131 sizeof(ident)))
132 return -EFAULT; 132 return -EFAULT;
133 return 0; 133 return 0;
134 case WDIOC_GETSTATUS: 134 case WDIOC_GETSTATUS:
135 case WDIOC_GETBOOTSTATUS: 135 case WDIOC_GETBOOTSTATUS:
136 return put_user(0,(int *)arg); 136 return put_user(0,(int __user *)argp);
137 case WDIOC_KEEPALIVE: 137 case WDIOC_KEEPALIVE:
138 return(ping_watchdog(harddog_out_fd)); 138 return(ping_watchdog(harddog_out_fd));
139 } 139 }
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 59602b81b240..37232f908cd7 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -67,8 +67,8 @@ MODULE_PARM_DESC(mixer, MIXER_HELP);
67 67
68/* /dev/dsp file operations */ 68/* /dev/dsp file operations */
69 69
70static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, 70static ssize_t hostaudio_read(struct file *file, char __user *buffer,
71 loff_t *ppos) 71 size_t count, loff_t *ppos)
72{ 72{
73 struct hostaudio_state *state = file->private_data; 73 struct hostaudio_state *state = file->private_data;
74 void *kbuf; 74 void *kbuf;
@@ -94,7 +94,7 @@ static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
94 return(err); 94 return(err);
95} 95}
96 96
97static ssize_t hostaudio_write(struct file *file, const char *buffer, 97static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
98 size_t count, loff_t *ppos) 98 size_t count, loff_t *ppos)
99{ 99{
100 struct hostaudio_state *state = file->private_data; 100 struct hostaudio_state *state = file->private_data;
@@ -152,7 +152,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
152 case SNDCTL_DSP_CHANNELS: 152 case SNDCTL_DSP_CHANNELS:
153 case SNDCTL_DSP_SUBDIVIDE: 153 case SNDCTL_DSP_SUBDIVIDE:
154 case SNDCTL_DSP_SETFRAGMENT: 154 case SNDCTL_DSP_SETFRAGMENT:
155 if(get_user(data, (int *) arg)) 155 if(get_user(data, (int __user *) arg))
156 return(-EFAULT); 156 return(-EFAULT);
157 break; 157 break;
158 default: 158 default:
@@ -168,7 +168,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
168 case SNDCTL_DSP_CHANNELS: 168 case SNDCTL_DSP_CHANNELS:
169 case SNDCTL_DSP_SUBDIVIDE: 169 case SNDCTL_DSP_SUBDIVIDE:
170 case SNDCTL_DSP_SETFRAGMENT: 170 case SNDCTL_DSP_SETFRAGMENT:
171 if(put_user(data, (int *) arg)) 171 if(put_user(data, (int __user *) arg))
172 return(-EFAULT); 172 return(-EFAULT);
173 break; 173 break;
174 default: 174 default:
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index c9b078fba03e..3a7af18cf944 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -124,18 +124,7 @@ static struct transport mcast_transport = {
124static int register_mcast(void) 124static int register_mcast(void)
125{ 125{
126 register_transport(&mcast_transport); 126 register_transport(&mcast_transport);
127 return(1); 127 return 0;
128} 128}
129 129
130__initcall(register_mcast); 130__initcall(register_mcast);
131
132/*
133 * Overrides for Emacs so that we follow Linus's tabbing style.
134 * Emacs will notice this stuff at the end of the file and automatically
135 * adjust the settings for this buffer only. This must remain at the end
136 * of the file.
137 * ---------------------------------------------------------------------------
138 * Local variables:
139 * c-file-style: "linux"
140 * End:
141 */
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 1488816588ea..28e3760e8b98 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -20,6 +20,8 @@
20#include "linux/namei.h" 20#include "linux/namei.h"
21#include "linux/proc_fs.h" 21#include "linux/proc_fs.h"
22#include "linux/syscalls.h" 22#include "linux/syscalls.h"
23#include "linux/list.h"
24#include "linux/mm.h"
23#include "linux/console.h" 25#include "linux/console.h"
24#include "asm/irq.h" 26#include "asm/irq.h"
25#include "asm/uaccess.h" 27#include "asm/uaccess.h"
@@ -347,6 +349,142 @@ static struct mc_device *mconsole_find_dev(char *name)
347 return(NULL); 349 return(NULL);
348} 350}
349 351
352#define UNPLUGGED_PER_PAGE \
353 ((PAGE_SIZE - sizeof(struct list_head)) / sizeof(unsigned long))
354
355struct unplugged_pages {
356 struct list_head list;
357 void *pages[UNPLUGGED_PER_PAGE];
358};
359
360static unsigned long long unplugged_pages_count = 0;
361static struct list_head unplugged_pages = LIST_HEAD_INIT(unplugged_pages);
362static int unplug_index = UNPLUGGED_PER_PAGE;
363
364static int mem_config(char *str)
365{
366 unsigned long long diff;
367 int err = -EINVAL, i, add;
368 char *ret;
369
370 if(str[0] != '=')
371 goto out;
372
373 str++;
374 if(str[0] == '-')
375 add = 0;
376 else if(str[0] == '+'){
377 add = 1;
378 }
379 else goto out;
380
381 str++;
382 diff = memparse(str, &ret);
383 if(*ret != '\0')
384 goto out;
385
386 diff /= PAGE_SIZE;
387
388 for(i = 0; i < diff; i++){
389 struct unplugged_pages *unplugged;
390 void *addr;
391
392 if(add){
393 if(list_empty(&unplugged_pages))
394 break;
395
396 unplugged = list_entry(unplugged_pages.next,
397 struct unplugged_pages, list);
398 if(unplug_index > 0)
399 addr = unplugged->pages[--unplug_index];
400 else {
401 list_del(&unplugged->list);
402 addr = unplugged;
403 unplug_index = UNPLUGGED_PER_PAGE;
404 }
405
406 free_page((unsigned long) addr);
407 unplugged_pages_count--;
408 }
409 else {
410 struct page *page;
411
412 page = alloc_page(GFP_ATOMIC);
413 if(page == NULL)
414 break;
415
416 unplugged = page_address(page);
417 if(unplug_index == UNPLUGGED_PER_PAGE){
418 INIT_LIST_HEAD(&unplugged->list);
419 list_add(&unplugged->list, &unplugged_pages);
420 unplug_index = 0;
421 }
422 else {
423 struct list_head *entry = unplugged_pages.next;
424 addr = unplugged;
425
426 unplugged = list_entry(entry,
427 struct unplugged_pages,
428 list);
429 unplugged->pages[unplug_index++] = addr;
430 err = os_drop_memory(addr, PAGE_SIZE);
431 if(err)
432 printk("Failed to release memory - "
433 "errno = %d\n", err);
434 }
435
436 unplugged_pages_count++;
437 }
438 }
439
440 err = 0;
441out:
442 return err;
443}
444
445static int mem_get_config(char *name, char *str, int size, char **error_out)
446{
447 char buf[sizeof("18446744073709551615")];
448 int len = 0;
449
450 sprintf(buf, "%ld", uml_physmem);
451 CONFIG_CHUNK(str, size, len, buf, 1);
452
453 return len;
454}
455
456static int mem_id(char **str, int *start_out, int *end_out)
457{
458 *start_out = 0;
459 *end_out = 0;
460
461 return 0;
462}
463
464static int mem_remove(int n)
465{
466 return -EBUSY;
467}
468
469static struct mc_device mem_mc = {
470 .name = "mem",
471 .config = mem_config,
472 .get_config = mem_get_config,
473 .id = mem_id,
474 .remove = mem_remove,
475};
476
477static int mem_mc_init(void)
478{
479 if(can_drop_memory())
480 mconsole_register_dev(&mem_mc);
481 else printk("Can't release memory to the host - memory hotplug won't "
482 "be supported\n");
483 return 0;
484}
485
486__initcall(mem_mc_init);
487
350#define CONFIG_BUF_SIZE 64 488#define CONFIG_BUF_SIZE 64
351 489
352static void mconsole_get_config(int (*get_config)(char *, char *, int, 490static void mconsole_get_config(int (*get_config)(char *, char *, int,
@@ -478,7 +616,7 @@ static void console_write(struct console *console, const char *string,
478 return; 616 return;
479 617
480 while(1){ 618 while(1){
481 n = min(len, ARRAY_SIZE(console_buf) - console_index); 619 n = min((size_t)len, ARRAY_SIZE(console_buf) - console_index);
482 strncpy(&console_buf[console_index], string, n); 620 strncpy(&console_buf[console_index], string, n);
483 console_index += n; 621 console_index += n;
484 string += n; 622 string += n;
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 07c80f2156ef..466ff2c2f918 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -106,18 +106,7 @@ static struct transport pcap_transport = {
106static int register_pcap(void) 106static int register_pcap(void)
107{ 107{
108 register_transport(&pcap_transport); 108 register_transport(&pcap_transport);
109 return(1); 109 return 0;
110} 110}
111 111
112__initcall(register_pcap); 112__initcall(register_pcap);
113
114/*
115 * Overrides for Emacs so that we follow Linus's tabbing style.
116 * Emacs will notice this stuff at the end of the file and automatically
117 * adjust the settings for this buffer only. This must remain at the end
118 * of the file.
119 * ---------------------------------------------------------------------------
120 * Local variables:
121 * c-file-style: "linux"
122 * End:
123 */
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index a62f5ef445cf..163ee0d5f75e 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -93,18 +93,7 @@ static struct transport slip_transport = {
93static int register_slip(void) 93static int register_slip(void)
94{ 94{
95 register_transport(&slip_transport); 95 register_transport(&slip_transport);
96 return(1); 96 return 0;
97} 97}
98 98
99__initcall(register_slip); 99__initcall(register_slip);
100
101/*
102 * Overrides for Emacs so that we follow Linus's tabbing style.
103 * Emacs will notice this stuff at the end of the file and automatically
104 * adjust the settings for this buffer only. This must remain at the end
105 * of the file.
106 * ---------------------------------------------------------------------------
107 * Local variables:
108 * c-file-style: "linux"
109 * End:
110 */
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 33d7982be5d3..95e50c943e14 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -77,7 +77,7 @@ static int slirp_setup(char *str, char **mac_out, void *data)
77 int i=0; 77 int i=0;
78 78
79 *init = ((struct slirp_init) 79 *init = ((struct slirp_init)
80 { argw : { { "slirp", NULL } } }); 80 { .argw = { { "slirp", NULL } } });
81 81
82 str = split_if_spec(str, mac_out, NULL); 82 str = split_if_spec(str, mac_out, NULL);
83 83
@@ -116,18 +116,7 @@ static struct transport slirp_transport = {
116static int register_slirp(void) 116static int register_slirp(void)
117{ 117{
118 register_transport(&slirp_transport); 118 register_transport(&slirp_transport);
119 return(1); 119 return 0;
120} 120}
121 121
122__initcall(register_slirp); 122__initcall(register_slirp);
123
124/*
125 * Overrides for Emacs so that we follow Linus's tabbing style.
126 * Emacs will notice this stuff at the end of the file and automatically
127 * adjust the settings for this buffer only. This must remain at the end
128 * of the file.
129 * ---------------------------------------------------------------------------
130 * Local variables:
131 * c-file-style: "linux"
132 * End:
133 */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0336575d2448..0897852b09a3 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -891,7 +891,7 @@ int ubd_driver_init(void){
891 SA_INTERRUPT, "ubd", ubd_dev); 891 SA_INTERRUPT, "ubd", ubd_dev);
892 if(err != 0) 892 if(err != 0)
893 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); 893 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
894 return(err); 894 return 0;
895} 895}
896 896
897device_initcall(ubd_driver_init); 897device_initcall(ubd_driver_init);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 07176d92e1c9..42557130a408 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -116,7 +116,11 @@ extern void *get_current(void);
116extern struct task_struct *get_task(int pid, int require); 116extern struct task_struct *get_task(int pid, int require);
117extern void machine_halt(void); 117extern void machine_halt(void);
118extern int is_syscall(unsigned long addr); 118extern int is_syscall(unsigned long addr);
119extern void arch_switch(void); 119
120extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to);
121
122extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to);
123
120extern void free_irq(unsigned int, void *); 124extern void free_irq(unsigned int, void *);
121extern int cpu(void); 125extern int cpu(void);
122 126
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 6f4d680dc1d4..6ac0f8252e21 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -58,23 +58,17 @@ struct line {
58}; 58};
59 59
60#define LINE_INIT(str, d) \ 60#define LINE_INIT(str, d) \
61 { init_str : str, \ 61 { .init_str = str, \
62 init_pri : INIT_STATIC, \ 62 .init_pri = INIT_STATIC, \
63 valid : 1, \ 63 .valid = 1, \
64 throttled : 0, \ 64 .lock = SPIN_LOCK_UNLOCKED, \
65 lock : SPIN_LOCK_UNLOCKED, \ 65 .driver = d }
66 buffer : NULL, \
67 head : NULL, \
68 tail : NULL, \
69 sigio : 0, \
70 driver : d, \
71 have_irq : 0 }
72 66
73struct lines { 67struct lines {
74 int num; 68 int num;
75}; 69};
76 70
77#define LINES_INIT(n) { num : n } 71#define LINES_INIT(n) { .num = n }
78 72
79extern void line_close(struct tty_struct *tty, struct file * filp); 73extern void line_close(struct tty_struct *tty, struct file * filp);
80extern int line_open(struct line *lines, struct tty_struct *tty); 74extern int line_open(struct line *lines, struct tty_struct *tty);
diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
index a1064c5823bf..a54514d2cc3a 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -49,7 +49,6 @@ extern int iomem_size;
49extern unsigned long host_task_size; 49extern unsigned long host_task_size;
50extern unsigned long task_size; 50extern unsigned long task_size;
51 51
52extern void check_devanon(void);
53extern int init_mem_user(void); 52extern int init_mem_user(void);
54extern void setup_memory(void *entry); 53extern void setup_memory(void *entry);
55extern unsigned long find_iomem(char *driver, unsigned long *len_out); 54extern unsigned long find_iomem(char *driver, unsigned long *len_out);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index d3d1bc6074ef..f88856c28a66 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -13,6 +13,7 @@
13#include "kern_util.h" 13#include "kern_util.h"
14#include "skas/mm_id.h" 14#include "skas/mm_id.h"
15#include "irq_user.h" 15#include "irq_user.h"
16#include "sysdep/tls.h"
16 17
17#define OS_TYPE_FILE 1 18#define OS_TYPE_FILE 1
18#define OS_TYPE_DIR 2 19#define OS_TYPE_DIR 2
@@ -172,6 +173,7 @@ extern int os_fchange_dir(int fd);
172extern void os_early_checks(void); 173extern void os_early_checks(void);
173extern int can_do_skas(void); 174extern int can_do_skas(void);
174extern void os_check_bugs(void); 175extern void os_check_bugs(void);
176extern void check_host_supports_tls(int *supports_tls, int *tls_min);
175 177
176/* Make sure they are clear when running in TT mode. Required by 178/* Make sure they are clear when running in TT mode. Required by
177 * SEGV_MAYBE_FIXABLE */ 179 * SEGV_MAYBE_FIXABLE */
@@ -205,6 +207,8 @@ extern int os_map_memory(void *virt, int fd, unsigned long long off,
205extern int os_protect_memory(void *addr, unsigned long len, 207extern int os_protect_memory(void *addr, unsigned long len,
206 int r, int w, int x); 208 int r, int w, int x);
207extern int os_unmap_memory(void *addr, int len); 209extern int os_unmap_memory(void *addr, int len);
210extern int os_drop_memory(void *addr, int length);
211extern int can_drop_memory(void);
208extern void os_flush_stdout(void); 212extern void os_flush_stdout(void);
209 213
210/* tt.c 214/* tt.c
@@ -234,8 +238,12 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
234 int stack_order); 238 int stack_order);
235extern int helper_wait(int pid); 239extern int helper_wait(int pid);
236 240
237/* umid.c */
238 241
242/* tls.c */
243extern int os_set_thread_area(user_desc_t *info, int pid);
244extern int os_get_thread_area(user_desc_t *info, int pid);
245
246/* umid.c */
239extern int umid_file_name(char *name, char *buf, int len); 247extern int umid_file_name(char *name, char *buf, int len);
240extern int set_umid(char *name); 248extern int set_umid(char *name);
241extern char *get_umid(void); 249extern char *get_umid(void);
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
index 7d3d202d7fff..052bb061a978 100644
--- a/arch/um/include/sysdep-i386/checksum.h
+++ b/arch/um/include/sysdep-i386/checksum.h
@@ -48,7 +48,8 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
48 */ 48 */
49 49
50static __inline__ 50static __inline__
51unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, 51unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
52 unsigned char *dst,
52 int len, int sum, int *err_ptr) 53 int len, int sum, int *err_ptr)
53{ 54{
54 if(copy_from_user(dst, src, len)){ 55 if(copy_from_user(dst, src, len)){
@@ -192,7 +193,7 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
192 */ 193 */
193#define HAVE_CSUM_COPY_USER 194#define HAVE_CSUM_COPY_USER
194static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, 195static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
195 unsigned char *dst, 196 unsigned char __user *dst,
196 int len, int sum, int *err_ptr) 197 int len, int sum, int *err_ptr)
197{ 198{
198 if (access_ok(VERIFY_WRITE, dst, len)){ 199 if (access_ok(VERIFY_WRITE, dst, len)){
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index c8ee9559f3ab..6670cc992ecb 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -14,7 +14,12 @@
14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
15#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
16 16
17#ifdef UML_CONFIG_PT_PROXY
17extern void update_debugregs(int seq); 18extern void update_debugregs(int seq);
19#else
20static inline void update_debugregs(int seq) {}
21#endif
22
18 23
19/* syscall emulation path in ptrace */ 24/* syscall emulation path in ptrace */
20 25
diff --git a/arch/um/include/sysdep-i386/tls.h b/arch/um/include/sysdep-i386/tls.h
new file mode 100644
index 000000000000..918fd3c5ff9c
--- /dev/null
+++ b/arch/um/include/sysdep-i386/tls.h
@@ -0,0 +1,32 @@
1#ifndef _SYSDEP_TLS_H
2#define _SYSDEP_TLS_H
3
4# ifndef __KERNEL__
5
6/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
7 * may be named user_desc (but in 2.4 and in header matching its API was named
8 * modify_ldt_ldt_s). */
9
10typedef struct um_dup_user_desc {
11 unsigned int entry_number;
12 unsigned int base_addr;
13 unsigned int limit;
14 unsigned int seg_32bit:1;
15 unsigned int contents:2;
16 unsigned int read_exec_only:1;
17 unsigned int limit_in_pages:1;
18 unsigned int seg_not_present:1;
19 unsigned int useable:1;
20} user_desc_t;
21
22# else /* __KERNEL__ */
23
24# include <asm/ldt.h>
25typedef struct user_desc user_desc_t;
26
27# endif /* __KERNEL__ */
28
29#define GDT_ENTRY_TLS_MIN_I386 6
30#define GDT_ENTRY_TLS_MIN_X86_64 12
31
32#endif /* _SYSDEP_TLS_H */
diff --git a/arch/um/include/sysdep-x86_64/tls.h b/arch/um/include/sysdep-x86_64/tls.h
new file mode 100644
index 000000000000..35f19f25bd3b
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/tls.h
@@ -0,0 +1,29 @@
1#ifndef _SYSDEP_TLS_H
2#define _SYSDEP_TLS_H
3
4# ifndef __KERNEL__
5
6/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
7 * may be named user_desc (but in 2.4 and in header matching its API was named
8 * modify_ldt_ldt_s). */
9
10typedef struct um_dup_user_desc {
11 unsigned int entry_number;
12 unsigned int base_addr;
13 unsigned int limit;
14 unsigned int seg_32bit:1;
15 unsigned int contents:2;
16 unsigned int read_exec_only:1;
17 unsigned int limit_in_pages:1;
18 unsigned int seg_not_present:1;
19 unsigned int useable:1;
20 unsigned int lm:1;
21} user_desc_t;
22
23# else /* __KERNEL__ */
24
25# include <asm/ldt.h>
26typedef struct user_desc user_desc_t;
27
28# endif /* __KERNEL__ */
29#endif /* _SYSDEP_TLS_H */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 992a7e1e0fca..fe0c29b5144d 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -8,6 +8,9 @@
8 8
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10 10
11/* Copied from kernel.h */
12#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
13
11#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) 14#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
12 15
13extern int mode_tt; 16extern int mode_tt;
@@ -31,7 +34,7 @@ extern unsigned long uml_physmem;
31extern unsigned long uml_reserved; 34extern unsigned long uml_reserved;
32extern unsigned long end_vm; 35extern unsigned long end_vm;
33extern unsigned long start_vm; 36extern unsigned long start_vm;
34extern unsigned long highmem; 37extern unsigned long long highmem;
35 38
36extern char host_info[]; 39extern char host_info[];
37 40
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index 1ca84319317d..c0cb627bf594 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -22,6 +22,7 @@
22 22
23void flush_thread(void) 23void flush_thread(void)
24{ 24{
25 arch_flush_thread(&current->thread.arch);
25 CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); 26 CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
26} 27}
27 28
@@ -58,14 +59,14 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
58 return(err); 59 return(err);
59} 60}
60 61
61long sys_execve(char *file, char __user *__user *argv, 62long sys_execve(char __user *file, char __user *__user *argv,
62 char __user *__user *env) 63 char __user *__user *env)
63{ 64{
64 long error; 65 long error;
65 char *filename; 66 char *filename;
66 67
67 lock_kernel(); 68 lock_kernel();
68 filename = getname((char __user *) file); 69 filename = getname(file);
69 error = PTR_ERR(filename); 70 error = PTR_ERR(filename);
70 if (IS_ERR(filename)) goto out; 71 if (IS_ERR(filename)) goto out;
71 error = execve1(filename, argv, env); 72 error = execve1(filename, argv, env);
@@ -74,14 +75,3 @@ long sys_execve(char *file, char __user *__user *argv,
74 unlock_kernel(); 75 unlock_kernel();
75 return(error); 76 return(error);
76} 77}
77
78/*
79 * Overrides for Emacs so that we follow Linus's tabbing style.
80 * Emacs will notice this stuff at the end of the file and automatically
81 * adjust the settings for this buffer only. This must remain at the end
82 * of the file.
83 * ---------------------------------------------------------------------------
84 * Local variables:
85 * c-file-style: "linux"
86 * End:
87 */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 92cce96b5e24..44e41a35f000 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -30,7 +30,7 @@ extern char __binary_start;
30unsigned long *empty_zero_page = NULL; 30unsigned long *empty_zero_page = NULL;
31unsigned long *empty_bad_page = NULL; 31unsigned long *empty_bad_page = NULL;
32pgd_t swapper_pg_dir[PTRS_PER_PGD]; 32pgd_t swapper_pg_dir[PTRS_PER_PGD];
33unsigned long highmem; 33unsigned long long highmem;
34int kmalloc_ok = 0; 34int kmalloc_ok = 0;
35 35
36static unsigned long brk_end; 36static unsigned long brk_end;
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 3113cab8675e..f6a5a502120b 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -156,9 +156,25 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
156 unsigned long stack_top, struct task_struct * p, 156 unsigned long stack_top, struct task_struct * p,
157 struct pt_regs *regs) 157 struct pt_regs *regs)
158{ 158{
159 int ret;
160
159 p->thread = (struct thread_struct) INIT_THREAD; 161 p->thread = (struct thread_struct) INIT_THREAD;
160 return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 162 ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
161 clone_flags, sp, stack_top, p, regs)); 163 clone_flags, sp, stack_top, p, regs);
164
165 if (ret || !current->thread.forking)
166 goto out;
167
168 clear_flushed_tls(p);
169
170 /*
171 * Set a new TLS for the child thread?
172 */
173 if (clone_flags & CLONE_SETTLS)
174 ret = arch_copy_tls(p);
175
176out:
177 return ret;
162} 178}
163 179
164void initial_thread_cb(void (*proc)(void *), void *arg) 180void initial_thread_cb(void (*proc)(void *), void *arg)
@@ -185,10 +201,6 @@ void default_idle(void)
185{ 201{
186 CHOOSE_MODE(uml_idle_timer(), (void) 0); 202 CHOOSE_MODE(uml_idle_timer(), (void) 0);
187 203
188 atomic_inc(&init_mm.mm_count);
189 current->mm = &init_mm;
190 current->active_mm = &init_mm;
191
192 while(1){ 204 while(1){
193 /* endless idle loop with no priority at all */ 205 /* endless idle loop with no priority at all */
194 206
@@ -407,7 +419,7 @@ static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int
407 return strlen(buf); 419 return strlen(buf);
408} 420}
409 421
410static int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) 422static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
411{ 423{
412 char tmp[2]; 424 char tmp[2];
413 425
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 98e09395c093..60d2eda995c1 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -46,6 +46,7 @@ extern int poke_user(struct task_struct * child, long addr, long data);
46long arch_ptrace(struct task_struct *child, long request, long addr, long data) 46long arch_ptrace(struct task_struct *child, long request, long addr, long data)
47{ 47{
48 int i, ret; 48 int i, ret;
49 unsigned long __user *p = (void __user *)(unsigned long)data;
49 50
50 switch (request) { 51 switch (request) {
51 /* when I and D space are separate, these will need to be fixed. */ 52 /* when I and D space are separate, these will need to be fixed. */
@@ -58,7 +59,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
58 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 59 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
59 if (copied != sizeof(tmp)) 60 if (copied != sizeof(tmp))
60 break; 61 break;
61 ret = put_user(tmp, (unsigned long __user *) data); 62 ret = put_user(tmp, p);
62 break; 63 break;
63 } 64 }
64 65
@@ -136,15 +137,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
136 137
137#ifdef PTRACE_GETREGS 138#ifdef PTRACE_GETREGS
138 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 139 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
139 if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 140 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
140 MAX_REG_OFFSET)) {
141 ret = -EIO; 141 ret = -EIO;
142 break; 142 break;
143 } 143 }
144 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { 144 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
145 __put_user(getreg(child, i), 145 __put_user(getreg(child, i), p);
146 (unsigned long __user *) data); 146 p++;
147 data += sizeof(long);
148 } 147 }
149 ret = 0; 148 ret = 0;
150 break; 149 break;
@@ -153,15 +152,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
153#ifdef PTRACE_SETREGS 152#ifdef PTRACE_SETREGS
154 case PTRACE_SETREGS: { /* Set all gp regs in the child. */ 153 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
155 unsigned long tmp = 0; 154 unsigned long tmp = 0;
156 if (!access_ok(VERIFY_READ, (unsigned *)data, 155 if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
157 MAX_REG_OFFSET)) {
158 ret = -EIO; 156 ret = -EIO;
159 break; 157 break;
160 } 158 }
161 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { 159 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
162 __get_user(tmp, (unsigned long __user *) data); 160 __get_user(tmp, p);
163 putreg(child, i, tmp); 161 putreg(child, i, tmp);
164 data += sizeof(long); 162 p++;
165 } 163 }
166 ret = 0; 164 ret = 0;
167 break; 165 break;
@@ -187,14 +185,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
187 ret = set_fpxregs(data, child); 185 ret = set_fpxregs(data, child);
188 break; 186 break;
189#endif 187#endif
188 case PTRACE_GET_THREAD_AREA:
189 ret = ptrace_get_thread_area(child, addr,
190 (struct user_desc __user *) data);
191 break;
192
193 case PTRACE_SET_THREAD_AREA:
194 ret = ptrace_set_thread_area(child, addr,
195 (struct user_desc __user *) data);
196 break;
197
190 case PTRACE_FAULTINFO: { 198 case PTRACE_FAULTINFO: {
191 /* Take the info from thread->arch->faultinfo, 199 /* Take the info from thread->arch->faultinfo,
192 * but transfer max. sizeof(struct ptrace_faultinfo). 200 * but transfer max. sizeof(struct ptrace_faultinfo).
193 * On i386, ptrace_faultinfo is smaller! 201 * On i386, ptrace_faultinfo is smaller!
194 */ 202 */
195 ret = copy_to_user((unsigned long __user *) data, 203 ret = copy_to_user(p, &child->thread.arch.faultinfo,
196 &child->thread.arch.faultinfo, 204 sizeof(struct ptrace_faultinfo));
197 sizeof(struct ptrace_faultinfo));
198 if(ret) 205 if(ret)
199 break; 206 break;
200 break; 207 break;
@@ -204,8 +211,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
204 case PTRACE_LDT: { 211 case PTRACE_LDT: {
205 struct ptrace_ldt ldt; 212 struct ptrace_ldt ldt;
206 213
207 if(copy_from_user(&ldt, (unsigned long __user *) data, 214 if(copy_from_user(&ldt, p, sizeof(ldt))){
208 sizeof(ldt))){
209 ret = -EIO; 215 ret = -EIO;
210 break; 216 break;
211 } 217 }
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 3f70a2e12f06..2135eaf98a93 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -35,6 +35,8 @@ void switch_to_skas(void *prev, void *next)
35 switch_threads(&from->thread.mode.skas.switch_buf, 35 switch_threads(&from->thread.mode.skas.switch_buf,
36 to->thread.mode.skas.switch_buf); 36 to->thread.mode.skas.switch_buf);
37 37
38 arch_switch_to_skas(current->thread.prev_sched, current);
39
38 if(current->pid == 0) 40 if(current->pid == 0)
39 switch_timers(1); 41 switch_timers(1);
40} 42}
@@ -89,10 +91,17 @@ void fork_handler(int sig)
89 panic("blech"); 91 panic("blech");
90 92
91 schedule_tail(current->thread.prev_sched); 93 schedule_tail(current->thread.prev_sched);
94
95 /* XXX: if interrupt_end() calls schedule, this call to
96 * arch_switch_to_skas isn't needed. We could want to apply this to
97 * improve performance. -bb */
98 arch_switch_to_skas(current->thread.prev_sched, current);
99
92 current->thread.prev_sched = NULL; 100 current->thread.prev_sched = NULL;
93 101
94/* Handle any immediate reschedules or signals */ 102/* Handle any immediate reschedules or signals */
95 interrupt_end(); 103 interrupt_end();
104
96 userspace(&current->thread.regs.regs); 105 userspace(&current->thread.regs.regs);
97} 106}
98 107
@@ -109,6 +118,8 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
109 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; 118 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
110 119
111 handler = fork_handler; 120 handler = fork_handler;
121
122 arch_copy_thread(&current->thread.arch, &p->thread.arch);
112 } 123 }
113 else { 124 else {
114 init_thread_registers(&p->thread.regs.regs); 125 init_thread_registers(&p->thread.regs.regs);
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index 8e1a3501ff46..37d3978337d8 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -104,7 +104,7 @@ long sys_pipe(unsigned long __user * fildes)
104} 104}
105 105
106 106
107long sys_uname(struct old_utsname * name) 107long sys_uname(struct old_utsname __user * name)
108{ 108{
109 long err; 109 long err;
110 if (!name) 110 if (!name)
@@ -115,7 +115,7 @@ long sys_uname(struct old_utsname * name)
115 return err?-EFAULT:0; 115 return err?-EFAULT:0;
116} 116}
117 117
118long sys_olduname(struct oldold_utsname * name) 118long sys_olduname(struct oldold_utsname __user * name)
119{ 119{
120 long error; 120 long error;
121 121
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index d56046c2aba2..02f6d4d8dc3a 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -198,7 +198,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
198 si.si_signo = SIGBUS; 198 si.si_signo = SIGBUS;
199 si.si_errno = 0; 199 si.si_errno = 0;
200 si.si_code = BUS_ADRERR; 200 si.si_code = BUS_ADRERR;
201 si.si_addr = (void *)address; 201 si.si_addr = (void __user *)address;
202 current->thread.arch.faultinfo = fi; 202 current->thread.arch.faultinfo = fi;
203 force_sig_info(SIGBUS, &si, current); 203 force_sig_info(SIGBUS, &si, current);
204 } else if (err == -ENOMEM) { 204 } else if (err == -ENOMEM) {
@@ -207,7 +207,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
207 } else { 207 } else {
208 BUG_ON(err != -EFAULT); 208 BUG_ON(err != -EFAULT);
209 si.si_signo = SIGSEGV; 209 si.si_signo = SIGSEGV;
210 si.si_addr = (void *) address; 210 si.si_addr = (void __user *) address;
211 current->thread.arch.faultinfo = fi; 211 current->thread.arch.faultinfo = fi;
212 force_sig_info(SIGSEGV, &si, current); 212 force_sig_info(SIGSEGV, &si, current);
213 } 213 }
@@ -220,8 +220,8 @@ void bad_segv(struct faultinfo fi, unsigned long ip)
220 220
221 si.si_signo = SIGSEGV; 221 si.si_signo = SIGSEGV;
222 si.si_code = SEGV_ACCERR; 222 si.si_code = SEGV_ACCERR;
223 si.si_addr = (void *) FAULT_ADDRESS(fi); 223 si.si_addr = (void __user *) FAULT_ADDRESS(fi);
224 current->thread.arch.faultinfo = fi; 224 current->thread.arch.faultinfo = fi;
225 force_sig_info(SIGSEGV, &si, current); 225 force_sig_info(SIGSEGV, &si, current);
226} 226}
227 227
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 295c1ac817b3..a9c1443fc548 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -51,6 +51,13 @@ void switch_to_tt(void *prev, void *next)
51 51
52 c = 0; 52 c = 0;
53 53
54 /* Notice that here we "up" the semaphore on which "to" is waiting, and
55 * below (the read) we wait on this semaphore (which is implemented by
56 * switch_pipe) and go sleeping. Thus, after that, we have resumed in
57 * "to", and can't use any more the value of "from" (which is outdated),
58 * nor the value in "to" (since it was the task which stole us the CPU,
59 * which we don't care about). */
60
54 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); 61 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
55 if(err != sizeof(c)) 62 if(err != sizeof(c))
56 panic("write of switch_pipe failed, err = %d", -err); 63 panic("write of switch_pipe failed, err = %d", -err);
@@ -77,7 +84,7 @@ void switch_to_tt(void *prev, void *next)
77 change_sig(SIGALRM, alrm); 84 change_sig(SIGALRM, alrm);
78 change_sig(SIGPROF, prof); 85 change_sig(SIGPROF, prof);
79 86
80 arch_switch(); 87 arch_switch_to_tt(prev_sched, current);
81 88
82 flush_tlb_all(); 89 flush_tlb_all();
83 local_irq_restore(flags); 90 local_irq_restore(flags);
@@ -141,7 +148,6 @@ static void new_thread_handler(int sig)
141 set_cmdline("(kernel thread)"); 148 set_cmdline("(kernel thread)");
142 149
143 change_sig(SIGUSR1, 1); 150 change_sig(SIGUSR1, 1);
144 change_sig(SIGVTALRM, 1);
145 change_sig(SIGPROF, 1); 151 change_sig(SIGPROF, 1);
146 local_irq_enable(); 152 local_irq_enable();
147 if(!run_kernel_thread(fn, arg, &current->thread.exec_buf)) 153 if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 1659386b42bb..f4bfc4c7ccac 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,7 +4,7 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ 6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
7 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o \ 7 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o tls.o \
8 user_syms.o util.o drivers/ sys-$(SUBARCH)/ 8 user_syms.o util.o drivers/ sys-$(SUBARCH)/
9 9
10obj-$(CONFIG_MODE_SKAS) += skas/ 10obj-$(CONFIG_MODE_SKAS) += skas/
@@ -12,12 +12,9 @@ obj-$(CONFIG_TTY_LOG) += tty_log.o
12user-objs-$(CONFIG_TTY_LOG) += tty_log.o 12user-objs-$(CONFIG_TTY_LOG) += tty_log.o
13 13
14USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ 14USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
15 process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o \ 15 process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o tls.o \
16 uaccess.o umid.o util.o 16 uaccess.o umid.o util.o
17 17
18elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
19CFLAGS_elf_aux.o += -I$(objtree)/arch/um
20
21CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 18CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
22 19
23HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \ 20HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 6ae4b19d9f50..768606bec233 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -102,18 +102,7 @@ static struct transport ethertap_transport = {
102static int register_ethertap(void) 102static int register_ethertap(void)
103{ 103{
104 register_transport(&ethertap_transport); 104 register_transport(&ethertap_transport);
105 return(1); 105 return 0;
106} 106}
107 107
108__initcall(register_ethertap); 108__initcall(register_ethertap);
109
110/*
111 * Overrides for Emacs so that we follow Linus's tabbing style.
112 * Emacs will notice this stuff at the end of the file and automatically
113 * adjust the settings for this buffer only. This must remain at the end
114 * of the file.
115 * ---------------------------------------------------------------------------
116 * Local variables:
117 * c-file-style: "linux"
118 * End:
119 */
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 4202b9ebad4c..190009a6f89c 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -87,18 +87,7 @@ static struct transport tuntap_transport = {
87static int register_tuntap(void) 87static int register_tuntap(void)
88{ 88{
89 register_transport(&tuntap_transport); 89 register_transport(&tuntap_transport);
90 return(1); 90 return 0;
91} 91}
92 92
93__initcall(register_tuntap); 93__initcall(register_tuntap);
94
95/*
96 * Overrides for Emacs so that we follow Linus's tabbing style.
97 * Emacs will notice this stuff at the end of the file and automatically
98 * adjust the settings for this buffer only. This must remain at the end
99 * of the file.
100 * ---------------------------------------------------------------------------
101 * Local variables:
102 * c-file-style: "linux"
103 * End:
104 */
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 9d7d69a523bb..6ab372da9657 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -121,36 +121,11 @@ int create_tmp_file(unsigned long long len)
121 return(fd); 121 return(fd);
122} 122}
123 123
124static int create_anon_file(unsigned long long len)
125{
126 void *addr;
127 int fd;
128
129 fd = open("/dev/anon", O_RDWR);
130 if(fd < 0) {
131 perror("opening /dev/anon");
132 exit(1);
133 }
134
135 addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
136 if(addr == MAP_FAILED){
137 perror("mapping physmem file");
138 exit(1);
139 }
140 munmap(addr, len);
141
142 return(fd);
143}
144
145extern int have_devanon;
146
147int create_mem_file(unsigned long long len) 124int create_mem_file(unsigned long long len)
148{ 125{
149 int err, fd; 126 int err, fd;
150 127
151 if(have_devanon) 128 fd = create_tmp_file(len);
152 fd = create_anon_file(len);
153 else fd = create_tmp_file(len);
154 129
155 err = os_set_exec_close(fd, 1); 130 err = os_set_exec_close(fd, 1);
156 if(err < 0){ 131 if(err < 0){
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index d261888f39c4..8176b0b52047 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -11,6 +11,7 @@
11#include <linux/unistd.h> 11#include <linux/unistd.h>
12#include <sys/mman.h> 12#include <sys/mman.h>
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include <sys/mman.h>
14#include "ptrace_user.h" 15#include "ptrace_user.h"
15#include "os.h" 16#include "os.h"
16#include "user.h" 17#include "user.h"
@@ -20,6 +21,7 @@
20#include "kern_util.h" 21#include "kern_util.h"
21#include "longjmp.h" 22#include "longjmp.h"
22#include "skas_ptrace.h" 23#include "skas_ptrace.h"
24#include "kern_constants.h"
23 25
24#define ARBITRARY_ADDR -1 26#define ARBITRARY_ADDR -1
25#define FAILURE_PID -1 27#define FAILURE_PID -1
@@ -187,6 +189,48 @@ int os_unmap_memory(void *addr, int len)
187 return(0); 189 return(0);
188} 190}
189 191
192#ifndef MADV_REMOVE
193#define MADV_REMOVE 0x5 /* remove these pages & resources */
194#endif
195
196int os_drop_memory(void *addr, int length)
197{
198 int err;
199
200 err = madvise(addr, length, MADV_REMOVE);
201 if(err < 0)
202 err = -errno;
203 return err;
204}
205
206int can_drop_memory(void)
207{
208 void *addr;
209 int fd;
210
211 printk("Checking host MADV_REMOVE support...");
212 fd = create_mem_file(UM_KERN_PAGE_SIZE);
213 if(fd < 0){
214 printk("Creating test memory file failed, err = %d\n", -fd);
215 return 0;
216 }
217
218 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
219 MAP_PRIVATE, fd, 0);
220 if(addr == MAP_FAILED){
221 printk("Mapping test memory file failed, err = %d\n", -errno);
222 return 0;
223 }
224
225 if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){
226 printk("MADV_REMOVE failed, err = %d\n", -errno);
227 return 0;
228 }
229
230 printk("OK\n");
231 return 1;
232}
233
190void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) 234void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
191{ 235{
192 int flags = 0, pages; 236 int flags = 0, pages;
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 32753131f8d8..387e26af301a 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -470,25 +470,6 @@ int can_do_skas(void)
470} 470}
471#endif 471#endif
472 472
473int have_devanon = 0;
474
475/* Runs on boot kernel stack - already safe to use printk. */
476
477void check_devanon(void)
478{
479 int fd;
480
481 printk("Checking for /dev/anon on the host...");
482 fd = open("/dev/anon", O_RDWR);
483 if(fd < 0){
484 printk("Not available (open failed with errno %d)\n", errno);
485 return;
486 }
487
488 printk("OK\n");
489 have_devanon = 1;
490}
491
492int __init parse_iomem(char *str, int *add) 473int __init parse_iomem(char *str, int *add)
493{ 474{
494 struct iomem_region *new; 475 struct iomem_region *new;
@@ -664,6 +645,5 @@ void os_check_bugs(void)
664{ 645{
665 check_ptrace(); 646 check_ptrace();
666 check_sigio(); 647 check_sigio();
667 check_devanon();
668} 648}
669 649
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
index 340ef26f5944..b3213613c41c 100644
--- a/arch/um/os-Linux/sys-i386/Makefile
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -3,7 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o 6obj-$(CONFIG_MODE_SKAS) = registers.o tls.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
new file mode 100644
index 000000000000..ba21f0e04a2f
--- /dev/null
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -0,0 +1,33 @@
1#include <linux/unistd.h>
2#include "sysdep/tls.h"
3#include "user_util.h"
4
5static _syscall1(int, get_thread_area, user_desc_t *, u_info);
6
7/* Checks whether host supports TLS, and sets *tls_min according to the value
8 * valid on the host.
9 * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
10void check_host_supports_tls(int *supports_tls, int *tls_min) {
11 /* Values for x86 and x86_64.*/
12 int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64};
13 int i;
14
15 for (i = 0; i < ARRAY_SIZE(val); i++) {
16 user_desc_t info;
17 info.entry_number = val[i];
18
19 if (get_thread_area(&info) == 0) {
20 *tls_min = val[i];
21 *supports_tls = 1;
22 return;
23 } else {
24 if (errno == EINVAL)
25 continue;
26 else if (errno == ENOSYS)
27 *supports_tls = 0;
28 return;
29 }
30 }
31
32 *supports_tls = 0;
33}
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
new file mode 100644
index 000000000000..9cb09a45546b
--- /dev/null
+++ b/arch/um/os-Linux/tls.c
@@ -0,0 +1,76 @@
1#include <errno.h>
2#include <sys/ptrace.h>
3#include <asm/ldt.h>
4#include "sysdep/tls.h"
5#include "uml-config.h"
6
7/* TLS support - we basically rely on the host's one.*/
8
9/* In TT mode, this should be called only by the tracing thread, and makes sense
10 * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally.
11 *
12 */
13
14#ifndef PTRACE_GET_THREAD_AREA
15#define PTRACE_GET_THREAD_AREA 25
16#endif
17
18#ifndef PTRACE_SET_THREAD_AREA
19#define PTRACE_SET_THREAD_AREA 26
20#endif
21
22int os_set_thread_area(user_desc_t *info, int pid)
23{
24 int ret;
25
26 ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number,
27 (unsigned long) info);
28 if (ret < 0)
29 ret = -errno;
30 return ret;
31}
32
33#ifdef UML_CONFIG_MODE_SKAS
34
35int os_get_thread_area(user_desc_t *info, int pid)
36{
37 int ret;
38
39 ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number,
40 (unsigned long) info);
41 if (ret < 0)
42 ret = -errno;
43 return ret;
44}
45
46#endif
47
48#ifdef UML_CONFIG_MODE_TT
49#include "linux/unistd.h"
50
51static _syscall1(int, get_thread_area, user_desc_t *, u_info);
52static _syscall1(int, set_thread_area, user_desc_t *, u_info);
53
54int do_set_thread_area_tt(user_desc_t *info)
55{
56 int ret;
57
58 ret = set_thread_area(info);
59 if (ret < 0) {
60 ret = -errno;
61 }
62 return ret;
63}
64
65int do_get_thread_area_tt(user_desc_t *info)
66{
67 int ret;
68
69 ret = get_thread_area(info);
70 if (ret < 0) {
71 ret = -errno;
72 }
73 return ret;
74}
75
76#endif /* UML_CONFIG_MODE_TT */
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 2e41cabd3d93..b696b451774c 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -20,25 +20,7 @@ define unprofile
20 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) 20 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
21endef 21endef
22 22
23 23ifdef subarch-obj-y
24# cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If 24obj-y += subarch.o
25# so, it's considered to be a path relative to $(srcdir) rather than 25subarch-y = $(addprefix ../../$(SUBARCH)/,$(subarch-obj-y))
26# $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from 26endif
27# arch/um/sys-i386 rather than arch/i386 like the other borrowed files. So,
28# it sets $(ldt.c-dir) to /arch/um/sys-i386.
29quiet_cmd_make_link = SYMLINK $@
30cmd_make_link = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@
31
32# this needs to be before the foreach, because targets does not accept
33# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
34# or we will get $(obj)/$(f) in the "targets" value.
35# Also, this forces you to use the := syntax when assigning to targets.
36# Otherwise the line below will cause an infinite loop (if you don't know why,
37# just do it).
38
39targets := $(targets) $(SYMLINKS)
40
41SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f))
42
43$(SYMLINKS): FORCE
44 $(call if_changed,make_link)
diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap
deleted file mode 100644
index b2165188d942..000000000000
--- a/arch/um/scripts/Makefile.unmap
+++ /dev/null
@@ -1,22 +0,0 @@
1clean-files += unmap_tmp.o unmap_fin.o unmap.o
2
3ifdef CONFIG_MODE_TT
4
5#Always build unmap_fin.o
6extra-y += unmap_fin.o
7#Do dependency tracking for unmap.o (it will be always built, but won't get the tracking unless we use this).
8targets += unmap.o
9
10#XXX: partially copied from arch/um/scripts/Makefile.rules
11$(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
12
13quiet_cmd_wrapld = LD $@
14define cmd_wrapld
15 $(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< ; \
16 $(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
17endef
18
19$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
20 $(call if_changed,wrapld)
21
22endif
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index f5fd5b0156d0..98b20b7bba4f 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,23 +1,18 @@
1obj-y := bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ 2 ptrace_user.o signal.o sigcontext.o syscalls.o sysrq.o \
3 sys_call_table.o 3 sys_call_table.o tls.o
4 4
5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o 5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
6 6
7obj-$(CONFIG_HIGHMEM) += highmem.o 7subarch-obj-y = lib/bitops.o kernel/semaphore.o
8obj-$(CONFIG_MODULES) += module.o 8subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o
9subarch-obj-$(CONFIG_MODULES) += kernel/module.o
9 10
10USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o 11USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o
11 12
12SYMLINKS = bitops.c semaphore.c highmem.c module.c
13
14include arch/um/scripts/Makefile.rules 13include arch/um/scripts/Makefile.rules
15 14
16bitops.c-dir = lib 15extra-$(CONFIG_MODE_TT) += unmap.o
17semaphore.c-dir = kernel
18highmem.c-dir = mm
19module.c-dir = kernel
20
21$(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS))
22 16
23include arch/um/scripts/Makefile.unmap 17$(obj)/stub_segv.o $(obj)/unmap.o: \
18 _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 8032a105949a..6028bc7cc01b 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -15,9 +15,22 @@
15#include "sysdep/sigcontext.h" 15#include "sysdep/sigcontext.h"
16#include "sysdep/sc.h" 16#include "sysdep/sc.h"
17 17
18void arch_switch(void) 18void arch_switch_to_tt(struct task_struct *from, struct task_struct *to)
19{ 19{
20 update_debugregs(current->thread.arch.debugregs_seq); 20 update_debugregs(to->thread.arch.debugregs_seq);
21 arch_switch_tls_tt(from, to);
22}
23
24void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
25{
26 int err = arch_switch_tls_skas(from, to);
27 if (!err)
28 return;
29
30 if (err != -EINVAL)
31 printk(KERN_WARNING "arch_switch_tls_skas failed, errno %d, not EINVAL\n", -err);
32 else
33 printk(KERN_WARNING "arch_switch_tls_skas failed, errno = EINVAL\n");
21} 34}
22 35
23int is_syscall(unsigned long addr) 36int is_syscall(unsigned long addr)
@@ -124,22 +137,22 @@ unsigned long getreg(struct task_struct *child, int regno)
124int peek_user(struct task_struct *child, long addr, long data) 137int peek_user(struct task_struct *child, long addr, long data)
125{ 138{
126/* read the word at location addr in the USER area. */ 139/* read the word at location addr in the USER area. */
127 unsigned long tmp; 140 unsigned long tmp;
128 141
129 if ((addr & 3) || addr < 0) 142 if ((addr & 3) || addr < 0)
130 return -EIO; 143 return -EIO;
131 144
132 tmp = 0; /* Default return condition */ 145 tmp = 0; /* Default return condition */
133 if(addr < MAX_REG_OFFSET){ 146 if(addr < MAX_REG_OFFSET){
134 tmp = getreg(child, addr); 147 tmp = getreg(child, addr);
135 } 148 }
136 else if((addr >= offsetof(struct user, u_debugreg[0])) && 149 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
137 (addr <= offsetof(struct user, u_debugreg[7]))){ 150 (addr <= offsetof(struct user, u_debugreg[7]))){
138 addr -= offsetof(struct user, u_debugreg[0]); 151 addr -= offsetof(struct user, u_debugreg[0]);
139 addr = addr >> 2; 152 addr = addr >> 2;
140 tmp = child->thread.arch.debugregs[addr]; 153 tmp = child->thread.arch.debugregs[addr];
141 } 154 }
142 return put_user(tmp, (unsigned long *) data); 155 return put_user(tmp, (unsigned long __user *) data);
143} 156}
144 157
145struct i387_fxsave_struct { 158struct i387_fxsave_struct {
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 7c376c95de50..9f3bd8ed78f5 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -14,6 +14,7 @@
14#include "sysdep/thread.h" 14#include "sysdep/thread.h"
15#include "user.h" 15#include "user.h"
16#include "os.h" 16#include "os.h"
17#include "uml-config.h"
17 18
18int ptrace_getregs(long pid, unsigned long *regs_out) 19int ptrace_getregs(long pid, unsigned long *regs_out)
19{ 20{
@@ -43,6 +44,7 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
43 return 0; 44 return 0;
44} 45}
45 46
47/* All the below stuff is of interest for TT mode only */
46static void write_debugregs(int pid, unsigned long *regs) 48static void write_debugregs(int pid, unsigned long *regs)
47{ 49{
48 struct user *dummy; 50 struct user *dummy;
@@ -75,7 +77,6 @@ static void read_debugregs(int pid, unsigned long *regs)
75 77
76/* Accessed only by the tracing thread */ 78/* Accessed only by the tracing thread */
77static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; 79static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
78static int debugregs_seq = 0;
79 80
80void arch_enter_kernel(void *task, int pid) 81void arch_enter_kernel(void *task, int pid)
81{ 82{
@@ -89,6 +90,11 @@ void arch_leave_kernel(void *task, int pid)
89 write_debugregs(pid, TASK_DEBUGREGS(task)); 90 write_debugregs(pid, TASK_DEBUGREGS(task));
90} 91}
91 92
93#ifdef UML_CONFIG_PT_PROXY
94/* Accessed only by the tracing thread */
95static int debugregs_seq;
96
97/* Only called by the ptrace proxy */
92void ptrace_pokeuser(unsigned long addr, unsigned long data) 98void ptrace_pokeuser(unsigned long addr, unsigned long data)
93{ 99{
94 if((addr < offsetof(struct user, u_debugreg[0])) || 100 if((addr < offsetof(struct user, u_debugreg[0])) ||
@@ -109,6 +115,7 @@ static void update_debugregs_cb(void *arg)
109 write_debugregs(pid, kernel_debugregs); 115 write_debugregs(pid, kernel_debugregs);
110} 116}
111 117
118/* Optimized out in its header when not defined */
112void update_debugregs(int seq) 119void update_debugregs(int seq)
113{ 120{
114 int me; 121 int me;
@@ -118,6 +125,7 @@ void update_debugregs(int seq)
118 me = os_getpid(); 125 me = os_getpid();
119 initial_thread_cb(update_debugregs_cb, &me); 126 initial_thread_cb(update_debugregs_cb, &me);
120} 127}
128#endif
121 129
122/* 130/*
123 * Overrides for Emacs so that we follow Linus's tabbing style. 131 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 33a40f5ef0d2..f5d0e1c37ea2 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -19,7 +19,7 @@
19#include "skas.h" 19#include "skas.h"
20 20
21static int copy_sc_from_user_skas(struct pt_regs *regs, 21static int copy_sc_from_user_skas(struct pt_regs *regs,
22 struct sigcontext *from) 22 struct sigcontext __user *from)
23{ 23{
24 struct sigcontext sc; 24 struct sigcontext sc;
25 unsigned long fpregs[HOST_FP_SIZE]; 25 unsigned long fpregs[HOST_FP_SIZE];
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
57 return(0); 57 return(0);
58} 58}
59 59
60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp,
61 struct pt_regs *regs, unsigned long sp) 61 struct pt_regs *regs, unsigned long sp)
62{ 62{
63 struct sigcontext sc; 63 struct sigcontext sc;
@@ -92,7 +92,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
92 "errno = %d\n", err); 92 "errno = %d\n", err);
93 return(1); 93 return(1);
94 } 94 }
95 to_fp = (to_fp ? to_fp : (struct _fpstate *) (to + 1)); 95 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
96 sc.fpstate = to_fp; 96 sc.fpstate = to_fp;
97 97
98 if(err) 98 if(err)
@@ -113,10 +113,11 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
113 * saved pointer is in the kernel, but the sigcontext is in userspace, so we 113 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
114 * copy_to_user it. 114 * copy_to_user it.
115 */ 115 */
116int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, 116int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
117 int fpsize) 117 int fpsize)
118{ 118{
119 struct _fpstate *to_fp, *from_fp; 119 struct _fpstate *to_fp;
120 struct _fpstate __user *from_fp;
120 unsigned long sigs; 121 unsigned long sigs;
121 int err; 122 int err;
122 123
@@ -131,13 +132,14 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
131 return(err); 132 return(err);
132} 133}
133 134
134int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, 135int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp,
135 struct sigcontext *from, int fpsize, unsigned long sp) 136 struct sigcontext *from, int fpsize, unsigned long sp)
136{ 137{
137 struct _fpstate *to_fp, *from_fp; 138 struct _fpstate __user *to_fp;
139 struct _fpstate *from_fp;
138 int err; 140 int err;
139 141
140 to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); 142 to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
141 from_fp = from->fpstate; 143 from_fp = from->fpstate;
142 err = copy_to_user(to, from, sizeof(*to)); 144 err = copy_to_user(to, from, sizeof(*to));
143 145
@@ -165,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
165 return(ret); 167 return(ret);
166} 168}
167 169
168static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, 170static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp,
169 struct pt_regs *from, unsigned long sp) 171 struct pt_regs *from, unsigned long sp)
170{ 172{
171 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 173 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
@@ -173,7 +175,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
173 copy_sc_to_user_skas(to, fp, from, sp))); 175 copy_sc_to_user_skas(to, fp, from, sp)));
174} 176}
175 177
176static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, 178static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
177 sigset_t *set, unsigned long sp) 179 sigset_t *set, unsigned long sp)
178{ 180{
179 int err = 0; 181 int err = 0;
@@ -188,7 +190,7 @@ static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
188 190
189struct sigframe 191struct sigframe
190{ 192{
191 char *pretcode; 193 char __user *pretcode;
192 int sig; 194 int sig;
193 struct sigcontext sc; 195 struct sigcontext sc;
194 struct _fpstate fpstate; 196 struct _fpstate fpstate;
@@ -198,10 +200,10 @@ struct sigframe
198 200
199struct rt_sigframe 201struct rt_sigframe
200{ 202{
201 char *pretcode; 203 char __user *pretcode;
202 int sig; 204 int sig;
203 struct siginfo *pinfo; 205 struct siginfo __user *pinfo;
204 void *puc; 206 void __user *puc;
205 struct siginfo info; 207 struct siginfo info;
206 struct ucontext uc; 208 struct ucontext uc;
207 struct _fpstate fpstate; 209 struct _fpstate fpstate;
@@ -213,16 +215,16 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
213 sigset_t *mask) 215 sigset_t *mask)
214{ 216{
215 struct sigframe __user *frame; 217 struct sigframe __user *frame;
216 void *restorer; 218 void __user *restorer;
217 unsigned long save_sp = PT_REGS_SP(regs); 219 unsigned long save_sp = PT_REGS_SP(regs);
218 int err = 0; 220 int err = 0;
219 221
220 stack_top &= -8UL; 222 stack_top &= -8UL;
221 frame = (struct sigframe *) stack_top - 1; 223 frame = (struct sigframe __user *) stack_top - 1;
222 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 224 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
223 return 1; 225 return 1;
224 226
225 restorer = (void *) frame->retcode; 227 restorer = frame->retcode;
226 if(ka->sa.sa_flags & SA_RESTORER) 228 if(ka->sa.sa_flags & SA_RESTORER)
227 restorer = ka->sa.sa_restorer; 229 restorer = ka->sa.sa_restorer;
228 230
@@ -278,16 +280,16 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
278 siginfo_t *info, sigset_t *mask) 280 siginfo_t *info, sigset_t *mask)
279{ 281{
280 struct rt_sigframe __user *frame; 282 struct rt_sigframe __user *frame;
281 void *restorer; 283 void __user *restorer;
282 unsigned long save_sp = PT_REGS_SP(regs); 284 unsigned long save_sp = PT_REGS_SP(regs);
283 int err = 0; 285 int err = 0;
284 286
285 stack_top &= -8UL; 287 stack_top &= -8UL;
286 frame = (struct rt_sigframe *) stack_top - 1; 288 frame = (struct rt_sigframe __user *) stack_top - 1;
287 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 289 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
288 return 1; 290 return 1;
289 291
290 restorer = (void *) frame->retcode; 292 restorer = frame->retcode;
291 if(ka->sa.sa_flags & SA_RESTORER) 293 if(ka->sa.sa_flags & SA_RESTORER)
292 restorer = ka->sa.sa_restorer; 294 restorer = ka->sa.sa_restorer;
293 295
@@ -333,7 +335,7 @@ err:
333long sys_sigreturn(struct pt_regs regs) 335long sys_sigreturn(struct pt_regs regs)
334{ 336{
335 unsigned long sp = PT_REGS_SP(&current->thread.regs); 337 unsigned long sp = PT_REGS_SP(&current->thread.regs);
336 struct sigframe __user *frame = (struct sigframe *)(sp - 8); 338 struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
337 sigset_t set; 339 sigset_t set;
338 struct sigcontext __user *sc = &frame->sc; 340 struct sigcontext __user *sc = &frame->sc;
339 unsigned long __user *oldmask = &sc->oldmask; 341 unsigned long __user *oldmask = &sc->oldmask;
@@ -365,8 +367,8 @@ long sys_sigreturn(struct pt_regs regs)
365 367
366long sys_rt_sigreturn(struct pt_regs regs) 368long sys_rt_sigreturn(struct pt_regs regs)
367{ 369{
368 unsigned long __user sp = PT_REGS_SP(&current->thread.regs); 370 unsigned long sp = PT_REGS_SP(&current->thread.regs);
369 struct rt_sigframe __user *frame = (struct rt_sigframe *) (sp - 4); 371 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4);
370 sigset_t set; 372 sigset_t set;
371 struct ucontext __user *uc = &frame->uc; 373 struct ucontext __user *uc = &frame->uc;
372 int sig_size = _NSIG_WORDS * sizeof(unsigned long); 374 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index ad75c27afe38..1ff61474b25c 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -6,8 +6,6 @@
6 6
7#define sys_vm86old sys_ni_syscall 7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall 8#define sys_vm86 sys_ni_syscall
9#define sys_set_thread_area sys_ni_syscall
10#define sys_get_thread_area sys_ni_syscall
11 9
12#define sys_stime um_stime 10#define sys_stime um_stime
13#define sys_time um_time 11#define sys_time um_time
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 83e9be820a86..749dd1bfe60f 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -61,21 +61,27 @@ long old_select(struct sel_arg_struct __user *arg)
61 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); 61 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
62} 62}
63 63
64/* The i386 version skips reading from %esi, the fourth argument. So we must do 64/*
65 * this, too. 65 * The prototype on i386 is:
66 *
67 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
68 *
69 * and the "newtls" arg. on i386 is read by copy_thread directly from the
70 * register saved on the stack.
66 */ 71 */
67long sys_clone(unsigned long clone_flags, unsigned long newsp, 72long sys_clone(unsigned long clone_flags, unsigned long newsp,
68 int __user *parent_tid, int unused, int __user *child_tid) 73 int __user *parent_tid, void *newtls, int __user *child_tid)
69{ 74{
70 long ret; 75 long ret;
71 76
72 if (!newsp) 77 if (!newsp)
73 newsp = UPT_SP(&current->thread.regs.regs); 78 newsp = UPT_SP(&current->thread.regs.regs);
79
74 current->thread.forking = 1; 80 current->thread.forking = 1;
75 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid, 81 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
76 child_tid); 82 child_tid);
77 current->thread.forking = 0; 83 current->thread.forking = 0;
78 return(ret); 84 return ret;
79} 85}
80 86
81/* 87/*
@@ -104,7 +110,7 @@ long sys_ipc (uint call, int first, int second,
104 union semun fourth; 110 union semun fourth;
105 if (!ptr) 111 if (!ptr)
106 return -EINVAL; 112 return -EINVAL;
107 if (get_user(fourth.__pad, (void **) ptr)) 113 if (get_user(fourth.__pad, (void __user * __user *) ptr))
108 return -EFAULT; 114 return -EFAULT;
109 return sys_semctl (first, second, third, fourth); 115 return sys_semctl (first, second, third, fourth);
110 } 116 }
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
new file mode 100644
index 000000000000..a3188e861cc7
--- /dev/null
+++ b/arch/um/sys-i386/tls.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
3 * Licensed under the GPL
4 */
5
6#include "linux/config.h"
7#include "linux/kernel.h"
8#include "linux/sched.h"
9#include "linux/slab.h"
10#include "linux/types.h"
11#include "asm/uaccess.h"
12#include "asm/ptrace.h"
13#include "asm/segment.h"
14#include "asm/smp.h"
15#include "asm/desc.h"
16#include "choose-mode.h"
17#include "kern.h"
18#include "kern_util.h"
19#include "mode_kern.h"
20#include "os.h"
21#include "mode.h"
22
23#ifdef CONFIG_MODE_SKAS
24#include "skas.h"
25#endif
26
27/* If needed we can detect when it's uninitialized. */
28static int host_supports_tls = -1;
29int host_gdt_entry_tls_min = -1;
30
31#ifdef CONFIG_MODE_SKAS
32int do_set_thread_area_skas(struct user_desc *info)
33{
34 int ret;
35 u32 cpu;
36
37 cpu = get_cpu();
38 ret = os_set_thread_area(info, userspace_pid[cpu]);
39 put_cpu();
40 return ret;
41}
42
43int do_get_thread_area_skas(struct user_desc *info)
44{
45 int ret;
46 u32 cpu;
47
48 cpu = get_cpu();
49 ret = os_get_thread_area(info, userspace_pid[cpu]);
50 put_cpu();
51 return ret;
52}
53#endif
54
55/*
56 * sys_get_thread_area: get a yet unused TLS descriptor index.
57 * XXX: Consider leaving one free slot for glibc usage at first place. This must
58 * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else.
59 *
60 * Also, this must be tested when compiling in SKAS mode with dinamic linking
61 * and running against NPTL.
62 */
63static int get_free_idx(struct task_struct* task)
64{
65 struct thread_struct *t = &task->thread;
66 int idx;
67
68 if (!t->arch.tls_array)
69 return GDT_ENTRY_TLS_MIN;
70
71 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
72 if (!t->arch.tls_array[idx].present)
73 return idx + GDT_ENTRY_TLS_MIN;
74 return -ESRCH;
75}
76
77static inline void clear_user_desc(struct user_desc* info)
78{
79 /* Postcondition: LDT_empty(info) returns true. */
80 memset(info, 0, sizeof(*info));
81
82 /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
83 * indeed an empty user_desc.
84 */
85 info->read_exec_only = 1;
86 info->seg_not_present = 1;
87}
88
89#define O_FORCE 1
90
91static int load_TLS(int flags, struct task_struct *to)
92{
93 int ret = 0;
94 int idx;
95
96 for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) {
97 struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
98
99 /* Actually, now if it wasn't flushed it gets cleared and
100 * flushed to the host, which will clear it.*/
101 if (!curr->present) {
102 if (!curr->flushed) {
103 clear_user_desc(&curr->tls);
104 curr->tls.entry_number = idx;
105 } else {
106 WARN_ON(!LDT_empty(&curr->tls));
107 continue;
108 }
109 }
110
111 if (!(flags & O_FORCE) && curr->flushed)
112 continue;
113
114 ret = do_set_thread_area(&curr->tls);
115 if (ret)
116 goto out;
117
118 curr->flushed = 1;
119 }
120out:
121 return ret;
122}
123
124/* Verify if we need to do a flush for the new process, i.e. if there are any
125 * present desc's, only if they haven't been flushed.
126 */
127static inline int needs_TLS_update(struct task_struct *task)
128{
129 int i;
130 int ret = 0;
131
132 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
133 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
134
135 /* Can't test curr->present, we may need to clear a descriptor
136 * which had a value. */
137 if (curr->flushed)
138 continue;
139 ret = 1;
140 break;
141 }
142 return ret;
143}
144
145/* On a newly forked process, the TLS descriptors haven't yet been flushed. So
146 * we mark them as such and the first switch_to will do the job.
147 */
148void clear_flushed_tls(struct task_struct *task)
149{
150 int i;
151
152 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
153 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
154
155 /* Still correct to do this, if it wasn't present on the host it
156 * will remain as flushed as it was. */
157 if (!curr->present)
158 continue;
159
160 curr->flushed = 0;
161 }
162}
163
164/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
165 * common host process. So this is needed in SKAS0 too.
166 *
167 * However, if each thread had a different host process (and this was discussed
168 * for SMP support) this won't be needed.
169 *
170 * And this will not need be used when (and if) we'll add support to the host
171 * SKAS patch. */
172
173int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to)
174{
175 if (!host_supports_tls)
176 return 0;
177
178 /* We have no need whatsoever to switch TLS for kernel threads; beyond
179 * that, that would also result in us calling os_set_thread_area with
180 * userspace_pid[cpu] == 0, which gives an error. */
181 if (likely(to->mm))
182 return load_TLS(O_FORCE, to);
183
184 return 0;
185}
186
187int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to)
188{
189 if (!host_supports_tls)
190 return 0;
191
192 if (needs_TLS_update(to))
193 return load_TLS(0, to);
194
195 return 0;
196}
197
198static int set_tls_entry(struct task_struct* task, struct user_desc *info,
199 int idx, int flushed)
200{
201 struct thread_struct *t = &task->thread;
202
203 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
204 return -EINVAL;
205
206 t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info;
207 t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1;
208 t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed;
209
210 return 0;
211}
212
213int arch_copy_tls(struct task_struct *new)
214{
215 struct user_desc info;
216 int idx, ret = -EFAULT;
217
218 if (copy_from_user(&info,
219 (void __user *) UPT_ESI(&new->thread.regs.regs),
220 sizeof(info)))
221 goto out;
222
223 ret = -EINVAL;
224 if (LDT_empty(&info))
225 goto out;
226
227 idx = info.entry_number;
228
229 ret = set_tls_entry(new, &info, idx, 0);
230out:
231 return ret;
232}
233
234/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */
235static int get_tls_entry(struct task_struct* task, struct user_desc *info, int idx)
236{
237 struct thread_struct *t = &task->thread;
238
239 if (!t->arch.tls_array)
240 goto clear;
241
242 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
243 return -EINVAL;
244
245 if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present)
246 goto clear;
247
248 *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls;
249
250out:
251 /* Temporary debugging check, to make sure that things have been
252 * flushed. This could be triggered if load_TLS() failed.
253 */
254 if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
255 printk(KERN_ERR "get_tls_entry: task with pid %d got here "
256 "without flushed TLS.", current->pid);
257 }
258
259 return 0;
260clear:
261 /* When the TLS entry has not been set, the values read to user in the
262 * tls_array are 0 (because it's cleared at boot, see
263 * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that.
264 */
265 clear_user_desc(info);
266 info->entry_number = idx;
267 goto out;
268}
269
270asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc)
271{
272 struct user_desc info;
273 int idx, ret;
274
275 if (!host_supports_tls)
276 return -ENOSYS;
277
278 if (copy_from_user(&info, user_desc, sizeof(info)))
279 return -EFAULT;
280
281 idx = info.entry_number;
282
283 if (idx == -1) {
284 idx = get_free_idx(current);
285 if (idx < 0)
286 return idx;
287 info.entry_number = idx;
288 /* Tell the user which slot we chose for him.*/
289 if (put_user(idx, &user_desc->entry_number))
290 return -EFAULT;
291 }
292
293 ret = CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, &info);
294 if (ret)
295 return ret;
296 return set_tls_entry(current, &info, idx, 1);
297}
298
299/*
300 * Perform set_thread_area on behalf of the traced child.
301 * Note: error handling is not done on the deferred load, and this differ from
302 * i386. However the only possible error are caused by bugs.
303 */
304int ptrace_set_thread_area(struct task_struct *child, int idx,
305 struct user_desc __user *user_desc)
306{
307 struct user_desc info;
308
309 if (!host_supports_tls)
310 return -EIO;
311
312 if (copy_from_user(&info, user_desc, sizeof(info)))
313 return -EFAULT;
314
315 return set_tls_entry(child, &info, idx, 0);
316}
317
318asmlinkage int sys_get_thread_area(struct user_desc __user *user_desc)
319{
320 struct user_desc info;
321 int idx, ret;
322
323 if (!host_supports_tls)
324 return -ENOSYS;
325
326 if (get_user(idx, &user_desc->entry_number))
327 return -EFAULT;
328
329 ret = get_tls_entry(current, &info, idx);
330 if (ret < 0)
331 goto out;
332
333 if (copy_to_user(user_desc, &info, sizeof(info)))
334 ret = -EFAULT;
335
336out:
337 return ret;
338}
339
340/*
341 * Perform get_thread_area on behalf of the traced child.
342 */
343int ptrace_get_thread_area(struct task_struct *child, int idx,
344 struct user_desc __user *user_desc)
345{
346 struct user_desc info;
347 int ret;
348
349 if (!host_supports_tls)
350 return -EIO;
351
352 ret = get_tls_entry(child, &info, idx);
353 if (ret < 0)
354 goto out;
355
356 if (copy_to_user(user_desc, &info, sizeof(info)))
357 ret = -EFAULT;
358out:
359 return ret;
360}
361
362
363/* XXX: This part is probably common to i386 and x86-64. Don't create a common
364 * file for now, do that when implementing x86-64 support.*/
365static int __init __setup_host_supports_tls(void) {
366 check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
367 if (host_supports_tls) {
368 printk(KERN_INFO "Host TLS support detected\n");
369 printk(KERN_INFO "Detected host type: ");
370 switch (host_gdt_entry_tls_min) {
371 case GDT_ENTRY_TLS_MIN_I386:
372 printk("i386\n");
373 break;
374 case GDT_ENTRY_TLS_MIN_X86_64:
375 printk("x86_64\n");
376 break;
377 }
378 } else
379 printk(KERN_ERR " Host TLS support NOT detected! "
380 "TLS support inside UML will not work\n");
381 return 1;
382}
383
384__initcall(__setup_host_supports_tls);
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index a351091fbd99..b5fc22babddf 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -4,31 +4,23 @@
4# Licensed under the GPL 4# Licensed under the GPL
5# 5#
6 6
7#XXX: why into lib-y? 7obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ 8 sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o ksyms.o \
9 ptrace.o ptrace_user.o sigcontext.o signal.o syscalls.o \ 9 tls.o
10 syscall_table.o sysrq.o thunk.o
11lib-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
12 10
13obj-y := ksyms.o 11obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
14obj-$(CONFIG_MODULES) += module.o um_module.o 12obj-$(CONFIG_MODULES) += um_module.o
15 13
16USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o 14subarch-obj-y = lib/bitops.o lib/csum-partial.o lib/memcpy.o lib/thunk.o
15subarch-obj-$(CONFIG_MODULES) += kernel/module.o
17 16
18SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \ 17ldt-y = ../sys-i386/ldt.o
19 thunk.S module.c
20 18
21include arch/um/scripts/Makefile.rules 19USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o
22 20
23bitops.c-dir = lib 21include arch/um/scripts/Makefile.rules
24csum-copy.S-dir = lib
25csum-partial.c-dir = lib
26csum-wrappers.c-dir = lib
27ldt.c-dir = /arch/um/sys-i386
28memcpy.S-dir = lib
29thunk.S-dir = lib
30module.c-dir = kernel
31 22
32$(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS)) 23extra-$(CONFIG_MODE_TT) += unmap.o
33 24
34include arch/um/scripts/Makefile.unmap 25$(obj)/stub_segv.o $(obj)/unmap.o: \
26 _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c
new file mode 100644
index 000000000000..ce1bf1b81c43
--- /dev/null
+++ b/arch/um/sys-x86_64/tls.c
@@ -0,0 +1,14 @@
1#include "linux/sched.h"
2
3void debug_arch_force_load_TLS(void)
4{
5}
6
7void clear_flushed_tls(struct task_struct *task)
8{
9}
10
11int arch_copy_tls(struct task_struct *t)
12{
13 return 0;
14}
diff --git a/arch/x86_64/ia32/vsyscall-sigreturn.S b/arch/x86_64/ia32/vsyscall-sigreturn.S
index d90321fe9bba..1384367cdbe1 100644
--- a/arch/x86_64/ia32/vsyscall-sigreturn.S
+++ b/arch/x86_64/ia32/vsyscall-sigreturn.S
@@ -32,9 +32,28 @@ __kernel_rt_sigreturn:
32 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn 32 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
33 33
34 .section .eh_frame,"a",@progbits 34 .section .eh_frame,"a",@progbits
35.LSTARTFRAMES:
36 .long .LENDCIES-.LSTARTCIES
37.LSTARTCIES:
38 .long 0 /* CIE ID */
39 .byte 1 /* Version number */
40 .string "zRS" /* NUL-terminated augmentation string */
41 .uleb128 1 /* Code alignment factor */
42 .sleb128 -4 /* Data alignment factor */
43 .byte 8 /* Return address register column */
44 .uleb128 1 /* Augmentation value length */
45 .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
46 .byte 0x0c /* DW_CFA_def_cfa */
47 .uleb128 4
48 .uleb128 4
49 .byte 0x88 /* DW_CFA_offset, column 0x8 */
50 .uleb128 1
51 .align 4
52.LENDCIES:
53
35 .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ 54 .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */
36.LSTARTFDE2: 55.LSTARTFDE2:
37 .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ 56 .long .LSTARTFDE2-.LSTARTFRAMES /* CIE pointer */
38 /* HACK: The dwarf2 unwind routines will subtract 1 from the 57 /* HACK: The dwarf2 unwind routines will subtract 1 from the
39 return address to get an address in the middle of the 58 return address to get an address in the middle of the
40 presumed call instruction. Since we didn't get here via 59 presumed call instruction. Since we didn't get here via
@@ -97,7 +116,7 @@ __kernel_rt_sigreturn:
97 116
98 .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ 117 .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */
99.LSTARTFDE3: 118.LSTARTFDE3:
100 .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ 119 .long .LSTARTFDE3-.LSTARTFRAMES /* CIE pointer */
101 /* HACK: See above wrt unwind library assumptions. */ 120 /* HACK: See above wrt unwind library assumptions. */
102 .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ 121 .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
103 .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 122 .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index d54620147e8e..100a30c40044 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -615,7 +615,7 @@ static int __init apic_set_verbosity(char *str)
615 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 615 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
616 " use apic=verbose or apic=debug", str); 616 " use apic=verbose or apic=debug", str);
617 617
618 return 0; 618 return 1;
619} 619}
620 620
621__setup("apic=", apic_set_verbosity); 621__setup("apic=", apic_set_verbosity);
@@ -1137,35 +1137,35 @@ int __init APIC_init_uniprocessor (void)
1137static __init int setup_disableapic(char *str) 1137static __init int setup_disableapic(char *str)
1138{ 1138{
1139 disable_apic = 1; 1139 disable_apic = 1;
1140 return 0; 1140 return 1;
1141} 1141}
1142 1142
1143static __init int setup_nolapic(char *str) 1143static __init int setup_nolapic(char *str)
1144{ 1144{
1145 disable_apic = 1; 1145 disable_apic = 1;
1146 return 0; 1146 return 1;
1147} 1147}
1148 1148
1149static __init int setup_noapictimer(char *str) 1149static __init int setup_noapictimer(char *str)
1150{ 1150{
1151 if (str[0] != ' ' && str[0] != 0) 1151 if (str[0] != ' ' && str[0] != 0)
1152 return -1; 1152 return 0;
1153 disable_apic_timer = 1; 1153 disable_apic_timer = 1;
1154 return 0; 1154 return 1;
1155} 1155}
1156 1156
1157static __init int setup_apicmaintimer(char *str) 1157static __init int setup_apicmaintimer(char *str)
1158{ 1158{
1159 apic_runs_main_timer = 1; 1159 apic_runs_main_timer = 1;
1160 nohpet = 1; 1160 nohpet = 1;
1161 return 0; 1161 return 1;
1162} 1162}
1163__setup("apicmaintimer", setup_apicmaintimer); 1163__setup("apicmaintimer", setup_apicmaintimer);
1164 1164
1165static __init int setup_noapicmaintimer(char *str) 1165static __init int setup_noapicmaintimer(char *str)
1166{ 1166{
1167 apic_runs_main_timer = -1; 1167 apic_runs_main_timer = -1;
1168 return 0; 1168 return 1;
1169} 1169}
1170__setup("noapicmaintimer", setup_noapicmaintimer); 1170__setup("noapicmaintimer", setup_noapicmaintimer);
1171 1171
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 13af920b6594..b93ef5b51980 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -221,7 +221,7 @@ int __init setup_early_printk(char *opt)
221 char buf[256]; 221 char buf[256];
222 222
223 if (early_console_initialized) 223 if (early_console_initialized)
224 return -1; 224 return 1;
225 225
226 strlcpy(buf,opt,sizeof(buf)); 226 strlcpy(buf,opt,sizeof(buf));
227 space = strchr(buf, ' '); 227 space = strchr(buf, ' ');
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 04282ef9fbd4..10b3e348fc99 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -501,7 +501,7 @@ static struct miscdevice mce_log_device = {
501static int __init mcheck_disable(char *str) 501static int __init mcheck_disable(char *str)
502{ 502{
503 mce_dont_init = 1; 503 mce_dont_init = 1;
504 return 0; 504 return 1;
505} 505}
506 506
507/* mce=off disables machine check. Note you can reenable it later 507/* mce=off disables machine check. Note you can reenable it later
@@ -521,7 +521,7 @@ static int __init mcheck_enable(char *str)
521 get_option(&str, &tolerant); 521 get_option(&str, &tolerant);
522 else 522 else
523 printk("mce= argument %s ignored. Please use /sys", str); 523 printk("mce= argument %s ignored. Please use /sys", str);
524 return 0; 524 return 1;
525} 525}
526 526
527__setup("nomce", mcheck_disable); 527__setup("nomce", mcheck_disable);
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c
index ee5ee4891f3d..b0444a415bd6 100644
--- a/arch/x86_64/kernel/pmtimer.c
+++ b/arch/x86_64/kernel/pmtimer.c
@@ -121,7 +121,7 @@ unsigned int do_gettimeoffset_pm(void)
121static int __init nopmtimer_setup(char *s) 121static int __init nopmtimer_setup(char *s)
122{ 122{
123 pmtmr_ioport = 0; 123 pmtmr_ioport = 0;
124 return 0; 124 return 1;
125} 125}
126 126
127__setup("nopmtimer", nopmtimer_setup); 127__setup("nopmtimer", nopmtimer_setup);
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index d1f3e9272c05..0856ad444f90 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -540,7 +540,7 @@ void __init alternative_instructions(void)
540static int __init noreplacement_setup(char *s) 540static int __init noreplacement_setup(char *s)
541{ 541{
542 no_replacement = 1; 542 no_replacement = 1;
543 return 0; 543 return 1;
544} 544}
545 545
546__setup("noreplacement", noreplacement_setup); 546__setup("noreplacement", noreplacement_setup);
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index eabdb63fec31..8a691fa6d393 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -55,7 +55,7 @@ int __init nonx_setup(char *str)
55 do_not_nx = 1; 55 do_not_nx = 1;
56 __supported_pte_mask &= ~_PAGE_NX; 56 __supported_pte_mask &= ~_PAGE_NX;
57 } 57 }
58 return 0; 58 return 1;
59} 59}
60__setup("noexec=", nonx_setup); /* parsed early actually */ 60__setup("noexec=", nonx_setup); /* parsed early actually */
61 61
@@ -74,7 +74,7 @@ static int __init nonx32_setup(char *str)
74 force_personality32 &= ~READ_IMPLIES_EXEC; 74 force_personality32 &= ~READ_IMPLIES_EXEC;
75 else if (!strcmp(str, "off")) 75 else if (!strcmp(str, "off"))
76 force_personality32 |= READ_IMPLIES_EXEC; 76 force_personality32 |= READ_IMPLIES_EXEC;
77 return 0; 77 return 1;
78} 78}
79__setup("noexec32=", nonx32_setup); 79__setup("noexec32=", nonx32_setup);
80 80
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index ea48fa638070..71a7222cf9ce 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -353,7 +353,7 @@ static void __cpuinit tsc_sync_wait(void)
353static __init int notscsync_setup(char *s) 353static __init int notscsync_setup(char *s)
354{ 354{
355 notscsync = 1; 355 notscsync = 1;
356 return 0; 356 return 1;
357} 357}
358__setup("notscsync", notscsync_setup); 358__setup("notscsync", notscsync_setup);
359 359
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 473b514b66e4..ef8bc46dc140 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -1306,7 +1306,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1306static int __init nohpet_setup(char *s) 1306static int __init nohpet_setup(char *s)
1307{ 1307{
1308 nohpet = 1; 1308 nohpet = 1;
1309 return 0; 1309 return 1;
1310} 1310}
1311 1311
1312__setup("nohpet", nohpet_setup); 1312__setup("nohpet", nohpet_setup);
@@ -1314,7 +1314,7 @@ __setup("nohpet", nohpet_setup);
1314int __init notsc_setup(char *s) 1314int __init notsc_setup(char *s)
1315{ 1315{
1316 notsc = 1; 1316 notsc = 1;
1317 return 0; 1317 return 1;
1318} 1318}
1319 1319
1320__setup("notsc", notsc_setup); 1320__setup("notsc", notsc_setup);
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index edaa9fe654dc..6bda322d3caf 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -973,14 +973,14 @@ void __init trap_init(void)
973static int __init oops_dummy(char *s) 973static int __init oops_dummy(char *s)
974{ 974{
975 panic_on_oops = 1; 975 panic_on_oops = 1;
976 return -1; 976 return 1;
977} 977}
978__setup("oops=", oops_dummy); 978__setup("oops=", oops_dummy);
979 979
980static int __init kstack_setup(char *s) 980static int __init kstack_setup(char *s)
981{ 981{
982 kstack_depth_to_print = simple_strtoul(s,NULL,0); 982 kstack_depth_to_print = simple_strtoul(s,NULL,0);
983 return 0; 983 return 1;
984} 984}
985__setup("kstack=", kstack_setup); 985__setup("kstack=", kstack_setup);
986 986
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index d96a9348e5a2..d78f46056bda 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -102,8 +102,6 @@ EXPORT_SYMBOL(cpu_callout_map);
102EXPORT_SYMBOL(screen_info); 102EXPORT_SYMBOL(screen_info);
103#endif 103#endif
104 104
105EXPORT_SYMBOL(get_wchan);
106
107EXPORT_SYMBOL(rtc_lock); 105EXPORT_SYMBOL(rtc_lock);
108 106
109EXPORT_SYMBOL_GPL(set_nmi_callback); 107EXPORT_SYMBOL_GPL(set_nmi_callback);
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 316c53de47bd..55250593d8c9 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -623,6 +623,6 @@ void vmalloc_sync_all(void)
623static int __init enable_pagefaulttrace(char *str) 623static int __init enable_pagefaulttrace(char *str)
624{ 624{
625 page_fault_trace = 1; 625 page_fault_trace = 1;
626 return 0; 626 return 1;
627} 627}
628__setup("pagefaulttrace", enable_pagefaulttrace); 628__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index efae56a51475..152b9370789b 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -113,8 +113,6 @@ EXPORT_SYMBOL(__xtensa_copy_user);
113// FIXME EXPORT_SYMBOL(screen_info); 113// FIXME EXPORT_SYMBOL(screen_info);
114#endif 114#endif
115 115
116EXPORT_SYMBOL(get_wchan);
117
118EXPORT_SYMBOL(outsb); 116EXPORT_SYMBOL(outsb);
119EXPORT_SYMBOL(outsw); 117EXPORT_SYMBOL(outsw);
120EXPORT_SYMBOL(outsl); 118EXPORT_SYMBOL(outsl);
diff --git a/block/Kconfig b/block/Kconfig
index 5536839886ff..b6f5f0a79655 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -27,10 +27,10 @@ config BLK_DEV_IO_TRACE
27config LSF 27config LSF
28 bool "Support for Large Single Files" 28 bool "Support for Large Single Files"
29 depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML 29 depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
30 default n
31 help 30 help
32 When CONFIG_LBD is disabled, say Y here if you want to 31 Say Y here if you want to be able to handle very large files (bigger
33 handle large file(bigger than 2TB), otherwise say N. 32 than 2TB), otherwise say N.
34 When CONFIG_LBD is enabled, Y is set automatically. 33
34 If unsure, say Y.
35 35
36source block/Kconfig.iosched 36source block/Kconfig.iosched
diff --git a/block/elevator.c b/block/elevator.c
index 56c2ed06a9e2..0d6be03d929e 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -145,7 +145,7 @@ static int __init elevator_setup(char *str)
145 strcpy(chosen_elevator, "anticipatory"); 145 strcpy(chosen_elevator, "anticipatory");
146 else 146 else
147 strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1); 147 strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
148 return 0; 148 return 1;
149} 149}
150 150
151__setup("elevator=", elevator_setup); 151__setup("elevator=", elevator_setup);
diff --git a/block/genhd.c b/block/genhd.c
index db4c60c802d6..5a8d3bf02f17 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,8 +17,6 @@
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19 19
20#define MAX_PROBE_HASH 255 /* random */
21
22static struct subsystem block_subsys; 20static struct subsystem block_subsys;
23 21
24static DEFINE_MUTEX(block_subsys_lock); 22static DEFINE_MUTEX(block_subsys_lock);
@@ -31,108 +29,29 @@ static struct blk_major_name {
31 struct blk_major_name *next; 29 struct blk_major_name *next;
32 int major; 30 int major;
33 char name[16]; 31 char name[16];
34} *major_names[MAX_PROBE_HASH]; 32} *major_names[BLKDEV_MAJOR_HASH_SIZE];
35 33
36/* index in the above - for now: assume no multimajor ranges */ 34/* index in the above - for now: assume no multimajor ranges */
37static inline int major_to_index(int major) 35static inline int major_to_index(int major)
38{ 36{
39 return major % MAX_PROBE_HASH; 37 return major % BLKDEV_MAJOR_HASH_SIZE;
40}
41
42struct blkdev_info {
43 int index;
44 struct blk_major_name *bd;
45};
46
47/*
48 * iterate over a list of blkdev_info structures. allows
49 * the major_names array to be iterated over from outside this file
50 * must be called with the block_subsys_lock held
51 */
52void *get_next_blkdev(void *dev)
53{
54 struct blkdev_info *info;
55
56 if (dev == NULL) {
57 info = kmalloc(sizeof(*info), GFP_KERNEL);
58 if (!info)
59 goto out;
60 info->index=0;
61 info->bd = major_names[info->index];
62 if (info->bd)
63 goto out;
64 } else {
65 info = dev;
66 }
67
68 while (info->index < ARRAY_SIZE(major_names)) {
69 if (info->bd)
70 info->bd = info->bd->next;
71 if (info->bd)
72 goto out;
73 /*
74 * No devices on this chain, move to the next
75 */
76 info->index++;
77 info->bd = (info->index < ARRAY_SIZE(major_names)) ?
78 major_names[info->index] : NULL;
79 if (info->bd)
80 goto out;
81 }
82
83out:
84 return info;
85}
86
87void *acquire_blkdev_list(void)
88{
89 mutex_lock(&block_subsys_lock);
90 return get_next_blkdev(NULL);
91}
92
93void release_blkdev_list(void *dev)
94{
95 mutex_unlock(&block_subsys_lock);
96 kfree(dev);
97} 38}
98 39
40#ifdef CONFIG_PROC_FS
99 41
100/* 42void blkdev_show(struct seq_file *f, off_t offset)
101 * Count the number of records in the blkdev_list.
102 * must be called with the block_subsys_lock held
103 */
104int count_blkdev_list(void)
105{ 43{
106 struct blk_major_name *n; 44 struct blk_major_name *dp;
107 int i, count;
108 45
109 count = 0; 46 if (offset < BLKDEV_MAJOR_HASH_SIZE) {
110 47 mutex_lock(&block_subsys_lock);
111 for (i = 0; i < ARRAY_SIZE(major_names); i++) { 48 for (dp = major_names[offset]; dp; dp = dp->next)
112 for (n = major_names[i]; n; n = n->next) 49 seq_printf(f, "%3d %s\n", dp->major, dp->name);
113 count++; 50 mutex_unlock(&block_subsys_lock);
114 } 51 }
115
116 return count;
117}
118
119/*
120 * extract the major and name values from a blkdev_info struct
121 * passed in as a void to *dev. Must be called with
122 * block_subsys_lock held
123 */
124int get_blkdev_info(void *dev, int *major, char **name)
125{
126 struct blkdev_info *info = dev;
127
128 if (info->bd == NULL)
129 return 1;
130
131 *major = info->bd->major;
132 *name = info->bd->name;
133 return 0;
134} 52}
135 53
54#endif /* CONFIG_PROC_FS */
136 55
137int register_blkdev(unsigned int major, const char *name) 56int register_blkdev(unsigned int major, const char *name)
138{ 57{
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 9f5c0da57c90..5c91d6afb117 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -64,6 +64,8 @@ source "drivers/usb/Kconfig"
64 64
65source "drivers/mmc/Kconfig" 65source "drivers/mmc/Kconfig"
66 66
67source "drivers/leds/Kconfig"
68
67source "drivers/infiniband/Kconfig" 69source "drivers/infiniband/Kconfig"
68 70
69source "drivers/sn/Kconfig" 71source "drivers/sn/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 424955274e60..d6e8ffbd8132 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_MCA) += mca/
69obj-$(CONFIG_EISA) += eisa/ 69obj-$(CONFIG_EISA) += eisa/
70obj-$(CONFIG_CPU_FREQ) += cpufreq/ 70obj-$(CONFIG_CPU_FREQ) += cpufreq/
71obj-$(CONFIG_MMC) += mmc/ 71obj-$(CONFIG_MMC) += mmc/
72obj-$(CONFIG_NEW_LEDS) += leds/
72obj-$(CONFIG_INFINIBAND) += infiniband/ 73obj-$(CONFIG_INFINIBAND) += infiniband/
73obj-$(CONFIG_SGI_SN) += sn/ 74obj-$(CONFIG_SGI_SN) += sn/
74obj-y += firmware/ 75obj-y += firmware/
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 79b09d76c180..eee0864ba300 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1572,7 +1572,7 @@ static void __exit acpi_ec_exit(void)
1572static int __init acpi_fake_ecdt_setup(char *str) 1572static int __init acpi_fake_ecdt_setup(char *str)
1573{ 1573{
1574 acpi_fake_ecdt_enabled = 1; 1574 acpi_fake_ecdt_enabled = 1;
1575 return 0; 1575 return 1;
1576} 1576}
1577 1577
1578__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); 1578__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
@@ -1591,7 +1591,7 @@ static int __init acpi_ec_set_intr_mode(char *str)
1591 acpi_ec_driver.ops.add = acpi_ec_poll_add; 1591 acpi_ec_driver.ops.add = acpi_ec_poll_add;
1592 } 1592 }
1593 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); 1593 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
1594 return 0; 1594 return 1;
1595} 1595}
1596 1596
1597__setup("ec_intr=", acpi_ec_set_intr_mode); 1597__setup("ec_intr=", acpi_ec_set_intr_mode);
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index b6e290956214..2a8af685926f 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1850,6 +1850,7 @@ static int __init amiga_floppy_setup (char *str)
1850 return 0; 1850 return 0;
1851 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n); 1851 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n);
1852 fd_def_df0 = n; 1852 fd_def_df0 = n;
1853 return 1;
1853} 1854}
1854 1855
1855__setup("floppy=", amiga_floppy_setup); 1856__setup("floppy=", amiga_floppy_setup);
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 932feedda262..e1c95374984c 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -42,7 +42,7 @@
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/devfs_fs_kernel.h> 43#include <linux/devfs_fs_kernel.h>
44#include <linux/ipmi.h> 44#include <linux/ipmi.h>
45#include <asm/semaphore.h> 45#include <linux/mutex.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include <linux/compat.h> 48#include <linux/compat.h>
@@ -55,7 +55,7 @@ struct ipmi_file_private
55 struct file *file; 55 struct file *file;
56 struct fasync_struct *fasync_queue; 56 struct fasync_struct *fasync_queue;
57 wait_queue_head_t wait; 57 wait_queue_head_t wait;
58 struct semaphore recv_sem; 58 struct mutex recv_mutex;
59 int default_retries; 59 int default_retries;
60 unsigned int default_retry_time_ms; 60 unsigned int default_retry_time_ms;
61}; 61};
@@ -141,7 +141,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
141 INIT_LIST_HEAD(&(priv->recv_msgs)); 141 INIT_LIST_HEAD(&(priv->recv_msgs));
142 init_waitqueue_head(&priv->wait); 142 init_waitqueue_head(&priv->wait);
143 priv->fasync_queue = NULL; 143 priv->fasync_queue = NULL;
144 sema_init(&(priv->recv_sem), 1); 144 mutex_init(&priv->recv_mutex);
145 145
146 /* Use the low-level defaults. */ 146 /* Use the low-level defaults. */
147 priv->default_retries = -1; 147 priv->default_retries = -1;
@@ -285,15 +285,15 @@ static int ipmi_ioctl(struct inode *inode,
285 break; 285 break;
286 } 286 }
287 287
288 /* We claim a semaphore because we don't want two 288 /* We claim a mutex because we don't want two
289 users getting something from the queue at a time. 289 users getting something from the queue at a time.
290 Since we have to release the spinlock before we can 290 Since we have to release the spinlock before we can
291 copy the data to the user, it's possible another 291 copy the data to the user, it's possible another
292 user will grab something from the queue, too. Then 292 user will grab something from the queue, too. Then
293 the messages might get out of order if something 293 the messages might get out of order if something
294 fails and the message gets put back onto the 294 fails and the message gets put back onto the
295 queue. This semaphore prevents that problem. */ 295 queue. This mutex prevents that problem. */
296 down(&(priv->recv_sem)); 296 mutex_lock(&priv->recv_mutex);
297 297
298 /* Grab the message off the list. */ 298 /* Grab the message off the list. */
299 spin_lock_irqsave(&(priv->recv_msg_lock), flags); 299 spin_lock_irqsave(&(priv->recv_msg_lock), flags);
@@ -352,7 +352,7 @@ static int ipmi_ioctl(struct inode *inode,
352 goto recv_putback_on_err; 352 goto recv_putback_on_err;
353 } 353 }
354 354
355 up(&(priv->recv_sem)); 355 mutex_unlock(&priv->recv_mutex);
356 ipmi_free_recv_msg(msg); 356 ipmi_free_recv_msg(msg);
357 break; 357 break;
358 358
@@ -362,11 +362,11 @@ static int ipmi_ioctl(struct inode *inode,
362 spin_lock_irqsave(&(priv->recv_msg_lock), flags); 362 spin_lock_irqsave(&(priv->recv_msg_lock), flags);
363 list_add(entry, &(priv->recv_msgs)); 363 list_add(entry, &(priv->recv_msgs));
364 spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); 364 spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
365 up(&(priv->recv_sem)); 365 mutex_unlock(&priv->recv_mutex);
366 break; 366 break;
367 367
368 recv_err: 368 recv_err:
369 up(&(priv->recv_sem)); 369 mutex_unlock(&priv->recv_mutex);
370 break; 370 break;
371 } 371 }
372 372
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index da1554194d3d..2062675f9e99 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -227,7 +227,7 @@ static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
227static inline int check_obf(struct si_sm_data *kcs, unsigned char status, 227static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
228 long time) 228 long time)
229{ 229{
230 if (! GET_STATUS_OBF(status)) { 230 if (!GET_STATUS_OBF(status)) {
231 kcs->obf_timeout -= time; 231 kcs->obf_timeout -= time;
232 if (kcs->obf_timeout < 0) { 232 if (kcs->obf_timeout < 0) {
233 start_error_recovery(kcs, "OBF not ready in time"); 233 start_error_recovery(kcs, "OBF not ready in time");
@@ -407,7 +407,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
407 } 407 }
408 408
409 if (state == KCS_READ_STATE) { 409 if (state == KCS_READ_STATE) {
410 if (! check_obf(kcs, status, time)) 410 if (!check_obf(kcs, status, time))
411 return SI_SM_CALL_WITH_DELAY; 411 return SI_SM_CALL_WITH_DELAY;
412 read_next_byte(kcs); 412 read_next_byte(kcs);
413 } else { 413 } else {
@@ -447,7 +447,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
447 "Not in read state for error2"); 447 "Not in read state for error2");
448 break; 448 break;
449 } 449 }
450 if (! check_obf(kcs, status, time)) 450 if (!check_obf(kcs, status, time))
451 return SI_SM_CALL_WITH_DELAY; 451 return SI_SM_CALL_WITH_DELAY;
452 452
453 clear_obf(kcs, status); 453 clear_obf(kcs, status);
@@ -462,7 +462,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
462 break; 462 break;
463 } 463 }
464 464
465 if (! check_obf(kcs, status, time)) 465 if (!check_obf(kcs, status, time))
466 return SI_SM_CALL_WITH_DELAY; 466 return SI_SM_CALL_WITH_DELAY;
467 467
468 clear_obf(kcs, status); 468 clear_obf(kcs, status);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 40eb005b9d77..0ded046d5aa8 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -38,6 +38,7 @@
38#include <linux/sched.h> 38#include <linux/sched.h>
39#include <linux/poll.h> 39#include <linux/poll.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/mutex.h>
41#include <linux/slab.h> 42#include <linux/slab.h>
42#include <linux/ipmi.h> 43#include <linux/ipmi.h>
43#include <linux/ipmi_smi.h> 44#include <linux/ipmi_smi.h>
@@ -234,7 +235,7 @@ struct ipmi_smi
234 235
235 /* The list of command receivers that are registered for commands 236 /* The list of command receivers that are registered for commands
236 on this interface. */ 237 on this interface. */
237 struct semaphore cmd_rcvrs_lock; 238 struct mutex cmd_rcvrs_mutex;
238 struct list_head cmd_rcvrs; 239 struct list_head cmd_rcvrs;
239 240
240 /* Events that were queues because no one was there to receive 241 /* Events that were queues because no one was there to receive
@@ -387,10 +388,10 @@ static void clean_up_interface_data(ipmi_smi_t intf)
387 388
388 /* Wholesale remove all the entries from the list in the 389 /* Wholesale remove all the entries from the list in the
389 * interface and wait for RCU to know that none are in use. */ 390 * interface and wait for RCU to know that none are in use. */
390 down(&intf->cmd_rcvrs_lock); 391 mutex_lock(&intf->cmd_rcvrs_mutex);
391 list_add_rcu(&list, &intf->cmd_rcvrs); 392 list_add_rcu(&list, &intf->cmd_rcvrs);
392 list_del_rcu(&intf->cmd_rcvrs); 393 list_del_rcu(&intf->cmd_rcvrs);
393 up(&intf->cmd_rcvrs_lock); 394 mutex_unlock(&intf->cmd_rcvrs_mutex);
394 synchronize_rcu(); 395 synchronize_rcu();
395 396
396 list_for_each_entry_safe(rcvr, rcvr2, &list, link) 397 list_for_each_entry_safe(rcvr, rcvr2, &list, link)
@@ -557,7 +558,7 @@ unsigned int ipmi_addr_length(int addr_type)
557 558
558static void deliver_response(struct ipmi_recv_msg *msg) 559static void deliver_response(struct ipmi_recv_msg *msg)
559{ 560{
560 if (! msg->user) { 561 if (!msg->user) {
561 ipmi_smi_t intf = msg->user_msg_data; 562 ipmi_smi_t intf = msg->user_msg_data;
562 unsigned long flags; 563 unsigned long flags;
563 564
@@ -598,11 +599,11 @@ static int intf_next_seq(ipmi_smi_t intf,
598 (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; 599 (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq;
599 i = (i+1)%IPMI_IPMB_NUM_SEQ) 600 i = (i+1)%IPMI_IPMB_NUM_SEQ)
600 { 601 {
601 if (! intf->seq_table[i].inuse) 602 if (!intf->seq_table[i].inuse)
602 break; 603 break;
603 } 604 }
604 605
605 if (! intf->seq_table[i].inuse) { 606 if (!intf->seq_table[i].inuse) {
606 intf->seq_table[i].recv_msg = recv_msg; 607 intf->seq_table[i].recv_msg = recv_msg;
607 608
608 /* Start with the maximum timeout, when the send response 609 /* Start with the maximum timeout, when the send response
@@ -763,7 +764,7 @@ int ipmi_create_user(unsigned int if_num,
763 } 764 }
764 765
765 new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); 766 new_user = kmalloc(sizeof(*new_user), GFP_KERNEL);
766 if (! new_user) 767 if (!new_user)
767 return -ENOMEM; 768 return -ENOMEM;
768 769
769 spin_lock_irqsave(&interfaces_lock, flags); 770 spin_lock_irqsave(&interfaces_lock, flags);
@@ -819,14 +820,13 @@ static void free_user(struct kref *ref)
819 820
820int ipmi_destroy_user(ipmi_user_t user) 821int ipmi_destroy_user(ipmi_user_t user)
821{ 822{
822 int rv = -ENODEV;
823 ipmi_smi_t intf = user->intf; 823 ipmi_smi_t intf = user->intf;
824 int i; 824 int i;
825 unsigned long flags; 825 unsigned long flags;
826 struct cmd_rcvr *rcvr; 826 struct cmd_rcvr *rcvr;
827 struct cmd_rcvr *rcvrs = NULL; 827 struct cmd_rcvr *rcvrs = NULL;
828 828
829 user->valid = 1; 829 user->valid = 0;
830 830
831 /* Remove the user from the interface's sequence table. */ 831 /* Remove the user from the interface's sequence table. */
832 spin_lock_irqsave(&intf->seq_lock, flags); 832 spin_lock_irqsave(&intf->seq_lock, flags);
@@ -847,7 +847,7 @@ int ipmi_destroy_user(ipmi_user_t user)
847 * since other things may be using it till we do 847 * since other things may be using it till we do
848 * synchronize_rcu()) then free everything in that list. 848 * synchronize_rcu()) then free everything in that list.
849 */ 849 */
850 down(&intf->cmd_rcvrs_lock); 850 mutex_lock(&intf->cmd_rcvrs_mutex);
851 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { 851 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
852 if (rcvr->user == user) { 852 if (rcvr->user == user) {
853 list_del_rcu(&rcvr->link); 853 list_del_rcu(&rcvr->link);
@@ -855,7 +855,7 @@ int ipmi_destroy_user(ipmi_user_t user)
855 rcvrs = rcvr; 855 rcvrs = rcvr;
856 } 856 }
857 } 857 }
858 up(&intf->cmd_rcvrs_lock); 858 mutex_unlock(&intf->cmd_rcvrs_mutex);
859 synchronize_rcu(); 859 synchronize_rcu();
860 while (rcvrs) { 860 while (rcvrs) {
861 rcvr = rcvrs; 861 rcvr = rcvrs;
@@ -871,7 +871,7 @@ int ipmi_destroy_user(ipmi_user_t user)
871 871
872 kref_put(&user->refcount, free_user); 872 kref_put(&user->refcount, free_user);
873 873
874 return rv; 874 return 0;
875} 875}
876 876
877void ipmi_get_version(ipmi_user_t user, 877void ipmi_get_version(ipmi_user_t user,
@@ -936,7 +936,8 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
936 936
937 if (val) { 937 if (val) {
938 /* Deliver any queued events. */ 938 /* Deliver any queued events. */
939 list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) { 939 list_for_each_entry_safe(msg, msg2, &intf->waiting_events,
940 link) {
940 list_del(&msg->link); 941 list_del(&msg->link);
941 list_add_tail(&msg->link, &msgs); 942 list_add_tail(&msg->link, &msgs);
942 } 943 }
@@ -978,13 +979,13 @@ int ipmi_register_for_cmd(ipmi_user_t user,
978 979
979 980
980 rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); 981 rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
981 if (! rcvr) 982 if (!rcvr)
982 return -ENOMEM; 983 return -ENOMEM;
983 rcvr->cmd = cmd; 984 rcvr->cmd = cmd;
984 rcvr->netfn = netfn; 985 rcvr->netfn = netfn;
985 rcvr->user = user; 986 rcvr->user = user;
986 987
987 down(&intf->cmd_rcvrs_lock); 988 mutex_lock(&intf->cmd_rcvrs_mutex);
988 /* Make sure the command/netfn is not already registered. */ 989 /* Make sure the command/netfn is not already registered. */
989 entry = find_cmd_rcvr(intf, netfn, cmd); 990 entry = find_cmd_rcvr(intf, netfn, cmd);
990 if (entry) { 991 if (entry) {
@@ -995,7 +996,7 @@ int ipmi_register_for_cmd(ipmi_user_t user,
995 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); 996 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
996 997
997 out_unlock: 998 out_unlock:
998 up(&intf->cmd_rcvrs_lock); 999 mutex_unlock(&intf->cmd_rcvrs_mutex);
999 if (rv) 1000 if (rv)
1000 kfree(rcvr); 1001 kfree(rcvr);
1001 1002
@@ -1009,17 +1010,17 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
1009 ipmi_smi_t intf = user->intf; 1010 ipmi_smi_t intf = user->intf;
1010 struct cmd_rcvr *rcvr; 1011 struct cmd_rcvr *rcvr;
1011 1012
1012 down(&intf->cmd_rcvrs_lock); 1013 mutex_lock(&intf->cmd_rcvrs_mutex);
1013 /* Make sure the command/netfn is not already registered. */ 1014 /* Make sure the command/netfn is not already registered. */
1014 rcvr = find_cmd_rcvr(intf, netfn, cmd); 1015 rcvr = find_cmd_rcvr(intf, netfn, cmd);
1015 if ((rcvr) && (rcvr->user == user)) { 1016 if ((rcvr) && (rcvr->user == user)) {
1016 list_del_rcu(&rcvr->link); 1017 list_del_rcu(&rcvr->link);
1017 up(&intf->cmd_rcvrs_lock); 1018 mutex_unlock(&intf->cmd_rcvrs_mutex);
1018 synchronize_rcu(); 1019 synchronize_rcu();
1019 kfree(rcvr); 1020 kfree(rcvr);
1020 return 0; 1021 return 0;
1021 } else { 1022 } else {
1022 up(&intf->cmd_rcvrs_lock); 1023 mutex_unlock(&intf->cmd_rcvrs_mutex);
1023 return -ENOENT; 1024 return -ENOENT;
1024 } 1025 }
1025} 1026}
@@ -1514,7 +1515,7 @@ int ipmi_request_settime(ipmi_user_t user,
1514 unsigned char saddr, lun; 1515 unsigned char saddr, lun;
1515 int rv; 1516 int rv;
1516 1517
1517 if (! user) 1518 if (!user)
1518 return -EINVAL; 1519 return -EINVAL;
1519 rv = check_addr(user->intf, addr, &saddr, &lun); 1520 rv = check_addr(user->intf, addr, &saddr, &lun);
1520 if (rv) 1521 if (rv)
@@ -1545,7 +1546,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user,
1545 unsigned char saddr, lun; 1546 unsigned char saddr, lun;
1546 int rv; 1547 int rv;
1547 1548
1548 if (! user) 1549 if (!user)
1549 return -EINVAL; 1550 return -EINVAL;
1550 rv = check_addr(user->intf, addr, &saddr, &lun); 1551 rv = check_addr(user->intf, addr, &saddr, &lun);
1551 if (rv) 1552 if (rv)
@@ -1570,7 +1571,7 @@ static int ipmb_file_read_proc(char *page, char **start, off_t off,
1570 char *out = (char *) page; 1571 char *out = (char *) page;
1571 ipmi_smi_t intf = data; 1572 ipmi_smi_t intf = data;
1572 int i; 1573 int i;
1573 int rv= 0; 1574 int rv = 0;
1574 1575
1575 for (i = 0; i < IPMI_MAX_CHANNELS; i++) 1576 for (i = 0; i < IPMI_MAX_CHANNELS; i++)
1576 rv += sprintf(out+rv, "%x ", intf->channels[i].address); 1577 rv += sprintf(out+rv, "%x ", intf->channels[i].address);
@@ -1989,7 +1990,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
1989 } else { 1990 } else {
1990 bmc->dev = platform_device_alloc("ipmi_bmc", 1991 bmc->dev = platform_device_alloc("ipmi_bmc",
1991 bmc->id.device_id); 1992 bmc->id.device_id);
1992 if (! bmc->dev) { 1993 if (!bmc->dev) {
1993 printk(KERN_ERR 1994 printk(KERN_ERR
1994 "ipmi_msghandler:" 1995 "ipmi_msghandler:"
1995 " Unable to allocate platform device\n"); 1996 " Unable to allocate platform device\n");
@@ -2305,8 +2306,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2305 void *send_info, 2306 void *send_info,
2306 struct ipmi_device_id *device_id, 2307 struct ipmi_device_id *device_id,
2307 struct device *si_dev, 2308 struct device *si_dev,
2308 unsigned char slave_addr, 2309 unsigned char slave_addr)
2309 ipmi_smi_t *new_intf)
2310{ 2310{
2311 int i, j; 2311 int i, j;
2312 int rv; 2312 int rv;
@@ -2366,7 +2366,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2366 spin_lock_init(&intf->events_lock); 2366 spin_lock_init(&intf->events_lock);
2367 INIT_LIST_HEAD(&intf->waiting_events); 2367 INIT_LIST_HEAD(&intf->waiting_events);
2368 intf->waiting_events_count = 0; 2368 intf->waiting_events_count = 0;
2369 init_MUTEX(&intf->cmd_rcvrs_lock); 2369 mutex_init(&intf->cmd_rcvrs_mutex);
2370 INIT_LIST_HEAD(&intf->cmd_rcvrs); 2370 INIT_LIST_HEAD(&intf->cmd_rcvrs);
2371 init_waitqueue_head(&intf->waitq); 2371 init_waitqueue_head(&intf->waitq);
2372 2372
@@ -2388,9 +2388,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2388 if (rv) 2388 if (rv)
2389 goto out; 2389 goto out;
2390 2390
2391 /* FIXME - this is an ugly kludge, this sets the intf for the 2391 rv = handlers->start_processing(send_info, intf);
2392 caller before sending any messages with it. */ 2392 if (rv)
2393 *new_intf = intf; 2393 goto out;
2394 2394
2395 get_guid(intf); 2395 get_guid(intf);
2396 2396
@@ -2622,7 +2622,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
2622 spin_unlock_irqrestore(&intf->counter_lock, flags); 2622 spin_unlock_irqrestore(&intf->counter_lock, flags);
2623 2623
2624 recv_msg = ipmi_alloc_recv_msg(); 2624 recv_msg = ipmi_alloc_recv_msg();
2625 if (! recv_msg) { 2625 if (!recv_msg) {
2626 /* We couldn't allocate memory for the 2626 /* We couldn't allocate memory for the
2627 message, so requeue it for handling 2627 message, so requeue it for handling
2628 later. */ 2628 later. */
@@ -2777,7 +2777,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
2777 spin_unlock_irqrestore(&intf->counter_lock, flags); 2777 spin_unlock_irqrestore(&intf->counter_lock, flags);
2778 2778
2779 recv_msg = ipmi_alloc_recv_msg(); 2779 recv_msg = ipmi_alloc_recv_msg();
2780 if (! recv_msg) { 2780 if (!recv_msg) {
2781 /* We couldn't allocate memory for the 2781 /* We couldn't allocate memory for the
2782 message, so requeue it for handling 2782 message, so requeue it for handling
2783 later. */ 2783 later. */
@@ -2869,13 +2869,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2869 events. */ 2869 events. */
2870 rcu_read_lock(); 2870 rcu_read_lock();
2871 list_for_each_entry_rcu(user, &intf->users, link) { 2871 list_for_each_entry_rcu(user, &intf->users, link) {
2872 if (! user->gets_events) 2872 if (!user->gets_events)
2873 continue; 2873 continue;
2874 2874
2875 recv_msg = ipmi_alloc_recv_msg(); 2875 recv_msg = ipmi_alloc_recv_msg();
2876 if (! recv_msg) { 2876 if (!recv_msg) {
2877 rcu_read_unlock(); 2877 rcu_read_unlock();
2878 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { 2878 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs,
2879 link) {
2879 list_del(&recv_msg->link); 2880 list_del(&recv_msg->link);
2880 ipmi_free_recv_msg(recv_msg); 2881 ipmi_free_recv_msg(recv_msg);
2881 } 2882 }
@@ -2905,7 +2906,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2905 /* No one to receive the message, put it in queue if there's 2906 /* No one to receive the message, put it in queue if there's
2906 not already too many things in the queue. */ 2907 not already too many things in the queue. */
2907 recv_msg = ipmi_alloc_recv_msg(); 2908 recv_msg = ipmi_alloc_recv_msg();
2908 if (! recv_msg) { 2909 if (!recv_msg) {
2909 /* We couldn't allocate memory for the 2910 /* We couldn't allocate memory for the
2910 message, so requeue it for handling 2911 message, so requeue it for handling
2911 later. */ 2912 later. */
@@ -3190,7 +3191,7 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
3190 3191
3191 rcu_read_lock(); 3192 rcu_read_lock();
3192 list_for_each_entry_rcu(user, &intf->users, link) { 3193 list_for_each_entry_rcu(user, &intf->users, link) {
3193 if (! user->handler->ipmi_watchdog_pretimeout) 3194 if (!user->handler->ipmi_watchdog_pretimeout)
3194 continue; 3195 continue;
3195 3196
3196 user->handler->ipmi_watchdog_pretimeout(user->handler_data); 3197 user->handler->ipmi_watchdog_pretimeout(user->handler_data);
@@ -3278,7 +3279,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
3278 3279
3279 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, 3280 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
3280 ent->seqid); 3281 ent->seqid);
3281 if (! smi_msg) 3282 if (!smi_msg)
3282 return; 3283 return;
3283 3284
3284 spin_unlock_irqrestore(&intf->seq_lock, *flags); 3285 spin_unlock_irqrestore(&intf->seq_lock, *flags);
@@ -3314,8 +3315,9 @@ static void ipmi_timeout_handler(long timeout_period)
3314 3315
3315 /* See if any waiting messages need to be processed. */ 3316 /* See if any waiting messages need to be processed. */
3316 spin_lock_irqsave(&intf->waiting_msgs_lock, flags); 3317 spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
3317 list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) { 3318 list_for_each_entry_safe(smi_msg, smi_msg2,
3318 if (! handle_new_recv_msg(intf, smi_msg)) { 3319 &intf->waiting_msgs, link) {
3320 if (!handle_new_recv_msg(intf, smi_msg)) {
3319 list_del(&smi_msg->link); 3321 list_del(&smi_msg->link);
3320 ipmi_free_smi_msg(smi_msg); 3322 ipmi_free_smi_msg(smi_msg);
3321 } else { 3323 } else {
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 786a2802ca34..d0b5c08e7b4e 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -346,7 +346,7 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user)
346{ 346{
347 const char ipmi_version_major = ipmi_version & 0xF; 347 const char ipmi_version_major = ipmi_version & 0xF;
348 const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; 348 const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
349 const char mfr[3]=DELL_IANA_MFR_ID; 349 const char mfr[3] = DELL_IANA_MFR_ID;
350 if (!memcmp(mfr, &mfg_id, sizeof(mfr)) && 350 if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
351 ipmi_version_major <= 1 && 351 ipmi_version_major <= 1 &&
352 ipmi_version_minor < 5) 352 ipmi_version_minor < 5)
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 35fbd4d8ed4b..a86c0f29953e 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -803,7 +803,7 @@ static int ipmi_thread(void *data)
803 set_user_nice(current, 19); 803 set_user_nice(current, 19);
804 while (!kthread_should_stop()) { 804 while (!kthread_should_stop()) {
805 spin_lock_irqsave(&(smi_info->si_lock), flags); 805 spin_lock_irqsave(&(smi_info->si_lock), flags);
806 smi_result=smi_event_handler(smi_info, 0); 806 smi_result = smi_event_handler(smi_info, 0);
807 spin_unlock_irqrestore(&(smi_info->si_lock), flags); 807 spin_unlock_irqrestore(&(smi_info->si_lock), flags);
808 if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { 808 if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
809 /* do nothing */ 809 /* do nothing */
@@ -972,10 +972,37 @@ static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
972 return si_irq_handler(irq, data, regs); 972 return si_irq_handler(irq, data, regs);
973} 973}
974 974
975static int smi_start_processing(void *send_info,
976 ipmi_smi_t intf)
977{
978 struct smi_info *new_smi = send_info;
979
980 new_smi->intf = intf;
981
982 /* Set up the timer that drives the interface. */
983 setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
984 new_smi->last_timeout_jiffies = jiffies;
985 mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
986
987 if (new_smi->si_type != SI_BT) {
988 new_smi->thread = kthread_run(ipmi_thread, new_smi,
989 "kipmi%d", new_smi->intf_num);
990 if (IS_ERR(new_smi->thread)) {
991 printk(KERN_NOTICE "ipmi_si_intf: Could not start"
992 " kernel thread due to error %ld, only using"
993 " timers to drive the interface\n",
994 PTR_ERR(new_smi->thread));
995 new_smi->thread = NULL;
996 }
997 }
998
999 return 0;
1000}
975 1001
976static struct ipmi_smi_handlers handlers = 1002static struct ipmi_smi_handlers handlers =
977{ 1003{
978 .owner = THIS_MODULE, 1004 .owner = THIS_MODULE,
1005 .start_processing = smi_start_processing,
979 .sender = sender, 1006 .sender = sender,
980 .request_events = request_events, 1007 .request_events = request_events,
981 .set_run_to_completion = set_run_to_completion, 1008 .set_run_to_completion = set_run_to_completion,
@@ -987,7 +1014,7 @@ static struct ipmi_smi_handlers handlers =
987 1014
988#define SI_MAX_PARMS 4 1015#define SI_MAX_PARMS 4
989static LIST_HEAD(smi_infos); 1016static LIST_HEAD(smi_infos);
990static DECLARE_MUTEX(smi_infos_lock); 1017static DEFINE_MUTEX(smi_infos_lock);
991static int smi_num; /* Used to sequence the SMIs */ 1018static int smi_num; /* Used to sequence the SMIs */
992 1019
993#define DEFAULT_REGSPACING 1 1020#define DEFAULT_REGSPACING 1
@@ -2162,9 +2189,13 @@ static void setup_xaction_handlers(struct smi_info *smi_info)
2162 2189
2163static inline void wait_for_timer_and_thread(struct smi_info *smi_info) 2190static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
2164{ 2191{
2165 if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM)) 2192 if (smi_info->intf) {
2166 kthread_stop(smi_info->thread); 2193 /* The timer and thread are only running if the
2167 del_timer_sync(&smi_info->si_timer); 2194 interface has been started up and registered. */
2195 if (smi_info->thread != NULL)
2196 kthread_stop(smi_info->thread);
2197 del_timer_sync(&smi_info->si_timer);
2198 }
2168} 2199}
2169 2200
2170static struct ipmi_default_vals 2201static struct ipmi_default_vals
@@ -2245,7 +2276,7 @@ static int try_smi_init(struct smi_info *new_smi)
2245 new_smi->slave_addr, new_smi->irq); 2276 new_smi->slave_addr, new_smi->irq);
2246 } 2277 }
2247 2278
2248 down(&smi_infos_lock); 2279 mutex_lock(&smi_infos_lock);
2249 if (!is_new_interface(new_smi)) { 2280 if (!is_new_interface(new_smi)) {
2250 printk(KERN_WARNING "ipmi_si: duplicate interface\n"); 2281 printk(KERN_WARNING "ipmi_si: duplicate interface\n");
2251 rv = -EBUSY; 2282 rv = -EBUSY;
@@ -2341,21 +2372,6 @@ static int try_smi_init(struct smi_info *new_smi)
2341 if (new_smi->irq) 2372 if (new_smi->irq)
2342 new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; 2373 new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
2343 2374
2344 /* The ipmi_register_smi() code does some operations to
2345 determine the channel information, so we must be ready to
2346 handle operations before it is called. This means we have
2347 to stop the timer if we get an error after this point. */
2348 init_timer(&(new_smi->si_timer));
2349 new_smi->si_timer.data = (long) new_smi;
2350 new_smi->si_timer.function = smi_timeout;
2351 new_smi->last_timeout_jiffies = jiffies;
2352 new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
2353
2354 add_timer(&(new_smi->si_timer));
2355 if (new_smi->si_type != SI_BT)
2356 new_smi->thread = kthread_run(ipmi_thread, new_smi,
2357 "kipmi%d", new_smi->intf_num);
2358
2359 if (!new_smi->dev) { 2375 if (!new_smi->dev) {
2360 /* If we don't already have a device from something 2376 /* If we don't already have a device from something
2361 * else (like PCI), then register a new one. */ 2377 * else (like PCI), then register a new one. */
@@ -2365,7 +2381,7 @@ static int try_smi_init(struct smi_info *new_smi)
2365 printk(KERN_ERR 2381 printk(KERN_ERR
2366 "ipmi_si_intf:" 2382 "ipmi_si_intf:"
2367 " Unable to allocate platform device\n"); 2383 " Unable to allocate platform device\n");
2368 goto out_err_stop_timer; 2384 goto out_err;
2369 } 2385 }
2370 new_smi->dev = &new_smi->pdev->dev; 2386 new_smi->dev = &new_smi->pdev->dev;
2371 new_smi->dev->driver = &ipmi_driver; 2387 new_smi->dev->driver = &ipmi_driver;
@@ -2377,7 +2393,7 @@ static int try_smi_init(struct smi_info *new_smi)
2377 " Unable to register system interface device:" 2393 " Unable to register system interface device:"
2378 " %d\n", 2394 " %d\n",
2379 rv); 2395 rv);
2380 goto out_err_stop_timer; 2396 goto out_err;
2381 } 2397 }
2382 new_smi->dev_registered = 1; 2398 new_smi->dev_registered = 1;
2383 } 2399 }
@@ -2386,8 +2402,7 @@ static int try_smi_init(struct smi_info *new_smi)
2386 new_smi, 2402 new_smi,
2387 &new_smi->device_id, 2403 &new_smi->device_id,
2388 new_smi->dev, 2404 new_smi->dev,
2389 new_smi->slave_addr, 2405 new_smi->slave_addr);
2390 &(new_smi->intf));
2391 if (rv) { 2406 if (rv) {
2392 printk(KERN_ERR 2407 printk(KERN_ERR
2393 "ipmi_si: Unable to register device: error %d\n", 2408 "ipmi_si: Unable to register device: error %d\n",
@@ -2417,7 +2432,7 @@ static int try_smi_init(struct smi_info *new_smi)
2417 2432
2418 list_add_tail(&new_smi->link, &smi_infos); 2433 list_add_tail(&new_smi->link, &smi_infos);
2419 2434
2420 up(&smi_infos_lock); 2435 mutex_unlock(&smi_infos_lock);
2421 2436
2422 printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); 2437 printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]);
2423 2438
@@ -2454,7 +2469,7 @@ static int try_smi_init(struct smi_info *new_smi)
2454 2469
2455 kfree(new_smi); 2470 kfree(new_smi);
2456 2471
2457 up(&smi_infos_lock); 2472 mutex_unlock(&smi_infos_lock);
2458 2473
2459 return rv; 2474 return rv;
2460} 2475}
@@ -2512,26 +2527,26 @@ static __devinit int init_ipmi_si(void)
2512#endif 2527#endif
2513 2528
2514 if (si_trydefaults) { 2529 if (si_trydefaults) {
2515 down(&smi_infos_lock); 2530 mutex_lock(&smi_infos_lock);
2516 if (list_empty(&smi_infos)) { 2531 if (list_empty(&smi_infos)) {
2517 /* No BMC was found, try defaults. */ 2532 /* No BMC was found, try defaults. */
2518 up(&smi_infos_lock); 2533 mutex_unlock(&smi_infos_lock);
2519 default_find_bmc(); 2534 default_find_bmc();
2520 } else { 2535 } else {
2521 up(&smi_infos_lock); 2536 mutex_unlock(&smi_infos_lock);
2522 } 2537 }
2523 } 2538 }
2524 2539
2525 down(&smi_infos_lock); 2540 mutex_lock(&smi_infos_lock);
2526 if (list_empty(&smi_infos)) { 2541 if (list_empty(&smi_infos)) {
2527 up(&smi_infos_lock); 2542 mutex_unlock(&smi_infos_lock);
2528#ifdef CONFIG_PCI 2543#ifdef CONFIG_PCI
2529 pci_unregister_driver(&ipmi_pci_driver); 2544 pci_unregister_driver(&ipmi_pci_driver);
2530#endif 2545#endif
2531 printk("ipmi_si: Unable to find any System Interface(s)\n"); 2546 printk("ipmi_si: Unable to find any System Interface(s)\n");
2532 return -ENODEV; 2547 return -ENODEV;
2533 } else { 2548 } else {
2534 up(&smi_infos_lock); 2549 mutex_unlock(&smi_infos_lock);
2535 return 0; 2550 return 0;
2536 } 2551 }
2537} 2552}
@@ -2607,10 +2622,10 @@ static __exit void cleanup_ipmi_si(void)
2607 pci_unregister_driver(&ipmi_pci_driver); 2622 pci_unregister_driver(&ipmi_pci_driver);
2608#endif 2623#endif
2609 2624
2610 down(&smi_infos_lock); 2625 mutex_lock(&smi_infos_lock);
2611 list_for_each_entry_safe(e, tmp_e, &smi_infos, link) 2626 list_for_each_entry_safe(e, tmp_e, &smi_infos, link)
2612 cleanup_one_si(e); 2627 cleanup_one_si(e);
2613 up(&smi_infos_lock); 2628 mutex_unlock(&smi_infos_lock);
2614 2629
2615 driver_unregister(&ipmi_driver); 2630 driver_unregister(&ipmi_driver);
2616} 2631}
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 7ece9f3c8f70..2d11ddd99e55 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -39,6 +39,7 @@
39#include <linux/watchdog.h> 39#include <linux/watchdog.h>
40#include <linux/miscdevice.h> 40#include <linux/miscdevice.h>
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/completion.h>
42#include <linux/rwsem.h> 43#include <linux/rwsem.h>
43#include <linux/errno.h> 44#include <linux/errno.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -303,21 +304,22 @@ static int ipmi_heartbeat(void);
303static void panic_halt_ipmi_heartbeat(void); 304static void panic_halt_ipmi_heartbeat(void);
304 305
305 306
306/* We use a semaphore to make sure that only one thing can send a set 307/* We use a mutex to make sure that only one thing can send a set
307 timeout at one time, because we only have one copy of the data. 308 timeout at one time, because we only have one copy of the data.
308 The semaphore is claimed when the set_timeout is sent and freed 309 The mutex is claimed when the set_timeout is sent and freed
309 when both messages are free. */ 310 when both messages are free. */
310static atomic_t set_timeout_tofree = ATOMIC_INIT(0); 311static atomic_t set_timeout_tofree = ATOMIC_INIT(0);
311static DECLARE_MUTEX(set_timeout_lock); 312static DEFINE_MUTEX(set_timeout_lock);
313static DECLARE_COMPLETION(set_timeout_wait);
312static void set_timeout_free_smi(struct ipmi_smi_msg *msg) 314static void set_timeout_free_smi(struct ipmi_smi_msg *msg)
313{ 315{
314 if (atomic_dec_and_test(&set_timeout_tofree)) 316 if (atomic_dec_and_test(&set_timeout_tofree))
315 up(&set_timeout_lock); 317 complete(&set_timeout_wait);
316} 318}
317static void set_timeout_free_recv(struct ipmi_recv_msg *msg) 319static void set_timeout_free_recv(struct ipmi_recv_msg *msg)
318{ 320{
319 if (atomic_dec_and_test(&set_timeout_tofree)) 321 if (atomic_dec_and_test(&set_timeout_tofree))
320 up(&set_timeout_lock); 322 complete(&set_timeout_wait);
321} 323}
322static struct ipmi_smi_msg set_timeout_smi_msg = 324static struct ipmi_smi_msg set_timeout_smi_msg =
323{ 325{
@@ -399,7 +401,7 @@ static int ipmi_set_timeout(int do_heartbeat)
399 401
400 402
401 /* We can only send one of these at a time. */ 403 /* We can only send one of these at a time. */
402 down(&set_timeout_lock); 404 mutex_lock(&set_timeout_lock);
403 405
404 atomic_set(&set_timeout_tofree, 2); 406 atomic_set(&set_timeout_tofree, 2);
405 407
@@ -407,16 +409,21 @@ static int ipmi_set_timeout(int do_heartbeat)
407 &set_timeout_recv_msg, 409 &set_timeout_recv_msg,
408 &send_heartbeat_now); 410 &send_heartbeat_now);
409 if (rv) { 411 if (rv) {
410 up(&set_timeout_lock); 412 mutex_unlock(&set_timeout_lock);
411 } else { 413 goto out;
412 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
413 || ((send_heartbeat_now)
414 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
415 {
416 rv = ipmi_heartbeat();
417 }
418 } 414 }
419 415
416 wait_for_completion(&set_timeout_wait);
417
418 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
419 || ((send_heartbeat_now)
420 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
421 {
422 rv = ipmi_heartbeat();
423 }
424 mutex_unlock(&set_timeout_lock);
425
426out:
420 return rv; 427 return rv;
421} 428}
422 429
@@ -458,17 +465,17 @@ static void panic_halt_ipmi_set_timeout(void)
458 The semaphore is claimed when the set_timeout is sent and freed 465 The semaphore is claimed when the set_timeout is sent and freed
459 when both messages are free. */ 466 when both messages are free. */
460static atomic_t heartbeat_tofree = ATOMIC_INIT(0); 467static atomic_t heartbeat_tofree = ATOMIC_INIT(0);
461static DECLARE_MUTEX(heartbeat_lock); 468static DEFINE_MUTEX(heartbeat_lock);
462static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); 469static DECLARE_COMPLETION(heartbeat_wait);
463static void heartbeat_free_smi(struct ipmi_smi_msg *msg) 470static void heartbeat_free_smi(struct ipmi_smi_msg *msg)
464{ 471{
465 if (atomic_dec_and_test(&heartbeat_tofree)) 472 if (atomic_dec_and_test(&heartbeat_tofree))
466 up(&heartbeat_wait_lock); 473 complete(&heartbeat_wait);
467} 474}
468static void heartbeat_free_recv(struct ipmi_recv_msg *msg) 475static void heartbeat_free_recv(struct ipmi_recv_msg *msg)
469{ 476{
470 if (atomic_dec_and_test(&heartbeat_tofree)) 477 if (atomic_dec_and_test(&heartbeat_tofree))
471 up(&heartbeat_wait_lock); 478 complete(&heartbeat_wait);
472} 479}
473static struct ipmi_smi_msg heartbeat_smi_msg = 480static struct ipmi_smi_msg heartbeat_smi_msg =
474{ 481{
@@ -511,14 +518,14 @@ static int ipmi_heartbeat(void)
511 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); 518 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
512 } 519 }
513 520
514 down(&heartbeat_lock); 521 mutex_lock(&heartbeat_lock);
515 522
516 atomic_set(&heartbeat_tofree, 2); 523 atomic_set(&heartbeat_tofree, 2);
517 524
518 /* Don't reset the timer if we have the timer turned off, that 525 /* Don't reset the timer if we have the timer turned off, that
519 re-enables the watchdog. */ 526 re-enables the watchdog. */
520 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { 527 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
521 up(&heartbeat_lock); 528 mutex_unlock(&heartbeat_lock);
522 return 0; 529 return 0;
523 } 530 }
524 531
@@ -539,14 +546,14 @@ static int ipmi_heartbeat(void)
539 &heartbeat_recv_msg, 546 &heartbeat_recv_msg,
540 1); 547 1);
541 if (rv) { 548 if (rv) {
542 up(&heartbeat_lock); 549 mutex_unlock(&heartbeat_lock);
543 printk(KERN_WARNING PFX "heartbeat failure: %d\n", 550 printk(KERN_WARNING PFX "heartbeat failure: %d\n",
544 rv); 551 rv);
545 return rv; 552 return rv;
546 } 553 }
547 554
548 /* Wait for the heartbeat to be sent. */ 555 /* Wait for the heartbeat to be sent. */
549 down(&heartbeat_wait_lock); 556 wait_for_completion(&heartbeat_wait);
550 557
551 if (heartbeat_recv_msg.msg.data[0] != 0) { 558 if (heartbeat_recv_msg.msg.data[0] != 0) {
552 /* Got an error in the heartbeat response. It was already 559 /* Got an error in the heartbeat response. It was already
@@ -555,7 +562,7 @@ static int ipmi_heartbeat(void)
555 rv = -EINVAL; 562 rv = -EINVAL;
556 } 563 }
557 564
558 up(&heartbeat_lock); 565 mutex_unlock(&heartbeat_lock);
559 566
560 return rv; 567 return rv;
561} 568}
@@ -589,7 +596,7 @@ static void panic_halt_ipmi_heartbeat(void)
589 1); 596 1);
590} 597}
591 598
592static struct watchdog_info ident= 599static struct watchdog_info ident =
593{ 600{
594 .options = 0, /* WDIOF_SETTIMEOUT, */ 601 .options = 0, /* WDIOF_SETTIMEOUT, */
595 .firmware_version = 1, 602 .firmware_version = 1,
@@ -790,13 +797,13 @@ static int ipmi_fasync(int fd, struct file *file, int on)
790 797
791static int ipmi_close(struct inode *ino, struct file *filep) 798static int ipmi_close(struct inode *ino, struct file *filep)
792{ 799{
793 if (iminor(ino)==WATCHDOG_MINOR) 800 if (iminor(ino) == WATCHDOG_MINOR) {
794 {
795 if (expect_close == 42) { 801 if (expect_close == 42) {
796 ipmi_watchdog_state = WDOG_TIMEOUT_NONE; 802 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
797 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); 803 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
798 } else { 804 } else {
799 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 805 printk(KERN_CRIT PFX
806 "Unexpected close, not stopping watchdog!\n");
800 ipmi_heartbeat(); 807 ipmi_heartbeat();
801 } 808 }
802 clear_bit(0, &ipmi_wdog_open); 809 clear_bit(0, &ipmi_wdog_open);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index e5247f85a446..ef20c1fc9c4c 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -706,7 +706,6 @@ static int stli_portcmdstats(stliport_t *portp);
706static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); 706static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp);
707static int stli_getportstruct(stliport_t __user *arg); 707static int stli_getportstruct(stliport_t __user *arg);
708static int stli_getbrdstruct(stlibrd_t __user *arg); 708static int stli_getbrdstruct(stlibrd_t __user *arg);
709static void *stli_memalloc(int len);
710static stlibrd_t *stli_allocbrd(void); 709static stlibrd_t *stli_allocbrd(void);
711 710
712static void stli_ecpinit(stlibrd_t *brdp); 711static void stli_ecpinit(stlibrd_t *brdp);
@@ -997,17 +996,6 @@ static int stli_parsebrd(stlconf_t *confp, char **argp)
997 996
998/*****************************************************************************/ 997/*****************************************************************************/
999 998
1000/*
1001 * Local driver kernel malloc routine.
1002 */
1003
1004static void *stli_memalloc(int len)
1005{
1006 return((void *) kmalloc(len, GFP_KERNEL));
1007}
1008
1009/*****************************************************************************/
1010
1011static int stli_open(struct tty_struct *tty, struct file *filp) 999static int stli_open(struct tty_struct *tty, struct file *filp)
1012{ 1000{
1013 stlibrd_t *brdp; 1001 stlibrd_t *brdp;
@@ -3227,13 +3215,12 @@ static int stli_initports(stlibrd_t *brdp)
3227#endif 3215#endif
3228 3216
3229 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { 3217 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
3230 portp = (stliport_t *) stli_memalloc(sizeof(stliport_t)); 3218 portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);
3231 if (portp == (stliport_t *) NULL) { 3219 if (!portp) {
3232 printk("STALLION: failed to allocate port structure\n"); 3220 printk("STALLION: failed to allocate port structure\n");
3233 continue; 3221 continue;
3234 } 3222 }
3235 3223
3236 memset(portp, 0, sizeof(stliport_t));
3237 portp->magic = STLI_PORTMAGIC; 3224 portp->magic = STLI_PORTMAGIC;
3238 portp->portnr = i; 3225 portp->portnr = i;
3239 portp->brdnr = brdp->brdnr; 3226 portp->brdnr = brdp->brdnr;
@@ -4610,14 +4597,13 @@ static stlibrd_t *stli_allocbrd(void)
4610{ 4597{
4611 stlibrd_t *brdp; 4598 stlibrd_t *brdp;
4612 4599
4613 brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t)); 4600 brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);
4614 if (brdp == (stlibrd_t *) NULL) { 4601 if (!brdp) {
4615 printk(KERN_ERR "STALLION: failed to allocate memory " 4602 printk(KERN_ERR "STALLION: failed to allocate memory "
4616 "(size=%d)\n", sizeof(stlibrd_t)); 4603 "(size=%d)\n", sizeof(stlibrd_t));
4617 return((stlibrd_t *) NULL); 4604 return NULL;
4618 } 4605 }
4619 4606
4620 memset(brdp, 0, sizeof(stlibrd_t));
4621 brdp->magic = STLI_BOARDMAGIC; 4607 brdp->magic = STLI_BOARDMAGIC;
4622 return(brdp); 4608 return(brdp);
4623} 4609}
@@ -5210,12 +5196,12 @@ int __init stli_init(void)
5210/* 5196/*
5211 * Allocate a temporary write buffer. 5197 * Allocate a temporary write buffer.
5212 */ 5198 */
5213 stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE); 5199 stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
5214 if (stli_tmpwritebuf == (char *) NULL) 5200 if (!stli_tmpwritebuf)
5215 printk(KERN_ERR "STALLION: failed to allocate memory " 5201 printk(KERN_ERR "STALLION: failed to allocate memory "
5216 "(size=%d)\n", STLI_TXBUFSIZE); 5202 "(size=%d)\n", STLI_TXBUFSIZE);
5217 stli_txcookbuf = stli_memalloc(STLI_TXBUFSIZE); 5203 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
5218 if (stli_txcookbuf == (char *) NULL) 5204 if (!stli_txcookbuf)
5219 printk(KERN_ERR "STALLION: failed to allocate memory " 5205 printk(KERN_ERR "STALLION: failed to allocate memory "
5220 "(size=%d)\n", STLI_TXBUFSIZE); 5206 "(size=%d)\n", STLI_TXBUFSIZE);
5221 5207
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 3f5d6077f39c..a9c5a7230f89 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -504,7 +504,6 @@ static int stl_echmcaintr(stlbrd_t *brdp);
504static int stl_echpciintr(stlbrd_t *brdp); 504static int stl_echpciintr(stlbrd_t *brdp);
505static int stl_echpci64intr(stlbrd_t *brdp); 505static int stl_echpci64intr(stlbrd_t *brdp);
506static void stl_offintr(void *private); 506static void stl_offintr(void *private);
507static void *stl_memalloc(int len);
508static stlbrd_t *stl_allocbrd(void); 507static stlbrd_t *stl_allocbrd(void);
509static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); 508static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
510 509
@@ -940,17 +939,6 @@ static int stl_parsebrd(stlconf_t *confp, char **argp)
940/*****************************************************************************/ 939/*****************************************************************************/
941 940
942/* 941/*
943 * Local driver kernel memory allocation routine.
944 */
945
946static void *stl_memalloc(int len)
947{
948 return (void *) kmalloc(len, GFP_KERNEL);
949}
950
951/*****************************************************************************/
952
953/*
954 * Allocate a new board structure. Fill out the basic info in it. 942 * Allocate a new board structure. Fill out the basic info in it.
955 */ 943 */
956 944
@@ -958,14 +946,13 @@ static stlbrd_t *stl_allocbrd(void)
958{ 946{
959 stlbrd_t *brdp; 947 stlbrd_t *brdp;
960 948
961 brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t)); 949 brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL);
962 if (brdp == (stlbrd_t *) NULL) { 950 if (!brdp) {
963 printk("STALLION: failed to allocate memory (size=%d)\n", 951 printk("STALLION: failed to allocate memory (size=%d)\n",
964 sizeof(stlbrd_t)); 952 sizeof(stlbrd_t));
965 return (stlbrd_t *) NULL; 953 return NULL;
966 } 954 }
967 955
968 memset(brdp, 0, sizeof(stlbrd_t));
969 brdp->magic = STL_BOARDMAGIC; 956 brdp->magic = STL_BOARDMAGIC;
970 return brdp; 957 return brdp;
971} 958}
@@ -1017,9 +1004,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
1017 portp->refcount++; 1004 portp->refcount++;
1018 1005
1019 if ((portp->flags & ASYNC_INITIALIZED) == 0) { 1006 if ((portp->flags & ASYNC_INITIALIZED) == 0) {
1020 if (portp->tx.buf == (char *) NULL) { 1007 if (!portp->tx.buf) {
1021 portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE); 1008 portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
1022 if (portp->tx.buf == (char *) NULL) 1009 if (!portp->tx.buf)
1023 return -ENOMEM; 1010 return -ENOMEM;
1024 portp->tx.head = portp->tx.buf; 1011 portp->tx.head = portp->tx.buf;
1025 portp->tx.tail = portp->tx.buf; 1012 portp->tx.tail = portp->tx.buf;
@@ -2178,13 +2165,12 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
2178 * each ports data structures. 2165 * each ports data structures.
2179 */ 2166 */
2180 for (i = 0; (i < panelp->nrports); i++) { 2167 for (i = 0; (i < panelp->nrports); i++) {
2181 portp = (stlport_t *) stl_memalloc(sizeof(stlport_t)); 2168 portp = kzalloc(sizeof(stlport_t), GFP_KERNEL);
2182 if (portp == (stlport_t *) NULL) { 2169 if (!portp) {
2183 printk("STALLION: failed to allocate memory " 2170 printk("STALLION: failed to allocate memory "
2184 "(size=%d)\n", sizeof(stlport_t)); 2171 "(size=%d)\n", sizeof(stlport_t));
2185 break; 2172 break;
2186 } 2173 }
2187 memset(portp, 0, sizeof(stlport_t));
2188 2174
2189 portp->magic = STL_PORTMAGIC; 2175 portp->magic = STL_PORTMAGIC;
2190 portp->portnr = i; 2176 portp->portnr = i;
@@ -2315,13 +2301,12 @@ static inline int stl_initeio(stlbrd_t *brdp)
2315 * can complete the setup. 2301 * can complete the setup.
2316 */ 2302 */
2317 2303
2318 panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); 2304 panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
2319 if (panelp == (stlpanel_t *) NULL) { 2305 if (!panelp) {
2320 printk(KERN_WARNING "STALLION: failed to allocate memory " 2306 printk(KERN_WARNING "STALLION: failed to allocate memory "
2321 "(size=%d)\n", sizeof(stlpanel_t)); 2307 "(size=%d)\n", sizeof(stlpanel_t));
2322 return(-ENOMEM); 2308 return -ENOMEM;
2323 } 2309 }
2324 memset(panelp, 0, sizeof(stlpanel_t));
2325 2310
2326 panelp->magic = STL_PANELMAGIC; 2311 panelp->magic = STL_PANELMAGIC;
2327 panelp->brdnr = brdp->brdnr; 2312 panelp->brdnr = brdp->brdnr;
@@ -2490,13 +2475,12 @@ static inline int stl_initech(stlbrd_t *brdp)
2490 status = inb(ioaddr + ECH_PNLSTATUS); 2475 status = inb(ioaddr + ECH_PNLSTATUS);
2491 if ((status & ECH_PNLIDMASK) != nxtid) 2476 if ((status & ECH_PNLIDMASK) != nxtid)
2492 break; 2477 break;
2493 panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); 2478 panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
2494 if (panelp == (stlpanel_t *) NULL) { 2479 if (!panelp) {
2495 printk("STALLION: failed to allocate memory " 2480 printk("STALLION: failed to allocate memory "
2496 "(size=%d)\n", sizeof(stlpanel_t)); 2481 "(size=%d)\n", sizeof(stlpanel_t));
2497 break; 2482 break;
2498 } 2483 }
2499 memset(panelp, 0, sizeof(stlpanel_t));
2500 panelp->magic = STL_PANELMAGIC; 2484 panelp->magic = STL_PANELMAGIC;
2501 panelp->brdnr = brdp->brdnr; 2485 panelp->brdnr = brdp->brdnr;
2502 panelp->panelnr = panelnr; 2486 panelp->panelnr = panelnr;
@@ -3074,8 +3058,8 @@ static int __init stl_init(void)
3074/* 3058/*
3075 * Allocate a temporary write buffer. 3059 * Allocate a temporary write buffer.
3076 */ 3060 */
3077 stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE); 3061 stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
3078 if (stl_tmpwritebuf == (char *) NULL) 3062 if (!stl_tmpwritebuf)
3079 printk("STALLION: failed to allocate memory (size=%d)\n", 3063 printk("STALLION: failed to allocate memory (size=%d)\n",
3080 STL_TXBUFSIZE); 3064 STL_TXBUFSIZE);
3081 3065
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 0bfd1b63662e..98b126c2ded8 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -376,7 +376,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s
376 return copied; 376 return copied;
377} 377}
378 378
379EXPORT_SYMBOL_GPL(tty_insert_flip_string); 379EXPORT_SYMBOL(tty_insert_flip_string);
380 380
381int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) 381int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size)
382{ 382{
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index ca4844c527da..acc5d47844eb 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2328,6 +2328,10 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2328 case TIOCL_SETVESABLANK: 2328 case TIOCL_SETVESABLANK:
2329 set_vesa_blanking(p); 2329 set_vesa_blanking(p);
2330 break; 2330 break;
2331 case TIOCL_GETKMSGREDIRECT:
2332 data = kmsg_redirect;
2333 ret = __put_user(data, p);
2334 break;
2331 case TIOCL_SETKMSGREDIRECT: 2335 case TIOCL_SETKMSGREDIRECT:
2332 if (!capable(CAP_SYS_ADMIN)) { 2336 if (!capable(CAP_SYS_ADMIN)) {
2333 ret = -EPERM; 2337 ret = -EPERM;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index b582d0cdc24f..4f0898400c6d 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -71,7 +71,7 @@ config EDAC_E7XXX
71 71
72config EDAC_E752X 72config EDAC_E752X
73 tristate "Intel e752x (e7520, e7525, e7320)" 73 tristate "Intel e752x (e7520, e7525, e7320)"
74 depends on EDAC_MM_EDAC && PCI && X86 74 depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG
75 help 75 help
76 Support for error detection and correction on the Intel 76 Support for error detection and correction on the Intel
77 E7520, E7525, E7320 server chipsets. 77 E7520, E7525, E7320 server chipsets.
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index ccf528d733bf..a5017de72da5 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -61,6 +61,7 @@
61#include <linux/slab.h> 61#include <linux/slab.h>
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/mutex.h> 63#include <linux/mutex.h>
64#include <linux/leds.h>
64 65
65#define _IDE_DISK 66#define _IDE_DISK
66 67
@@ -317,6 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s
317 return ide_stopped; 318 return ide_stopped;
318 } 319 }
319 320
321 ledtrig_ide_activity();
322
320 pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", 323 pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
321 drive->name, rq_data_dir(rq) == READ ? "read" : "writ", 324 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
322 (unsigned long long)block, rq->nr_sectors, 325 (unsigned long long)block, rq->nr_sectors,
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 0606bd2f6020..9233b8109a0f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -375,7 +375,13 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
375 } 375 }
376 } 376 }
377 377
378 ide_end_request(drive, 1, rq->hard_nr_sectors); 378 if (rq->rq_disk) {
379 ide_driver_t *drv;
380
381 drv = *(ide_driver_t **)rq->rq_disk->private_data;;
382 drv->end_request(drive, 1, rq->hard_nr_sectors);
383 } else
384 ide_end_request(drive, 1, rq->hard_nr_sectors);
379} 385}
380 386
381/* 387/*
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c
index 94c9afb7017c..f4f71226a078 100644
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -46,7 +46,8 @@ int sc_ioctl(int card, scs_ioctl *data)
46 pr_debug("%s: SCIOCRESET: ioctl received\n", 46 pr_debug("%s: SCIOCRESET: ioctl received\n",
47 sc_adapter[card]->devicename); 47 sc_adapter[card]->devicename);
48 sc_adapter[card]->StartOnReset = 0; 48 sc_adapter[card]->StartOnReset = 0;
49 return (reset(card)); 49 kfree(rcvmsg);
50 return reset(card);
50 } 51 }
51 52
52 case SCIOCLOAD: 53 case SCIOCLOAD:
@@ -183,7 +184,7 @@ int sc_ioctl(int card, scs_ioctl *data)
183 sc_adapter[card]->devicename); 184 sc_adapter[card]->devicename);
184 185
185 spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); 186 spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
186 if(!spid) { 187 if (!spid) {
187 kfree(rcvmsg); 188 kfree(rcvmsg);
188 return -ENOMEM; 189 return -ENOMEM;
189 } 190 }
@@ -195,10 +196,10 @@ int sc_ioctl(int card, scs_ioctl *data)
195 if (!status) { 196 if (!status) {
196 pr_debug("%s: SCIOCGETSPID: command successful\n", 197 pr_debug("%s: SCIOCGETSPID: command successful\n",
197 sc_adapter[card]->devicename); 198 sc_adapter[card]->devicename);
198 } 199 } else {
199 else {
200 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", 200 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
201 sc_adapter[card]->devicename, status); 201 sc_adapter[card]->devicename, status);
202 kfree(spid);
202 kfree(rcvmsg); 203 kfree(rcvmsg);
203 return status; 204 return status;
204 } 205 }
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
new file mode 100644
index 000000000000..2c4f20b7f021
--- /dev/null
+++ b/drivers/leds/Kconfig
@@ -0,0 +1,77 @@
1
2menu "LED devices"
3
4config NEW_LEDS
5 bool "LED Support"
6 help
7 Say Y to enable Linux LED support. This is not related to standard
8 keyboard LEDs which are controlled via the input system.
9
10config LEDS_CLASS
11 tristate "LED Class Support"
12 depends NEW_LEDS
13 help
14 This option enables the led sysfs class in /sys/class/leds. You'll
15 need this to do anything useful with LEDs. If unsure, say N.
16
17config LEDS_TRIGGERS
18 bool "LED Trigger support"
19 depends NEW_LEDS
20 help
21 This option enables trigger support for the leds class.
22 These triggers allow kernel events to drive the LEDs and can
23 be configured via sysfs. If unsure, say Y.
24
25config LEDS_CORGI
26 tristate "LED Support for the Sharp SL-C7x0 series"
27 depends LEDS_CLASS && PXA_SHARP_C7xx
28 help
29 This option enables support for the LEDs on Sharp Zaurus
30 SL-C7x0 series (C700, C750, C760, C860).
31
32config LEDS_LOCOMO
33 tristate "LED Support for Locomo device"
34 depends LEDS_CLASS && SHARP_LOCOMO
35 help
36 This option enables support for the LEDs on Sharp Locomo.
37 Zaurus models SL-5500 and SL-5600.
38
39config LEDS_SPITZ
40 tristate "LED Support for the Sharp SL-Cxx00 series"
41 depends LEDS_CLASS && PXA_SHARP_Cxx00
42 help
43 This option enables support for the LEDs on Sharp Zaurus
44 SL-Cxx00 series (C1000, C3000, C3100).
45
46config LEDS_IXP4XX
47 tristate "LED Support for GPIO connected LEDs on IXP4XX processors"
48 depends LEDS_CLASS && ARCH_IXP4XX
49 help
50 This option enables support for the LEDs connected to GPIO
51 outputs of the Intel IXP4XX processors. To be useful the
52 particular board must have LEDs and they must be connected
53 to the GPIO lines. If unsure, say Y.
54
55config LEDS_TOSA
56 tristate "LED Support for the Sharp SL-6000 series"
57 depends LEDS_CLASS && PXA_SHARPSL
58 help
59 This option enables support for the LEDs on Sharp Zaurus
60 SL-6000 series.
61
62config LEDS_TRIGGER_TIMER
63 tristate "LED Timer Trigger"
64 depends LEDS_TRIGGERS
65 help
66 This allows LEDs to be controlled by a programmable timer
67 via sysfs. If unsure, say Y.
68
69config LEDS_TRIGGER_IDE_DISK
70 bool "LED Timer Trigger"
71 depends LEDS_TRIGGERS && BLK_DEV_IDEDISK
72 help
73 This allows LEDs to be controlled by IDE disk activity.
74 If unsure, say Y.
75
76endmenu
77
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
new file mode 100644
index 000000000000..40699d3cabbf
--- /dev/null
+++ b/drivers/leds/Makefile
@@ -0,0 +1,16 @@
1
2# LED Core
3obj-$(CONFIG_NEW_LEDS) += led-core.o
4obj-$(CONFIG_LEDS_CLASS) += led-class.o
5obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
6
7# LED Platform Drivers
8obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o
9obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
10obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
11obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o
12obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
13
14# LED Triggers
15obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
16obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
new file mode 100644
index 000000000000..b0b5d05fadd6
--- /dev/null
+++ b/drivers/leds/led-class.c
@@ -0,0 +1,167 @@
1/*
2 * LED Class Core
3 *
4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
5 * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/list.h>
17#include <linux/spinlock.h>
18#include <linux/device.h>
19#include <linux/sysdev.h>
20#include <linux/timer.h>
21#include <linux/err.h>
22#include <linux/leds.h>
23#include "leds.h"
24
25static struct class *leds_class;
26
27static ssize_t led_brightness_show(struct class_device *dev, char *buf)
28{
29 struct led_classdev *led_cdev = class_get_devdata(dev);
30 ssize_t ret = 0;
31
32 /* no lock needed for this */
33 sprintf(buf, "%u\n", led_cdev->brightness);
34 ret = strlen(buf) + 1;
35
36 return ret;
37}
38
39static ssize_t led_brightness_store(struct class_device *dev,
40 const char *buf, size_t size)
41{
42 struct led_classdev *led_cdev = class_get_devdata(dev);
43 ssize_t ret = -EINVAL;
44 char *after;
45 unsigned long state = simple_strtoul(buf, &after, 10);
46
47 if (after - buf > 0) {
48 ret = after - buf;
49 led_set_brightness(led_cdev, state);
50 }
51
52 return ret;
53}
54
55static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show,
56 led_brightness_store);
57#ifdef CONFIG_LEDS_TRIGGERS
58static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
59#endif
60
61/**
62 * led_classdev_suspend - suspend an led_classdev.
63 * @led_cdev: the led_classdev to suspend.
64 */
65void led_classdev_suspend(struct led_classdev *led_cdev)
66{
67 led_cdev->flags |= LED_SUSPENDED;
68 led_cdev->brightness_set(led_cdev, 0);
69}
70EXPORT_SYMBOL_GPL(led_classdev_suspend);
71
72/**
73 * led_classdev_resume - resume an led_classdev.
74 * @led_cdev: the led_classdev to resume.
75 */
76void led_classdev_resume(struct led_classdev *led_cdev)
77{
78 led_cdev->brightness_set(led_cdev, led_cdev->brightness);
79 led_cdev->flags &= ~LED_SUSPENDED;
80}
81EXPORT_SYMBOL_GPL(led_classdev_resume);
82
83/**
84 * led_classdev_register - register a new object of led_classdev class.
85 * @dev: The device to register.
86 * @led_cdev: the led_classdev structure for this device.
87 */
88int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
89{
90 led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
91 parent, "%s", led_cdev->name);
92 if (unlikely(IS_ERR(led_cdev->class_dev)))
93 return PTR_ERR(led_cdev->class_dev);
94
95 class_set_devdata(led_cdev->class_dev, led_cdev);
96
97 /* register the attributes */
98 class_device_create_file(led_cdev->class_dev,
99 &class_device_attr_brightness);
100
101 /* add to the list of leds */
102 write_lock(&leds_list_lock);
103 list_add_tail(&led_cdev->node, &leds_list);
104 write_unlock(&leds_list_lock);
105
106#ifdef CONFIG_LEDS_TRIGGERS
107 rwlock_init(&led_cdev->trigger_lock);
108
109 led_trigger_set_default(led_cdev);
110
111 class_device_create_file(led_cdev->class_dev,
112 &class_device_attr_trigger);
113#endif
114
115 printk(KERN_INFO "Registered led device: %s\n",
116 led_cdev->class_dev->class_id);
117
118 return 0;
119}
120EXPORT_SYMBOL_GPL(led_classdev_register);
121
122/**
123 * led_classdev_unregister - unregisters a object of led_properties class.
124 * @led_cdev: the led device to unreigister
125 *
126 * Unregisters a previously registered via led_classdev_register object.
127 */
128void led_classdev_unregister(struct led_classdev *led_cdev)
129{
130 class_device_remove_file(led_cdev->class_dev,
131 &class_device_attr_brightness);
132#ifdef CONFIG_LEDS_TRIGGERS
133 class_device_remove_file(led_cdev->class_dev,
134 &class_device_attr_trigger);
135 write_lock(&led_cdev->trigger_lock);
136 if (led_cdev->trigger)
137 led_trigger_set(led_cdev, NULL);
138 write_unlock(&led_cdev->trigger_lock);
139#endif
140
141 class_device_unregister(led_cdev->class_dev);
142
143 write_lock(&leds_list_lock);
144 list_del(&led_cdev->node);
145 write_unlock(&leds_list_lock);
146}
147EXPORT_SYMBOL_GPL(led_classdev_unregister);
148
149static int __init leds_init(void)
150{
151 leds_class = class_create(THIS_MODULE, "leds");
152 if (IS_ERR(leds_class))
153 return PTR_ERR(leds_class);
154 return 0;
155}
156
157static void __exit leds_exit(void)
158{
159 class_destroy(leds_class);
160}
161
162subsys_initcall(leds_init);
163module_exit(leds_exit);
164
165MODULE_AUTHOR("John Lenz, Richard Purdie");
166MODULE_LICENSE("GPL");
167MODULE_DESCRIPTION("LED Class Interface");
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
new file mode 100644
index 000000000000..fe6541326c71
--- /dev/null
+++ b/drivers/leds/led-core.c
@@ -0,0 +1,25 @@
1/*
2 * LED Class Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include <linux/spinlock.h>
18#include <linux/leds.h>
19#include "leds.h"
20
21rwlock_t leds_list_lock = RW_LOCK_UNLOCKED;
22LIST_HEAD(leds_list);
23
24EXPORT_SYMBOL_GPL(leds_list);
25EXPORT_SYMBOL_GPL(leds_list_lock);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
new file mode 100644
index 000000000000..5e2cd8be1191
--- /dev/null
+++ b/drivers/leds/led-triggers.c
@@ -0,0 +1,239 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/list.h>
19#include <linux/spinlock.h>
20#include <linux/device.h>
21#include <linux/sysdev.h>
22#include <linux/timer.h>
23#include <linux/leds.h>
24#include "leds.h"
25
26/*
27 * Nests outside led_cdev->trigger_lock
28 */
29static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED;
30static LIST_HEAD(trigger_list);
31
32ssize_t led_trigger_store(struct class_device *dev, const char *buf,
33 size_t count)
34{
35 struct led_classdev *led_cdev = class_get_devdata(dev);
36 char trigger_name[TRIG_NAME_MAX];
37 struct led_trigger *trig;
38 size_t len;
39
40 trigger_name[sizeof(trigger_name) - 1] = '\0';
41 strncpy(trigger_name, buf, sizeof(trigger_name) - 1);
42 len = strlen(trigger_name);
43
44 if (len && trigger_name[len - 1] == '\n')
45 trigger_name[len - 1] = '\0';
46
47 if (!strcmp(trigger_name, "none")) {
48 write_lock(&led_cdev->trigger_lock);
49 led_trigger_set(led_cdev, NULL);
50 write_unlock(&led_cdev->trigger_lock);
51 return count;
52 }
53
54 read_lock(&triggers_list_lock);
55 list_for_each_entry(trig, &trigger_list, next_trig) {
56 if (!strcmp(trigger_name, trig->name)) {
57 write_lock(&led_cdev->trigger_lock);
58 led_trigger_set(led_cdev, trig);
59 write_unlock(&led_cdev->trigger_lock);
60
61 read_unlock(&triggers_list_lock);
62 return count;
63 }
64 }
65 read_unlock(&triggers_list_lock);
66
67 return -EINVAL;
68}
69
70
71ssize_t led_trigger_show(struct class_device *dev, char *buf)
72{
73 struct led_classdev *led_cdev = class_get_devdata(dev);
74 struct led_trigger *trig;
75 int len = 0;
76
77 read_lock(&triggers_list_lock);
78 read_lock(&led_cdev->trigger_lock);
79
80 if (!led_cdev->trigger)
81 len += sprintf(buf+len, "[none] ");
82 else
83 len += sprintf(buf+len, "none ");
84
85 list_for_each_entry(trig, &trigger_list, next_trig) {
86 if (led_cdev->trigger && !strcmp(led_cdev->trigger->name,
87 trig->name))
88 len += sprintf(buf+len, "[%s] ", trig->name);
89 else
90 len += sprintf(buf+len, "%s ", trig->name);
91 }
92 read_unlock(&led_cdev->trigger_lock);
93 read_unlock(&triggers_list_lock);
94
95 len += sprintf(len+buf, "\n");
96 return len;
97}
98
99void led_trigger_event(struct led_trigger *trigger,
100 enum led_brightness brightness)
101{
102 struct list_head *entry;
103
104 if (!trigger)
105 return;
106
107 read_lock(&trigger->leddev_list_lock);
108 list_for_each(entry, &trigger->led_cdevs) {
109 struct led_classdev *led_cdev;
110
111 led_cdev = list_entry(entry, struct led_classdev, trig_list);
112 led_set_brightness(led_cdev, brightness);
113 }
114 read_unlock(&trigger->leddev_list_lock);
115}
116
117/* Caller must ensure led_cdev->trigger_lock held */
118void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
119{
120 unsigned long flags;
121
122 /* Remove any existing trigger */
123 if (led_cdev->trigger) {
124 write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
125 list_del(&led_cdev->trig_list);
126 write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
127 if (led_cdev->trigger->deactivate)
128 led_cdev->trigger->deactivate(led_cdev);
129 }
130 if (trigger) {
131 write_lock_irqsave(&trigger->leddev_list_lock, flags);
132 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs);
133 write_unlock_irqrestore(&trigger->leddev_list_lock, flags);
134 if (trigger->activate)
135 trigger->activate(led_cdev);
136 }
137 led_cdev->trigger = trigger;
138}
139
140void led_trigger_set_default(struct led_classdev *led_cdev)
141{
142 struct led_trigger *trig;
143
144 if (!led_cdev->default_trigger)
145 return;
146
147 read_lock(&triggers_list_lock);
148 write_lock(&led_cdev->trigger_lock);
149 list_for_each_entry(trig, &trigger_list, next_trig) {
150 if (!strcmp(led_cdev->default_trigger, trig->name))
151 led_trigger_set(led_cdev, trig);
152 }
153 write_unlock(&led_cdev->trigger_lock);
154 read_unlock(&triggers_list_lock);
155}
156
157int led_trigger_register(struct led_trigger *trigger)
158{
159 struct led_classdev *led_cdev;
160
161 rwlock_init(&trigger->leddev_list_lock);
162 INIT_LIST_HEAD(&trigger->led_cdevs);
163
164 /* Add to the list of led triggers */
165 write_lock(&triggers_list_lock);
166 list_add_tail(&trigger->next_trig, &trigger_list);
167 write_unlock(&triggers_list_lock);
168
169 /* Register with any LEDs that have this as a default trigger */
170 read_lock(&leds_list_lock);
171 list_for_each_entry(led_cdev, &leds_list, node) {
172 write_lock(&led_cdev->trigger_lock);
173 if (!led_cdev->trigger && led_cdev->default_trigger &&
174 !strcmp(led_cdev->default_trigger, trigger->name))
175 led_trigger_set(led_cdev, trigger);
176 write_unlock(&led_cdev->trigger_lock);
177 }
178 read_unlock(&leds_list_lock);
179
180 return 0;
181}
182
183void led_trigger_register_simple(const char *name, struct led_trigger **tp)
184{
185 struct led_trigger *trigger;
186
187 trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
188
189 if (trigger) {
190 trigger->name = name;
191 led_trigger_register(trigger);
192 }
193 *tp = trigger;
194}
195
196void led_trigger_unregister(struct led_trigger *trigger)
197{
198 struct led_classdev *led_cdev;
199
200 /* Remove from the list of led triggers */
201 write_lock(&triggers_list_lock);
202 list_del(&trigger->next_trig);
203 write_unlock(&triggers_list_lock);
204
205 /* Remove anyone actively using this trigger */
206 read_lock(&leds_list_lock);
207 list_for_each_entry(led_cdev, &leds_list, node) {
208 write_lock(&led_cdev->trigger_lock);
209 if (led_cdev->trigger == trigger)
210 led_trigger_set(led_cdev, NULL);
211 write_unlock(&led_cdev->trigger_lock);
212 }
213 read_unlock(&leds_list_lock);
214}
215
216void led_trigger_unregister_simple(struct led_trigger *trigger)
217{
218 led_trigger_unregister(trigger);
219 kfree(trigger);
220}
221
222/* Used by LED Class */
223EXPORT_SYMBOL_GPL(led_trigger_set);
224EXPORT_SYMBOL_GPL(led_trigger_set_default);
225EXPORT_SYMBOL_GPL(led_trigger_show);
226EXPORT_SYMBOL_GPL(led_trigger_store);
227
228/* LED Trigger Interface */
229EXPORT_SYMBOL_GPL(led_trigger_register);
230EXPORT_SYMBOL_GPL(led_trigger_unregister);
231
232/* Simple LED Tigger Interface */
233EXPORT_SYMBOL_GPL(led_trigger_register_simple);
234EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
235EXPORT_SYMBOL_GPL(led_trigger_event);
236
237MODULE_AUTHOR("Richard Purdie");
238MODULE_LICENSE("GPL");
239MODULE_DESCRIPTION("LED Triggers Core");
diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c
new file mode 100644
index 000000000000..bb7d84df0121
--- /dev/null
+++ b/drivers/leds/leds-corgi.c
@@ -0,0 +1,121 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <asm/mach-types.h>
20#include <asm/arch/corgi.h>
21#include <asm/arch/hardware.h>
22#include <asm/arch/pxa-regs.h>
23#include <asm/hardware/scoop.h>
24
25static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value)
26{
27 if (value)
28 GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
29 else
30 GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
31}
32
33static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
34{
35 if (value)
36 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
37 else
38 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
39}
40
41static struct led_classdev corgi_amber_led = {
42 .name = "corgi:amber",
43 .default_trigger = "sharpsl-charge",
44 .brightness_set = corgiled_amber_set,
45};
46
47static struct led_classdev corgi_green_led = {
48 .name = "corgi:green",
49 .default_trigger = "nand-disk",
50 .brightness_set = corgiled_green_set,
51};
52
53#ifdef CONFIG_PM
54static int corgiled_suspend(struct platform_device *dev, pm_message_t state)
55{
56#ifdef CONFIG_LEDS_TRIGGERS
57 if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge"))
58#endif
59 led_classdev_suspend(&corgi_amber_led);
60 led_classdev_suspend(&corgi_green_led);
61 return 0;
62}
63
64static int corgiled_resume(struct platform_device *dev)
65{
66 led_classdev_resume(&corgi_amber_led);
67 led_classdev_resume(&corgi_green_led);
68 return 0;
69}
70#endif
71
72static int corgiled_probe(struct platform_device *pdev)
73{
74 int ret;
75
76 ret = led_classdev_register(&pdev->dev, &corgi_amber_led);
77 if (ret < 0)
78 return ret;
79
80 ret = led_classdev_register(&pdev->dev, &corgi_green_led);
81 if (ret < 0)
82 led_classdev_unregister(&corgi_amber_led);
83
84 return ret;
85}
86
87static int corgiled_remove(struct platform_device *pdev)
88{
89 led_classdev_unregister(&corgi_amber_led);
90 led_classdev_unregister(&corgi_green_led);
91 return 0;
92}
93
94static struct platform_driver corgiled_driver = {
95 .probe = corgiled_probe,
96 .remove = corgiled_remove,
97#ifdef CONFIG_PM
98 .suspend = corgiled_suspend,
99 .resume = corgiled_resume,
100#endif
101 .driver = {
102 .name = "corgi-led",
103 },
104};
105
106static int __init corgiled_init(void)
107{
108 return platform_driver_register(&corgiled_driver);
109}
110
111static void __exit corgiled_exit(void)
112{
113 platform_driver_unregister(&corgiled_driver);
114}
115
116module_init(corgiled_init);
117module_exit(corgiled_exit);
118
119MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
120MODULE_DESCRIPTION("Corgi LED driver");
121MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-ixp4xx-gpio.c b/drivers/leds/leds-ixp4xx-gpio.c
new file mode 100644
index 000000000000..30ced150e4cf
--- /dev/null
+++ b/drivers/leds/leds-ixp4xx-gpio.c
@@ -0,0 +1,215 @@
1/*
2 * IXP4XX GPIO driver LED driver
3 *
4 * Author: John Bowler <jbowler@acm.org>
5 *
6 * Copyright (c) 2006 John Bowler
7 *
8 * Permission is hereby granted, free of charge, to any
9 * person obtaining a copy of this software and associated
10 * documentation files (the "Software"), to deal in the
11 * Software without restriction, including without
12 * limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of
14 * the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the
16 * following conditions:
17 *
18 * The above copyright notice and this permission notice
19 * shall be included in all copies or substantial portions
20 * of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
23 * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
24 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
25 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
26 * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
27 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 * OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34#include <linux/config.h>
35#include <linux/kernel.h>
36#include <linux/init.h>
37#include <linux/platform_device.h>
38#include <linux/spinlock.h>
39#include <linux/leds.h>
40#include <asm/arch/hardware.h>
41
42extern spinlock_t gpio_lock;
43
44/* Up to 16 gpio lines are possible. */
45#define GPIO_MAX 16
46static struct ixp4xxgpioled_device {
47 struct led_classdev ancestor;
48 int flags;
49} ixp4xxgpioled_devices[GPIO_MAX];
50
51void ixp4xxgpioled_brightness_set(struct led_classdev *pled,
52 enum led_brightness value)
53{
54 const struct ixp4xxgpioled_device *const ixp4xx_dev =
55 container_of(pled, struct ixp4xxgpioled_device, ancestor);
56 const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices;
57
58 if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) {
59 /* Set or clear the 'gpio_pin' bit according to the style
60 * and the required setting (value > 0 == on)
61 */
62 const int gpio_value =
63 (value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ?
64 IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW;
65
66 {
67 unsigned long flags;
68 spin_lock_irqsave(&gpio_lock, flags);
69 gpio_line_set(gpio_pin, gpio_value);
70 spin_unlock_irqrestore(&gpio_lock, flags);
71 }
72 }
73}
74
75/* LEDs are described in resources, the following iterates over the valid
76 * LED resources.
77 */
78#define for_all_leds(i, pdev) \
79 for (i=0; i<pdev->num_resources; ++i) \
80 if (pdev->resource[i].start < GPIO_MAX && \
81 pdev->resource[i].name != 0)
82
83/* The following applies 'operation' to each LED from the given platform,
84 * the function always returns 0 to allow tail call elimination.
85 */
86static int apply_to_all_leds(struct platform_device *pdev,
87 void (*operation)(struct led_classdev *pled))
88{
89 int i;
90
91 for_all_leds(i, pdev)
92 operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor);
93 return 0;
94}
95
96#ifdef CONFIG_PM
97static int ixp4xxgpioled_suspend(struct platform_device *pdev,
98 pm_message_t state)
99{
100 return apply_to_all_leds(pdev, led_classdev_suspend);
101}
102
103static int ixp4xxgpioled_resume(struct platform_device *pdev)
104{
105 return apply_to_all_leds(pdev, led_classdev_resume);
106}
107#endif
108
109static void ixp4xxgpioled_remove_one_led(struct led_classdev *pled)
110{
111 led_classdev_unregister(pled);
112 pled->name = 0;
113}
114
115static int ixp4xxgpioled_remove(struct platform_device *pdev)
116{
117 return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led);
118}
119
120static int ixp4xxgpioled_probe(struct platform_device *pdev)
121{
122 /* The board level has to tell the driver where the
123 * LEDs are connected - there is no way to find out
124 * electrically. It must also say whether the GPIO
125 * lines are active high or active low.
126 *
127 * To do this read the num_resources (the number of
128 * LEDs) and the struct resource (the data for each
129 * LED). The name comes from the resource, and it
130 * isn't copied.
131 */
132 int i;
133
134 for_all_leds(i, pdev) {
135 const u8 gpio_pin = pdev->resource[i].start;
136 int rc;
137
138 if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) {
139 unsigned long flags;
140
141 spin_lock_irqsave(&gpio_lock, flags);
142 gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT);
143 /* The config can, apparently, reset the state,
144 * I suspect the gpio line may be an input and
145 * the config may cause the line to be latched,
146 * so the setting depends on how the LED is
147 * connected to the line (which affects how it
148 * floats if not driven).
149 */
150 gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH);
151 spin_unlock_irqrestore(&gpio_lock, flags);
152
153 ixp4xxgpioled_devices[gpio_pin].flags =
154 pdev->resource[i].flags & IORESOURCE_BITS;
155
156 ixp4xxgpioled_devices[gpio_pin].ancestor.name =
157 pdev->resource[i].name;
158
159 /* This is how a board manufacturer makes the LED
160 * come on on reset - the GPIO line will be high, so
161 * make the LED light when the line is low...
162 */
163 if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW)
164 ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100;
165 else
166 ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0;
167
168 ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0;
169
170 ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set =
171 ixp4xxgpioled_brightness_set;
172
173 ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0;
174 }
175
176 rc = led_classdev_register(&pdev->dev,
177 &ixp4xxgpioled_devices[gpio_pin].ancestor);
178 if (rc < 0) {
179 ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0;
180 ixp4xxgpioled_remove(pdev);
181 return rc;
182 }
183 }
184
185 return 0;
186}
187
188static struct platform_driver ixp4xxgpioled_driver = {
189 .probe = ixp4xxgpioled_probe,
190 .remove = ixp4xxgpioled_remove,
191#ifdef CONFIG_PM
192 .suspend = ixp4xxgpioled_suspend,
193 .resume = ixp4xxgpioled_resume,
194#endif
195 .driver = {
196 .name = "IXP4XX-GPIO-LED",
197 },
198};
199
200static int __init ixp4xxgpioled_init(void)
201{
202 return platform_driver_register(&ixp4xxgpioled_driver);
203}
204
205static void __exit ixp4xxgpioled_exit(void)
206{
207 platform_driver_unregister(&ixp4xxgpioled_driver);
208}
209
210module_init(ixp4xxgpioled_init);
211module_exit(ixp4xxgpioled_exit);
212
213MODULE_AUTHOR("John Bowler <jbowler@acm.org>");
214MODULE_DESCRIPTION("IXP4XX GPIO LED driver");
215MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
new file mode 100644
index 000000000000..749a86c2adb6
--- /dev/null
+++ b/drivers/leds/leds-locomo.c
@@ -0,0 +1,95 @@
1/*
2 * linux/drivers/leds/locomo.c
3 *
4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/device.h>
15#include <linux/leds.h>
16
17#include <asm/hardware.h>
18#include <asm/hardware/locomo.h>
19
20static void locomoled_brightness_set(struct led_classdev *led_cdev,
21 enum led_brightness value, int offset)
22{
23 struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev);
24 unsigned long flags;
25
26 local_irq_save(flags);
27 if (value)
28 locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
29 else
30 locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
31 local_irq_restore(flags);
32}
33
34static void locomoled_brightness_set0(struct led_classdev *led_cdev,
35 enum led_brightness value)
36{
37 locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
38}
39
40static void locomoled_brightness_set1(struct led_classdev *led_cdev,
41 enum led_brightness value)
42{
43 locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
44}
45
46static struct led_classdev locomo_led0 = {
47 .name = "locomo:amber",
48 .brightness_set = locomoled_brightness_set0,
49};
50
51static struct led_classdev locomo_led1 = {
52 .name = "locomo:green",
53 .brightness_set = locomoled_brightness_set1,
54};
55
56static int locomoled_probe(struct locomo_dev *ldev)
57{
58 int ret;
59
60 ret = led_classdev_register(&ldev->dev, &locomo_led0);
61 if (ret < 0)
62 return ret;
63
64 ret = led_classdev_register(&ldev->dev, &locomo_led1);
65 if (ret < 0)
66 led_classdev_unregister(&locomo_led0);
67
68 return ret;
69}
70
71static int locomoled_remove(struct locomo_dev *dev)
72{
73 led_classdev_unregister(&locomo_led0);
74 led_classdev_unregister(&locomo_led1);
75 return 0;
76}
77
78static struct locomo_driver locomoled_driver = {
79 .drv = {
80 .name = "locomoled"
81 },
82 .devid = LOCOMO_DEVID_LED,
83 .probe = locomoled_probe,
84 .remove = locomoled_remove,
85};
86
87static int __init locomoled_init(void)
88{
89 return locomo_driver_register(&locomoled_driver);
90}
91module_init(locomoled_init);
92
93MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
94MODULE_DESCRIPTION("Locomo LED driver");
95MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c
new file mode 100644
index 000000000000..65bbef4a5e09
--- /dev/null
+++ b/drivers/leds/leds-spitz.c
@@ -0,0 +1,125 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <asm/hardware/scoop.h>
20#include <asm/mach-types.h>
21#include <asm/arch/hardware.h>
22#include <asm/arch/pxa-regs.h>
23#include <asm/arch/spitz.h>
24
25static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value)
26{
27 if (value)
28 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
29 else
30 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
31}
32
33static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
34{
35 if (value)
36 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
37 else
38 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
39}
40
41static struct led_classdev spitz_amber_led = {
42 .name = "spitz:amber",
43 .default_trigger = "sharpsl-charge",
44 .brightness_set = spitzled_amber_set,
45};
46
47static struct led_classdev spitz_green_led = {
48 .name = "spitz:green",
49 .default_trigger = "ide-disk",
50 .brightness_set = spitzled_green_set,
51};
52
53#ifdef CONFIG_PM
54static int spitzled_suspend(struct platform_device *dev, pm_message_t state)
55{
56#ifdef CONFIG_LEDS_TRIGGERS
57 if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge"))
58#endif
59 led_classdev_suspend(&spitz_amber_led);
60 led_classdev_suspend(&spitz_green_led);
61 return 0;
62}
63
64static int spitzled_resume(struct platform_device *dev)
65{
66 led_classdev_resume(&spitz_amber_led);
67 led_classdev_resume(&spitz_green_led);
68 return 0;
69}
70#endif
71
72static int spitzled_probe(struct platform_device *pdev)
73{
74 int ret;
75
76 if (machine_is_akita())
77 spitz_green_led.default_trigger = "nand-disk";
78
79 ret = led_classdev_register(&pdev->dev, &spitz_amber_led);
80 if (ret < 0)
81 return ret;
82
83 ret = led_classdev_register(&pdev->dev, &spitz_green_led);
84 if (ret < 0)
85 led_classdev_unregister(&spitz_amber_led);
86
87 return ret;
88}
89
90static int spitzled_remove(struct platform_device *pdev)
91{
92 led_classdev_unregister(&spitz_amber_led);
93 led_classdev_unregister(&spitz_green_led);
94
95 return 0;
96}
97
98static struct platform_driver spitzled_driver = {
99 .probe = spitzled_probe,
100 .remove = spitzled_remove,
101#ifdef CONFIG_PM
102 .suspend = spitzled_suspend,
103 .resume = spitzled_resume,
104#endif
105 .driver = {
106 .name = "spitz-led",
107 },
108};
109
110static int __init spitzled_init(void)
111{
112 return platform_driver_register(&spitzled_driver);
113}
114
115static void __exit spitzled_exit(void)
116{
117 platform_driver_unregister(&spitzled_driver);
118}
119
120module_init(spitzled_init);
121module_exit(spitzled_exit);
122
123MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
124MODULE_DESCRIPTION("Spitz LED driver");
125MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c
new file mode 100644
index 000000000000..c9e8cc1ec481
--- /dev/null
+++ b/drivers/leds/leds-tosa.c
@@ -0,0 +1,131 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005 Dirk Opfer
5 *
6 * Author: Dirk Opfer <Dirk@Opfer-Online.de>
7 * based on spitz.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/config.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/leds.h>
20#include <asm/hardware/scoop.h>
21#include <asm/mach-types.h>
22#include <asm/arch/hardware.h>
23#include <asm/arch/pxa-regs.h>
24#include <asm/arch/tosa.h>
25
26static void tosaled_amber_set(struct led_classdev *led_cdev,
27 enum led_brightness value)
28{
29 if (value)
30 set_scoop_gpio(&tosascoop_jc_device.dev,
31 TOSA_SCOOP_JC_CHRG_ERR_LED);
32 else
33 reset_scoop_gpio(&tosascoop_jc_device.dev,
34 TOSA_SCOOP_JC_CHRG_ERR_LED);
35}
36
37static void tosaled_green_set(struct led_classdev *led_cdev,
38 enum led_brightness value)
39{
40 if (value)
41 set_scoop_gpio(&tosascoop_jc_device.dev,
42 TOSA_SCOOP_JC_NOTE_LED);
43 else
44 reset_scoop_gpio(&tosascoop_jc_device.dev,
45 TOSA_SCOOP_JC_NOTE_LED);
46}
47
48static struct led_classdev tosa_amber_led = {
49 .name = "tosa:amber",
50 .default_trigger = "sharpsl-charge",
51 .brightness_set = tosaled_amber_set,
52};
53
54static struct led_classdev tosa_green_led = {
55 .name = "tosa:green",
56 .default_trigger = "nand-disk",
57 .brightness_set = tosaled_green_set,
58};
59
60#ifdef CONFIG_PM
61static int tosaled_suspend(struct platform_device *dev, pm_message_t state)
62{
63#ifdef CONFIG_LEDS_TRIGGERS
64 if (tosa_amber_led.trigger && strcmp(tosa_amber_led.trigger->name,
65 "sharpsl-charge"))
66#endif
67 led_classdev_suspend(&tosa_amber_led);
68 led_classdev_suspend(&tosa_green_led);
69 return 0;
70}
71
72static int tosaled_resume(struct platform_device *dev)
73{
74 led_classdev_resume(&tosa_amber_led);
75 led_classdev_resume(&tosa_green_led);
76 return 0;
77}
78#else
79#define tosaled_suspend NULL
80#define tosaled_resume NULL
81#endif
82
83static int tosaled_probe(struct platform_device *pdev)
84{
85 int ret;
86
87 ret = led_classdev_register(&pdev->dev, &tosa_amber_led);
88 if (ret < 0)
89 return ret;
90
91 ret = led_classdev_register(&pdev->dev, &tosa_green_led);
92 if (ret < 0)
93 led_classdev_unregister(&tosa_amber_led);
94
95 return ret;
96}
97
98static int tosaled_remove(struct platform_device *pdev)
99{
100 led_classdev_unregister(&tosa_amber_led);
101 led_classdev_unregister(&tosa_green_led);
102
103 return 0;
104}
105
106static struct platform_driver tosaled_driver = {
107 .probe = tosaled_probe,
108 .remove = tosaled_remove,
109 .suspend = tosaled_suspend,
110 .resume = tosaled_resume,
111 .driver = {
112 .name = "tosa-led",
113 },
114};
115
116static int __init tosaled_init(void)
117{
118 return platform_driver_register(&tosaled_driver);
119}
120
121static void __exit tosaled_exit(void)
122{
123 platform_driver_unregister(&tosaled_driver);
124}
125
126module_init(tosaled_init);
127module_exit(tosaled_exit);
128
129MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
130MODULE_DESCRIPTION("Tosa LED driver");
131MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
new file mode 100644
index 000000000000..a715c4ed93ff
--- /dev/null
+++ b/drivers/leds/leds.h
@@ -0,0 +1,44 @@
1/*
2 * LED Core
3 *
4 * Copyright 2005 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13#ifndef __LEDS_H_INCLUDED
14#define __LEDS_H_INCLUDED
15
16#include <linux/leds.h>
17
18static inline void led_set_brightness(struct led_classdev *led_cdev,
19 enum led_brightness value)
20{
21 if (value > LED_FULL)
22 value = LED_FULL;
23 led_cdev->brightness = value;
24 if (!(led_cdev->flags & LED_SUSPENDED))
25 led_cdev->brightness_set(led_cdev, value);
26}
27
28extern rwlock_t leds_list_lock;
29extern struct list_head leds_list;
30
31#ifdef CONFIG_LEDS_TRIGGERS
32void led_trigger_set_default(struct led_classdev *led_cdev);
33void led_trigger_set(struct led_classdev *led_cdev,
34 struct led_trigger *trigger);
35#else
36#define led_trigger_set_default(x) do {} while(0)
37#define led_trigger_set(x, y) do {} while(0)
38#endif
39
40ssize_t led_trigger_store(struct class_device *dev, const char *buf,
41 size_t count);
42ssize_t led_trigger_show(struct class_device *dev, char *buf);
43
44#endif /* __LEDS_H_INCLUDED */
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
new file mode 100644
index 000000000000..fa651886ab4f
--- /dev/null
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -0,0 +1,62 @@
1/*
2 * LED IDE-Disk Activity Trigger
3 *
4 * Copyright 2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/timer.h>
18#include <linux/leds.h>
19
20static void ledtrig_ide_timerfunc(unsigned long data);
21
22DEFINE_LED_TRIGGER(ledtrig_ide);
23static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
24static int ide_activity;
25static int ide_lastactivity;
26
27void ledtrig_ide_activity(void)
28{
29 ide_activity++;
30 if (!timer_pending(&ledtrig_ide_timer))
31 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
32}
33EXPORT_SYMBOL(ledtrig_ide_activity);
34
35static void ledtrig_ide_timerfunc(unsigned long data)
36{
37 if (ide_lastactivity != ide_activity) {
38 ide_lastactivity = ide_activity;
39 led_trigger_event(ledtrig_ide, LED_FULL);
40 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
41 } else {
42 led_trigger_event(ledtrig_ide, LED_OFF);
43 }
44}
45
46static int __init ledtrig_ide_init(void)
47{
48 led_trigger_register_simple("ide-disk", &ledtrig_ide);
49 return 0;
50}
51
52static void __exit ledtrig_ide_exit(void)
53{
54 led_trigger_unregister_simple(ledtrig_ide);
55}
56
57module_init(ledtrig_ide_init);
58module_exit(ledtrig_ide_exit);
59
60MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
61MODULE_DESCRIPTION("LED IDE Disk Activity Trigger");
62MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
new file mode 100644
index 000000000000..f484b5d6dbf8
--- /dev/null
+++ b/drivers/leds/ledtrig-timer.c
@@ -0,0 +1,170 @@
1/*
2 * LED Kernel Timer Trigger
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/list.h>
19#include <linux/spinlock.h>
20#include <linux/device.h>
21#include <linux/sysdev.h>
22#include <linux/timer.h>
23#include <linux/leds.h>
24#include "leds.h"
25
26struct timer_trig_data {
27 unsigned long delay_on; /* milliseconds on */
28 unsigned long delay_off; /* milliseconds off */
29 struct timer_list timer;
30};
31
32static void led_timer_function(unsigned long data)
33{
34 struct led_classdev *led_cdev = (struct led_classdev *) data;
35 struct timer_trig_data *timer_data = led_cdev->trigger_data;
36 unsigned long brightness = LED_OFF;
37 unsigned long delay = timer_data->delay_off;
38
39 if (!timer_data->delay_on || !timer_data->delay_off) {
40 led_set_brightness(led_cdev, LED_OFF);
41 return;
42 }
43
44 if (!led_cdev->brightness) {
45 brightness = LED_FULL;
46 delay = timer_data->delay_on;
47 }
48
49 led_set_brightness(led_cdev, brightness);
50
51 mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
52}
53
54static ssize_t led_delay_on_show(struct class_device *dev, char *buf)
55{
56 struct led_classdev *led_cdev = class_get_devdata(dev);
57 struct timer_trig_data *timer_data = led_cdev->trigger_data;
58
59 sprintf(buf, "%lu\n", timer_data->delay_on);
60
61 return strlen(buf) + 1;
62}
63
64static ssize_t led_delay_on_store(struct class_device *dev, const char *buf,
65 size_t size)
66{
67 struct led_classdev *led_cdev = class_get_devdata(dev);
68 struct timer_trig_data *timer_data = led_cdev->trigger_data;
69 int ret = -EINVAL;
70 char *after;
71 unsigned long state = simple_strtoul(buf, &after, 10);
72
73 if (after - buf > 0) {
74 timer_data->delay_on = state;
75 mod_timer(&timer_data->timer, jiffies + 1);
76 ret = after - buf;
77 }
78
79 return ret;
80}
81
82static ssize_t led_delay_off_show(struct class_device *dev, char *buf)
83{
84 struct led_classdev *led_cdev = class_get_devdata(dev);
85 struct timer_trig_data *timer_data = led_cdev->trigger_data;
86
87 sprintf(buf, "%lu\n", timer_data->delay_off);
88
89 return strlen(buf) + 1;
90}
91
92static ssize_t led_delay_off_store(struct class_device *dev, const char *buf,
93 size_t size)
94{
95 struct led_classdev *led_cdev = class_get_devdata(dev);
96 struct timer_trig_data *timer_data = led_cdev->trigger_data;
97 int ret = -EINVAL;
98 char *after;
99 unsigned long state = simple_strtoul(buf, &after, 10);
100
101 if (after - buf > 0) {
102 timer_data->delay_off = state;
103 mod_timer(&timer_data->timer, jiffies + 1);
104 ret = after - buf;
105 }
106
107 return ret;
108}
109
110static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show,
111 led_delay_on_store);
112static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show,
113 led_delay_off_store);
114
115static void timer_trig_activate(struct led_classdev *led_cdev)
116{
117 struct timer_trig_data *timer_data;
118
119 timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL);
120 if (!timer_data)
121 return;
122
123 led_cdev->trigger_data = timer_data;
124
125 init_timer(&timer_data->timer);
126 timer_data->timer.function = led_timer_function;
127 timer_data->timer.data = (unsigned long) led_cdev;
128
129 class_device_create_file(led_cdev->class_dev,
130 &class_device_attr_delay_on);
131 class_device_create_file(led_cdev->class_dev,
132 &class_device_attr_delay_off);
133}
134
135static void timer_trig_deactivate(struct led_classdev *led_cdev)
136{
137 struct timer_trig_data *timer_data = led_cdev->trigger_data;
138
139 if (timer_data) {
140 class_device_remove_file(led_cdev->class_dev,
141 &class_device_attr_delay_on);
142 class_device_remove_file(led_cdev->class_dev,
143 &class_device_attr_delay_off);
144 del_timer_sync(&timer_data->timer);
145 kfree(timer_data);
146 }
147}
148
149static struct led_trigger timer_led_trigger = {
150 .name = "timer",
151 .activate = timer_trig_activate,
152 .deactivate = timer_trig_deactivate,
153};
154
155static int __init timer_trig_init(void)
156{
157 return led_trigger_register(&timer_led_trigger);
158}
159
160static void __exit timer_trig_exit(void)
161{
162 led_trigger_unregister(&timer_led_trigger);
163}
164
165module_init(timer_trig_init);
166module_exit(timer_trig_exit);
167
168MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
169MODULE_DESCRIPTION("Timer LED trigger");
170MODULE_LICENSE("GPL");
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 039e071c1007..1ed5152db450 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -215,13 +215,11 @@ static void mddev_put(mddev_t *mddev)
215 return; 215 return;
216 if (!mddev->raid_disks && list_empty(&mddev->disks)) { 216 if (!mddev->raid_disks && list_empty(&mddev->disks)) {
217 list_del(&mddev->all_mddevs); 217 list_del(&mddev->all_mddevs);
218 /* that blocks */ 218 spin_unlock(&all_mddevs_lock);
219 blk_cleanup_queue(mddev->queue); 219 blk_cleanup_queue(mddev->queue);
220 /* that also blocks */
221 kobject_unregister(&mddev->kobj); 220 kobject_unregister(&mddev->kobj);
222 /* result blows... */ 221 } else
223 } 222 spin_unlock(&all_mddevs_lock);
224 spin_unlock(&all_mddevs_lock);
225} 223}
226 224
227static mddev_t * mddev_find(dev_t unit) 225static mddev_t * mddev_find(dev_t unit)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3cb0872a845d..9b374c91db66 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1135,8 +1135,19 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error)
1135 mirror = i; 1135 mirror = i;
1136 break; 1136 break;
1137 } 1137 }
1138 if (!uptodate) 1138 if (!uptodate) {
1139 int sync_blocks = 0;
1140 sector_t s = r1_bio->sector;
1141 long sectors_to_go = r1_bio->sectors;
1142 /* make sure these bits doesn't get cleared. */
1143 do {
1144 bitmap_end_sync(mddev->bitmap, r1_bio->sector,
1145 &sync_blocks, 1);
1146 s += sync_blocks;
1147 sectors_to_go -= sync_blocks;
1148 } while (sectors_to_go > 0);
1139 md_error(mddev, conf->mirrors[mirror].rdev); 1149 md_error(mddev, conf->mirrors[mirror].rdev);
1150 }
1140 1151
1141 update_head_pos(mirror, r1_bio); 1152 update_head_pos(mirror, r1_bio);
1142 1153
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 6df4930fddec..ab64b37e4996 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -2151,6 +2151,8 @@ static int run(mddev_t *mddev)
2151 } 2151 }
2152 2152
2153 /* Ok, everything is just fine now */ 2153 /* Ok, everything is just fine now */
2154 sysfs_create_group(&mddev->kobj, &raid6_attrs_group);
2155
2154 mddev->array_size = mddev->size * (mddev->raid_disks - 2); 2156 mddev->array_size = mddev->size * (mddev->raid_disks - 2);
2155 2157
2156 mddev->queue->unplug_fn = raid6_unplug_device; 2158 mddev->queue->unplug_fn = raid6_unplug_device;
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 3021f21aae36..0b00e6027dfb 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -873,7 +873,7 @@ static int __init cpia_pp_setup(char *str)
873 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; 873 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
874 } 874 }
875 875
876 return 0; 876 return 1;
877} 877}
878 878
879__setup("cpia_pp=", cpia_pp_setup); 879__setup("cpia_pp=", cpia_pp_setup);
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index fdb91b6f1d97..57115618c496 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -664,7 +664,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
664 printk("%s: Probing for AMD compatible flash...\n", map->name); 664 printk("%s: Probing for AMD compatible flash...\n", map->name);
665 665
666 if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, 666 if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table,
667 sizeof(table)/sizeof(table[0]))) 667 ARRAY_SIZE(table)))
668 == -1) { 668 == -1) {
669 printk(KERN_WARNING 669 printk(KERN_WARNING
670 "%s: Found no AMD compatible device at location zero\n", 670 "%s: Found no AMD compatible device at location zero\n",
@@ -696,7 +696,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
696 base += (1 << temp.chipshift)) { 696 base += (1 << temp.chipshift)) {
697 int numchips = temp.numchips; 697 int numchips = temp.numchips;
698 table_pos[numchips] = probe_new_chip(mtd, base, chips, 698 table_pos[numchips] = probe_new_chip(mtd, base, chips,
699 &temp, table, sizeof(table)/sizeof(table[0])); 699 &temp, table, ARRAY_SIZE(table));
700 } 700 }
701 701
702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * 702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index edb306c03c0a..517ea33e7260 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -34,6 +34,7 @@
34#define MANUFACTURER_MACRONIX 0x00C2 34#define MANUFACTURER_MACRONIX 0x00C2
35#define MANUFACTURER_NEC 0x0010 35#define MANUFACTURER_NEC 0x0010
36#define MANUFACTURER_PMC 0x009D 36#define MANUFACTURER_PMC 0x009D
37#define MANUFACTURER_SHARP 0x00b0
37#define MANUFACTURER_SST 0x00BF 38#define MANUFACTURER_SST 0x00BF
38#define MANUFACTURER_ST 0x0020 39#define MANUFACTURER_ST 0x0020
39#define MANUFACTURER_TOSHIBA 0x0098 40#define MANUFACTURER_TOSHIBA 0x0098
@@ -124,6 +125,9 @@
124#define PM49FL004 0x006E 125#define PM49FL004 0x006E
125#define PM49FL008 0x006A 126#define PM49FL008 0x006A
126 127
128/* Sharp */
129#define LH28F640BF 0x00b0
130
127/* ST - www.st.com */ 131/* ST - www.st.com */
128#define M29W800DT 0x00D7 132#define M29W800DT 0x00D7
129#define M29W800DB 0x005B 133#define M29W800DB 0x005B
@@ -1267,6 +1271,19 @@ static const struct amd_flash_info jedec_table[] = {
1267 .regions = { 1271 .regions = {
1268 ERASEINFO( 0x01000, 256 ) 1272 ERASEINFO( 0x01000, 256 )
1269 } 1273 }
1274 }, {
1275 .mfr_id = MANUFACTURER_SHARP,
1276 .dev_id = LH28F640BF,
1277 .name = "LH28F640BF",
1278 .uaddr = {
1279 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1280 },
1281 .DevSize = SIZE_4MiB,
1282 .CmdSet = P_ID_INTEL_STD,
1283 .NumEraseRegions= 1,
1284 .regions = {
1285 ERASEINFO(0x40000,16),
1286 }
1270 }, { 1287 }, {
1271 .mfr_id = MANUFACTURER_SST, 1288 .mfr_id = MANUFACTURER_SST,
1272 .dev_id = SST39LF512, 1289 .dev_id = SST39LF512,
@@ -2035,7 +2052,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2035 DEBUG(MTD_DEBUG_LEVEL3, 2052 DEBUG(MTD_DEBUG_LEVEL3,
2036 "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 2053 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
2037 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); 2054 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
2038 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { 2055 for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
2039 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { 2056 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
2040 DEBUG( MTD_DEBUG_LEVEL3, 2057 DEBUG( MTD_DEBUG_LEVEL3,
2041 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", 2058 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index 36f61a6a766e..3cc0b23c5865 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -64,7 +64,7 @@
64 64
65#undef AUTOUNLOCK /* automatically unlocks blocks before erasing */ 65#undef AUTOUNLOCK /* automatically unlocks blocks before erasing */
66 66
67struct mtd_info *sharp_probe(struct map_info *); 67static struct mtd_info *sharp_probe(struct map_info *);
68 68
69static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd); 69static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
70 70
@@ -96,7 +96,6 @@ struct sharp_info{
96 struct flchip chips[1]; 96 struct flchip chips[1];
97}; 97};
98 98
99struct mtd_info *sharp_probe(struct map_info *map);
100static void sharp_destroy(struct mtd_info *mtd); 99static void sharp_destroy(struct mtd_info *mtd);
101 100
102static struct mtd_chip_driver sharp_chipdrv = { 101static struct mtd_chip_driver sharp_chipdrv = {
@@ -107,7 +106,7 @@ static struct mtd_chip_driver sharp_chipdrv = {
107}; 106};
108 107
109 108
110struct mtd_info *sharp_probe(struct map_info *map) 109static struct mtd_info *sharp_probe(struct map_info *map)
111{ 110{
112 struct mtd_info *mtd = NULL; 111 struct mtd_info *mtd = NULL;
113 struct sharp_info *sharp = NULL; 112 struct sharp_info *sharp = NULL;
@@ -581,7 +580,7 @@ static void sharp_destroy(struct mtd_info *mtd)
581 580
582} 581}
583 582
584int __init sharp_probe_init(void) 583static int __init sharp_probe_init(void)
585{ 584{
586 printk("MTD Sharp chip driver <ds@lineo.com>\n"); 585 printk("MTD Sharp chip driver <ds@lineo.com>\n");
587 586
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 6b8bb2e4dcfd..a7a7bfe33879 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -42,7 +42,8 @@
42 42
43 43
44/* special size referring to all the remaining space in a partition */ 44/* special size referring to all the remaining space in a partition */
45#define SIZE_REMAINING 0xffffffff 45#define SIZE_REMAINING UINT_MAX
46#define OFFSET_CONTINUOUS UINT_MAX
46 47
47struct cmdline_mtd_partition { 48struct cmdline_mtd_partition {
48 struct cmdline_mtd_partition *next; 49 struct cmdline_mtd_partition *next;
@@ -75,7 +76,7 @@ static struct mtd_partition * newpart(char *s,
75{ 76{
76 struct mtd_partition *parts; 77 struct mtd_partition *parts;
77 unsigned long size; 78 unsigned long size;
78 unsigned long offset = 0; 79 unsigned long offset = OFFSET_CONTINUOUS;
79 char *name; 80 char *name;
80 int name_len; 81 int name_len;
81 unsigned char *extra_mem; 82 unsigned char *extra_mem;
@@ -314,7 +315,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
314 { 315 {
315 for(i = 0, offset = 0; i < part->num_parts; i++) 316 for(i = 0, offset = 0; i < part->num_parts; i++)
316 { 317 {
317 if (!part->parts[i].offset) 318 if (part->parts[i].offset == OFFSET_CONTINUOUS)
318 part->parts[i].offset = offset; 319 part->parts[i].offset = offset;
319 else 320 else
320 offset = part->parts[i].offset; 321 offset = part->parts[i].offset;
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 04f864d238db..79f2e1f23ebd 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -28,8 +28,9 @@
28#include <linux/pagemap.h> 28#include <linux/pagemap.h>
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/mount.h>
31#include <linux/mtd/mtd.h> 32#include <linux/mtd/mtd.h>
32 33#include <linux/mutex.h>
33 34
34#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) 35#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg)
35#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) 36#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg)
@@ -46,7 +47,7 @@ struct blkmtd_dev {
46 struct list_head list; 47 struct list_head list;
47 struct block_device *blkdev; 48 struct block_device *blkdev;
48 struct mtd_info mtd_info; 49 struct mtd_info mtd_info;
49 struct semaphore wrbuf_mutex; 50 struct mutex wrbuf_mutex;
50}; 51};
51 52
52 53
@@ -268,7 +269,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
268 if(end_len) 269 if(end_len)
269 pagecnt++; 270 pagecnt++;
270 271
271 down(&dev->wrbuf_mutex); 272 mutex_lock(&dev->wrbuf_mutex);
272 273
273 DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", 274 DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n",
274 start_len, len, end_len, pagecnt); 275 start_len, len, end_len, pagecnt);
@@ -376,7 +377,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
376 blkmtd_write_out(bio); 377 blkmtd_write_out(bio);
377 378
378 DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); 379 DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err);
379 up(&dev->wrbuf_mutex); 380 mutex_unlock(&dev->wrbuf_mutex);
380 381
381 if(retlen) 382 if(retlen)
382 *retlen = thislen; 383 *retlen = thislen;
@@ -614,8 +615,6 @@ static struct mtd_erase_region_info *calc_erase_regions(
614} 615}
615 616
616 617
617extern dev_t __init name_to_dev_t(const char *line);
618
619static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) 618static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size)
620{ 619{
621 struct block_device *bdev; 620 struct block_device *bdev;
@@ -659,7 +658,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
659 memset(dev, 0, sizeof(struct blkmtd_dev)); 658 memset(dev, 0, sizeof(struct blkmtd_dev));
660 dev->blkdev = bdev; 659 dev->blkdev = bdev;
661 if(!readonly) { 660 if(!readonly) {
662 init_MUTEX(&dev->wrbuf_mutex); 661 mutex_init(&dev->wrbuf_mutex);
663 } 662 }
664 663
665 dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; 664 dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 7ff403b2a0a0..4160b8334c53 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -18,6 +18,7 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <linux/mutex.h>
21 22
22#define VERSION "$Revision: 1.30 $" 23#define VERSION "$Revision: 1.30 $"
23 24
@@ -31,7 +32,7 @@ struct block2mtd_dev {
31 struct list_head list; 32 struct list_head list;
32 struct block_device *blkdev; 33 struct block_device *blkdev;
33 struct mtd_info mtd; 34 struct mtd_info mtd;
34 struct semaphore write_mutex; 35 struct mutex write_mutex;
35}; 36};
36 37
37 38
@@ -134,9 +135,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
134 int err; 135 int err;
135 136
136 instr->state = MTD_ERASING; 137 instr->state = MTD_ERASING;
137 down(&dev->write_mutex); 138 mutex_lock(&dev->write_mutex);
138 err = _block2mtd_erase(dev, from, len); 139 err = _block2mtd_erase(dev, from, len);
139 up(&dev->write_mutex); 140 mutex_unlock(&dev->write_mutex);
140 if (err) { 141 if (err) {
141 ERROR("erase failed err = %d", err); 142 ERROR("erase failed err = %d", err);
142 instr->state = MTD_ERASE_FAILED; 143 instr->state = MTD_ERASE_FAILED;
@@ -249,9 +250,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
249 if (to + len > mtd->size) 250 if (to + len > mtd->size)
250 len = mtd->size - to; 251 len = mtd->size - to;
251 252
252 down(&dev->write_mutex); 253 mutex_lock(&dev->write_mutex);
253 err = _block2mtd_write(dev, buf, to, len, retlen); 254 err = _block2mtd_write(dev, buf, to, len, retlen);
254 up(&dev->write_mutex); 255 mutex_unlock(&dev->write_mutex);
255 if (err > 0) 256 if (err > 0)
256 err = 0; 257 err = 0;
257 return err; 258 return err;
@@ -310,7 +311,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
310 goto devinit_err; 311 goto devinit_err;
311 } 312 }
312 313
313 init_MUTEX(&dev->write_mutex); 314 mutex_init(&dev->write_mutex);
314 315
315 /* Setup the MTD structure */ 316 /* Setup the MTD structure */
316 /* make the name contain the block device in */ 317 /* make the name contain the block device in */
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index e4345cf744a2..23e7a5c7d2c1 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -20,6 +20,7 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/mutex.h>
23 24
24#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
25#include <linux/mtd/nand.h> 26#include <linux/mtd/nand.h>
@@ -605,7 +606,7 @@ static void DoC2k_init(struct mtd_info *mtd)
605 606
606 this->curfloor = -1; 607 this->curfloor = -1;
607 this->curchip = -1; 608 this->curchip = -1;
608 init_MUTEX(&this->lock); 609 mutex_init(&this->lock);
609 610
610 /* Ident all the chips present. */ 611 /* Ident all the chips present. */
611 DoC_ScanChips(this, maxchips); 612 DoC_ScanChips(this, maxchips);
@@ -645,7 +646,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
645 if (from >= this->totlen) 646 if (from >= this->totlen)
646 return -EINVAL; 647 return -EINVAL;
647 648
648 down(&this->lock); 649 mutex_lock(&this->lock);
649 650
650 *retlen = 0; 651 *retlen = 0;
651 while (left) { 652 while (left) {
@@ -774,7 +775,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
774 buf += len; 775 buf += len;
775 } 776 }
776 777
777 up(&this->lock); 778 mutex_unlock(&this->lock);
778 779
779 return ret; 780 return ret;
780} 781}
@@ -803,7 +804,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
803 if (to >= this->totlen) 804 if (to >= this->totlen)
804 return -EINVAL; 805 return -EINVAL;
805 806
806 down(&this->lock); 807 mutex_lock(&this->lock);
807 808
808 *retlen = 0; 809 *retlen = 0;
809 while (left) { 810 while (left) {
@@ -873,7 +874,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
873 printk(KERN_ERR "Error programming flash\n"); 874 printk(KERN_ERR "Error programming flash\n");
874 /* Error in programming */ 875 /* Error in programming */
875 *retlen = 0; 876 *retlen = 0;
876 up(&this->lock); 877 mutex_unlock(&this->lock);
877 return -EIO; 878 return -EIO;
878 } 879 }
879 880
@@ -935,7 +936,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
935 printk(KERN_ERR "Error programming flash\n"); 936 printk(KERN_ERR "Error programming flash\n");
936 /* Error in programming */ 937 /* Error in programming */
937 *retlen = 0; 938 *retlen = 0;
938 up(&this->lock); 939 mutex_unlock(&this->lock);
939 return -EIO; 940 return -EIO;
940 } 941 }
941 942
@@ -956,7 +957,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
956 957
957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); 958 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
958 if (ret) { 959 if (ret) {
959 up(&this->lock); 960 mutex_unlock(&this->lock);
960 return ret; 961 return ret;
961 } 962 }
962 } 963 }
@@ -966,7 +967,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
966 buf += len; 967 buf += len;
967 } 968 }
968 969
969 up(&this->lock); 970 mutex_unlock(&this->lock);
970 return 0; 971 return 0;
971} 972}
972 973
@@ -975,13 +976,13 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
975 u_char *eccbuf, struct nand_oobinfo *oobsel) 976 u_char *eccbuf, struct nand_oobinfo *oobsel)
976{ 977{
977 static char static_buf[512]; 978 static char static_buf[512];
978 static DECLARE_MUTEX(writev_buf_sem); 979 static DEFINE_MUTEX(writev_buf_mutex);
979 980
980 size_t totretlen = 0; 981 size_t totretlen = 0;
981 size_t thisvecofs = 0; 982 size_t thisvecofs = 0;
982 int ret= 0; 983 int ret= 0;
983 984
984 down(&writev_buf_sem); 985 mutex_lock(&writev_buf_mutex);
985 986
986 while(count) { 987 while(count) {
987 size_t thislen, thisretlen; 988 size_t thislen, thisretlen;
@@ -1024,7 +1025,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1024 to += thislen; 1025 to += thislen;
1025 } 1026 }
1026 1027
1027 up(&writev_buf_sem); 1028 mutex_unlock(&writev_buf_mutex);
1028 *retlen = totretlen; 1029 *retlen = totretlen;
1029 return ret; 1030 return ret;
1030} 1031}
@@ -1037,7 +1038,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1037 int len256 = 0, ret; 1038 int len256 = 0, ret;
1038 struct Nand *mychip; 1039 struct Nand *mychip;
1039 1040
1040 down(&this->lock); 1041 mutex_lock(&this->lock);
1041 1042
1042 mychip = &this->chips[ofs >> this->chipshift]; 1043 mychip = &this->chips[ofs >> this->chipshift];
1043 1044
@@ -1083,7 +1084,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1083 1084
1084 ret = DoC_WaitReady(this); 1085 ret = DoC_WaitReady(this);
1085 1086
1086 up(&this->lock); 1087 mutex_unlock(&this->lock);
1087 return ret; 1088 return ret;
1088 1089
1089} 1090}
@@ -1197,10 +1198,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1197 struct DiskOnChip *this = mtd->priv; 1198 struct DiskOnChip *this = mtd->priv;
1198 int ret; 1199 int ret;
1199 1200
1200 down(&this->lock); 1201 mutex_lock(&this->lock);
1201 ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); 1202 ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);
1202 1203
1203 up(&this->lock); 1204 mutex_unlock(&this->lock);
1204 return ret; 1205 return ret;
1205} 1206}
1206 1207
@@ -1214,10 +1215,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1214 struct Nand *mychip; 1215 struct Nand *mychip;
1215 int status; 1216 int status;
1216 1217
1217 down(&this->lock); 1218 mutex_lock(&this->lock);
1218 1219
1219 if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) { 1220 if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
1220 up(&this->lock); 1221 mutex_unlock(&this->lock);
1221 return -EINVAL; 1222 return -EINVAL;
1222 } 1223 }
1223 1224
@@ -1265,7 +1266,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1265 callback: 1266 callback:
1266 mtd_erase_callback(instr); 1267 mtd_erase_callback(instr);
1267 1268
1268 up(&this->lock); 1269 mutex_unlock(&this->lock);
1269 return 0; 1270 return 0;
1270} 1271}
1271 1272
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index 1e876fcb0408..29b0ddaa324e 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -581,8 +581,6 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen
581 581
582/***************************************************************************************************/ 582/***************************************************************************************************/
583 583
584#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
585
586static struct mtd_info mtd; 584static struct mtd_info mtd;
587 585
588static struct mtd_erase_region_info erase_regions[] = { 586static struct mtd_erase_region_info erase_regions[] = {
@@ -640,7 +638,7 @@ int __init lart_flash_init (void)
640 mtd.flags = MTD_CAP_NORFLASH; 638 mtd.flags = MTD_CAP_NORFLASH;
641 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; 639 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
642 mtd.erasesize = FLASH_BLOCKSIZE_MAIN; 640 mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
643 mtd.numeraseregions = NB_OF (erase_regions); 641 mtd.numeraseregions = ARRAY_SIZE(erase_regions);
644 mtd.eraseregions = erase_regions; 642 mtd.eraseregions = erase_regions;
645 mtd.erase = flash_erase; 643 mtd.erase = flash_erase;
646 mtd.read = flash_read; 644 mtd.read = flash_read;
@@ -670,9 +668,9 @@ int __init lart_flash_init (void)
670 result,mtd.eraseregions[result].numblocks); 668 result,mtd.eraseregions[result].numblocks);
671 669
672#ifdef HAVE_PARTITIONS 670#ifdef HAVE_PARTITIONS
673 printk ("\npartitions = %d\n",NB_OF (lart_partitions)); 671 printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions));
674 672
675 for (result = 0; result < NB_OF (lart_partitions); result++) 673 for (result = 0; result < ARRAY_SIZE(lart_partitions); result++)
676 printk (KERN_DEBUG 674 printk (KERN_DEBUG
677 "\n\n" 675 "\n\n"
678 "lart_partitions[%d].name = %s\n" 676 "lart_partitions[%d].name = %s\n"
@@ -687,7 +685,7 @@ int __init lart_flash_init (void)
687#ifndef HAVE_PARTITIONS 685#ifndef HAVE_PARTITIONS
688 result = add_mtd_device (&mtd); 686 result = add_mtd_device (&mtd);
689#else 687#else
690 result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions)); 688 result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions));
691#endif 689#endif
692 690
693 return (result); 691 return (result);
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d5f24089be71..04e65d5dae00 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -186,7 +186,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
186 struct m25p *flash = mtd_to_m25p(mtd); 186 struct m25p *flash = mtd_to_m25p(mtd);
187 u32 addr,len; 187 u32 addr,len;
188 188
189 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", 189 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
190 flash->spi->dev.bus_id, __FUNCTION__, "at", 190 flash->spi->dev.bus_id, __FUNCTION__, "at",
191 (u32)instr->addr, instr->len); 191 (u32)instr->addr, instr->len);
192 192
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 0ff2e4378244..485f663493d2 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -308,7 +308,7 @@ static int __init ms02nv_init(void)
308 break; 308 break;
309 } 309 }
310 310
311 for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++) 311 for (i = 0; i < ARRAY_SIZE(ms02nv_addrs); i++)
312 if (!ms02nv_init_one(ms02nv_addrs[i] << stride)) 312 if (!ms02nv_init_one(ms02nv_addrs[i] << stride))
313 count++; 313 count++;
314 314
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 8a544890173d..a3b92479719d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -47,9 +47,6 @@
47 */ 47 */
48#define MAX_LOOPS 10000 48#define MAX_LOOPS 10000
49 49
50extern void INFTL_dumptables(struct INFTLrecord *inftl);
51extern void INFTL_dumpVUchains(struct INFTLrecord *inftl);
52
53static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) 50static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
54{ 51{
55 struct INFTLrecord *inftl; 52 struct INFTLrecord *inftl;
@@ -132,7 +129,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
132 return; 129 return;
133 } 130 }
134#ifdef PSYCHO_DEBUG 131#ifdef PSYCHO_DEBUG
135 printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); 132 printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a');
136#endif 133#endif
137 return; 134 return;
138} 135}
@@ -885,8 +882,6 @@ static struct mtd_blktrans_ops inftl_tr = {
885 .owner = THIS_MODULE, 882 .owner = THIS_MODULE,
886}; 883};
887 884
888extern char inftlmountrev[];
889
890static int __init init_inftl(void) 885static int __init init_inftl(void)
891{ 886{
892 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " 887 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index a57791a6ce40..b933a2a27b18 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -126,8 +126,6 @@ static struct mtd_partition alchemy_partitions[] = {
126 } 126 }
127}; 127};
128 128
129#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
130
131static struct mtd_info *mymtd; 129static struct mtd_info *mymtd;
132 130
133int __init alchemy_mtd_init(void) 131int __init alchemy_mtd_init(void)
@@ -154,7 +152,7 @@ int __init alchemy_mtd_init(void)
154 * Static partition definition selection 152 * Static partition definition selection
155 */ 153 */
156 parts = alchemy_partitions; 154 parts = alchemy_partitions;
157 nb_parts = NB_OF(alchemy_partitions); 155 nb_parts = ARRAY_SIZE(alchemy_partitions);
158 alchemy_map.size = window_size; 156 alchemy_map.size = window_size;
159 157
160 /* 158 /*
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index 6a8c0415bde8..fd0f0d3187de 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -86,7 +86,7 @@ struct mtd_partition flagadm_parts[] = {
86 } 86 }
87}; 87};
88 88
89#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition)) 89#define PARTITION_COUNT ARRAY_SIZE(flagadm_parts)
90 90
91static struct mtd_info *mymtd; 91static struct mtd_info *mymtd;
92 92
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index 49d90542fc75..652813cd6c2d 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -57,7 +57,7 @@ static struct mtd_partition partition_info[]= {
57 } 57 }
58}; 58};
59 59
60#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) 60#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
61 61
62#define WINDOW_ADDR 0x10000000 62#define WINDOW_ADDR 0x10000000
63#define WINDOW_SIZE 0x800000 63#define WINDOW_SIZE 0x800000
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index efb221692641..c299d10b33e6 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -300,7 +300,7 @@ static struct mtd_partition partition_info[]=
300 }, 300 },
301}; 301};
302 302
303#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) 303#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
304 304
305static struct mtd_info *mymtd; 305static struct mtd_info *mymtd;
306static struct mtd_info *lowlvl_parts[NUM_PARTITIONS]; 306static struct mtd_info *lowlvl_parts[NUM_PARTITIONS];
@@ -345,7 +345,7 @@ static struct mtd_partition higlvl_partition_info[]=
345 }, 345 },
346}; 346};
347 347
348#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0])) 348#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info)
349 349
350 350
351static int dnp_adnp_probe(void) 351static int dnp_adnp_probe(void)
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index b993ac01a9a5..2bb3c0f0f970 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -99,7 +99,7 @@ static struct mtd_info *this_mtd;
99static int __init init_svme182(void) 99static int __init init_svme182(void)
100{ 100{
101 struct mtd_partition *partitions; 101 struct mtd_partition *partitions;
102 int num_parts = sizeof(svme182_partitions) / sizeof(struct mtd_partition); 102 int num_parts = ARRAY_SIZE(svme182_partitions);
103 103
104 partitions = svme182_partitions; 104 partitions = svme182_partitions;
105 105
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index 319094821101..0667101ccbe1 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -59,7 +59,7 @@ static struct mtd_partition h720x_partitions[] = {
59 } 59 }
60}; 60};
61 61
62#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) 62#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions)
63 63
64static int nr_mtd_parts; 64static int nr_mtd_parts;
65static struct mtd_partition *mtd_parts; 65static struct mtd_partition *mtd_parts;
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index 33060a315722..ed215470158b 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -76,7 +76,7 @@ static struct mtd_partition partition_info[]={
76 .size = 0x80000 76 .size = 0x80000
77 }, 77 },
78}; 78};
79#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) 79#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
80 80
81#define WINDOW_SIZE 0x00100000 81#define WINDOW_SIZE 0x00100000
82#define WINDOW_ADDR 0x00200000 82#define WINDOW_ADDR 0x00200000
@@ -88,7 +88,7 @@ static struct map_info netsc520_map = {
88 .phys = WINDOW_ADDR, 88 .phys = WINDOW_ADDR,
89}; 89};
90 90
91#define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) 91#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map)
92 92
93static struct mtd_info *mymtd; 93static struct mtd_info *mymtd;
94 94
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 632eb2aa968f..54a3102ab19a 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -128,8 +128,7 @@ static struct mtd_partition nettel_amd_partitions[] = {
128 } 128 }
129}; 129};
130 130
131#define NUM_AMD_PARTITIONS \ 131#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)
132 (sizeof(nettel_amd_partitions)/sizeof(nettel_amd_partitions[0]))
133 132
134/****************************************************************************/ 133/****************************************************************************/
135 134
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index c223514ca2eb..a21fcd195ab4 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -58,8 +58,6 @@ static struct mtd_partition ocotea_large_partitions[] = {
58 } 58 }
59}; 59};
60 60
61#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
62
63int __init init_ocotea(void) 61int __init init_ocotea(void)
64{ 62{
65 u8 fpga0_reg; 63 u8 fpga0_reg;
@@ -97,7 +95,7 @@ int __init init_ocotea(void)
97 if (flash) { 95 if (flash) {
98 flash->owner = THIS_MODULE; 96 flash->owner = THIS_MODULE;
99 add_mtd_partitions(flash, ocotea_small_partitions, 97 add_mtd_partitions(flash, ocotea_small_partitions,
100 NB_OF(ocotea_small_partitions)); 98 ARRAY_SIZE(ocotea_small_partitions));
101 } else { 99 } else {
102 printk("map probe failed for flash\n"); 100 printk("map probe failed for flash\n");
103 return -ENXIO; 101 return -ENXIO;
@@ -118,7 +116,7 @@ int __init init_ocotea(void)
118 if (flash) { 116 if (flash) {
119 flash->owner = THIS_MODULE; 117 flash->owner = THIS_MODULE;
120 add_mtd_partitions(flash, ocotea_large_partitions, 118 add_mtd_partitions(flash, ocotea_large_partitions,
121 NB_OF(ocotea_large_partitions)); 119 ARRAY_SIZE(ocotea_large_partitions));
122 } else { 120 } else {
123 printk("map probe failed for flash\n"); 121 printk("map probe failed for flash\n");
124 return -ENXIO; 122 return -ENXIO;
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 21822c2edbe4..d2ab1bae9c34 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -334,9 +334,6 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
334 return 0; 334 return 0;
335 335
336release: 336release:
337 if (mtd)
338 map_destroy(mtd);
339
340 if (map) { 337 if (map) {
341 map->exit(dev, map); 338 map->exit(dev, map);
342 kfree(map); 339 kfree(map);
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index f988c817e196..8bbc751a6021 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -616,7 +616,7 @@ static void pcmciamtd_config(dev_link_t *link)
616 } else if(mem_type == 2) { 616 } else if(mem_type == 2) {
617 mtd = do_map_probe("map_rom", &dev->pcmcia_map); 617 mtd = do_map_probe("map_rom", &dev->pcmcia_map);
618 } else { 618 } else {
619 for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { 619 for(i = 0; i < ARRAY_SIZE(probes); i++) {
620 DEBUG(1, "Trying %s", probes[i]); 620 DEBUG(1, "Trying %s", probes[i]);
621 mtd = do_map_probe(probes[i], &dev->pcmcia_map); 621 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
622 if(mtd) 622 if(mtd)
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index 5b76ed886185..50b14033613f 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -121,8 +121,7 @@ struct map_info redwood_flash_map = {
121}; 121};
122 122
123 123
124#define NUM_REDWOOD_FLASH_PARTITIONS \ 124#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions)
125 (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0]))
126 125
127static struct mtd_info *redwood_mtd; 126static struct mtd_info *redwood_mtd;
128 127
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index 225cdd9ba5b2..350286dc1d2e 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -66,7 +66,7 @@ static struct map_info sbc8240_map[2] = {
66 } 66 }
67}; 67};
68 68
69#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) 69#define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map)
70 70
71/* 71/*
72 * The following defines the partition layout of SBC8240 boards. 72 * The following defines the partition layout of SBC8240 boards.
@@ -125,8 +125,6 @@ static struct mtd_partition sbc8240_fs_partitions [] = {
125 } 125 }
126}; 126};
127 127
128#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
129
130/* trivial struct to describe partition information */ 128/* trivial struct to describe partition information */
131struct mtd_part_def 129struct mtd_part_def
132{ 130{
@@ -190,10 +188,10 @@ int __init init_sbc8240_mtd (void)
190#ifdef CONFIG_MTD_PARTITIONS 188#ifdef CONFIG_MTD_PARTITIONS
191 sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; 189 sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
192 sbc8240_part_banks[0].type = "static image"; 190 sbc8240_part_banks[0].type = "static image";
193 sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); 191 sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions);
194 sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; 192 sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
195 sbc8240_part_banks[1].type = "static file system"; 193 sbc8240_part_banks[1].type = "static file system";
196 sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); 194 sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions);
197 195
198 for (i = 0; i < NUM_FLASH_BANKS; i++) { 196 for (i = 0; i < NUM_FLASH_BANKS; i++) {
199 197
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index ed92afadd8a9..e8c130e1efd3 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -107,7 +107,7 @@ static struct map_info sc520cdp_map[] = {
107 }, 107 },
108}; 108};
109 109
110#define NUM_FLASH_BANKS (sizeof(sc520cdp_map)/sizeof(struct map_info)) 110#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map)
111 111
112static struct mtd_info *mymtd[NUM_FLASH_BANKS]; 112static struct mtd_info *mymtd[NUM_FLASH_BANKS];
113static struct mtd_info *merged_mtd; 113static struct mtd_info *merged_mtd;
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 2c91dff8bb60..28b8a571a91a 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -70,7 +70,7 @@ static struct mtd_partition partition_info[] = {
70 .size = 0x80000 70 .size = 0x80000
71 }, 71 },
72}; 72};
73#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) 73#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
74#endif 74#endif
75 75
76 76
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index 999f4bb3d845..12fe53c0d2fc 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -49,8 +49,6 @@ static struct mtd_partition sharpsl_partitions[1] = {
49 } 49 }
50}; 50};
51 51
52#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
53
54int __init init_sharpsl(void) 52int __init init_sharpsl(void)
55{ 53{
56 struct mtd_partition *parts; 54 struct mtd_partition *parts;
@@ -92,7 +90,7 @@ int __init init_sharpsl(void)
92 } 90 }
93 91
94 parts = sharpsl_partitions; 92 parts = sharpsl_partitions;
95 nb_parts = NB_OF(sharpsl_partitions); 93 nb_parts = ARRAY_SIZE(sharpsl_partitions);
96 94
97 printk(KERN_NOTICE "Using %s partision definition\n", part_type); 95 printk(KERN_NOTICE "Using %s partision definition\n", part_type);
98 add_mtd_partitions(mymtd, parts, nb_parts); 96 add_mtd_partitions(mymtd, parts, nb_parts);
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
index 4b372bcb17f1..a7422c200567 100644
--- a/drivers/mtd/maps/ts5500_flash.c
+++ b/drivers/mtd/maps/ts5500_flash.c
@@ -64,7 +64,7 @@ static struct mtd_partition ts5500_partitions[] = {
64 } 64 }
65}; 65};
66 66
67#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) 67#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions)
68 68
69static struct mtd_info *mymtd; 69static struct mtd_info *mymtd;
70 70
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index 79d92808b766..f7264dc2ac9b 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -37,7 +37,7 @@ struct mtd_partition uclinux_romfs[] = {
37 { .name = "ROMfs" } 37 { .name = "ROMfs" }
38}; 38};
39 39
40#define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) 40#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs)
41 41
42/****************************************************************************/ 42/****************************************************************************/
43 43
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index e0063941c0df..b3e487395435 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -182,7 +182,7 @@ int __init init_vmax301(void)
182 } 182 }
183 } 183 }
184 184
185 if (!vmax_mtd[1] && !vmax_mtd[2]) { 185 if (!vmax_mtd[0] && !vmax_mtd[1]) {
186 iounmap((void *)iomapadr); 186 iounmap((void *)iomapadr);
187 return -ENXIO; 187 return -ENXIO;
188 } 188 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 840dd66ce2dc..458d3c8ae1ee 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -19,12 +19,12 @@
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/hdreg.h> 20#include <linux/hdreg.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <asm/semaphore.h> 22#include <linux/mutex.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24 24
25static LIST_HEAD(blktrans_majors); 25static LIST_HEAD(blktrans_majors);
26 26
27extern struct semaphore mtd_table_mutex; 27extern struct mutex mtd_table_mutex;
28extern struct mtd_info *mtd_table[]; 28extern struct mtd_info *mtd_table[];
29 29
30struct mtd_blkcore_priv { 30struct mtd_blkcore_priv {
@@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg)
122 122
123 spin_unlock_irq(rq->queue_lock); 123 spin_unlock_irq(rq->queue_lock);
124 124
125 down(&dev->sem); 125 mutex_lock(&dev->lock);
126 res = do_blktrans_request(tr, dev, req); 126 res = do_blktrans_request(tr, dev, req);
127 up(&dev->sem); 127 mutex_unlock(&dev->lock);
128 128
129 spin_lock_irq(rq->queue_lock); 129 spin_lock_irq(rq->queue_lock);
130 130
@@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
235 int last_devnum = -1; 235 int last_devnum = -1;
236 struct gendisk *gd; 236 struct gendisk *gd;
237 237
238 if (!down_trylock(&mtd_table_mutex)) { 238 if (!!mutex_trylock(&mtd_table_mutex)) {
239 up(&mtd_table_mutex); 239 mutex_unlock(&mtd_table_mutex);
240 BUG(); 240 BUG();
241 } 241 }
242 242
@@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
267 return -EBUSY; 267 return -EBUSY;
268 } 268 }
269 269
270 init_MUTEX(&new->sem); 270 mutex_init(&new->lock);
271 list_add_tail(&new->list, &tr->devs); 271 list_add_tail(&new->list, &tr->devs);
272 added: 272 added:
273 if (!tr->writesect) 273 if (!tr->writesect)
@@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
313 313
314int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) 314int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
315{ 315{
316 if (!down_trylock(&mtd_table_mutex)) { 316 if (!!mutex_trylock(&mtd_table_mutex)) {
317 up(&mtd_table_mutex); 317 mutex_unlock(&mtd_table_mutex);
318 BUG(); 318 BUG();
319 } 319 }
320 320
@@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
378 378
379 memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); 379 memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
380 380
381 down(&mtd_table_mutex); 381 mutex_lock(&mtd_table_mutex);
382 382
383 ret = register_blkdev(tr->major, tr->name); 383 ret = register_blkdev(tr->major, tr->name);
384 if (ret) { 384 if (ret) {
385 printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", 385 printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
386 tr->name, tr->major, ret); 386 tr->name, tr->major, ret);
387 kfree(tr->blkcore_priv); 387 kfree(tr->blkcore_priv);
388 up(&mtd_table_mutex); 388 mutex_unlock(&mtd_table_mutex);
389 return ret; 389 return ret;
390 } 390 }
391 spin_lock_init(&tr->blkcore_priv->queue_lock); 391 spin_lock_init(&tr->blkcore_priv->queue_lock);
@@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
396 if (!tr->blkcore_priv->rq) { 396 if (!tr->blkcore_priv->rq) {
397 unregister_blkdev(tr->major, tr->name); 397 unregister_blkdev(tr->major, tr->name);
398 kfree(tr->blkcore_priv); 398 kfree(tr->blkcore_priv);
399 up(&mtd_table_mutex); 399 mutex_unlock(&mtd_table_mutex);
400 return -ENOMEM; 400 return -ENOMEM;
401 } 401 }
402 402
@@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
407 blk_cleanup_queue(tr->blkcore_priv->rq); 407 blk_cleanup_queue(tr->blkcore_priv->rq);
408 unregister_blkdev(tr->major, tr->name); 408 unregister_blkdev(tr->major, tr->name);
409 kfree(tr->blkcore_priv); 409 kfree(tr->blkcore_priv);
410 up(&mtd_table_mutex); 410 mutex_unlock(&mtd_table_mutex);
411 return ret; 411 return ret;
412 } 412 }
413 413
@@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
419 tr->add_mtd(tr, mtd_table[i]); 419 tr->add_mtd(tr, mtd_table[i]);
420 } 420 }
421 421
422 up(&mtd_table_mutex); 422 mutex_unlock(&mtd_table_mutex);
423 423
424 return 0; 424 return 0;
425} 425}
@@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
428{ 428{
429 struct list_head *this, *next; 429 struct list_head *this, *next;
430 430
431 down(&mtd_table_mutex); 431 mutex_lock(&mtd_table_mutex);
432 432
433 /* Clean up the kernel thread */ 433 /* Clean up the kernel thread */
434 tr->blkcore_priv->exiting = 1; 434 tr->blkcore_priv->exiting = 1;
@@ -446,7 +446,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
446 blk_cleanup_queue(tr->blkcore_priv->rq); 446 blk_cleanup_queue(tr->blkcore_priv->rq);
447 unregister_blkdev(tr->major, tr->name); 447 unregister_blkdev(tr->major, tr->name);
448 448
449 up(&mtd_table_mutex); 449 mutex_unlock(&mtd_table_mutex);
450 450
451 kfree(tr->blkcore_priv); 451 kfree(tr->blkcore_priv);
452 452
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index e84756644fd1..2cef280e388c 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -19,11 +19,13 @@
19 19
20#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
21#include <linux/mtd/blktrans.h> 21#include <linux/mtd/blktrans.h>
22#include <linux/mutex.h>
23
22 24
23static struct mtdblk_dev { 25static struct mtdblk_dev {
24 struct mtd_info *mtd; 26 struct mtd_info *mtd;
25 int count; 27 int count;
26 struct semaphore cache_sem; 28 struct mutex cache_mutex;
27 unsigned char *cache_data; 29 unsigned char *cache_data;
28 unsigned long cache_offset; 30 unsigned long cache_offset;
29 unsigned int cache_size; 31 unsigned int cache_size;
@@ -284,7 +286,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
284 mtdblk->count = 1; 286 mtdblk->count = 1;
285 mtdblk->mtd = mtd; 287 mtdblk->mtd = mtd;
286 288
287 init_MUTEX (&mtdblk->cache_sem); 289 mutex_init(&mtdblk->cache_mutex);
288 mtdblk->cache_state = STATE_EMPTY; 290 mtdblk->cache_state = STATE_EMPTY;
289 if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && 291 if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
290 mtdblk->mtd->erasesize) { 292 mtdblk->mtd->erasesize) {
@@ -306,9 +308,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
306 308
307 DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); 309 DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
308 310
309 down(&mtdblk->cache_sem); 311 mutex_lock(&mtdblk->cache_mutex);
310 write_cached_data(mtdblk); 312 write_cached_data(mtdblk);
311 up(&mtdblk->cache_sem); 313 mutex_unlock(&mtdblk->cache_mutex);
312 314
313 if (!--mtdblk->count) { 315 if (!--mtdblk->count) {
314 /* It was the last usage. Free the device */ 316 /* It was the last usage. Free the device */
@@ -327,9 +329,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev)
327{ 329{
328 struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; 330 struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
329 331
330 down(&mtdblk->cache_sem); 332 mutex_lock(&mtdblk->cache_mutex);
331 write_cached_data(mtdblk); 333 write_cached_data(mtdblk);
332 up(&mtdblk->cache_sem); 334 mutex_unlock(&mtdblk->cache_mutex);
333 335
334 if (mtdblk->mtd->sync) 336 if (mtdblk->mtd->sync)
335 mtdblk->mtd->sync(mtdblk->mtd); 337 mtdblk->mtd->sync(mtdblk->mtd);
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dade02ab0687..9905870f56e5 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,15 +19,13 @@
19#include <linux/ioctl.h> 19#include <linux/ioctl.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/mtd/compatmac.h> 21#include <linux/mtd/compatmac.h>
22#ifdef CONFIG_PROC_FS
23#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
24#endif
25 23
26#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
27 25
28/* These are exported solely for the purpose of mtd_blkdevs.c. You 26/* These are exported solely for the purpose of mtd_blkdevs.c. You
29 should not use them for _anything_ else */ 27 should not use them for _anything_ else */
30DECLARE_MUTEX(mtd_table_mutex); 28DEFINE_MUTEX(mtd_table_mutex);
31struct mtd_info *mtd_table[MAX_MTD_DEVICES]; 29struct mtd_info *mtd_table[MAX_MTD_DEVICES];
32 30
33EXPORT_SYMBOL_GPL(mtd_table_mutex); 31EXPORT_SYMBOL_GPL(mtd_table_mutex);
@@ -49,7 +47,7 @@ int add_mtd_device(struct mtd_info *mtd)
49{ 47{
50 int i; 48 int i;
51 49
52 down(&mtd_table_mutex); 50 mutex_lock(&mtd_table_mutex);
53 51
54 for (i=0; i < MAX_MTD_DEVICES; i++) 52 for (i=0; i < MAX_MTD_DEVICES; i++)
55 if (!mtd_table[i]) { 53 if (!mtd_table[i]) {
@@ -67,7 +65,7 @@ int add_mtd_device(struct mtd_info *mtd)
67 not->add(mtd); 65 not->add(mtd);
68 } 66 }
69 67
70 up(&mtd_table_mutex); 68 mutex_unlock(&mtd_table_mutex);
71 /* We _know_ we aren't being removed, because 69 /* We _know_ we aren't being removed, because
72 our caller is still holding us here. So none 70 our caller is still holding us here. So none
73 of this try_ nonsense, and no bitching about it 71 of this try_ nonsense, and no bitching about it
@@ -76,7 +74,7 @@ int add_mtd_device(struct mtd_info *mtd)
76 return 0; 74 return 0;
77 } 75 }
78 76
79 up(&mtd_table_mutex); 77 mutex_unlock(&mtd_table_mutex);
80 return 1; 78 return 1;
81} 79}
82 80
@@ -94,7 +92,7 @@ int del_mtd_device (struct mtd_info *mtd)
94{ 92{
95 int ret; 93 int ret;
96 94
97 down(&mtd_table_mutex); 95 mutex_lock(&mtd_table_mutex);
98 96
99 if (mtd_table[mtd->index] != mtd) { 97 if (mtd_table[mtd->index] != mtd) {
100 ret = -ENODEV; 98 ret = -ENODEV;
@@ -118,7 +116,7 @@ int del_mtd_device (struct mtd_info *mtd)
118 ret = 0; 116 ret = 0;
119 } 117 }
120 118
121 up(&mtd_table_mutex); 119 mutex_unlock(&mtd_table_mutex);
122 return ret; 120 return ret;
123} 121}
124 122
@@ -135,7 +133,7 @@ void register_mtd_user (struct mtd_notifier *new)
135{ 133{
136 int i; 134 int i;
137 135
138 down(&mtd_table_mutex); 136 mutex_lock(&mtd_table_mutex);
139 137
140 list_add(&new->list, &mtd_notifiers); 138 list_add(&new->list, &mtd_notifiers);
141 139
@@ -145,7 +143,7 @@ void register_mtd_user (struct mtd_notifier *new)
145 if (mtd_table[i]) 143 if (mtd_table[i])
146 new->add(mtd_table[i]); 144 new->add(mtd_table[i]);
147 145
148 up(&mtd_table_mutex); 146 mutex_unlock(&mtd_table_mutex);
149} 147}
150 148
151/** 149/**
@@ -162,7 +160,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
162{ 160{
163 int i; 161 int i;
164 162
165 down(&mtd_table_mutex); 163 mutex_lock(&mtd_table_mutex);
166 164
167 module_put(THIS_MODULE); 165 module_put(THIS_MODULE);
168 166
@@ -171,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
171 old->remove(mtd_table[i]); 169 old->remove(mtd_table[i]);
172 170
173 list_del(&old->list); 171 list_del(&old->list);
174 up(&mtd_table_mutex); 172 mutex_unlock(&mtd_table_mutex);
175 return 0; 173 return 0;
176} 174}
177 175
@@ -193,7 +191,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
193 struct mtd_info *ret = NULL; 191 struct mtd_info *ret = NULL;
194 int i; 192 int i;
195 193
196 down(&mtd_table_mutex); 194 mutex_lock(&mtd_table_mutex);
197 195
198 if (num == -1) { 196 if (num == -1) {
199 for (i=0; i< MAX_MTD_DEVICES; i++) 197 for (i=0; i< MAX_MTD_DEVICES; i++)
@@ -211,7 +209,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
211 if (ret) 209 if (ret)
212 ret->usecount++; 210 ret->usecount++;
213 211
214 up(&mtd_table_mutex); 212 mutex_unlock(&mtd_table_mutex);
215 return ret; 213 return ret;
216} 214}
217 215
@@ -219,9 +217,9 @@ void put_mtd_device(struct mtd_info *mtd)
219{ 217{
220 int c; 218 int c;
221 219
222 down(&mtd_table_mutex); 220 mutex_lock(&mtd_table_mutex);
223 c = --mtd->usecount; 221 c = --mtd->usecount;
224 up(&mtd_table_mutex); 222 mutex_unlock(&mtd_table_mutex);
225 BUG_ON(c < 0); 223 BUG_ON(c < 0);
226 224
227 module_put(mtd->owner); 225 module_put(mtd->owner);
@@ -296,10 +294,11 @@ EXPORT_SYMBOL(unregister_mtd_user);
296EXPORT_SYMBOL(default_mtd_writev); 294EXPORT_SYMBOL(default_mtd_writev);
297EXPORT_SYMBOL(default_mtd_readv); 295EXPORT_SYMBOL(default_mtd_readv);
298 296
297#ifdef CONFIG_PROC_FS
298
299/*====================================================================*/ 299/*====================================================================*/
300/* Support for /proc/mtd */ 300/* Support for /proc/mtd */
301 301
302#ifdef CONFIG_PROC_FS
303static struct proc_dir_entry *proc_mtd; 302static struct proc_dir_entry *proc_mtd;
304 303
305static inline int mtd_proc_info (char *buf, int i) 304static inline int mtd_proc_info (char *buf, int i)
@@ -319,7 +318,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
319 int len, l, i; 318 int len, l, i;
320 off_t begin = 0; 319 off_t begin = 0;
321 320
322 down(&mtd_table_mutex); 321 mutex_lock(&mtd_table_mutex);
323 322
324 len = sprintf(page, "dev: size erasesize name\n"); 323 len = sprintf(page, "dev: size erasesize name\n");
325 for (i=0; i< MAX_MTD_DEVICES; i++) { 324 for (i=0; i< MAX_MTD_DEVICES; i++) {
@@ -337,38 +336,34 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
337 *eof = 1; 336 *eof = 1;
338 337
339done: 338done:
340 up(&mtd_table_mutex); 339 mutex_unlock(&mtd_table_mutex);
341 if (off >= len+begin) 340 if (off >= len+begin)
342 return 0; 341 return 0;
343 *start = page + (off-begin); 342 *start = page + (off-begin);
344 return ((count < begin+len-off) ? count : begin+len-off); 343 return ((count < begin+len-off) ? count : begin+len-off);
345} 344}
346 345
347#endif /* CONFIG_PROC_FS */
348
349/*====================================================================*/ 346/*====================================================================*/
350/* Init code */ 347/* Init code */
351 348
352static int __init init_mtd(void) 349static int __init init_mtd(void)
353{ 350{
354#ifdef CONFIG_PROC_FS
355 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 351 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
356 proc_mtd->read_proc = mtd_read_proc; 352 proc_mtd->read_proc = mtd_read_proc;
357#endif
358 return 0; 353 return 0;
359} 354}
360 355
361static void __exit cleanup_mtd(void) 356static void __exit cleanup_mtd(void)
362{ 357{
363#ifdef CONFIG_PROC_FS
364 if (proc_mtd) 358 if (proc_mtd)
365 remove_proc_entry( "mtd", NULL); 359 remove_proc_entry( "mtd", NULL);
366#endif
367} 360}
368 361
369module_init(init_mtd); 362module_init(init_mtd);
370module_exit(cleanup_mtd); 363module_exit(cleanup_mtd);
371 364
365#endif /* CONFIG_PROC_FS */
366
372 367
373MODULE_LICENSE("GPL"); 368MODULE_LICENSE("GPL");
374MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 369MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1fc4c134d939..cfe288a6e853 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -178,17 +178,16 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
178 Even if you leave this disabled, you can enable BBT writes at module 178 Even if you leave this disabled, you can enable BBT writes at module
179 load time (assuming you build diskonchip as a module) with the module 179 load time (assuming you build diskonchip as a module) with the module
180 parameter "inftl_bbt_write=1". 180 parameter "inftl_bbt_write=1".
181
182 config MTD_NAND_SHARPSL
183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA
185
186 config MTD_NAND_NANDSIM
187 bool "Support for NAND Flash Simulator"
188 depends on MTD_NAND && MTD_PARTITIONS
189 181
182config MTD_NAND_SHARPSL
183 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA
185
186config MTD_NAND_NANDSIM
187 tristate "Support for NAND Flash Simulator"
188 depends on MTD_NAND && MTD_PARTITIONS
190 help 189 help
191 The simulator may simulate verious NAND flash chips for the 190 The simulator may simulate verious NAND flash chips for the
192 MTD nand layer. 191 MTD nand layer.
193 192
194endmenu 193endmenu
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 201e1362da14..bde3550910a2 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -55,8 +55,6 @@ static const struct mtd_partition partition_info[] = {
55 .size = MTDPART_SIZ_FULL 55 .size = MTDPART_SIZ_FULL
56 } 56 }
57}; 57};
58#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
59
60 58
61/** 59/**
62 * au_read_byte - read one byte from the chip 60 * au_read_byte - read one byte from the chip
@@ -462,7 +460,7 @@ int __init au1xxx_nand_init (void)
462 } 460 }
463 461
464 /* Register the partitions */ 462 /* Register the partitions */
465 add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info)); 463 add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info));
466 464
467 return 0; 465 return 0;
468 466
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5d222460b42a..95e96fa1fceb 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -80,6 +80,7 @@
80#include <linux/mtd/compatmac.h> 80#include <linux/mtd/compatmac.h>
81#include <linux/interrupt.h> 81#include <linux/interrupt.h>
82#include <linux/bitops.h> 82#include <linux/bitops.h>
83#include <linux/leds.h>
83#include <asm/io.h> 84#include <asm/io.h>
84 85
85#ifdef CONFIG_MTD_PARTITIONS 86#ifdef CONFIG_MTD_PARTITIONS
@@ -515,6 +516,8 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i
515 return nand_isbad_bbt (mtd, ofs, allowbbt); 516 return nand_isbad_bbt (mtd, ofs, allowbbt);
516} 517}
517 518
519DEFINE_LED_TRIGGER(nand_led_trigger);
520
518/* 521/*
519 * Wait for the ready pin, after a command 522 * Wait for the ready pin, after a command
520 * The timeout is catched later. 523 * The timeout is catched later.
@@ -524,12 +527,14 @@ static void nand_wait_ready(struct mtd_info *mtd)
524 struct nand_chip *this = mtd->priv; 527 struct nand_chip *this = mtd->priv;
525 unsigned long timeo = jiffies + 2; 528 unsigned long timeo = jiffies + 2;
526 529
530 led_trigger_event(nand_led_trigger, LED_FULL);
527 /* wait until command is processed or timeout occures */ 531 /* wait until command is processed or timeout occures */
528 do { 532 do {
529 if (this->dev_ready(mtd)) 533 if (this->dev_ready(mtd))
530 return; 534 break;
531 touch_softlockup_watchdog(); 535 touch_softlockup_watchdog();
532 } while (time_before(jiffies, timeo)); 536 } while (time_before(jiffies, timeo));
537 led_trigger_event(nand_led_trigger, LED_OFF);
533} 538}
534 539
535/** 540/**
@@ -817,6 +822,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
817 else 822 else
818 timeo += (HZ * 20) / 1000; 823 timeo += (HZ * 20) / 1000;
819 824
825 led_trigger_event(nand_led_trigger, LED_FULL);
826
820 /* Apply this short delay always to ensure that we do wait tWB in 827 /* Apply this short delay always to ensure that we do wait tWB in
821 * any case on any machine. */ 828 * any case on any machine. */
822 ndelay (100); 829 ndelay (100);
@@ -840,6 +847,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
840 } 847 }
841 cond_resched(); 848 cond_resched();
842 } 849 }
850 led_trigger_event(nand_led_trigger, LED_OFF);
851
843 status = (int) this->read_byte(mtd); 852 status = (int) this->read_byte(mtd);
844 return status; 853 return status;
845} 854}
@@ -2724,6 +2733,21 @@ void nand_release (struct mtd_info *mtd)
2724EXPORT_SYMBOL_GPL (nand_scan); 2733EXPORT_SYMBOL_GPL (nand_scan);
2725EXPORT_SYMBOL_GPL (nand_release); 2734EXPORT_SYMBOL_GPL (nand_release);
2726 2735
2736
2737static int __init nand_base_init(void)
2738{
2739 led_trigger_register_simple("nand-disk", &nand_led_trigger);
2740 return 0;
2741}
2742
2743static void __exit nand_base_exit(void)
2744{
2745 led_trigger_unregister_simple(nand_led_trigger);
2746}
2747
2748module_init(nand_base_init);
2749module_exit(nand_base_exit);
2750
2727MODULE_LICENSE ("GPL"); 2751MODULE_LICENSE ("GPL");
2728MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); 2752MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
2729MODULE_DESCRIPTION ("Generic NAND flash driver code"); 2753MODULE_DESCRIPTION ("Generic NAND flash driver code");
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 8815c8dbef2d..c077d2ec9cdd 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -85,10 +85,6 @@ static int parse_redboot_partitions(struct mtd_info *master,
85 85
86 numslots = (master->erasesize / sizeof(struct fis_image_desc)); 86 numslots = (master->erasesize / sizeof(struct fis_image_desc));
87 for (i = 0; i < numslots; i++) { 87 for (i = 0; i < numslots; i++) {
88 if (buf[i].name[0] == 0xff) {
89 i = numslots;
90 break;
91 }
92 if (!memcmp(buf[i].name, "FIS directory", 14)) { 88 if (!memcmp(buf[i].name, "FIS directory", 14)) {
93 /* This is apparently the FIS directory entry for the 89 /* This is apparently the FIS directory entry for the
94 * FIS directory itself. The FIS directory size is 90 * FIS directory itself. The FIS directory size is
@@ -128,7 +124,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
128 struct fis_list *new_fl, **prev; 124 struct fis_list *new_fl, **prev;
129 125
130 if (buf[i].name[0] == 0xff) 126 if (buf[i].name[0] == 0xff)
131 break; 127 continue;
132 if (!redboot_checksum(&buf[i])) 128 if (!redboot_checksum(&buf[i]))
133 break; 129 break;
134 130
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 70f63891b19c..274b0138d442 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -788,7 +788,7 @@ struct vortex_private {
788 int options; /* User-settable misc. driver options. */ 788 int options; /* User-settable misc. driver options. */
789 unsigned int media_override:4, /* Passed-in media type. */ 789 unsigned int media_override:4, /* Passed-in media type. */
790 default_media:4, /* Read from the EEPROM/Wn3_Config. */ 790 default_media:4, /* Read from the EEPROM/Wn3_Config. */
791 full_duplex:1, force_fd:1, autoselect:1, 791 full_duplex:1, autoselect:1,
792 bus_master:1, /* Vortex can only do a fragment bus-m. */ 792 bus_master:1, /* Vortex can only do a fragment bus-m. */
793 full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ 793 full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */
794 flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ 794 flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */
@@ -1633,12 +1633,6 @@ vortex_set_duplex(struct net_device *dev)
1633 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 1633 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ?
1634 0x100 : 0), 1634 0x100 : 0),
1635 ioaddr + Wn3_MAC_Ctrl); 1635 ioaddr + Wn3_MAC_Ctrl);
1636
1637 issue_and_wait(dev, TxReset);
1638 /*
1639 * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
1640 */
1641 issue_and_wait(dev, RxReset|0x04);
1642} 1636}
1643 1637
1644static void vortex_check_media(struct net_device *dev, unsigned int init) 1638static void vortex_check_media(struct net_device *dev, unsigned int init)
@@ -1663,7 +1657,7 @@ vortex_up(struct net_device *dev)
1663 struct vortex_private *vp = netdev_priv(dev); 1657 struct vortex_private *vp = netdev_priv(dev);
1664 void __iomem *ioaddr = vp->ioaddr; 1658 void __iomem *ioaddr = vp->ioaddr;
1665 unsigned int config; 1659 unsigned int config;
1666 int i; 1660 int i, mii_reg1, mii_reg5;
1667 1661
1668 if (VORTEX_PCI(vp)) { 1662 if (VORTEX_PCI(vp)) {
1669 pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ 1663 pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */
@@ -1723,14 +1717,23 @@ vortex_up(struct net_device *dev)
1723 printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); 1717 printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
1724 iowrite32(config, ioaddr + Wn3_Config); 1718 iowrite32(config, ioaddr + Wn3_Config);
1725 1719
1726 netif_carrier_off(dev);
1727 if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { 1720 if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
1728 EL3WINDOW(4); 1721 EL3WINDOW(4);
1722 mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
1723 mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
1724 vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
1725
1729 vortex_check_media(dev, 1); 1726 vortex_check_media(dev, 1);
1730 } 1727 }
1731 else 1728 else
1732 vortex_set_duplex(dev); 1729 vortex_set_duplex(dev);
1733 1730
1731 issue_and_wait(dev, TxReset);
1732 /*
1733 * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
1734 */
1735 issue_and_wait(dev, RxReset|0x04);
1736
1734 1737
1735 iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); 1738 iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
1736 1739
@@ -2083,16 +2086,14 @@ vortex_error(struct net_device *dev, int status)
2083 } 2086 }
2084 if (tx_status & 0x14) vp->stats.tx_fifo_errors++; 2087 if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
2085 if (tx_status & 0x38) vp->stats.tx_aborted_errors++; 2088 if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
2089 if (tx_status & 0x08) vp->xstats.tx_max_collisions++;
2086 iowrite8(0, ioaddr + TxStatus); 2090 iowrite8(0, ioaddr + TxStatus);
2087 if (tx_status & 0x30) { /* txJabber or txUnderrun */ 2091 if (tx_status & 0x30) { /* txJabber or txUnderrun */
2088 do_tx_reset = 1; 2092 do_tx_reset = 1;
2089 } else if (tx_status & 0x08) { /* maxCollisions */ 2093 } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
2090 vp->xstats.tx_max_collisions++; 2094 do_tx_reset = 1;
2091 if (vp->drv_flags & MAX_COLLISION_RESET) { 2095 reset_mask = 0x0108; /* Reset interface logic, but not download logic */
2092 do_tx_reset = 1; 2096 } else { /* Merely re-enable the transmitter. */
2093 reset_mask = 0x0108; /* Reset interface logic, but not download logic */
2094 }
2095 } else { /* Merely re-enable the transmitter. */
2096 iowrite16(TxEnable, ioaddr + EL3_CMD); 2097 iowrite16(TxEnable, ioaddr + EL3_CMD);
2097 } 2098 }
2098 } 2099 }
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e20b849a22e8..bdaaad8f2123 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2313,13 +2313,11 @@ config S2IO_NAPI
2313 2313
2314endmenu 2314endmenu
2315 2315
2316if !UML
2317source "drivers/net/tokenring/Kconfig" 2316source "drivers/net/tokenring/Kconfig"
2318 2317
2319source "drivers/net/wireless/Kconfig" 2318source "drivers/net/wireless/Kconfig"
2320 2319
2321source "drivers/net/pcmcia/Kconfig" 2320source "drivers/net/pcmcia/Kconfig"
2322endif
2323 2321
2324source "drivers/net/wan/Kconfig" 2322source "drivers/net/wan/Kconfig"
2325 2323
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index edd1b5306b16..75b35ad760de 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -94,7 +94,7 @@ static struct console netconsole = {
94static int option_setup(char *opt) 94static int option_setup(char *opt)
95{ 95{
96 configured = !netpoll_parse_options(&np, opt); 96 configured = !netpoll_parse_options(&np, opt);
97 return 0; 97 return 1;
98} 98}
99 99
100__setup("netconsole=", option_setup); 100__setup("netconsole=", option_setup);
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index eed496803fe4..e8f849e12976 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1973,7 +1973,7 @@ static int __init setup_xirc2ps_cs(char *str)
1973 MAYBE_SET(lockup_hack, 6); 1973 MAYBE_SET(lockup_hack, 6);
1974#undef MAYBE_SET 1974#undef MAYBE_SET
1975 1975
1976 return 0; 1976 return 1;
1977} 1977}
1978 1978
1979__setup("xirc2ps_cs=", setup_xirc2ps_cs); 1979__setup("xirc2ps_cs=", setup_xirc2ps_cs);
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
index e4cfc80b283b..99c4c1922f19 100644
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -3,7 +3,7 @@
3# 3#
4 4
5menu "Token Ring devices" 5menu "Token Ring devices"
6 depends on NETDEVICES 6 depends on NETDEVICES && !UML
7 7
8# So far, we only have PCI, ISA, and MCA token ring devices 8# So far, we only have PCI, ISA, and MCA token ring devices
9config TR 9config TR
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f85e30190008..bad09ebdb50b 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -356,7 +356,7 @@ config PCI_HERMES
356 356
357config ATMEL 357config ATMEL
358 tristate "Atmel at76c50x chipset 802.11b support" 358 tristate "Atmel at76c50x chipset 802.11b support"
359 depends on NET_RADIO 359 depends on NET_RADIO && (PCI || PCMCIA)
360 select FW_LOADER 360 select FW_LOADER
361 select CRC32 361 select CRC32
362 ---help--- 362 ---help---
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 0574efd7828a..459e6e1946fd 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -634,7 +634,7 @@ static void vrc4171_remove_sockets(void)
634static int __devinit vrc4171_card_setup(char *options) 634static int __devinit vrc4171_card_setup(char *options)
635{ 635{
636 if (options == NULL || *options == '\0') 636 if (options == NULL || *options == '\0')
637 return 0; 637 return 1;
638 638
639 if (strncmp(options, "irq:", 4) == 0) { 639 if (strncmp(options, "irq:", 4) == 0) {
640 int irq; 640 int irq;
@@ -644,7 +644,7 @@ static int __devinit vrc4171_card_setup(char *options)
644 vrc4171_irq = irq; 644 vrc4171_irq = irq;
645 645
646 if (*options != ',') 646 if (*options != ',')
647 return 0; 647 return 1;
648 options++; 648 options++;
649 } 649 }
650 650
@@ -663,10 +663,10 @@ static int __devinit vrc4171_card_setup(char *options)
663 } 663 }
664 664
665 if (*options != ',') 665 if (*options != ',')
666 return 0; 666 return 1;
667 options++; 667 options++;
668 } else 668 } else
669 return 0; 669 return 1;
670 670
671 } 671 }
672 672
@@ -688,7 +688,7 @@ static int __devinit vrc4171_card_setup(char *options)
688 } 688 }
689 689
690 if (*options != ',') 690 if (*options != ',')
691 return 0; 691 return 1;
692 options++; 692 options++;
693 693
694 if (strncmp(options, "memnoprobe", 10) == 0) 694 if (strncmp(options, "memnoprobe", 10) == 0)
@@ -700,7 +700,7 @@ static int __devinit vrc4171_card_setup(char *options)
700 } 700 }
701 } 701 }
702 702
703 return 0; 703 return 1;
704} 704}
705 705
706__setup("vrc4171_card=", vrc4171_card_setup); 706__setup("vrc4171_card=", vrc4171_card_setup);
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index 57f38dba0a48..6004196f7cc1 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -516,7 +516,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
516static int __devinit vrc4173_cardu_setup(char *options) 516static int __devinit vrc4173_cardu_setup(char *options)
517{ 517{
518 if (options == NULL || *options == '\0') 518 if (options == NULL || *options == '\0')
519 return 0; 519 return 1;
520 520
521 if (strncmp(options, "cardu1:", 7) == 0) { 521 if (strncmp(options, "cardu1:", 7) == 0) {
522 options += 7; 522 options += 7;
@@ -527,9 +527,9 @@ static int __devinit vrc4173_cardu_setup(char *options)
527 } 527 }
528 528
529 if (*options != ',') 529 if (*options != ',')
530 return 0; 530 return 1;
531 } else 531 } else
532 return 0; 532 return 1;
533 } 533 }
534 534
535 if (strncmp(options, "cardu2:", 7) == 0) { 535 if (strncmp(options, "cardu2:", 7) == 0) {
@@ -538,7 +538,7 @@ static int __devinit vrc4173_cardu_setup(char *options)
538 cardu_sockets[CARDU2].noprobe = 1; 538 cardu_sockets[CARDU2].noprobe = 1;
539 } 539 }
540 540
541 return 0; 541 return 1;
542} 542}
543 543
544__setup("vrc4173_cardu=", vrc4173_cardu_setup); 544__setup("vrc4173_cardu=", vrc4173_cardu_setup);
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index ffba65656a83..1bd82c4e52a0 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -293,6 +293,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
293 board_ahci }, /* JMicron JMB360 */ 293 board_ahci }, /* JMicron JMB360 */
294 { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 294 { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
295 board_ahci }, /* JMicron JMB363 */ 295 board_ahci }, /* JMicron JMB363 */
296 { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
297 board_ahci }, /* ATI SB600 non-raid */
298 { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
299 board_ahci }, /* ATI SB600 raid */
296 { } /* terminate list */ 300 { } /* terminate list */
297}; 301};
298 302
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 2d5be84d8bd4..24e71b555172 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -301,7 +301,7 @@ static struct piix_map_db ich6_map_db = {
301 .mask = 0x3, 301 .mask = 0x3,
302 .map = { 302 .map = {
303 /* PM PS SM SS MAP */ 303 /* PM PS SM SS MAP */
304 { P0, P1, P2, P3 }, /* 00b */ 304 { P0, P2, P1, P3 }, /* 00b */
305 { IDE, IDE, P1, P3 }, /* 01b */ 305 { IDE, IDE, P1, P3 }, /* 01b */
306 { P0, P2, IDE, IDE }, /* 10b */ 306 { P0, P2, IDE, IDE }, /* 10b */
307 { RV, RV, RV, RV }, 307 { RV, RV, RV, RV },
@@ -312,7 +312,7 @@ static struct piix_map_db ich6m_map_db = {
312 .mask = 0x3, 312 .mask = 0x3,
313 .map = { 313 .map = {
314 /* PM PS SM SS MAP */ 314 /* PM PS SM SS MAP */
315 { P0, P1, P2, P3 }, /* 00b */ 315 { P0, P2, RV, RV }, /* 00b */
316 { RV, RV, RV, RV }, 316 { RV, RV, RV, RV },
317 { P0, P2, IDE, IDE }, /* 10b */ 317 { P0, P2, IDE, IDE }, /* 10b */
318 { RV, RV, RV, RV }, 318 { RV, RV, RV, RV },
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 3a8462e8d063..24eb59e143a9 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -2488,7 +2488,7 @@ static int option_setup(char *str)
2488 } 2488 }
2489 ints[0] = i - 1; 2489 ints[0] = i - 1;
2490 internal_ibmmca_scsi_setup(cur, ints); 2490 internal_ibmmca_scsi_setup(cur, ints);
2491 return 0; 2491 return 1;
2492} 2492}
2493 2493
2494__setup("ibmmcascsi=", option_setup); 2494__setup("ibmmcascsi=", option_setup);
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 21b0ed583b8a..e63c1ff1e102 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -278,7 +278,7 @@ static void ata_unpack_xfermask(unsigned int xfer_mask,
278} 278}
279 279
280static const struct ata_xfer_ent { 280static const struct ata_xfer_ent {
281 unsigned int shift, bits; 281 int shift, bits;
282 u8 base; 282 u8 base;
283} ata_xfer_tbl[] = { 283} ata_xfer_tbl[] = {
284 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, 284 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
@@ -989,9 +989,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
989 qc->private_data = &wait; 989 qc->private_data = &wait;
990 qc->complete_fn = ata_qc_complete_internal; 990 qc->complete_fn = ata_qc_complete_internal;
991 991
992 qc->err_mask = ata_qc_issue(qc); 992 ata_qc_issue(qc);
993 if (qc->err_mask)
994 ata_qc_complete(qc);
995 993
996 spin_unlock_irqrestore(&ap->host_set->lock, flags); 994 spin_unlock_irqrestore(&ap->host_set->lock, flags);
997 995
@@ -3997,15 +3995,14 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
3997 * 3995 *
3998 * LOCKING: 3996 * LOCKING:
3999 * spin_lock_irqsave(host_set lock) 3997 * spin_lock_irqsave(host_set lock)
4000 *
4001 * RETURNS:
4002 * Zero on success, AC_ERR_* mask on failure
4003 */ 3998 */
4004 3999void ata_qc_issue(struct ata_queued_cmd *qc)
4005unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
4006{ 4000{
4007 struct ata_port *ap = qc->ap; 4001 struct ata_port *ap = qc->ap;
4008 4002
4003 qc->ap->active_tag = qc->tag;
4004 qc->flags |= ATA_QCFLAG_ACTIVE;
4005
4009 if (ata_should_dma_map(qc)) { 4006 if (ata_should_dma_map(qc)) {
4010 if (qc->flags & ATA_QCFLAG_SG) { 4007 if (qc->flags & ATA_QCFLAG_SG) {
4011 if (ata_sg_setup(qc)) 4008 if (ata_sg_setup(qc))
@@ -4020,17 +4017,18 @@ unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
4020 4017
4021 ap->ops->qc_prep(qc); 4018 ap->ops->qc_prep(qc);
4022 4019
4023 qc->ap->active_tag = qc->tag; 4020 qc->err_mask |= ap->ops->qc_issue(qc);
4024 qc->flags |= ATA_QCFLAG_ACTIVE; 4021 if (unlikely(qc->err_mask))
4025 4022 goto err;
4026 return ap->ops->qc_issue(qc); 4023 return;
4027 4024
4028sg_err: 4025sg_err:
4029 qc->flags &= ~ATA_QCFLAG_DMAMAP; 4026 qc->flags &= ~ATA_QCFLAG_DMAMAP;
4030 return AC_ERR_SYSTEM; 4027 qc->err_mask |= AC_ERR_SYSTEM;
4028err:
4029 ata_qc_complete(qc);
4031} 4030}
4032 4031
4033
4034/** 4032/**
4035 * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner 4033 * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
4036 * @qc: command to issue to device 4034 * @qc: command to issue to device
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 628191bfd990..53f5b0d9161c 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1431,9 +1431,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
1431 goto early_finish; 1431 goto early_finish;
1432 1432
1433 /* select device, send command to hardware */ 1433 /* select device, send command to hardware */
1434 qc->err_mask = ata_qc_issue(qc); 1434 ata_qc_issue(qc);
1435 if (qc->err_mask)
1436 ata_qc_complete(qc);
1437 1435
1438 VPRINTK("EXIT\n"); 1436 VPRINTK("EXIT\n");
1439 return; 1437 return;
@@ -2199,9 +2197,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
2199 2197
2200 qc->complete_fn = atapi_sense_complete; 2198 qc->complete_fn = atapi_sense_complete;
2201 2199
2202 qc->err_mask = ata_qc_issue(qc); 2200 ata_qc_issue(qc);
2203 if (qc->err_mask)
2204 ata_qc_complete(qc);
2205 2201
2206 DPRINTK("EXIT\n"); 2202 DPRINTK("EXIT\n");
2207} 2203}
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 65f52beea884..1c755b14521a 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -47,7 +47,7 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
47extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); 47extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
48extern void ata_port_flush_task(struct ata_port *ap); 48extern void ata_port_flush_task(struct ata_port *ap);
49extern void ata_qc_free(struct ata_queued_cmd *qc); 49extern void ata_qc_free(struct ata_queued_cmd *qc);
50extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc); 50extern void ata_qc_issue(struct ata_queued_cmd *qc);
51extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); 51extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
52extern void ata_dev_select(struct ata_port *ap, unsigned int device, 52extern void ata_dev_select(struct ata_port *ap, unsigned int device,
53 unsigned int wait, unsigned int can_sleep); 53 unsigned int wait, unsigned int can_sleep);
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 4d48b625cd3d..7d823705193c 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -142,12 +142,14 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
142{ 142{
143 unsigned long lock_flags; 143 unsigned long lock_flags;
144 struct jsm_channel *channel = (struct jsm_channel *)port; 144 struct jsm_channel *channel = (struct jsm_channel *)port;
145 struct termios *termios;
145 146
146 spin_lock_irqsave(&port->lock, lock_flags); 147 spin_lock_irqsave(&port->lock, lock_flags);
147 if (ch == port->info->tty->termios->c_cc[VSTART]) 148 termios = port->info->tty->termios;
149 if (ch == termios->c_cc[VSTART])
148 channel->ch_bd->bd_ops->send_start_character(channel); 150 channel->ch_bd->bd_ops->send_start_character(channel);
149 151
150 if (ch == port->info->tty->termios->c_cc[VSTOP]) 152 if (ch == termios->c_cc[VSTOP])
151 channel->ch_bd->bd_ops->send_stop_character(channel); 153 channel->ch_bd->bd_ops->send_stop_character(channel);
152 spin_unlock_irqrestore(&port->lock, lock_flags); 154 spin_unlock_irqrestore(&port->lock, lock_flags);
153} 155}
@@ -178,6 +180,7 @@ static int jsm_tty_open(struct uart_port *port)
178 struct jsm_board *brd; 180 struct jsm_board *brd;
179 int rc = 0; 181 int rc = 0;
180 struct jsm_channel *channel = (struct jsm_channel *)port; 182 struct jsm_channel *channel = (struct jsm_channel *)port;
183 struct termios *termios;
181 184
182 /* Get board pointer from our array of majors we have allocated */ 185 /* Get board pointer from our array of majors we have allocated */
183 brd = channel->ch_bd; 186 brd = channel->ch_bd;
@@ -239,12 +242,13 @@ static int jsm_tty_open(struct uart_port *port)
239 channel->ch_cached_lsr = 0; 242 channel->ch_cached_lsr = 0;
240 channel->ch_stops_sent = 0; 243 channel->ch_stops_sent = 0;
241 244
242 channel->ch_c_cflag = port->info->tty->termios->c_cflag; 245 termios = port->info->tty->termios;
243 channel->ch_c_iflag = port->info->tty->termios->c_iflag; 246 channel->ch_c_cflag = termios->c_cflag;
244 channel->ch_c_oflag = port->info->tty->termios->c_oflag; 247 channel->ch_c_iflag = termios->c_iflag;
245 channel->ch_c_lflag = port->info->tty->termios->c_lflag; 248 channel->ch_c_oflag = termios->c_oflag;
246 channel->ch_startc = port->info->tty->termios->c_cc[VSTART]; 249 channel->ch_c_lflag = termios->c_lflag;
247 channel->ch_stopc = port->info->tty->termios->c_cc[VSTOP]; 250 channel->ch_startc = termios->c_cc[VSTART];
251 channel->ch_stopc = termios->c_cc[VSTOP];
248 252
249 /* Tell UART to init itself */ 253 /* Tell UART to init itself */
250 brd->bd_ops->uart_init(channel); 254 brd->bd_ops->uart_init(channel);
@@ -784,6 +788,7 @@ static void jsm_carrier(struct jsm_channel *ch)
784 788
785void jsm_check_queue_flow_control(struct jsm_channel *ch) 789void jsm_check_queue_flow_control(struct jsm_channel *ch)
786{ 790{
791 struct board_ops *bd_ops = ch->ch_bd->bd_ops;
787 int qleft = 0; 792 int qleft = 0;
788 793
789 /* Store how much space we have left in the queue */ 794 /* Store how much space we have left in the queue */
@@ -809,7 +814,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
809 /* HWFLOW */ 814 /* HWFLOW */
810 if (ch->ch_c_cflag & CRTSCTS) { 815 if (ch->ch_c_cflag & CRTSCTS) {
811 if(!(ch->ch_flags & CH_RECEIVER_OFF)) { 816 if(!(ch->ch_flags & CH_RECEIVER_OFF)) {
812 ch->ch_bd->bd_ops->disable_receiver(ch); 817 bd_ops->disable_receiver(ch);
813 ch->ch_flags |= (CH_RECEIVER_OFF); 818 ch->ch_flags |= (CH_RECEIVER_OFF);
814 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 819 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
815 "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", 820 "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n",
@@ -819,7 +824,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
819 /* SWFLOW */ 824 /* SWFLOW */
820 else if (ch->ch_c_iflag & IXOFF) { 825 else if (ch->ch_c_iflag & IXOFF) {
821 if (ch->ch_stops_sent <= MAX_STOPS_SENT) { 826 if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
822 ch->ch_bd->bd_ops->send_stop_character(ch); 827 bd_ops->send_stop_character(ch);
823 ch->ch_stops_sent++; 828 ch->ch_stops_sent++;
824 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 829 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
825 "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); 830 "Sending stop char! Times sent: %x\n", ch->ch_stops_sent);
@@ -846,7 +851,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
846 /* HWFLOW */ 851 /* HWFLOW */
847 if (ch->ch_c_cflag & CRTSCTS) { 852 if (ch->ch_c_cflag & CRTSCTS) {
848 if (ch->ch_flags & CH_RECEIVER_OFF) { 853 if (ch->ch_flags & CH_RECEIVER_OFF) {
849 ch->ch_bd->bd_ops->enable_receiver(ch); 854 bd_ops->enable_receiver(ch);
850 ch->ch_flags &= ~(CH_RECEIVER_OFF); 855 ch->ch_flags &= ~(CH_RECEIVER_OFF);
851 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 856 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
852 "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", 857 "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n",
@@ -856,7 +861,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
856 /* SWFLOW */ 861 /* SWFLOW */
857 else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { 862 else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
858 ch->ch_stops_sent = 0; 863 ch->ch_stops_sent = 0;
859 ch->ch_bd->bd_ops->send_start_character(ch); 864 bd_ops->send_start_character(ch);
860 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); 865 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n");
861 } 866 }
862 } 867 }
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 22e9d696fdd2..f87c0171f4ec 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -904,18 +904,6 @@ config FB_MATROX_MULTIHEAD
904 There is no need for enabling 'Matrox multihead support' if you have 904 There is no need for enabling 'Matrox multihead support' if you have
905 only one Matrox card in the box. 905 only one Matrox card in the box.
906 906
907config FB_RADEON_OLD
908 tristate "ATI Radeon display support (Old driver)"
909 depends on FB && PCI
910 select FB_CFB_FILLRECT
911 select FB_CFB_COPYAREA
912 select FB_CFB_IMAGEBLIT
913 select FB_MACMODES if PPC
914 help
915 Choose this option if you want to use an ATI Radeon graphics card as
916 a framebuffer device. There are both PCI and AGP versions. You
917 don't need to choose this to run the Radeon in plain VGA mode.
918
919config FB_RADEON 907config FB_RADEON
920 tristate "ATI Radeon display support" 908 tristate "ATI Radeon display support"
921 depends on FB && PCI 909 depends on FB && PCI
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index cb90218515ac..23de3b2c7856 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -39,7 +39,6 @@ obj-$(CONFIG_FB_KYRO) += kyro/
39obj-$(CONFIG_FB_SAVAGE) += savage/ 39obj-$(CONFIG_FB_SAVAGE) += savage/
40obj-$(CONFIG_FB_GEODE) += geode/ 40obj-$(CONFIG_FB_GEODE) += geode/
41obj-$(CONFIG_FB_I810) += vgastate.o 41obj-$(CONFIG_FB_I810) += vgastate.o
42obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o
43obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o 42obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
44obj-$(CONFIG_FB_VIRGE) += virgefb.o 43obj-$(CONFIG_FB_VIRGE) += virgefb.o
45obj-$(CONFIG_FB_3DFX) += tdfxfb.o 44obj-$(CONFIG_FB_3DFX) += tdfxfb.o
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 9d996f2c10d5..b895eaaa73fd 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -43,11 +43,11 @@ config LCD_DEVICE
43 default y 43 default y
44 44
45config BACKLIGHT_CORGI 45config BACKLIGHT_CORGI
46 tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)" 46 tristate "Sharp Corgi Backlight Driver (SL Series)"
47 depends on BACKLIGHT_DEVICE && PXA_SHARPSL 47 depends on BACKLIGHT_DEVICE && PXA_SHARPSL
48 default y 48 default y
49 help 49 help
50 If you have a Sharp Zaurus SL-C7xx, say y to enable the 50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
51 backlight driver. 51 backlight driver.
52 52
53config BACKLIGHT_HP680 53config BACKLIGHT_HP680
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 151fda8dded0..334b1db1bd7c 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -16,14 +16,12 @@
16 16
17static ssize_t backlight_show_power(struct class_device *cdev, char *buf) 17static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
18{ 18{
19 int rc; 19 int rc = -ENXIO;
20 struct backlight_device *bd = to_backlight_device(cdev); 20 struct backlight_device *bd = to_backlight_device(cdev);
21 21
22 down(&bd->sem); 22 down(&bd->sem);
23 if (likely(bd->props && bd->props->get_power)) 23 if (likely(bd->props))
24 rc = sprintf(buf, "%d\n", bd->props->get_power(bd)); 24 rc = sprintf(buf, "%d\n", bd->props->power);
25 else
26 rc = -ENXIO;
27 up(&bd->sem); 25 up(&bd->sem);
28 26
29 return rc; 27 return rc;
@@ -31,7 +29,7 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
31 29
32static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) 30static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
33{ 31{
34 int rc, power; 32 int rc = -ENXIO, power;
35 char *endp; 33 char *endp;
36 struct backlight_device *bd = to_backlight_device(cdev); 34 struct backlight_device *bd = to_backlight_device(cdev);
37 35
@@ -40,12 +38,13 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
40 return -EINVAL; 38 return -EINVAL;
41 39
42 down(&bd->sem); 40 down(&bd->sem);
43 if (likely(bd->props && bd->props->set_power)) { 41 if (likely(bd->props)) {
44 pr_debug("backlight: set power to %d\n", power); 42 pr_debug("backlight: set power to %d\n", power);
45 bd->props->set_power(bd, power); 43 bd->props->power = power;
44 if (likely(bd->props->update_status))
45 bd->props->update_status(bd);
46 rc = count; 46 rc = count;
47 } else 47 }
48 rc = -ENXIO;
49 up(&bd->sem); 48 up(&bd->sem);
50 49
51 return rc; 50 return rc;
@@ -53,14 +52,12 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
53 52
54static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) 53static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
55{ 54{
56 int rc; 55 int rc = -ENXIO;
57 struct backlight_device *bd = to_backlight_device(cdev); 56 struct backlight_device *bd = to_backlight_device(cdev);
58 57
59 down(&bd->sem); 58 down(&bd->sem);
60 if (likely(bd->props && bd->props->get_brightness)) 59 if (likely(bd->props))
61 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); 60 rc = sprintf(buf, "%d\n", bd->props->brightness);
62 else
63 rc = -ENXIO;
64 up(&bd->sem); 61 up(&bd->sem);
65 62
66 return rc; 63 return rc;
@@ -68,7 +65,7 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
68 65
69static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) 66static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
70{ 67{
71 int rc, brightness; 68 int rc = -ENXIO, brightness;
72 char *endp; 69 char *endp;
73 struct backlight_device *bd = to_backlight_device(cdev); 70 struct backlight_device *bd = to_backlight_device(cdev);
74 71
@@ -77,12 +74,18 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
77 return -EINVAL; 74 return -EINVAL;
78 75
79 down(&bd->sem); 76 down(&bd->sem);
80 if (likely(bd->props && bd->props->set_brightness)) { 77 if (likely(bd->props)) {
81 pr_debug("backlight: set brightness to %d\n", brightness); 78 if (brightness > bd->props->max_brightness)
82 bd->props->set_brightness(bd, brightness); 79 rc = -EINVAL;
83 rc = count; 80 else {
84 } else 81 pr_debug("backlight: set brightness to %d\n",
85 rc = -ENXIO; 82 brightness);
83 bd->props->brightness = brightness;
84 if (likely(bd->props->update_status))
85 bd->props->update_status(bd);
86 rc = count;
87 }
88 }
86 up(&bd->sem); 89 up(&bd->sem);
87 90
88 return rc; 91 return rc;
@@ -90,14 +93,26 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
90 93
91static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) 94static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
92{ 95{
93 int rc; 96 int rc = -ENXIO;
94 struct backlight_device *bd = to_backlight_device(cdev); 97 struct backlight_device *bd = to_backlight_device(cdev);
95 98
96 down(&bd->sem); 99 down(&bd->sem);
97 if (likely(bd->props)) 100 if (likely(bd->props))
98 rc = sprintf(buf, "%d\n", bd->props->max_brightness); 101 rc = sprintf(buf, "%d\n", bd->props->max_brightness);
99 else 102 up(&bd->sem);
100 rc = -ENXIO; 103
104 return rc;
105}
106
107static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
108 char *buf)
109{
110 int rc = -ENXIO;
111 struct backlight_device *bd = to_backlight_device(cdev);
112
113 down(&bd->sem);
114 if (likely(bd->props && bd->props->get_brightness))
115 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
101 up(&bd->sem); 116 up(&bd->sem);
102 117
103 return rc; 118 return rc;
@@ -123,7 +138,10 @@ static struct class backlight_class = {
123 138
124static struct class_device_attribute bl_class_device_attributes[] = { 139static struct class_device_attribute bl_class_device_attributes[] = {
125 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), 140 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
126 DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness), 141 DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
142 backlight_store_brightness),
143 DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
144 NULL),
127 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), 145 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
128}; 146};
129 147
@@ -144,8 +162,12 @@ static int fb_notifier_callback(struct notifier_block *self,
144 bd = container_of(self, struct backlight_device, fb_notif); 162 bd = container_of(self, struct backlight_device, fb_notif);
145 down(&bd->sem); 163 down(&bd->sem);
146 if (bd->props) 164 if (bd->props)
147 if (!bd->props->check_fb || bd->props->check_fb(evdata->info)) 165 if (!bd->props->check_fb ||
148 bd->props->set_power(bd, *(int *)evdata->data); 166 bd->props->check_fb(evdata->info)) {
167 bd->props->fb_blank = *(int *)evdata->data;
168 if (likely(bd->props && bd->props->update_status))
169 bd->props->update_status(bd);
170 }
149 up(&bd->sem); 171 up(&bd->sem);
150 return 0; 172 return 0;
151} 173}
@@ -231,6 +253,12 @@ void backlight_device_unregister(struct backlight_device *bd)
231 &bl_class_device_attributes[i]); 253 &bl_class_device_attributes[i]);
232 254
233 down(&bd->sem); 255 down(&bd->sem);
256 if (likely(bd->props && bd->props->update_status)) {
257 bd->props->brightness = 0;
258 bd->props->power = 0;
259 bd->props->update_status(bd);
260 }
261
234 bd->props = NULL; 262 bd->props = NULL;
235 up(&bd->sem); 263 up(&bd->sem);
236 264
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index d0aaf450e8c7..2ebbfd95145f 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Backlight Driver for Sharp Corgi 2 * Backlight Driver for Sharp Zaurus Handhelds (various models)
3 * 3 *
4 * Copyright (c) 2004-2005 Richard Purdie 4 * Copyright (c) 2004-2006 Richard Purdie
5 * 5 *
6 * Based on Sharp's 2.4 Backlight Driver 6 * Based on Sharp's 2.4 Backlight Driver
7 * 7 *
@@ -15,80 +15,63 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/spinlock.h> 18#include <linux/mutex.h>
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/backlight.h> 20#include <linux/backlight.h>
21
22#include <asm/arch/sharpsl.h> 21#include <asm/arch/sharpsl.h>
23#include <asm/hardware/sharpsl_pm.h> 22#include <asm/hardware/sharpsl_pm.h>
24 23
25#define CORGI_DEFAULT_INTENSITY 0x1f 24static int corgibl_intensity;
26#define CORGI_LIMIT_MASK 0x0b 25static DEFINE_MUTEX(bl_mutex);
27
28static int corgibl_powermode = FB_BLANK_UNBLANK;
29static int current_intensity = 0;
30static int corgibl_limit = 0;
31static void (*corgibl_mach_set_intensity)(int intensity);
32static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
33static struct backlight_properties corgibl_data; 26static struct backlight_properties corgibl_data;
27static struct backlight_device *corgi_backlight_device;
28static struct corgibl_machinfo *bl_machinfo;
34 29
35static void corgibl_send_intensity(int intensity) 30static unsigned long corgibl_flags;
31#define CORGIBL_SUSPENDED 0x01
32#define CORGIBL_BATTLOW 0x02
33
34static int corgibl_send_intensity(struct backlight_device *bd)
36{ 35{
37 unsigned long flags;
38 void (*corgi_kick_batt)(void); 36 void (*corgi_kick_batt)(void);
37 int intensity = bd->props->brightness;
39 38
40 if (corgibl_powermode != FB_BLANK_UNBLANK) { 39 if (bd->props->power != FB_BLANK_UNBLANK)
41 intensity = 0; 40 intensity = 0;
42 } else { 41 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
43 if (corgibl_limit) 42 intensity = 0;
44 intensity &= CORGI_LIMIT_MASK; 43 if (corgibl_flags & CORGIBL_SUSPENDED)
45 } 44 intensity = 0;
46 45 if (corgibl_flags & CORGIBL_BATTLOW)
47 spin_lock_irqsave(&bl_lock, flags); 46 intensity &= bl_machinfo->limit_mask;
48 47
49 corgibl_mach_set_intensity(intensity); 48 mutex_lock(&bl_mutex);
49 bl_machinfo->set_bl_intensity(intensity);
50 mutex_unlock(&bl_mutex);
50 51
51 spin_unlock_irqrestore(&bl_lock, flags); 52 corgibl_intensity = intensity;
52 53
53 corgi_kick_batt = symbol_get(sharpsl_battery_kick); 54 corgi_kick_batt = symbol_get(sharpsl_battery_kick);
54 if (corgi_kick_batt) { 55 if (corgi_kick_batt) {
55 corgi_kick_batt(); 56 corgi_kick_batt();
56 symbol_put(sharpsl_battery_kick); 57 symbol_put(sharpsl_battery_kick);
57 } 58 }
58}
59 59
60static void corgibl_blank(int blank) 60 return 0;
61{
62 switch(blank) {
63
64 case FB_BLANK_NORMAL:
65 case FB_BLANK_VSYNC_SUSPEND:
66 case FB_BLANK_HSYNC_SUSPEND:
67 case FB_BLANK_POWERDOWN:
68 if (corgibl_powermode == FB_BLANK_UNBLANK) {
69 corgibl_send_intensity(0);
70 corgibl_powermode = blank;
71 }
72 break;
73 case FB_BLANK_UNBLANK:
74 if (corgibl_powermode != FB_BLANK_UNBLANK) {
75 corgibl_powermode = blank;
76 corgibl_send_intensity(current_intensity);
77 }
78 break;
79 }
80} 61}
81 62
82#ifdef CONFIG_PM 63#ifdef CONFIG_PM
83static int corgibl_suspend(struct platform_device *dev, pm_message_t state) 64static int corgibl_suspend(struct platform_device *dev, pm_message_t state)
84{ 65{
85 corgibl_blank(FB_BLANK_POWERDOWN); 66 corgibl_flags |= CORGIBL_SUSPENDED;
67 corgibl_send_intensity(corgi_backlight_device);
86 return 0; 68 return 0;
87} 69}
88 70
89static int corgibl_resume(struct platform_device *dev) 71static int corgibl_resume(struct platform_device *dev)
90{ 72{
91 corgibl_blank(FB_BLANK_UNBLANK); 73 corgibl_flags &= ~CORGIBL_SUSPENDED;
74 corgibl_send_intensity(corgi_backlight_device);
92 return 0; 75 return 0;
93} 76}
94#else 77#else
@@ -96,68 +79,55 @@ static int corgibl_resume(struct platform_device *dev)
96#define corgibl_resume NULL 79#define corgibl_resume NULL
97#endif 80#endif
98 81
99 82static int corgibl_get_intensity(struct backlight_device *bd)
100static int corgibl_set_power(struct backlight_device *bd, int state)
101{
102 corgibl_blank(state);
103 return 0;
104}
105
106static int corgibl_get_power(struct backlight_device *bd)
107{ 83{
108 return corgibl_powermode; 84 return corgibl_intensity;
109} 85}
110 86
111static int corgibl_set_intensity(struct backlight_device *bd, int intensity) 87static int corgibl_set_intensity(struct backlight_device *bd)
112{ 88{
113 if (intensity > corgibl_data.max_brightness) 89 corgibl_send_intensity(corgi_backlight_device);
114 intensity = corgibl_data.max_brightness;
115 corgibl_send_intensity(intensity);
116 current_intensity=intensity;
117 return 0; 90 return 0;
118} 91}
119 92
120static int corgibl_get_intensity(struct backlight_device *bd)
121{
122 return current_intensity;
123}
124
125/* 93/*
126 * Called when the battery is low to limit the backlight intensity. 94 * Called when the battery is low to limit the backlight intensity.
127 * If limit==0 clear any limit, otherwise limit the intensity 95 * If limit==0 clear any limit, otherwise limit the intensity
128 */ 96 */
129void corgibl_limit_intensity(int limit) 97void corgibl_limit_intensity(int limit)
130{ 98{
131 corgibl_limit = (limit ? 1 : 0); 99 if (limit)
132 corgibl_send_intensity(current_intensity); 100 corgibl_flags |= CORGIBL_BATTLOW;
101 else
102 corgibl_flags &= ~CORGIBL_BATTLOW;
103 corgibl_send_intensity(corgi_backlight_device);
133} 104}
134EXPORT_SYMBOL(corgibl_limit_intensity); 105EXPORT_SYMBOL(corgibl_limit_intensity);
135 106
136 107
137static struct backlight_properties corgibl_data = { 108static struct backlight_properties corgibl_data = {
138 .owner = THIS_MODULE, 109 .owner = THIS_MODULE,
139 .get_power = corgibl_get_power,
140 .set_power = corgibl_set_power,
141 .get_brightness = corgibl_get_intensity, 110 .get_brightness = corgibl_get_intensity,
142 .set_brightness = corgibl_set_intensity, 111 .update_status = corgibl_set_intensity,
143}; 112};
144 113
145static struct backlight_device *corgi_backlight_device;
146
147static int __init corgibl_probe(struct platform_device *pdev) 114static int __init corgibl_probe(struct platform_device *pdev)
148{ 115{
149 struct corgibl_machinfo *machinfo = pdev->dev.platform_data; 116 struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
150 117
118 bl_machinfo = machinfo;
151 corgibl_data.max_brightness = machinfo->max_intensity; 119 corgibl_data.max_brightness = machinfo->max_intensity;
152 corgibl_mach_set_intensity = machinfo->set_bl_intensity; 120 if (!machinfo->limit_mask)
121 machinfo->limit_mask = -1;
153 122
154 corgi_backlight_device = backlight_device_register ("corgi-bl", 123 corgi_backlight_device = backlight_device_register ("corgi-bl",
155 NULL, &corgibl_data); 124 NULL, &corgibl_data);
156 if (IS_ERR (corgi_backlight_device)) 125 if (IS_ERR (corgi_backlight_device))
157 return PTR_ERR (corgi_backlight_device); 126 return PTR_ERR (corgi_backlight_device);
158 127
159 corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); 128 corgibl_data.power = FB_BLANK_UNBLANK;
160 corgibl_limit_intensity(0); 129 corgibl_data.brightness = machinfo->default_intensity;
130 corgibl_send_intensity(corgi_backlight_device);
161 131
162 printk("Corgi Backlight Driver Initialized.\n"); 132 printk("Corgi Backlight Driver Initialized.\n");
163 return 0; 133 return 0;
@@ -167,8 +137,6 @@ static int corgibl_remove(struct platform_device *dev)
167{ 137{
168 backlight_device_unregister(corgi_backlight_device); 138 backlight_device_unregister(corgi_backlight_device);
169 139
170 corgibl_set_intensity(NULL, 0);
171
172 printk("Corgi Backlight Driver Unloaded\n"); 140 printk("Corgi Backlight Driver Unloaded\n");
173 return 0; 141 return 0;
174} 142}
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 95da4c9ed1f1..a71e984c93d4 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -13,7 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/fb.h> 18#include <linux/fb.h>
19#include <linux/backlight.h> 19#include <linux/backlight.h>
@@ -25,66 +25,58 @@
25#define HP680_MAX_INTENSITY 255 25#define HP680_MAX_INTENSITY 255
26#define HP680_DEFAULT_INTENSITY 10 26#define HP680_DEFAULT_INTENSITY 10
27 27
28static int hp680bl_powermode = FB_BLANK_UNBLANK; 28static int hp680bl_suspended;
29static int current_intensity = 0; 29static int current_intensity = 0;
30static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; 30static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
31static struct backlight_device *hp680_backlight_device;
31 32
32static void hp680bl_send_intensity(int intensity) 33static void hp680bl_send_intensity(struct backlight_device *bd)
33{ 34{
34 unsigned long flags; 35 unsigned long flags;
36 u16 v;
37 int intensity = bd->props->brightness;
35 38
36 if (hp680bl_powermode != FB_BLANK_UNBLANK) 39 if (bd->props->power != FB_BLANK_UNBLANK)
40 intensity = 0;
41 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
42 intensity = 0;
43 if (hp680bl_suspended)
37 intensity = 0; 44 intensity = 0;
38 45
39 spin_lock_irqsave(&bl_lock, flags); 46 spin_lock_irqsave(&bl_lock, flags);
40 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); 47 if (intensity && current_intensity == 0) {
48 sh_dac_enable(DAC_LCD_BRIGHTNESS);
49 v = inw(HD64461_GPBDR);
50 v &= ~HD64461_GPBDR_LCDOFF;
51 outw(v, HD64461_GPBDR);
52 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
53 } else if (intensity == 0 && current_intensity != 0) {
54 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
55 sh_dac_disable(DAC_LCD_BRIGHTNESS);
56 v = inw(HD64461_GPBDR);
57 v |= HD64461_GPBDR_LCDOFF;
58 outw(v, HD64461_GPBDR);
59 } else if (intensity) {
60 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
61 }
41 spin_unlock_irqrestore(&bl_lock, flags); 62 spin_unlock_irqrestore(&bl_lock, flags);
42}
43 63
44static void hp680bl_blank(int blank) 64 current_intensity = intensity;
45{
46 u16 v;
47
48 switch(blank) {
49
50 case FB_BLANK_NORMAL:
51 case FB_BLANK_VSYNC_SUSPEND:
52 case FB_BLANK_HSYNC_SUSPEND:
53 case FB_BLANK_POWERDOWN:
54 if (hp680bl_powermode == FB_BLANK_UNBLANK) {
55 hp680bl_send_intensity(0);
56 hp680bl_powermode = blank;
57 sh_dac_disable(DAC_LCD_BRIGHTNESS);
58 v = inw(HD64461_GPBDR);
59 v |= HD64461_GPBDR_LCDOFF;
60 outw(v, HD64461_GPBDR);
61 }
62 break;
63 case FB_BLANK_UNBLANK:
64 if (hp680bl_powermode != FB_BLANK_UNBLANK) {
65 sh_dac_enable(DAC_LCD_BRIGHTNESS);
66 v = inw(HD64461_GPBDR);
67 v &= ~HD64461_GPBDR_LCDOFF;
68 outw(v, HD64461_GPBDR);
69 hp680bl_powermode = blank;
70 hp680bl_send_intensity(current_intensity);
71 }
72 break;
73 }
74} 65}
75 66
67
76#ifdef CONFIG_PM 68#ifdef CONFIG_PM
77static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level) 69static int hp680bl_suspend(struct platform_device *dev, pm_message_t state)
78{ 70{
79 if (level == SUSPEND_POWER_DOWN) 71 hp680bl_suspended = 1;
80 hp680bl_blank(FB_BLANK_POWERDOWN); 72 hp680bl_send_intensity(hp680_backlight_device);
81 return 0; 73 return 0;
82} 74}
83 75
84static int hp680bl_resume(struct device *dev, u32 level) 76static int hp680bl_resume(struct platform_device *dev)
85{ 77{
86 if (level == RESUME_POWER_ON) 78 hp680bl_suspended = 0;
87 hp680bl_blank(FB_BLANK_UNBLANK); 79 hp680bl_send_intensity(hp680_backlight_device);
88 return 0; 80 return 0;
89} 81}
90#else 82#else
@@ -92,24 +84,9 @@ static int hp680bl_resume(struct device *dev, u32 level)
92#define hp680bl_resume NULL 84#define hp680bl_resume NULL
93#endif 85#endif
94 86
95 87static int hp680bl_set_intensity(struct backlight_device *bd)
96static int hp680bl_set_power(struct backlight_device *bd, int state)
97{ 88{
98 hp680bl_blank(state); 89 hp680bl_send_intensity(bd);
99 return 0;
100}
101
102static int hp680bl_get_power(struct backlight_device *bd)
103{
104 return hp680bl_powermode;
105}
106
107static int hp680bl_set_intensity(struct backlight_device *bd, int intensity)
108{
109 if (intensity > HP680_MAX_INTENSITY)
110 intensity = HP680_MAX_INTENSITY;
111 hp680bl_send_intensity(intensity);
112 current_intensity = intensity;
113 return 0; 90 return 0;
114} 91}
115 92
@@ -120,65 +97,67 @@ static int hp680bl_get_intensity(struct backlight_device *bd)
120 97
121static struct backlight_properties hp680bl_data = { 98static struct backlight_properties hp680bl_data = {
122 .owner = THIS_MODULE, 99 .owner = THIS_MODULE,
123 .get_power = hp680bl_get_power,
124 .set_power = hp680bl_set_power,
125 .max_brightness = HP680_MAX_INTENSITY, 100 .max_brightness = HP680_MAX_INTENSITY,
126 .get_brightness = hp680bl_get_intensity, 101 .get_brightness = hp680bl_get_intensity,
127 .set_brightness = hp680bl_set_intensity, 102 .update_status = hp680bl_set_intensity,
128}; 103};
129 104
130static struct backlight_device *hp680_backlight_device; 105static int __init hp680bl_probe(struct platform_device *dev)
131
132static int __init hp680bl_probe(struct device *dev)
133{ 106{
134 hp680_backlight_device = backlight_device_register ("hp680-bl", 107 hp680_backlight_device = backlight_device_register ("hp680-bl",
135 NULL, &hp680bl_data); 108 NULL, &hp680bl_data);
136 if (IS_ERR (hp680_backlight_device)) 109 if (IS_ERR (hp680_backlight_device))
137 return PTR_ERR (hp680_backlight_device); 110 return PTR_ERR (hp680_backlight_device);
138 111
139 hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY); 112 hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY;
113 hp680bl_send_intensity(hp680_backlight_device);
140 114
141 return 0; 115 return 0;
142} 116}
143 117
144static int hp680bl_remove(struct device *dev) 118static int hp680bl_remove(struct platform_device *dev)
145{ 119{
146 backlight_device_unregister(hp680_backlight_device); 120 backlight_device_unregister(hp680_backlight_device);
147 121
148 return 0; 122 return 0;
149} 123}
150 124
151static struct device_driver hp680bl_driver = { 125static struct platform_driver hp680bl_driver = {
152 .name = "hp680-bl",
153 .bus = &platform_bus_type,
154 .probe = hp680bl_probe, 126 .probe = hp680bl_probe,
155 .remove = hp680bl_remove, 127 .remove = hp680bl_remove,
156 .suspend = hp680bl_suspend, 128 .suspend = hp680bl_suspend,
157 .resume = hp680bl_resume, 129 .resume = hp680bl_resume,
130 .driver = {
131 .name = "hp680-bl",
132 },
158}; 133};
159 134
160static struct platform_device hp680bl_device = { 135static struct platform_device *hp680bl_device;
161 .name = "hp680-bl",
162 .id = -1,
163};
164 136
165static int __init hp680bl_init(void) 137static int __init hp680bl_init(void)
166{ 138{
167 int ret; 139 int ret;
168 140
169 ret=driver_register(&hp680bl_driver); 141 ret = platform_driver_register(&hp680bl_driver);
170 if (!ret) { 142 if (!ret) {
171 ret = platform_device_register(&hp680bl_device); 143 hp680bl_device = platform_device_alloc("hp680-bl", -1);
172 if (ret) 144 if (!hp680bl_device)
173 driver_unregister(&hp680bl_driver); 145 return -ENOMEM;
146
147 ret = platform_device_add(hp680bl_device);
148
149 if (ret) {
150 platform_device_put(hp680bl_device);
151 platform_driver_unregister(&hp680bl_driver);
152 }
174 } 153 }
175 return ret; 154 return ret;
176} 155}
177 156
178static void __exit hp680bl_exit(void) 157static void __exit hp680bl_exit(void)
179{ 158{
180 platform_device_unregister(&hp680bl_device); 159 platform_device_unregister(hp680bl_device);
181 driver_unregister(&hp680bl_driver); 160 platform_driver_unregister(&hp680bl_driver);
182} 161}
183 162
184module_init(hp680bl_init); 163module_init(hp680bl_init);
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 910e2338a27e..8ba6152db2fd 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -169,7 +169,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
169 169
170 while (j--) { 170 while (j--) {
171 l--; 171 l--;
172 color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; 172 color = (*s & (1 << l)) ? fgcolor : bgcolor;
173 val |= FB_SHIFT_HIGH(color, shift); 173 val |= FB_SHIFT_HIGH(color, shift);
174 174
175 /* Did the bitshift spill bits to the next long? */ 175 /* Did the bitshift spill bits to the next long? */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 041d06987861..ca020719d20b 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -466,7 +466,7 @@ static int __init fb_console_setup(char *this_opt)
466 int i, j; 466 int i, j;
467 467
468 if (!this_opt || !*this_opt) 468 if (!this_opt || !*this_opt)
469 return 0; 469 return 1;
470 470
471 while ((options = strsep(&this_opt, ",")) != NULL) { 471 while ((options = strsep(&this_opt, ",")) != NULL) {
472 if (!strncmp(options, "font:", 5)) 472 if (!strncmp(options, "font:", 5))
@@ -481,10 +481,10 @@ static int __init fb_console_setup(char *this_opt)
481 options++; 481 options++;
482 } 482 }
483 if (*options != ',') 483 if (*options != ',')
484 return 0; 484 return 1;
485 options++; 485 options++;
486 } else 486 } else
487 return 0; 487 return 1;
488 } 488 }
489 489
490 if (!strncmp(options, "map:", 4)) { 490 if (!strncmp(options, "map:", 4)) {
@@ -496,7 +496,7 @@ static int __init fb_console_setup(char *this_opt)
496 con2fb_map_boot[i] = 496 con2fb_map_boot[i] =
497 (options[j++]-'0') % FB_MAX; 497 (options[j++]-'0') % FB_MAX;
498 } 498 }
499 return 0; 499 return 1;
500 } 500 }
501 501
502 if (!strncmp(options, "vc:", 3)) { 502 if (!strncmp(options, "vc:", 3)) {
@@ -518,7 +518,7 @@ static int __init fb_console_setup(char *this_opt)
518 rotate = 0; 518 rotate = 0;
519 } 519 }
520 } 520 }
521 return 0; 521 return 1;
522} 522}
523 523
524__setup("fbcon=", fb_console_setup); 524__setup("fbcon=", fb_console_setup);
@@ -1142,6 +1142,7 @@ static void fbcon_init(struct vc_data *vc, int init)
1142 set_blitting_type(vc, info); 1142 set_blitting_type(vc, info);
1143 } 1143 }
1144 1144
1145 ops->p = &fb_display[fg_console];
1145} 1146}
1146 1147
1147static void fbcon_deinit(struct vc_data *vc) 1148static void fbcon_deinit(struct vc_data *vc)
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index d6041e781aca..74ac2acaf72c 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -275,7 +275,7 @@ static int __init sti_setup(char *str)
275 if (str) 275 if (str)
276 strlcpy (default_sti_path, str, sizeof (default_sti_path)); 276 strlcpy (default_sti_path, str, sizeof (default_sti_path));
277 277
278 return 0; 278 return 1;
279} 279}
280 280
281/* Assuming the machine has multiple STI consoles (=graphic cards) which 281/* Assuming the machine has multiple STI consoles (=graphic cards) which
@@ -321,7 +321,7 @@ static int __init sti_font_setup(char *str)
321 i++; 321 i++;
322 } 322 }
323 323
324 return 0; 324 return 1;
325} 325}
326 326
327/* The optional linux kernel parameter "sti_font" defines which font 327/* The optional linux kernel parameter "sti_font" defines which font
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index b1a8dca76430..944855b3e4af 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1588,7 +1588,7 @@ static int __init video_setup(char *options)
1588 } 1588 }
1589 } 1589 }
1590 1590
1591 return 0; 1591 return 1;
1592} 1592}
1593__setup("video=", video_setup); 1593__setup("video=", video_setup);
1594#endif 1594#endif
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 53ad61f1038c..809fc5eefc15 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -232,9 +232,9 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
232 if (var->yres < MIN_YRES) 232 if (var->yres < MIN_YRES)
233 var->yres = MIN_YRES; 233 var->yres = MIN_YRES;
234 if (var->xres > fbi->max_xres) 234 if (var->xres > fbi->max_xres)
235 var->xres = fbi->max_xres; 235 return -EINVAL;
236 if (var->yres > fbi->max_yres) 236 if (var->yres > fbi->max_yres)
237 var->yres = fbi->max_yres; 237 return -EINVAL;
238 var->xres_virtual = 238 var->xres_virtual =
239 max(var->xres_virtual, var->xres); 239 max(var->xres_virtual, var->xres);
240 var->yres_virtual = 240 var->yres_virtual =
@@ -781,7 +781,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
781 LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ 781 LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
782 LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ 782 LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */
783 783
784 schedule_timeout(20 * HZ / 1000); 784 schedule_timeout(200 * HZ / 1000);
785 remove_wait_queue(&fbi->ctrlr_wait, &wait); 785 remove_wait_queue(&fbi->ctrlr_wait, &wait);
786 786
787 /* disable LCD controller clock */ 787 /* disable LCD controller clock */
@@ -1274,7 +1274,7 @@ int __init pxafb_probe(struct platform_device *dev)
1274 struct pxafb_mach_info *inf; 1274 struct pxafb_mach_info *inf;
1275 int ret; 1275 int ret;
1276 1276
1277 dev_dbg(dev, "pxafb_probe\n"); 1277 dev_dbg(&dev->dev, "pxafb_probe\n");
1278 1278
1279 inf = dev->dev.platform_data; 1279 inf = dev->dev.platform_data;
1280 ret = -ENOMEM; 1280 ret = -ENOMEM;
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
deleted file mode 100644
index afb6c2ead599..000000000000
--- a/drivers/video/radeonfb.c
+++ /dev/null
@@ -1,3167 +0,0 @@
1/*
2 * drivers/video/radeonfb.c
3 * framebuffer driver for ATI Radeon chipset video boards
4 *
5 * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org>
6 *
7 *
8 * ChangeLog:
9 * 2000-08-03 initial version 0.0.1
10 * 2000-09-10 more bug fixes, public release 0.0.5
11 * 2001-02-19 mode bug fixes, 0.0.7
12 * 2001-07-05 fixed scrolling issues, engine initialization,
13 * and minor mode tweaking, 0.0.9
14 * 2001-09-07 Radeon VE support, Nick Kurshev
15 * blanking, pan_display, and cmap fixes, 0.1.0
16 * 2001-10-10 Radeon 7500 and 8500 support, and experimental
17 * flat panel support, 0.1.1
18 * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
19 * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3
20 * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt
21 * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4
22 * 2002-06-02 console switching, mode set fixes, accel fixes
23 * 2002-06-03 MTRR support, Peter Horton, 0.1.5
24 * 2002-09-21 rv250, r300, m9 initial support,
25 * added mirror option, 0.1.6
26 *
27 * Special thanks to ATI DevRel team for their hardware donations.
28 *
29 */
30
31
32#define RADEON_VERSION "0.1.6"
33
34
35#include <linux/config.h>
36#include <linux/module.h>
37#include <linux/kernel.h>
38#include <linux/errno.h>
39#include <linux/string.h>
40#include <linux/mm.h>
41#include <linux/tty.h>
42#include <linux/slab.h>
43#include <linux/delay.h>
44#include <linux/fb.h>
45#include <linux/ioport.h>
46#include <linux/init.h>
47#include <linux/pci.h>
48#include <linux/vmalloc.h>
49
50#include <asm/io.h>
51#include <asm/uaccess.h>
52#if defined(__powerpc__)
53#include <asm/prom.h>
54#include <asm/pci-bridge.h>
55#include "macmodes.h"
56
57#ifdef CONFIG_NVRAM
58#include <linux/nvram.h>
59#endif
60
61#ifdef CONFIG_PMAC_BACKLIGHT
62#include <asm/backlight.h>
63#endif
64
65#ifdef CONFIG_BOOTX_TEXT
66#include <asm/btext.h>
67#endif
68
69#ifdef CONFIG_ADB_PMU
70#include <linux/adb.h>
71#include <linux/pmu.h>
72#endif
73
74#endif /* __powerpc__ */
75
76#ifdef CONFIG_MTRR
77#include <asm/mtrr.h>
78#endif
79
80#include <video/radeon.h>
81#include <linux/radeonfb.h>
82
83#define DEBUG 0
84
85#if DEBUG
86#define RTRACE printk
87#else
88#define RTRACE if(0) printk
89#endif
90
91// XXX
92#undef CONFIG_PMAC_PBOOK
93
94
95enum radeon_chips {
96 RADEON_QD,
97 RADEON_QE,
98 RADEON_QF,
99 RADEON_QG,
100 RADEON_QY,
101 RADEON_QZ,
102 RADEON_LW,
103 RADEON_LX,
104 RADEON_LY,
105 RADEON_LZ,
106 RADEON_QL,
107 RADEON_QN,
108 RADEON_QO,
109 RADEON_Ql,
110 RADEON_BB,
111 RADEON_QW,
112 RADEON_QX,
113 RADEON_Id,
114 RADEON_Ie,
115 RADEON_If,
116 RADEON_Ig,
117 RADEON_Ya,
118 RADEON_Yd,
119 RADEON_Ld,
120 RADEON_Le,
121 RADEON_Lf,
122 RADEON_Lg,
123 RADEON_ND,
124 RADEON_NE,
125 RADEON_NF,
126 RADEON_NG,
127 RADEON_QM
128};
129
130enum radeon_arch {
131 RADEON_R100,
132 RADEON_RV100,
133 RADEON_R200,
134 RADEON_RV200,
135 RADEON_RV250,
136 RADEON_R300,
137 RADEON_M6,
138 RADEON_M7,
139 RADEON_M9
140};
141
142static struct radeon_chip_info {
143 const char *name;
144 unsigned char arch;
145} radeon_chip_info[] __devinitdata = {
146 { "QD", RADEON_R100 },
147 { "QE", RADEON_R100 },
148 { "QF", RADEON_R100 },
149 { "QG", RADEON_R100 },
150 { "VE QY", RADEON_RV100 },
151 { "VE QZ", RADEON_RV100 },
152 { "M7 LW", RADEON_M7 },
153 { "M7 LX", RADEON_M7 },
154 { "M6 LY", RADEON_M6 },
155 { "M6 LZ", RADEON_M6 },
156 { "8500 QL", RADEON_R200 },
157 { "8500 QN", RADEON_R200 },
158 { "8500 QO", RADEON_R200 },
159 { "8500 Ql", RADEON_R200 },
160 { "8500 BB", RADEON_R200 },
161 { "7500 QW", RADEON_RV200 },
162 { "7500 QX", RADEON_RV200 },
163 { "9000 Id", RADEON_RV250 },
164 { "9000 Ie", RADEON_RV250 },
165 { "9000 If", RADEON_RV250 },
166 { "9000 Ig", RADEON_RV250 },
167 { "M9 Ld", RADEON_M9 },
168 { "M9 Le", RADEON_M9 },
169 { "M9 Lf", RADEON_M9 },
170 { "M9 Lg", RADEON_M9 },
171 { "9700 ND", RADEON_R300 },
172 { "9700 NE", RADEON_R300 },
173 { "9700 NF", RADEON_R300 },
174 { "9700 NG", RADEON_R300 },
175 { "9100 QM", RADEON_R200 }
176};
177
178
179enum radeon_montype
180{
181 MT_NONE,
182 MT_CRT, /* CRT */
183 MT_LCD, /* LCD */
184 MT_DFP, /* DVI */
185 MT_CTV, /* composite TV */
186 MT_STV /* S-Video out */
187};
188
189
190static struct pci_device_id radeonfb_pci_table[] = {
191 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
192 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
193 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
194 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
195 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
196 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
197 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
198 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
199 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
200 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
201 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
202 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
203 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
204 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
205 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
206 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
207 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
208 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
209 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
210 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
211 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
212 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ya, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ya},
213 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd},
214 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
215 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
216 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
217 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
218 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
219 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
220 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
221 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
222 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QM},
223 { 0, }
224};
225MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
226
227
228typedef struct {
229 u16 reg;
230 u32 val;
231} reg_val;
232
233
234/* these common regs are cleared before mode setting so they do not
235 * interfere with anything
236 */
237static reg_val common_regs[] = {
238 { OVR_CLR, 0 },
239 { OVR_WID_LEFT_RIGHT, 0 },
240 { OVR_WID_TOP_BOTTOM, 0 },
241 { OV0_SCALE_CNTL, 0 },
242 { SUBPIC_CNTL, 0 },
243 { VIPH_CONTROL, 0 },
244 { I2C_CNTL_1, 0 },
245 { GEN_INT_CNTL, 0 },
246 { CAP0_TRIG_CNTL, 0 },
247};
248
249static reg_val common_regs_m6[] = {
250 { OVR_CLR, 0 },
251 { OVR_WID_LEFT_RIGHT, 0 },
252 { OVR_WID_TOP_BOTTOM, 0 },
253 { OV0_SCALE_CNTL, 0 },
254 { SUBPIC_CNTL, 0 },
255 { GEN_INT_CNTL, 0 },
256 { CAP0_TRIG_CNTL, 0 }
257};
258
259typedef struct {
260 u8 clock_chip_type;
261 u8 struct_size;
262 u8 accelerator_entry;
263 u8 VGA_entry;
264 u16 VGA_table_offset;
265 u16 POST_table_offset;
266 u16 XCLK;
267 u16 MCLK;
268 u8 num_PLL_blocks;
269 u8 size_PLL_blocks;
270 u16 PCLK_ref_freq;
271 u16 PCLK_ref_divider;
272 u32 PCLK_min_freq;
273 u32 PCLK_max_freq;
274 u16 MCLK_ref_freq;
275 u16 MCLK_ref_divider;
276 u32 MCLK_min_freq;
277 u32 MCLK_max_freq;
278 u16 XCLK_ref_freq;
279 u16 XCLK_ref_divider;
280 u32 XCLK_min_freq;
281 u32 XCLK_max_freq;
282} __attribute__ ((packed)) PLL_BLOCK;
283
284
285struct pll_info {
286 int ppll_max;
287 int ppll_min;
288 int xclk;
289 int ref_div;
290 int ref_clk;
291};
292
293
294struct ram_info {
295 int ml;
296 int mb;
297 int trcd;
298 int trp;
299 int twr;
300 int cl;
301 int tr2w;
302 int loop_latency;
303 int rloop;
304};
305
306
307struct radeon_regs {
308 /* CRTC regs */
309 u32 crtc_h_total_disp;
310 u32 crtc_h_sync_strt_wid;
311 u32 crtc_v_total_disp;
312 u32 crtc_v_sync_strt_wid;
313 u32 crtc_pitch;
314 u32 crtc_gen_cntl;
315 u32 crtc_ext_cntl;
316 u32 dac_cntl;
317
318 u32 flags;
319 u32 pix_clock;
320 int xres, yres;
321
322 /* DDA regs */
323 u32 dda_config;
324 u32 dda_on_off;
325
326 /* PLL regs */
327 u32 ppll_div_3;
328 u32 ppll_ref_div;
329 u32 vclk_ecp_cntl;
330
331 /* Flat panel regs */
332 u32 fp_crtc_h_total_disp;
333 u32 fp_crtc_v_total_disp;
334 u32 fp_gen_cntl;
335 u32 fp_h_sync_strt_wid;
336 u32 fp_horz_stretch;
337 u32 fp_panel_cntl;
338 u32 fp_v_sync_strt_wid;
339 u32 fp_vert_stretch;
340 u32 lvds_gen_cntl;
341 u32 lvds_pll_cntl;
342 u32 tmds_crc;
343 u32 tmds_transmitter_cntl;
344
345#if defined(__BIG_ENDIAN)
346 u32 surface_cntl;
347#endif
348};
349
350
351struct radeonfb_info {
352 struct fb_info info;
353
354 struct radeon_regs state;
355 struct radeon_regs init_state;
356
357 char name[32];
358 char ram_type[12];
359
360 unsigned long mmio_base_phys;
361 unsigned long fb_base_phys;
362
363 void __iomem *mmio_base;
364 void __iomem *fb_base;
365
366 struct pci_dev *pdev;
367
368 unsigned char *EDID;
369 unsigned char __iomem *bios_seg;
370
371 u32 pseudo_palette[17];
372 struct { u8 red, green, blue, pad; } palette[256];
373
374 int chipset;
375 unsigned char arch;
376 int video_ram;
377 u8 rev;
378 int pitch, bpp, depth;
379 int xres, yres, pixclock;
380 int xres_virtual, yres_virtual;
381 u32 accel_flags;
382
383 int use_default_var;
384 int got_dfpinfo;
385
386 int hasCRTC2;
387 int crtDisp_type;
388 int dviDisp_type;
389
390 int panel_xres, panel_yres;
391 int clock;
392 int hOver_plus, hSync_width, hblank;
393 int vOver_plus, vSync_width, vblank;
394 int hAct_high, vAct_high, interlaced;
395 int synct, misc;
396
397 u32 dp_gui_master_cntl;
398
399 struct pll_info pll;
400 int pll_output_freq, post_div, fb_div;
401
402 struct ram_info ram;
403
404 int mtrr_hdl;
405
406#ifdef CONFIG_PMAC_PBOOK
407 int pm_reg;
408 u32 save_regs[64];
409 u32 mdll, mdll2;
410#endif /* CONFIG_PMAC_PBOOK */
411 int asleep;
412
413 struct radeonfb_info *next;
414};
415
416
417static struct fb_var_screeninfo radeonfb_default_var = {
418 640, 480, 640, 480, 0, 0, 8, 0,
419 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
420 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
421 0, FB_VMODE_NONINTERLACED
422};
423
424/*
425 * IO macros
426 */
427
428#define INREG8(addr) readb((rinfo->mmio_base)+addr)
429#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
430#define INREG(addr) readl((rinfo->mmio_base)+addr)
431#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
432
433#define OUTPLL(addr,val) \
434 do { \
435 OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
436 OUTREG(CLOCK_CNTL_DATA, val); \
437 } while(0)
438
439#define OUTPLLP(addr,val,mask) \
440 do { \
441 unsigned int _tmp = INPLL(addr); \
442 _tmp &= (mask); \
443 _tmp |= (val); \
444 OUTPLL(addr, _tmp); \
445 } while (0)
446
447#define OUTREGP(addr,val,mask) \
448 do { \
449 unsigned int _tmp = INREG(addr); \
450 _tmp &= (mask); \
451 _tmp |= (val); \
452 OUTREG(addr, _tmp); \
453 } while (0)
454
455
456static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
457{
458 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
459 return (INREG(CLOCK_CNTL_DATA));
460}
461
462#define INPLL(addr) _INPLL(rinfo, addr)
463
464#define PRIMARY_MONITOR(rinfo) ((rinfo->dviDisp_type != MT_NONE) && \
465 (rinfo->dviDisp_type != MT_STV) && \
466 (rinfo->dviDisp_type != MT_CTV) ? \
467 rinfo->dviDisp_type : rinfo->crtDisp_type)
468
469static char *GET_MON_NAME(int type)
470{
471 char *pret = NULL;
472
473 switch (type) {
474 case MT_NONE:
475 pret = "no";
476 break;
477 case MT_CRT:
478 pret = "CRT";
479 break;
480 case MT_DFP:
481 pret = "DFP";
482 break;
483 case MT_LCD:
484 pret = "LCD";
485 break;
486 case MT_CTV:
487 pret = "CTV";
488 break;
489 case MT_STV:
490 pret = "STV";
491 break;
492 }
493
494 return pret;
495}
496
497
498/*
499 * 2D engine routines
500 */
501
502static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
503{
504 int i;
505
506 /* initiate flush */
507 OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
508 ~RB2D_DC_FLUSH_ALL);
509
510 for (i=0; i < 2000000; i++) {
511 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
512 break;
513 }
514}
515
516
517static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
518{
519 int i;
520
521 for (i=0; i<2000000; i++)
522 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
523 return;
524}
525
526
527static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
528{
529 int i;
530
531 /* ensure FIFO is empty before waiting for idle */
532 _radeon_fifo_wait (rinfo, 64);
533
534 for (i=0; i<2000000; i++) {
535 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
536 radeon_engine_flush (rinfo);
537 return;
538 }
539 }
540}
541
542
543#define radeon_engine_idle() _radeon_engine_idle(rinfo)
544#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
545
546
547
548/*
549 * helper routines
550 */
551
552static __inline__ u32 radeon_get_dstbpp(u16 depth)
553{
554 switch (depth) {
555 case 8:
556 return DST_8BPP;
557 case 15:
558 return DST_15BPP;
559 case 16:
560 return DST_16BPP;
561 case 32:
562 return DST_32BPP;
563 default:
564 return 0;
565 }
566}
567
568
569static inline int var_to_depth(const struct fb_var_screeninfo *var)
570{
571 if (var->bits_per_pixel != 16)
572 return var->bits_per_pixel;
573 return (var->green.length == 6) ? 16 : 15;
574}
575
576
577static void _radeon_engine_reset(struct radeonfb_info *rinfo)
578{
579 u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
580
581 radeon_engine_flush (rinfo);
582
583 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
584 mclk_cntl = INPLL(MCLK_CNTL);
585
586 OUTPLL(MCLK_CNTL, (mclk_cntl |
587 FORCEON_MCLKA |
588 FORCEON_MCLKB |
589 FORCEON_YCLKA |
590 FORCEON_YCLKB |
591 FORCEON_MC |
592 FORCEON_AIC));
593 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
594
595 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
596 SOFT_RESET_CP |
597 SOFT_RESET_HI |
598 SOFT_RESET_SE |
599 SOFT_RESET_RE |
600 SOFT_RESET_PP |
601 SOFT_RESET_E2 |
602 SOFT_RESET_RB);
603 INREG(RBBM_SOFT_RESET);
604 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
605 ~(SOFT_RESET_CP |
606 SOFT_RESET_HI |
607 SOFT_RESET_SE |
608 SOFT_RESET_RE |
609 SOFT_RESET_PP |
610 SOFT_RESET_E2 |
611 SOFT_RESET_RB));
612 INREG(RBBM_SOFT_RESET);
613
614 OUTPLL(MCLK_CNTL, mclk_cntl);
615 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
616 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
617
618 return;
619}
620
621#define radeon_engine_reset() _radeon_engine_reset(rinfo)
622
623
624static __inline__ int round_div(int num, int den)
625{
626 return (num + (den / 2)) / den;
627}
628
629
630
631static __inline__ int min_bits_req(int val)
632{
633 int bits_req = 0;
634
635 if (val == 0)
636 bits_req = 1;
637
638 while (val) {
639 val >>= 1;
640 bits_req++;
641 }
642
643 return (bits_req);
644}
645
646
647static __inline__ int _max(int val1, int val2)
648{
649 if (val1 >= val2)
650 return val1;
651 else
652 return val2;
653}
654
655
656
657/*
658 * globals
659 */
660
661#ifndef MODULE
662static char *mode_option;
663#endif
664
665static char noaccel = 0;
666static char mirror = 0;
667static int panel_yres = 0;
668static char force_dfp = 0;
669static struct radeonfb_info *board_list = NULL;
670static char nomtrr = 0;
671
672/*
673 * prototypes
674 */
675
676static void radeon_save_state (struct radeonfb_info *rinfo,
677 struct radeon_regs *save);
678static void radeon_engine_init (struct radeonfb_info *rinfo);
679static void radeon_write_mode (struct radeonfb_info *rinfo,
680 struct radeon_regs *mode);
681static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
682static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
683static int radeon_init_disp_var (struct radeonfb_info *rinfo, struct fb_var_screeninfo *var);
684static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo);
685static void radeon_get_pllinfo(struct radeonfb_info *rinfo, void __iomem *bios_seg);
686static void radeon_get_moninfo (struct radeonfb_info *rinfo);
687static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
688static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
689static void radeon_get_EDID(struct radeonfb_info *rinfo);
690static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
691static void radeon_update_default_var(struct radeonfb_info *rinfo);
692
693#ifdef CONFIG_PPC_OF
694
695static int radeon_read_OF (struct radeonfb_info *rinfo);
696static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
697extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
698
699#ifdef CONFIG_PMAC_PBOOK
700int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
701static struct pmu_sleep_notifier radeon_sleep_notifier = {
702 radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
703};
704#endif /* CONFIG_PMAC_PBOOK */
705#ifdef CONFIG_PMAC_BACKLIGHT
706static int radeon_set_backlight_enable(int on, int level, void *data);
707static int radeon_set_backlight_level(int level, void *data);
708static struct backlight_controller radeon_backlight_controller = {
709 radeon_set_backlight_enable,
710 radeon_set_backlight_level
711};
712#endif /* CONFIG_PMAC_BACKLIGHT */
713
714#endif /* CONFIG_PPC_OF */
715
716
717static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo)
718{
719#if defined(__i386__)
720 u32 segstart;
721 char __iomem *rom_base;
722 char __iomem *rom;
723 int stage;
724 int i,j;
725 char aty_rom_sig[] = "761295520";
726 char *radeon_sig[] = {
727 "RG6",
728 "RADEON"
729 };
730
731 for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
732
733 stage = 1;
734
735 rom_base = ioremap(segstart, 0x1000);
736
737 if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
738 stage = 2;
739
740
741 if (stage != 2) {
742 iounmap(rom_base);
743 continue;
744 }
745
746 rom = rom_base;
747
748 for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
749 if (aty_rom_sig[0] == *rom)
750 if (strncmp(aty_rom_sig, rom,
751 strlen(aty_rom_sig)) == 0)
752 stage = 3;
753 rom++;
754 }
755 if (stage != 3) {
756 iounmap(rom_base);
757 continue;
758 }
759 rom = rom_base;
760
761 for (i = 0; (i < 512) && (stage != 4); i++) {
762 for (j = 0; j < ARRAY_SIZE(radeon_sig); j++) {
763 if (radeon_sig[j][0] == *rom)
764 if (strncmp(radeon_sig[j], rom,
765 strlen(radeon_sig[j])) == 0) {
766 stage = 4;
767 break;
768 }
769 }
770 rom++;
771 }
772 if (stage != 4) {
773 iounmap(rom_base);
774 continue;
775 }
776
777 return rom_base;
778 }
779#endif
780 return NULL;
781}
782
783
784
785
786static void radeon_get_pllinfo(struct radeonfb_info *rinfo, void __iomem *bios_seg)
787{
788 void __iomem *bios_header;
789 void __iomem *header_ptr;
790 u16 bios_header_offset, pll_info_offset;
791 PLL_BLOCK pll;
792
793 if (bios_seg) {
794 bios_header = bios_seg + 0x48L;
795 header_ptr = bios_header;
796
797 bios_header_offset = readw(header_ptr);
798 bios_header = bios_seg + bios_header_offset;
799 bios_header += 0x30;
800
801 header_ptr = bios_header;
802 pll_info_offset = readw(header_ptr);
803 header_ptr = bios_seg + pll_info_offset;
804
805 memcpy_fromio(&pll, header_ptr, 50);
806
807 rinfo->pll.xclk = (u32)pll.XCLK;
808 rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
809 rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
810 rinfo->pll.ppll_min = pll.PCLK_min_freq;
811 rinfo->pll.ppll_max = pll.PCLK_max_freq;
812
813 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
814 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
815 } else {
816#ifdef CONFIG_PPC_OF
817 if (radeon_read_OF(rinfo)) {
818 unsigned int tmp, Nx, M, ref_div, xclk;
819
820 tmp = INPLL(M_SPLL_REF_FB_DIV);
821 ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
822
823 Nx = (tmp & 0xff00) >> 8;
824 M = (tmp & 0xff);
825 xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
826 (2 * M)));
827
828 rinfo->pll.xclk = xclk;
829 rinfo->pll.ref_div = ref_div;
830 rinfo->pll.ppll_min = 12000;
831 rinfo->pll.ppll_max = 35000;
832
833 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
834 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
835
836 return;
837 }
838#endif
839 /* no BIOS or BIOS not found, use defaults */
840 switch (rinfo->chipset) {
841 case PCI_DEVICE_ID_ATI_RADEON_QW:
842 case PCI_DEVICE_ID_ATI_RADEON_QX:
843 rinfo->pll.ppll_max = 35000;
844 rinfo->pll.ppll_min = 12000;
845 rinfo->pll.xclk = 23000;
846 rinfo->pll.ref_div = 12;
847 rinfo->pll.ref_clk = 2700;
848 break;
849 case PCI_DEVICE_ID_ATI_RADEON_QL:
850 case PCI_DEVICE_ID_ATI_RADEON_QN:
851 case PCI_DEVICE_ID_ATI_RADEON_QO:
852 case PCI_DEVICE_ID_ATI_RADEON_Ql:
853 case PCI_DEVICE_ID_ATI_RADEON_BB:
854 rinfo->pll.ppll_max = 35000;
855 rinfo->pll.ppll_min = 12000;
856 rinfo->pll.xclk = 27500;
857 rinfo->pll.ref_div = 12;
858 rinfo->pll.ref_clk = 2700;
859 break;
860 case PCI_DEVICE_ID_ATI_RADEON_Id:
861 case PCI_DEVICE_ID_ATI_RADEON_Ie:
862 case PCI_DEVICE_ID_ATI_RADEON_If:
863 case PCI_DEVICE_ID_ATI_RADEON_Ig:
864 rinfo->pll.ppll_max = 35000;
865 rinfo->pll.ppll_min = 12000;
866 rinfo->pll.xclk = 25000;
867 rinfo->pll.ref_div = 12;
868 rinfo->pll.ref_clk = 2700;
869 break;
870 case PCI_DEVICE_ID_ATI_RADEON_ND:
871 case PCI_DEVICE_ID_ATI_RADEON_NE:
872 case PCI_DEVICE_ID_ATI_RADEON_NF:
873 case PCI_DEVICE_ID_ATI_RADEON_NG:
874 rinfo->pll.ppll_max = 40000;
875 rinfo->pll.ppll_min = 20000;
876 rinfo->pll.xclk = 27000;
877 rinfo->pll.ref_div = 12;
878 rinfo->pll.ref_clk = 2700;
879 break;
880 case PCI_DEVICE_ID_ATI_RADEON_QD:
881 case PCI_DEVICE_ID_ATI_RADEON_QE:
882 case PCI_DEVICE_ID_ATI_RADEON_QF:
883 case PCI_DEVICE_ID_ATI_RADEON_QG:
884 default:
885 rinfo->pll.ppll_max = 35000;
886 rinfo->pll.ppll_min = 12000;
887 rinfo->pll.xclk = 16600;
888 rinfo->pll.ref_div = 67;
889 rinfo->pll.ref_clk = 2700;
890 break;
891 }
892
893 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
894 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
895 }
896}
897
898
899static void radeon_get_moninfo (struct radeonfb_info *rinfo)
900{
901 unsigned int tmp;
902
903 if (force_dfp) {
904 rinfo->dviDisp_type = MT_DFP;
905 return;
906 }
907
908 tmp = INREG(BIOS_4_SCRATCH);
909 printk(KERN_DEBUG "radeon_get_moninfo: bios 4 scratch = %x\n", tmp);
910
911 if (rinfo->hasCRTC2) {
912 /* primary DVI port */
913 if (tmp & 0x08)
914 rinfo->dviDisp_type = MT_DFP;
915 else if (tmp & 0x4)
916 rinfo->dviDisp_type = MT_LCD;
917 else if (tmp & 0x200)
918 rinfo->dviDisp_type = MT_CRT;
919 else if (tmp & 0x10)
920 rinfo->dviDisp_type = MT_CTV;
921 else if (tmp & 0x20)
922 rinfo->dviDisp_type = MT_STV;
923
924 /* secondary CRT port */
925 if (tmp & 0x2)
926 rinfo->crtDisp_type = MT_CRT;
927 else if (tmp & 0x800)
928 rinfo->crtDisp_type = MT_DFP;
929 else if (tmp & 0x400)
930 rinfo->crtDisp_type = MT_LCD;
931 else if (tmp & 0x1000)
932 rinfo->crtDisp_type = MT_CTV;
933 else if (tmp & 0x2000)
934 rinfo->crtDisp_type = MT_STV;
935 } else {
936 rinfo->dviDisp_type = MT_NONE;
937
938 tmp = INREG(FP_GEN_CNTL);
939
940 if (tmp & FP_EN_TMDS)
941 rinfo->crtDisp_type = MT_DFP;
942 else
943 rinfo->crtDisp_type = MT_CRT;
944 }
945}
946
947
948
949static void radeon_get_EDID(struct radeonfb_info *rinfo)
950{
951#ifdef CONFIG_PPC_OF
952 if (!radeon_get_EDID_OF(rinfo))
953 RTRACE("radeonfb: could not retrieve EDID from OF\n");
954#else
955 /* XXX use other methods later */
956#endif
957}
958
959
960#ifdef CONFIG_PPC_OF
961static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
962{
963 struct device_node *dp;
964 unsigned char *pedid = NULL;
965 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
966 int i;
967
968 dp = pci_device_to_OF_node(rinfo->pdev);
969 while (dp != NULL) {
970 for (i = 0; propnames[i] != NULL; ++i) {
971 pedid = (unsigned char *)
972 get_property(dp, propnames[i], NULL);
973 if (pedid != NULL) {
974 rinfo->EDID = pedid;
975 return 1;
976 }
977 }
978 dp = dp->child;
979 }
980 return 0;
981}
982#endif /* CONFIG_PPC_OF */
983
984
985static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
986{
987 unsigned char *block = rinfo->EDID;
988
989 if (!block)
990 return 0;
991
992 /* jump to the detailed timing block section */
993 block += 54;
994
995 rinfo->clock = (block[0] + (block[1] << 8));
996 rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
997 rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
998 rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
999 rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1000 rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1001 rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1002 rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1003 rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1004 rinfo->interlaced = ((block[17] & 0x80) >> 7);
1005 rinfo->synct = ((block[17] & 0x18) >> 3);
1006 rinfo->misc = ((block[17] & 0x06) >> 1);
1007 rinfo->hAct_high = rinfo->vAct_high = 0;
1008 if (rinfo->synct == 3) {
1009 if (rinfo->misc & 2)
1010 rinfo->hAct_high = 1;
1011 if (rinfo->misc & 1)
1012 rinfo->vAct_high = 1;
1013 }
1014
1015 printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
1016 rinfo->panel_xres, rinfo->panel_yres);
1017
1018 rinfo->got_dfpinfo = 1;
1019
1020 return 1;
1021}
1022
1023
1024static void radeon_update_default_var(struct radeonfb_info *rinfo)
1025{
1026 struct fb_var_screeninfo *var = &radeonfb_default_var;
1027
1028 var->xres = rinfo->panel_xres;
1029 var->yres = rinfo->panel_yres;
1030 var->xres_virtual = rinfo->panel_xres;
1031 var->yres_virtual = rinfo->panel_yres;
1032 var->xoffset = var->yoffset = 0;
1033 var->bits_per_pixel = 8;
1034 var->pixclock = 100000000 / rinfo->clock;
1035 var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
1036 var->right_margin = rinfo->hOver_plus;
1037 var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
1038 var->lower_margin = rinfo->vOver_plus;
1039 var->hsync_len = rinfo->hSync_width;
1040 var->vsync_len = rinfo->vSync_width;
1041 var->sync = 0;
1042 if (rinfo->synct == 3) {
1043 if (rinfo->hAct_high)
1044 var->sync |= FB_SYNC_HOR_HIGH_ACT;
1045 if (rinfo->vAct_high)
1046 var->sync |= FB_SYNC_VERT_HIGH_ACT;
1047 }
1048
1049 var->vmode = 0;
1050 if (rinfo->interlaced)
1051 var->vmode |= FB_VMODE_INTERLACED;
1052
1053 rinfo->use_default_var = 1;
1054}
1055
1056
1057static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
1058{
1059 char __iomem *fpbiosstart, *tmp, *tmp0;
1060 char stmp[30];
1061 int i;
1062
1063 if (!rinfo->bios_seg)
1064 return 0;
1065
1066 if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
1067 printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1068 return 0;
1069 }
1070
1071 if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
1072 printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1073 return 0;
1074 }
1075
1076 for(i=0; i<24; i++)
1077 stmp[i] = readb(tmp+i+1);
1078 stmp[24] = 0;
1079 printk("radeonfb: panel ID string: %s\n", stmp);
1080 rinfo->panel_xres = readw(tmp + 25);
1081 rinfo->panel_yres = readw(tmp + 27);
1082 printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
1083 rinfo->panel_xres, rinfo->panel_yres);
1084
1085 for(i=0; i<32; i++) {
1086 tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
1087 if (tmp0 == 0)
1088 break;
1089 if ((readw(tmp0) == rinfo->panel_xres) &&
1090 (readw(tmp0+2) == rinfo->panel_yres)) {
1091 rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
1092 rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
1093 rinfo->hSync_width = readb(tmp0+23) * 8;
1094 rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
1095 rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
1096 rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
1097 rinfo->clock = readw(tmp0+9);
1098
1099 rinfo->got_dfpinfo = 1;
1100 return 1;
1101 }
1102 }
1103
1104 return 0;
1105}
1106
1107
1108
1109static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
1110{
1111 unsigned int tmp;
1112 unsigned short a, b;
1113
1114 if (radeon_get_dfpinfo_BIOS(rinfo))
1115 radeon_update_default_var(rinfo);
1116
1117 if (radeon_dfp_parse_EDID(rinfo))
1118 radeon_update_default_var(rinfo);
1119
1120 if (!rinfo->got_dfpinfo) {
1121 /*
1122 * it seems all else has failed now and we
1123 * resort to probing registers for our DFP info
1124 */
1125 if (panel_yres) {
1126 rinfo->panel_yres = panel_yres;
1127 } else {
1128 tmp = INREG(FP_VERT_STRETCH);
1129 tmp &= 0x00fff000;
1130 rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
1131 }
1132
1133 switch (rinfo->panel_yres) {
1134 case 480:
1135 rinfo->panel_xres = 640;
1136 break;
1137 case 600:
1138 rinfo->panel_xres = 800;
1139 break;
1140 case 768:
1141#if defined(__powerpc__)
1142 if (rinfo->dviDisp_type == MT_LCD)
1143 rinfo->panel_xres = 1152;
1144 else
1145#endif
1146 rinfo->panel_xres = 1024;
1147 break;
1148 case 1024:
1149 rinfo->panel_xres = 1280;
1150 break;
1151 case 1050:
1152 rinfo->panel_xres = 1400;
1153 break;
1154 case 1200:
1155 rinfo->panel_xres = 1600;
1156 break;
1157 default:
1158 printk("radeonfb: Failed to detect DFP panel size\n");
1159 return 0;
1160 }
1161
1162 printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
1163 rinfo->panel_xres, rinfo->panel_yres);
1164
1165 tmp = INREG(FP_CRTC_H_TOTAL_DISP);
1166 a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
1167 b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
1168 rinfo->hblank = (a - b + 1) * 8;
1169
1170 tmp = INREG(FP_H_SYNC_STRT_WID);
1171 rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
1172 FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
1173 rinfo->hOver_plus *= 8;
1174 rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
1175 FP_H_SYNC_WID_SHIFT);
1176 rinfo->hSync_width *= 8;
1177 tmp = INREG(FP_CRTC_V_TOTAL_DISP);
1178 a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
1179 b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
1180 rinfo->vblank = a - b /* + 24 */ ;
1181
1182 tmp = INREG(FP_V_SYNC_STRT_WID);
1183 rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
1184 - b + 1;
1185 rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
1186 FP_V_SYNC_WID_SHIFT);
1187
1188 return 1;
1189 }
1190
1191 return 1;
1192}
1193
1194
1195#ifdef CONFIG_PPC_OF
1196static int radeon_read_OF (struct radeonfb_info *rinfo)
1197{
1198 struct device_node *dp;
1199 unsigned int *xtal;
1200
1201 dp = pci_device_to_OF_node(rinfo->pdev);
1202
1203 xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", NULL);
1204
1205 rinfo->pll.ref_clk = *xtal / 10;
1206
1207 if (*xtal)
1208 return 1;
1209 else
1210 return 0;
1211}
1212#endif
1213
1214
1215static void radeon_engine_init (struct radeonfb_info *rinfo)
1216{
1217 u32 temp;
1218
1219 /* disable 3D engine */
1220 OUTREG(RB3D_CNTL, 0);
1221
1222 radeon_engine_reset ();
1223
1224 radeon_fifo_wait (1);
1225 OUTREG(RB2D_DSTCACHE_MODE, 0);
1226
1227 radeon_fifo_wait (1);
1228 temp = INREG(DEFAULT_PITCH_OFFSET);
1229 OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) |
1230 (rinfo->pitch << 0x16)));
1231
1232 radeon_fifo_wait (1);
1233 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
1234
1235 radeon_fifo_wait (1);
1236 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
1237 DEFAULT_SC_BOTTOM_MAX));
1238
1239 temp = radeon_get_dstbpp(rinfo->depth);
1240 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
1241 radeon_fifo_wait (1);
1242 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
1243 GMC_BRUSH_SOLID_COLOR |
1244 GMC_SRC_DATATYPE_COLOR));
1245
1246 radeon_fifo_wait (7);
1247
1248 /* clear line drawing regs */
1249 OUTREG(DST_LINE_START, 0);
1250 OUTREG(DST_LINE_END, 0);
1251
1252 /* set brush color regs */
1253 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
1254 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
1255
1256 /* set source color regs */
1257 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
1258 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
1259
1260 /* default write mask */
1261 OUTREG(DP_WRITE_MSK, 0xffffffff);
1262
1263 radeon_engine_idle ();
1264}
1265
1266
1267static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
1268{
1269 struct fb_info *info = &rinfo->info;
1270 struct fb_var_screeninfo var;
1271
1272 var = radeonfb_default_var;
1273 if ((radeon_init_disp_var(rinfo, &var)) < 0)
1274 return -1;
1275
1276 rinfo->depth = var_to_depth(&var);
1277 rinfo->bpp = var.bits_per_pixel;
1278
1279 info->var = var;
1280 fb_alloc_cmap(&info->cmap, 256, 0);
1281
1282 var.activate = FB_ACTIVATE_NOW;
1283 return 0;
1284}
1285
1286
1287static int radeon_init_disp_var (struct radeonfb_info *rinfo,
1288 struct fb_var_screeninfo *var)
1289{
1290#ifndef MODULE
1291 if (mode_option)
1292 fb_find_mode (var, &rinfo->info, mode_option,
1293 NULL, 0, NULL, 8);
1294 else
1295#endif
1296 if (rinfo->use_default_var)
1297 /* We will use the modified default far */
1298 *var = radeonfb_default_var;
1299 else
1300
1301 fb_find_mode (var, &rinfo->info, "640x480-8@60",
1302 NULL, 0, NULL, 0);
1303
1304 if (noaccel)
1305 var->accel_flags &= ~FB_ACCELF_TEXT;
1306 else
1307 var->accel_flags |= FB_ACCELF_TEXT;
1308
1309 return 0;
1310}
1311
1312
1313static int radeon_do_maximize(struct radeonfb_info *rinfo,
1314 struct fb_var_screeninfo *var,
1315 struct fb_var_screeninfo *v,
1316 int nom, int den)
1317{
1318 static struct {
1319 int xres, yres;
1320 } modes[] = {
1321 {1600, 1280},
1322 {1280, 1024},
1323 {1024, 768},
1324 {800, 600},
1325 {640, 480},
1326 {-1, -1}
1327 };
1328 int i;
1329
1330 /* use highest possible virtual resolution */
1331 if (v->xres_virtual == -1 && v->yres_virtual == -1) {
1332 printk("radeonfb: using max available virtual resolution\n");
1333 for (i=0; modes[i].xres != -1; i++) {
1334 if (modes[i].xres * nom / den * modes[i].yres <
1335 rinfo->video_ram / 2)
1336 break;
1337 }
1338 if (modes[i].xres == -1) {
1339 printk("radeonfb: could not find virtual resolution that fits into video memory!\n");
1340 return -EINVAL;
1341 }
1342 v->xres_virtual = modes[i].xres;
1343 v->yres_virtual = modes[i].yres;
1344
1345 printk("radeonfb: virtual resolution set to max of %dx%d\n",
1346 v->xres_virtual, v->yres_virtual);
1347 } else if (v->xres_virtual == -1) {
1348 v->xres_virtual = (rinfo->video_ram * den /
1349 (nom * v->yres_virtual * 2)) & ~15;
1350 } else if (v->yres_virtual == -1) {
1351 v->xres_virtual = (v->xres_virtual + 15) & ~15;
1352 v->yres_virtual = rinfo->video_ram * den /
1353 (nom * v->xres_virtual *2);
1354 } else {
1355 if (v->xres_virtual * nom / den * v->yres_virtual >
1356 rinfo->video_ram) {
1357 return -EINVAL;
1358 }
1359 }
1360
1361 if (v->xres_virtual * nom / den >= 8192) {
1362 v->xres_virtual = 8192 * den / nom - 16;
1363 }
1364
1365 if (v->xres_virtual < v->xres)
1366 return -EINVAL;
1367
1368 if (v->yres_virtual < v->yres)
1369 return -EINVAL;
1370
1371 return 0;
1372}
1373
1374
1375static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
1376{
1377 struct radeonfb_info *rinfo = (struct radeonfb_info *) info->par;
1378 struct fb_var_screeninfo v;
1379 int nom, den;
1380
1381 memcpy (&v, var, sizeof (v));
1382
1383 switch (v.bits_per_pixel) {
1384 case 0 ... 8:
1385 v.bits_per_pixel = 8;
1386 break;
1387 case 9 ... 16:
1388 v.bits_per_pixel = 16;
1389 break;
1390 case 17 ... 24:
1391#if 0 /* Doesn't seem to work */
1392 v.bits_per_pixel = 24;
1393 break;
1394#endif
1395 return -EINVAL;
1396 case 25 ... 32:
1397 v.bits_per_pixel = 32;
1398 break;
1399 default:
1400 return -EINVAL;
1401 }
1402
1403 switch (var_to_depth(&v)) {
1404 case 8:
1405 nom = den = 1;
1406 v.red.offset = v.green.offset = v.blue.offset = 0;
1407 v.red.length = v.green.length = v.blue.length = 8;
1408 v.transp.offset = v.transp.length = 0;
1409 break;
1410 case 15:
1411 nom = 2;
1412 den = 1;
1413 v.red.offset = 10;
1414 v.green.offset = 5;
1415 v.blue.offset = 0;
1416 v.red.length = v.green.length = v.blue.length = 5;
1417 v.transp.offset = v.transp.length = 0;
1418 break;
1419 case 16:
1420 nom = 2;
1421 den = 1;
1422 v.red.offset = 11;
1423 v.green.offset = 5;
1424 v.blue.offset = 0;
1425 v.red.length = 5;
1426 v.green.length = 6;
1427 v.blue.length = 5;
1428 v.transp.offset = v.transp.length = 0;
1429 break;
1430 case 24:
1431 nom = 4;
1432 den = 1;
1433 v.red.offset = 16;
1434 v.green.offset = 8;
1435 v.blue.offset = 0;
1436 v.red.length = v.blue.length = v.green.length = 8;
1437 v.transp.offset = v.transp.length = 0;
1438 break;
1439 case 32:
1440 nom = 4;
1441 den = 1;
1442 v.red.offset = 16;
1443 v.green.offset = 8;
1444 v.blue.offset = 0;
1445 v.red.length = v.blue.length = v.green.length = 8;
1446 v.transp.offset = 24;
1447 v.transp.length = 8;
1448 break;
1449 default:
1450 printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
1451 var->xres, var->yres, var->bits_per_pixel);
1452 return -EINVAL;
1453 }
1454
1455 if (radeon_do_maximize(rinfo, var, &v, nom, den) < 0)
1456 return -EINVAL;
1457
1458 if (v.xoffset < 0)
1459 v.xoffset = 0;
1460 if (v.yoffset < 0)
1461 v.yoffset = 0;
1462
1463 if (v.xoffset > v.xres_virtual - v.xres)
1464 v.xoffset = v.xres_virtual - v.xres - 1;
1465
1466 if (v.yoffset > v.yres_virtual - v.yres)
1467 v.yoffset = v.yres_virtual - v.yres - 1;
1468
1469 v.red.msb_right = v.green.msb_right = v.blue.msb_right =
1470 v.transp.offset = v.transp.length =
1471 v.transp.msb_right = 0;
1472
1473 if (noaccel)
1474 v.accel_flags = 0;
1475
1476 memcpy(var, &v, sizeof(v));
1477
1478 return 0;
1479}
1480
1481
1482static int radeonfb_pan_display (struct fb_var_screeninfo *var,
1483 struct fb_info *info)
1484{
1485 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1486
1487 if ((var->xoffset + var->xres > var->xres_virtual)
1488 || (var->yoffset + var->yres > var->yres_virtual))
1489 return -EINVAL;
1490
1491 if (rinfo->asleep)
1492 return 0;
1493
1494 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
1495 * var->bits_per_pixel / 8) & ~7);
1496 return 0;
1497}
1498
1499
1500static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
1501 unsigned long arg)
1502{
1503 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1504 unsigned int tmp;
1505 u32 value = 0;
1506 int rc;
1507
1508 switch (cmd) {
1509 /*
1510 * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's
1511 */
1512 case FBIO_RADEON_SET_MIRROR:
1513 switch (rinfo->arch) {
1514 case RADEON_R100:
1515 case RADEON_RV100:
1516 case RADEON_R200:
1517 case RADEON_RV200:
1518 case RADEON_RV250:
1519 case RADEON_R300:
1520 return -EINVAL;
1521 default:
1522 /* RADEON M6, RADEON_M7, RADEON_M9 */
1523 break;
1524 }
1525
1526 rc = get_user(value, (__u32 __user *)arg);
1527
1528 if (rc)
1529 return rc;
1530
1531 if (value & 0x01) {
1532 tmp = INREG(LVDS_GEN_CNTL);
1533
1534 tmp |= (LVDS_ON | LVDS_BLON);
1535 } else {
1536 tmp = INREG(LVDS_GEN_CNTL);
1537
1538 tmp &= ~(LVDS_ON | LVDS_BLON);
1539 }
1540
1541 OUTREG(LVDS_GEN_CNTL, tmp);
1542
1543 if (value & 0x02) {
1544 tmp = INREG(CRTC_EXT_CNTL);
1545 tmp |= CRTC_CRT_ON;
1546
1547 mirror = 1;
1548 } else {
1549 tmp = INREG(CRTC_EXT_CNTL);
1550 tmp &= ~CRTC_CRT_ON;
1551
1552 mirror = 0;
1553 }
1554
1555 OUTREG(CRTC_EXT_CNTL, tmp);
1556
1557 break;
1558 case FBIO_RADEON_GET_MIRROR:
1559 switch (rinfo->arch) {
1560 case RADEON_R100:
1561 case RADEON_RV100:
1562 case RADEON_R200:
1563 case RADEON_RV200:
1564 case RADEON_RV250:
1565 case RADEON_R300:
1566 return -EINVAL;
1567 default:
1568 /* RADEON M6, RADEON_M7, RADEON_M9 */
1569 break;
1570 }
1571
1572 tmp = INREG(LVDS_GEN_CNTL);
1573 if ((LVDS_ON | LVDS_BLON) & tmp)
1574 value |= 0x01;
1575
1576 tmp = INREG(CRTC_EXT_CNTL);
1577 if (CRTC_CRT_ON & tmp)
1578 value |= 0x02;
1579
1580 return put_user(value, (__u32 __user *)arg);
1581 default:
1582 return -EINVAL;
1583 }
1584
1585 return -EINVAL;
1586}
1587
1588
1589static int radeonfb_blank (int blank, struct fb_info *info)
1590{
1591 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1592 u32 val = INREG(CRTC_EXT_CNTL);
1593 u32 val2 = INREG(LVDS_GEN_CNTL);
1594
1595 if (rinfo->asleep)
1596 return 0;
1597
1598#ifdef CONFIG_PMAC_BACKLIGHT
1599 if (rinfo->dviDisp_type == MT_LCD && machine_is(powermac)) {
1600 set_backlight_enable(!blank);
1601 return 0;
1602 }
1603#endif
1604
1605 /* reset it */
1606 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
1607 CRTC_VSYNC_DIS);
1608 val2 &= ~(LVDS_DISPLAY_DIS);
1609
1610 switch (blank) {
1611 case FB_BLANK_UNBLANK:
1612 case FB_BLANK_NORMAL:
1613 break;
1614 case FB_BLANK_VSYNC_SUSPEND:
1615 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
1616 break;
1617 case FB_BLANK_HSYNC_SUSPEND:
1618 val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
1619 break;
1620 case FB_BLANK_POWERDOWN:
1621 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
1622 CRTC_HSYNC_DIS);
1623 val2 |= (LVDS_DISPLAY_DIS);
1624 break;
1625 }
1626
1627 switch (rinfo->dviDisp_type) {
1628 case MT_LCD:
1629 OUTREG(LVDS_GEN_CNTL, val2);
1630 break;
1631 case MT_CRT:
1632 default:
1633 OUTREG(CRTC_EXT_CNTL, val);
1634 break;
1635 }
1636
1637 /* let fbcon do a soft blank for us */
1638 return (blank == FB_BLANK_NORMAL) ? 1 : 0;
1639}
1640
1641
1642static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1643 unsigned blue, unsigned transp, struct fb_info *info)
1644{
1645 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1646 u32 pindex, vclk_cntl;
1647 unsigned int i;
1648
1649 if (regno > 255)
1650 return 1;
1651
1652 red >>= 8;
1653 green >>= 8;
1654 blue >>= 8;
1655 rinfo->palette[regno].red = red;
1656 rinfo->palette[regno].green = green;
1657 rinfo->palette[regno].blue = blue;
1658
1659 /* default */
1660 pindex = regno;
1661
1662 if (!rinfo->asleep) {
1663 vclk_cntl = INPLL(VCLK_ECP_CNTL);
1664 OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
1665
1666 if (rinfo->bpp == 16) {
1667 pindex = regno * 8;
1668
1669 if (rinfo->depth == 16 && regno > 63)
1670 return 1;
1671 if (rinfo->depth == 15 && regno > 31)
1672 return 1;
1673
1674 /* For 565, the green component is mixed one order below */
1675 if (rinfo->depth == 16) {
1676 OUTREG(PALETTE_INDEX, pindex>>1);
1677 OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
1678 (green << 8) | (rinfo->palette[regno>>1].blue));
1679 green = rinfo->palette[regno<<1].green;
1680 }
1681 }
1682
1683 if (rinfo->depth != 16 || regno < 32) {
1684 OUTREG(PALETTE_INDEX, pindex);
1685 OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
1686 }
1687
1688 OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
1689 }
1690 if (regno < 16) {
1691 switch (rinfo->depth) {
1692 case 15:
1693 ((u16 *) (info->pseudo_palette))[regno] =
1694 (regno << 10) | (regno << 5) | regno;
1695 break;
1696 case 16:
1697 ((u16 *) (info->pseudo_palette))[regno] =
1698 (regno << 11) | (regno << 6) | regno;
1699 break;
1700 case 24:
1701 ((u32 *) (info->pseudo_palette))[regno] =
1702 (regno << 16) | (regno << 8) | regno;
1703 break;
1704 case 32:
1705 i = (regno << 8) | regno;
1706 ((u32 *) (info->pseudo_palette))[regno] =
1707 (i << 16) | i;
1708 break;
1709 }
1710 }
1711 return 0;
1712}
1713
1714
1715
1716static void radeon_save_state (struct radeonfb_info *rinfo,
1717 struct radeon_regs *save)
1718{
1719 /* CRTC regs */
1720 save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
1721 save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
1722 save->dac_cntl = INREG(DAC_CNTL);
1723 save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
1724 save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
1725 save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
1726 save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
1727 save->crtc_pitch = INREG(CRTC_PITCH);
1728#if defined(__BIG_ENDIAN)
1729 save->surface_cntl = INREG(SURFACE_CNTL);
1730#endif
1731
1732 /* FP regs */
1733 save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
1734 save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
1735 save->fp_gen_cntl = INREG(FP_GEN_CNTL);
1736 save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
1737 save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
1738 save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
1739 save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
1740 save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
1741 save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
1742 save->tmds_crc = INREG(TMDS_CRC);
1743 save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
1744 save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
1745}
1746
1747
1748
1749static int radeonfb_set_par (struct fb_info *info)
1750{
1751 struct radeonfb_info *rinfo = (struct radeonfb_info *)info->par;
1752 struct fb_var_screeninfo *mode = &info->var;
1753 struct radeon_regs newmode;
1754 int hTotal, vTotal, hSyncStart, hSyncEnd,
1755 hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
1756 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
1757 u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
1758 u32 dotClock = 1000000000 / mode->pixclock,
1759 sync, h_sync_pol, v_sync_pol;
1760 int freq = dotClock / 10; /* x 100 */
1761 int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
1762 int useable_precision, roff, ron;
1763 int min_bits, format = 0;
1764 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
1765 int primary_mon = PRIMARY_MONITOR(rinfo);
1766 int depth = var_to_depth(mode);
1767 int accel = (mode->accel_flags & FB_ACCELF_TEXT) != 0;
1768
1769 rinfo->xres = mode->xres;
1770 rinfo->yres = mode->yres;
1771 rinfo->xres_virtual = mode->xres_virtual;
1772 rinfo->yres_virtual = mode->yres_virtual;
1773 rinfo->pixclock = mode->pixclock;
1774
1775 hSyncStart = mode->xres + mode->right_margin;
1776 hSyncEnd = hSyncStart + mode->hsync_len;
1777 hTotal = hSyncEnd + mode->left_margin;
1778
1779 vSyncStart = mode->yres + mode->lower_margin;
1780 vSyncEnd = vSyncStart + mode->vsync_len;
1781 vTotal = vSyncEnd + mode->upper_margin;
1782
1783 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1784 if (rinfo->panel_xres < mode->xres)
1785 rinfo->xres = mode->xres = rinfo->panel_xres;
1786 if (rinfo->panel_yres < mode->yres)
1787 rinfo->yres = mode->yres = rinfo->panel_yres;
1788
1789 hTotal = mode->xres + rinfo->hblank;
1790 hSyncStart = mode->xres + rinfo->hOver_plus;
1791 hSyncEnd = hSyncStart + rinfo->hSync_width;
1792
1793 vTotal = mode->yres + rinfo->vblank;
1794 vSyncStart = mode->yres + rinfo->vOver_plus;
1795 vSyncEnd = vSyncStart + rinfo->vSync_width;
1796 }
1797
1798 sync = mode->sync;
1799 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1800 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1801
1802 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
1803 hSyncStart, hSyncEnd, hTotal);
1804 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
1805 vSyncStart, vSyncEnd, vTotal);
1806
1807 hsync_wid = (hSyncEnd - hSyncStart) / 8;
1808 vsync_wid = vSyncEnd - vSyncStart;
1809 if (hsync_wid == 0)
1810 hsync_wid = 1;
1811 else if (hsync_wid > 0x3f) /* max */
1812 hsync_wid = 0x3f;
1813
1814 if (vsync_wid == 0)
1815 vsync_wid = 1;
1816 else if (vsync_wid > 0x1f) /* max */
1817 vsync_wid = 0x1f;
1818
1819 hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1820 vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1821
1822 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
1823
1824 format = radeon_get_dstbpp(depth);
1825 bytpp = mode->bits_per_pixel >> 3;
1826
1827 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
1828 hsync_fudge = hsync_fudge_fp[format-1];
1829 else
1830 hsync_fudge = hsync_adj_tab[format-1];
1831
1832 hsync_start = hSyncStart - 8 + hsync_fudge;
1833
1834 newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
1835 (format << 8);
1836
1837 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1838 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
1839 if (mirror)
1840 newmode.crtc_ext_cntl |= CRTC_CRT_ON;
1841
1842 newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
1843 CRTC_INTERLACE_EN);
1844 } else {
1845 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
1846 CRTC_CRT_ON;
1847 }
1848
1849 newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
1850 DAC_8BIT_EN;
1851
1852 newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
1853 (((mode->xres / 8) - 1) << 16));
1854
1855 newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
1856 (hsync_wid << 16) | (h_sync_pol << 23));
1857
1858 newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
1859 ((mode->yres - 1) << 16);
1860
1861 newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
1862 (vsync_wid << 16) | (v_sync_pol << 23));
1863
1864 if (accel) {
1865 /* We first calculate the engine pitch */
1866 rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
1867 & ~(0x3f)) >> 6;
1868
1869 /* Then, re-multiply it to get the CRTC pitch */
1870 newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
1871 } else
1872 newmode.crtc_pitch = (mode->xres_virtual >> 3);
1873 newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
1874
1875#if defined(__BIG_ENDIAN)
1876 /*
1877 * It looks like recent chips have a problem with SURFACE_CNTL,
1878 * setting SURF_TRANSLATION_DIS completely disables the
1879 * swapper as well, so we leave it unset now.
1880 */
1881 newmode.surface_cntl = 0;
1882
1883 /* Setup swapping on both apertures, though we currently
1884 * only use aperture 0, enabling swapper on aperture 1
1885 * won't harm
1886 */
1887 switch (mode->bits_per_pixel) {
1888 case 16:
1889 newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
1890 newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
1891 break;
1892 case 24:
1893 case 32:
1894 newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
1895 newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
1896 break;
1897 }
1898#endif
1899
1900 rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
1901 & ~(0x3f)) / 64;
1902
1903 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n",
1904 newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
1905 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n",
1906 newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
1907
1908 newmode.xres = mode->xres;
1909 newmode.yres = mode->yres;
1910
1911 rinfo->bpp = mode->bits_per_pixel;
1912 rinfo->depth = depth;
1913
1914 if (freq > rinfo->pll.ppll_max)
1915 freq = rinfo->pll.ppll_max;
1916 if (freq*12 < rinfo->pll.ppll_min)
1917 freq = rinfo->pll.ppll_min / 12;
1918
1919 {
1920 struct {
1921 int divider;
1922 int bitvalue;
1923 } *post_div,
1924 post_divs[] = {
1925 { 1, 0 },
1926 { 2, 1 },
1927 { 4, 2 },
1928 { 8, 3 },
1929 { 3, 4 },
1930 { 16, 5 },
1931 { 6, 6 },
1932 { 12, 7 },
1933 { 0, 0 },
1934 };
1935
1936 for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
1937 rinfo->pll_output_freq = post_div->divider * freq;
1938 if (rinfo->pll_output_freq >= rinfo->pll.ppll_min &&
1939 rinfo->pll_output_freq <= rinfo->pll.ppll_max)
1940 break;
1941 }
1942
1943 rinfo->post_div = post_div->divider;
1944 rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
1945 rinfo->pll.ref_clk);
1946 newmode.ppll_ref_div = rinfo->pll.ref_div;
1947 newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
1948 }
1949 newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
1950
1951#ifdef CONFIG_PPC_OF
1952 /* Gross hack for iBook with M7 until I find out a proper fix */
1953 if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
1954 newmode.ppll_div_3 = 0x000600ad;
1955#endif /* CONFIG_PPC_OF */
1956
1957 RTRACE("post div = 0x%x\n", rinfo->post_div);
1958 RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
1959 RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
1960
1961 /* DDA */
1962 vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
1963 rinfo->pll.ref_div * rinfo->post_div);
1964 xclk_freq = rinfo->pll.xclk;
1965
1966 xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
1967
1968 min_bits = min_bits_req(xclk_per_trans);
1969 useable_precision = min_bits + 1;
1970
1971 xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
1972 vclk_freq * mode->bits_per_pixel);
1973
1974 ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
1975 2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
1976 xclk_per_trans) << (11 - useable_precision);
1977 roff = xclk_per_trans_precise * (32 - 4);
1978
1979 RTRACE("ron = %d, roff = %d\n", ron, roff);
1980 RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
1981
1982 if ((ron + rinfo->ram.rloop) >= roff) {
1983 printk("radeonfb: error ron out of range\n");
1984 return -EINVAL;
1985 }
1986
1987 newmode.dda_config = (xclk_per_trans_precise |
1988 (useable_precision << 16) |
1989 (rinfo->ram.rloop << 20));
1990 newmode.dda_on_off = (ron << 16) | roff;
1991
1992 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1993 unsigned int hRatio, vRatio;
1994
1995 /* We force the pixel clock to be always enabled. Allowing it
1996 * to be power managed during blanking would save power, but has
1997 * nasty interactions with the 2D engine & sleep code that haven't
1998 * been solved yet. --BenH
1999 */
2000 newmode.vclk_ecp_cntl &= ~PIXCLK_DAC_ALWAYS_ONb;
2001
2002 if (mode->xres > rinfo->panel_xres)
2003 mode->xres = rinfo->panel_xres;
2004 if (mode->yres > rinfo->panel_yres)
2005 mode->yres = rinfo->panel_yres;
2006
2007 newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
2008 << HORZ_PANEL_SHIFT);
2009 newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
2010 << VERT_PANEL_SHIFT);
2011
2012 if (mode->xres != rinfo->panel_xres) {
2013 hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
2014 rinfo->panel_xres);
2015 newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
2016 (newmode.fp_horz_stretch &
2017 (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
2018 HORZ_AUTO_RATIO_INC)));
2019 newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
2020 HORZ_STRETCH_ENABLE);
2021 }
2022 newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
2023
2024 if (mode->yres != rinfo->panel_yres) {
2025 vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
2026 rinfo->panel_yres);
2027 newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
2028 (newmode.fp_vert_stretch &
2029 (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
2030 newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
2031 VERT_STRETCH_ENABLE);
2032 }
2033 newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
2034
2035 newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
2036 ~(FP_SEL_CRTC2 |
2037 FP_RMX_HVSYNC_CONTROL_EN |
2038 FP_DFP_SYNC_SEL |
2039 FP_CRT_SYNC_SEL |
2040 FP_CRTC_LOCK_8DOT |
2041 FP_USE_SHADOW_EN |
2042 FP_CRTC_USE_SHADOW_VEND |
2043 FP_CRT_SYNC_ALT));
2044
2045 newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
2046 FP_CRTC_DONT_SHADOW_HEND);
2047
2048 newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
2049 newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
2050 newmode.tmds_crc = rinfo->init_state.tmds_crc;
2051 newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
2052
2053 if (primary_mon == MT_LCD) {
2054 newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
2055 newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
2056 } else {
2057 /* DFP */
2058 newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
2059 newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
2060 TMDS_ICHCSEL | TMDS_PLL_EN) &
2061 ~(TMDS_PLLRST);
2062 newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
2063 }
2064
2065 newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
2066 (((mode->xres / 8) - 1) << 16));
2067 newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
2068 ((mode->yres - 1) << 16);
2069 newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
2070 (hsync_wid << 16) | (h_sync_pol << 23));
2071 newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
2072 (vsync_wid << 16) | (v_sync_pol << 23));
2073 }
2074
2075 /* do it! */
2076 if (!rinfo->asleep) {
2077 radeon_write_mode (rinfo, &newmode);
2078 /* (re)initialize the engine */
2079 if (noaccel)
2080 radeon_engine_init (rinfo);
2081
2082 }
2083 /* Update fix */
2084 if (accel)
2085 info->fix.line_length = rinfo->pitch*64;
2086 else
2087 info->fix.line_length = mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8);
2088 info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
2089
2090#ifdef CONFIG_BOOTX_TEXT
2091 /* Update debug text engine */
2092 btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
2093 rinfo->depth, info->fix.line_length);
2094#endif
2095
2096 return 0;
2097}
2098
2099
2100static void radeon_write_mode (struct radeonfb_info *rinfo,
2101 struct radeon_regs *mode)
2102{
2103 int i;
2104 int primary_mon = PRIMARY_MONITOR(rinfo);
2105
2106 radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
2107
2108
2109 if (rinfo->arch == RADEON_M6) {
2110 for (i=0; i<7; i++)
2111 OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
2112 } else {
2113 for (i=0; i<9; i++)
2114 OUTREG(common_regs[i].reg, common_regs[i].val);
2115 }
2116
2117 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
2118 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
2119 CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
2120 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
2121 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
2122 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
2123 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
2124 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
2125 OUTREG(CRTC_OFFSET, 0);
2126 OUTREG(CRTC_OFFSET_CNTL, 0);
2127 OUTREG(CRTC_PITCH, mode->crtc_pitch);
2128
2129#if defined(__BIG_ENDIAN)
2130 OUTREG(SURFACE_CNTL, mode->surface_cntl);
2131#endif
2132
2133 while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
2134 PPLL_DIV_SEL_MASK) {
2135 OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
2136 }
2137
2138 OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
2139
2140 while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
2141 (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
2142 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
2143 }
2144
2145 while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
2146 (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
2147 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
2148 }
2149
2150 while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
2151 (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
2152 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
2153 }
2154
2155 OUTPLL(HTOTAL_CNTL, 0);
2156
2157 OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
2158
2159// OUTREG(DDA_CONFIG, mode->dda_config);
2160// OUTREG(DDA_ON_OFF, mode->dda_on_off);
2161
2162 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
2163 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
2164 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
2165 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
2166 OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
2167 OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
2168 OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
2169 OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
2170 OUTREG(TMDS_CRC, mode->tmds_crc);
2171 OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
2172
2173 if (primary_mon == MT_LCD) {
2174 unsigned int tmp = INREG(LVDS_GEN_CNTL);
2175
2176 mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
2177 mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
2178
2179 if ((tmp & (LVDS_ON | LVDS_BLON)) ==
2180 (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
2181 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2182 } else {
2183 if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
2184 udelay(1000);
2185 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2186 } else {
2187 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
2188 LVDS_BLON);
2189 udelay(1000);
2190 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2191 }
2192 }
2193 }
2194 }
2195
2196 radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
2197
2198 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
2199
2200 return;
2201}
2202
2203static struct fb_ops radeonfb_ops = {
2204 .owner = THIS_MODULE,
2205 .fb_check_var = radeonfb_check_var,
2206 .fb_set_par = radeonfb_set_par,
2207 .fb_setcolreg = radeonfb_setcolreg,
2208 .fb_pan_display = radeonfb_pan_display,
2209 .fb_blank = radeonfb_blank,
2210 .fb_ioctl = radeonfb_ioctl,
2211#if 0
2212 .fb_fillrect = radeonfb_fillrect,
2213 .fb_copyarea = radeonfb_copyarea,
2214 .fb_imageblit = radeonfb_imageblit,
2215 .fb_rasterimg = radeonfb_rasterimg,
2216#else
2217 .fb_fillrect = cfb_fillrect,
2218 .fb_copyarea = cfb_copyarea,
2219 .fb_imageblit = cfb_imageblit,
2220#endif
2221};
2222
2223
2224static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
2225{
2226 struct fb_info *info;
2227
2228 info = &rinfo->info;
2229
2230 info->par = rinfo;
2231 info->pseudo_palette = rinfo->pseudo_palette;
2232 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
2233 info->fbops = &radeonfb_ops;
2234 info->screen_base = rinfo->fb_base;
2235
2236 /* Fill fix common fields */
2237 strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
2238 info->fix.smem_start = rinfo->fb_base_phys;
2239 info->fix.smem_len = rinfo->video_ram;
2240 info->fix.type = FB_TYPE_PACKED_PIXELS;
2241 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
2242 info->fix.xpanstep = 8;
2243 info->fix.ypanstep = 1;
2244 info->fix.ywrapstep = 0;
2245 info->fix.type_aux = 0;
2246 info->fix.mmio_start = rinfo->mmio_base_phys;
2247 info->fix.mmio_len = RADEON_REGSIZE;
2248 if (noaccel)
2249 info->fix.accel = FB_ACCEL_NONE;
2250 else
2251 info->fix.accel = FB_ACCEL_ATI_RADEON;
2252
2253 if (radeon_init_disp (rinfo) < 0)
2254 return -1;
2255
2256 return 0;
2257}
2258
2259
2260#ifdef CONFIG_PMAC_BACKLIGHT
2261
2262/* TODO: Dbl check these tables, we don't go up to full ON backlight
2263 * in these, possibly because we noticed MacOS doesn't, but I'd prefer
2264 * having some more official numbers from ATI
2265 */
2266static int backlight_conv_m6[] = {
2267 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
2268 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
2269};
2270static int backlight_conv_m7[] = {
2271 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
2272 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
2273};
2274
2275#define BACKLIGHT_LVDS_OFF
2276#undef BACKLIGHT_DAC_OFF
2277
2278/* We turn off the LCD completely instead of just dimming the backlight.
2279 * This provides some greater power saving and the display is useless
2280 * without backlight anyway.
2281 */
2282
2283static int radeon_set_backlight_enable(int on, int level, void *data)
2284{
2285 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
2286 unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
2287 int* conv_table;
2288
2289 /* Pardon me for that hack... maybe some day we can figure
2290 * out in what direction backlight should work on a given
2291 * panel ?
2292 */
2293 if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
2294 && !machine_is_compatible("PowerBook4,3"))
2295 conv_table = backlight_conv_m7;
2296 else
2297 conv_table = backlight_conv_m6;
2298
2299 lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
2300 if (on && (level > BACKLIGHT_OFF)) {
2301 lvds_gen_cntl |= LVDS_DIGON;
2302 if (!(lvds_gen_cntl & LVDS_ON)) {
2303 lvds_gen_cntl &= ~LVDS_BLON;
2304 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2305 (void)INREG(LVDS_GEN_CNTL);
2306 mdelay(10);
2307 lvds_gen_cntl |= LVDS_BLON;
2308 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2309 }
2310 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
2311 lvds_gen_cntl |= (conv_table[level] <<
2312 LVDS_BL_MOD_LEVEL_SHIFT);
2313 lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
2314 lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
2315 } else {
2316 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
2317 lvds_gen_cntl |= (conv_table[0] <<
2318 LVDS_BL_MOD_LEVEL_SHIFT);
2319 lvds_gen_cntl |= LVDS_DISPLAY_DIS;
2320 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2321 udelay(10);
2322 lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
2323 }
2324
2325 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2326 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
2327 rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
2328
2329 return 0;
2330}
2331
2332static int radeon_set_backlight_level(int level, void *data)
2333{
2334 return radeon_set_backlight_enable(1, level, data);
2335}
2336#endif /* CONFIG_PMAC_BACKLIGHT */
2337
2338
2339#ifdef CONFIG_PMAC_PBOOK
2340
2341static u32 dbg_clk;
2342
2343/*
2344 * Radeon M6 Power Management code. This code currently only supports
2345 * the mobile chips, it's based from some informations provided by ATI
2346 * along with hours of tracing of MacOS drivers
2347 */
2348
2349static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
2350{
2351 rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
2352 rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
2353 rinfo->save_regs[2] = INPLL(MCLK_CNTL);
2354 rinfo->save_regs[3] = INPLL(SCLK_CNTL);
2355 rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
2356 rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
2357 rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
2358 rinfo->save_regs[7] = INPLL(MCLK_MISC);
2359 rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
2360
2361 rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
2362 rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
2363 rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
2364 rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
2365 rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
2366 rinfo->save_regs[14] = INREG(BUS_CNTL1);
2367 rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
2368 rinfo->save_regs[16] = INREG(AGP_CNTL);
2369 rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
2370 rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
2371 rinfo->save_regs[19] = INREG(GPIOPAD_A);
2372 rinfo->save_regs[20] = INREG(GPIOPAD_EN);
2373 rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
2374 rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
2375 rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
2376 rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
2377 rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
2378 rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
2379 rinfo->save_regs[27] = INREG(GPIO_MONID);
2380 rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
2381
2382 rinfo->save_regs[29] = INREG(SURFACE_CNTL);
2383 rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
2384 rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
2385 rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
2386 rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
2387}
2388
2389static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
2390{
2391 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
2392
2393 OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
2394 OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
2395 OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
2396 OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
2397 OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
2398 OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
2399 OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
2400 OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
2401
2402 OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
2403 OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
2404 OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
2405 OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
2406 OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
2407 OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
2408 OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
2409 OUTREG(AGP_CNTL, rinfo->save_regs[16]);
2410 OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
2411 OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
2412
2413 // wait VBL before that one ?
2414 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
2415
2416 OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
2417 OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
2418 OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
2419 OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
2420 OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
2421 OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
2422 OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
2423 OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
2424 OUTREG(GPIO_MONID, rinfo->save_regs[27]);
2425 OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
2426}
2427
2428static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
2429{
2430 OUTREG(GPIOPAD_MASK, 0x0001ffff);
2431 OUTREG(GPIOPAD_EN, 0x00000400);
2432 OUTREG(GPIOPAD_A, 0x00000000);
2433 OUTREG(ZV_LCDPAD_MASK, 0x00000000);
2434 OUTREG(ZV_LCDPAD_EN, 0x00000000);
2435 OUTREG(ZV_LCDPAD_A, 0x00000000);
2436 OUTREG(GPIO_VGA_DDC, 0x00030000);
2437 OUTREG(GPIO_DVI_DDC, 0x00000000);
2438 OUTREG(GPIO_MONID, 0x00030000);
2439 OUTREG(GPIO_CRT2_DDC, 0x00000000);
2440}
2441
2442static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
2443{
2444//
2445// u32 reg;
2446//
2447// OUTPLL(P2PLL_REF_DIV, 0x0c);
2448//
2449// .../... figure out what macos does here
2450}
2451
2452static void radeon_pm_low_current(struct radeonfb_info *rinfo)
2453{
2454 u32 reg;
2455
2456 reg = INREG(BUS_CNTL1);
2457 reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
2458 reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
2459 OUTREG(BUS_CNTL1, reg);
2460
2461 reg = INPLL(PLL_PWRMGT_CNTL);
2462 reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
2463 PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
2464 reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
2465 reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
2466 OUTPLL(PLL_PWRMGT_CNTL, reg);
2467
2468// reg = INPLL(TV_PLL_CNTL1);
2469// reg |= TV_PLL_CNTL1__TVPLL_RESET | TV_PLL_CNTL1__TVPLL_SLEEP;
2470// OUTPLL(TV_PLL_CNTL1, reg);
2471
2472 reg = INREG(TV_DAC_CNTL);
2473 reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
2474 reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
2475 TV_DAC_CNTL_BDACPD |
2476 (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
2477 OUTREG(TV_DAC_CNTL, reg);
2478
2479 reg = INREG(TMDS_TRANSMITTER_CNTL);
2480 reg &= ~(TMDS_PLL_EN |TMDS_PLLRST);
2481 OUTREG(TMDS_TRANSMITTER_CNTL, reg);
2482
2483// lvds_pll_cntl = regr32(g, LVDS_PLL_CNTL);
2484// lvds_pll_cntl &= ~LVDS_PLL_CNTL__LVDS_PLL_EN;
2485// lvds_pll_cntl |= LVDS_PLL_CNTL__LVDS_PLL_RESET;
2486// regw32(g, LVDS_PLL_CNTL, lvds_pll_cntl);
2487
2488 reg = INREG(DAC_CNTL);
2489 reg &= ~DAC_CMP_EN;
2490 OUTREG(DAC_CNTL, reg);
2491
2492 reg = INREG(DAC_CNTL2);
2493 reg &= ~DAC2_CMP_EN;
2494 OUTREG(DAC_CNTL2, reg);
2495
2496 reg = INREG(TV_DAC_CNTL);
2497 reg &= ~TV_DAC_CNTL_DETECT;
2498 OUTREG(TV_DAC_CNTL, reg);
2499}
2500
2501static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
2502{
2503 /* This code is disabled. It does what is in the pm_init
2504 * function of the MacOS driver code ATI sent me. However,
2505 * it doesn't fix my sleep problem, and is causing other issues
2506 * on wakeup (bascially the machine dying when switching consoles
2507 * I haven't had time to investigate this yet
2508 */
2509#if 0
2510 u32 disp_misc_cntl;
2511 u32 disp_pwr_man;
2512 u32 temp;
2513
2514 // set SPLL, MPLL, PPLL, P2PLL, TVPLL, SCLK, MCLK, PCLK, P2CLK,
2515 // TCLK and TEST_MODE to 0
2516 temp = INPLL(CLK_PWRMGT_CNTL);
2517 OUTPLL(CLK_PWRMGT_CNTL , temp & ~0xc00002ff);
2518
2519 // Turn on Power Management
2520 temp = INPLL(CLK_PWRMGT_CNTL);
2521 OUTPLL(CLK_PWRMGT_CNTL , temp | 0x00000400);
2522
2523 // Turn off display clock if using mobile chips
2524 temp = INPLL(CLK_PWRMGT_CNTL);
2525 OUTREG(CLK_PWRMGT_CNTL , temp | 0x00100000);
2526
2527 // Force PIXCLK_ALWAYS_ON and PIXCLK_DAC_ALWAYS_ON
2528 temp = INPLL(VCLK_ECP_CNTL);
2529 OUTPLL(VCLK_ECP_CNTL, temp & ~0x000000c0);
2530
2531 // Force ECP_FORCE_ON to 1
2532 temp = INPLL(VCLK_ECP_CNTL);
2533 OUTPLL(VCLK_ECP_CNTL, temp | 0x00040000);
2534
2535 // Force PIXCLK_BLEND_ALWAYS_ON and PIXCLK_GV_ALWAYS_ON
2536 temp = INPLL(PIXCLKS_CNTL);
2537 OUTPLL(PIXCLKS_CNTL, temp & ~0x00001800);
2538
2539 // Forcing SCLK_CNTL to ON
2540 OUTPLL(SCLK_CNTL, (INPLL(SCLK_CNTL)& 0x00000007) | 0xffff8000 );
2541
2542 // Set PM control over XTALIN pad
2543 temp = INPLL(CLK_PIN_CNTL);
2544 OUTPLL(CLK_PIN_CNTL, temp | 0x00080000);
2545
2546 // Force MCLK and YCLK and MC as dynamic
2547 temp = INPLL(MCLK_CNTL);
2548 OUTPLL(MCLK_CNTL, temp & 0xffeaffff);
2549
2550 // PLL_TURNOFF
2551 temp = INPLL(PLL_PWRMGT_CNTL);
2552 OUTPLL(PLL_PWRMGT_CNTL, temp | 0x0000001f);
2553
2554 // set MOBILE_SU to 1 if M6 or DDR64 is detected
2555 temp = INPLL(PLL_PWRMGT_CNTL);
2556 OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00010000);
2557
2558 // select PM access mode (PM_MODE_SEL) (use ACPI mode)
2559// temp = INPLL(PLL_PWRMGT_CNTL);
2560// OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00002000);
2561 temp = INPLL(PLL_PWRMGT_CNTL);
2562 OUTPLL(PLL_PWRMGT_CNTL, temp & ~0x00002000);
2563
2564 // set DISP_MISC_CNTL register
2565 disp_misc_cntl = INREG(DISP_MISC_CNTL);
2566 disp_misc_cntl &= ~( DISP_MISC_CNTL_SOFT_RESET_GRPH_PP |
2567 DISP_MISC_CNTL_SOFT_RESET_SUBPIC_PP |
2568 DISP_MISC_CNTL_SOFT_RESET_OV0_PP |
2569 DISP_MISC_CNTL_SOFT_RESET_GRPH_SCLK |
2570 DISP_MISC_CNTL_SOFT_RESET_SUBPIC_SCLK |
2571 DISP_MISC_CNTL_SOFT_RESET_OV0_SCLK |
2572 DISP_MISC_CNTL_SOFT_RESET_GRPH2_PP |
2573 DISP_MISC_CNTL_SOFT_RESET_GRPH2_SCLK |
2574 DISP_MISC_CNTL_SOFT_RESET_LVDS |
2575 DISP_MISC_CNTL_SOFT_RESET_TMDS |
2576 DISP_MISC_CNTL_SOFT_RESET_DIG_TMDS |
2577 DISP_MISC_CNTL_SOFT_RESET_TV);
2578 OUTREG(DISP_MISC_CNTL, disp_misc_cntl);
2579
2580 // set DISP_PWR_MAN register
2581 disp_pwr_man = INREG(DISP_PWR_MAN);
2582 // clau - 9.29.2000 - changes made to bit23:18 to set to 1 as requested by George
2583 disp_pwr_man |= (DISP_PWR_MAN_DIG_TMDS_ENABLE_RST |
2584 DISP_PWR_MAN_TV_ENABLE_RST |
2585 // DISP_PWR_MAN_AUTO_PWRUP_EN |
2586 DISP_PWR_MAN_DISP_D3_GRPH_RST |
2587 DISP_PWR_MAN_DISP_D3_SUBPIC_RST |
2588 DISP_PWR_MAN_DISP_D3_OV0_RST |
2589 DISP_PWR_MAN_DISP_D1D2_GRPH_RST |
2590 DISP_PWR_MAN_DISP_D1D2_SUBPIC_RST |
2591 DISP_PWR_MAN_DISP_D1D2_OV0_RST);
2592 disp_pwr_man &= ~(DISP_PWR_MAN_DISP_PWR_MAN_D3_CRTC_EN |
2593 DISP_PWR_MAN_DISP2_PWR_MAN_D3_CRTC2_EN|
2594 DISP_PWR_MAN_DISP_D3_RST |
2595 DISP_PWR_MAN_DISP_D3_REG_RST);
2596 OUTREG(DISP_PWR_MAN, disp_pwr_man);
2597
2598 // clau - 10.24.2000
2599 // - add in setting for BUS_CNTL1 b27:26 = 0x01 and b31 = 0x1
2600 // - add in setting for AGP_CNTL b7:0 = 0x20
2601 // - add in setting for DVI_DDC_DATA_OUT_EN b17:16 = 0x0
2602
2603 // the following settings (two lines) are applied at a later part of this function, only on mobile platform
2604 // requres -mobile flag
2605 OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & 0xf3ffffff) | 0x04000000);
2606 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | 0x80000000);
2607 OUTREG(AGP_CNTL, (INREG(AGP_CNTL) & 0xffffff00) | 0x20);
2608 OUTREG(GPIO_DVI_DDC, INREG(GPIO_DVI_DDC) & 0xfffcffff);
2609
2610 // yulee - 12.12.2000
2611 // A12 only
2612 // EN_MCLK_TRISTATE_IN_SUSPEND@MCLK_MISC = 1
2613 // ACCESS_REGS_IN_SUSPEND@CLK_PIN_CNTL = 0
2614 // only on mobile platform
2615 OUTPLL(MCLK_MISC, INPLL(MCLK_MISC) | 0x00040000 );
2616
2617 // yulee -12.12.2000
2618 // AGPCLK_VALID@BUS_CNTL1 = 1
2619 // MOBILE_PLATFORM_SEL@BUS_CNTL1 = 01
2620 // CRTC_STEREO_SYNC_OUT_EN@CRTC_OFFSET_CNTL = 0
2621 // CG_CLK_TO_OUTPIN@CLK_PIN_CNTL = 0
2622 // only on mobile platform
2623 OUTPLL(CLK_PIN_CNTL, INPLL(CLK_PIN_CNTL ) & 0xFFFFF7FF );
2624 OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1 ) & 0xF3FFFFFF) | 0x84000000 );
2625 OUTREG(CRTC_OFFSET_CNTL, INREG(CRTC_OFFSET_CNTL ) & 0xFFEFFFFF );
2626
2627 mdelay(100);
2628#endif
2629
2630 /* Disable CRTCs */
2631 OUTREG(CRTC_GEN_CNTL, (INREG(CRTC_GEN_CNTL) & ~CRTC_EN) | CRTC_DISP_REQ_EN_B);
2632 OUTREG(CRTC2_GEN_CNTL, (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
2633 (void)INREG(CRTC2_GEN_CNTL);
2634 mdelay(17);
2635}
2636
2637static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2638{
2639 u16 pwr_cmd;
2640
2641 if (!rinfo->pm_reg)
2642 return;
2643
2644 /* Set the chip into appropriate suspend mode (we use D2,
2645 * D3 would require a compete re-initialization of the chip,
2646 * including PCI config registers, clocks, AGP conf, ...)
2647 */
2648 if (suspend) {
2649 /* According to ATI, we should program V2CLK here, I have
2650 * to verify what's up exactly
2651 */
2652 /* Save some registers */
2653 radeon_pm_save_regs(rinfo);
2654
2655 /* Check that on M7 too, might work might not. M7 may also
2656 * need explicit enabling of PM
2657 */
2658 if (rinfo->arch == RADEON_M6) {
2659 /* Program V2CLK */
2660 radeon_pm_program_v2clk(rinfo);
2661
2662 /* Disable IO PADs */
2663 radeon_pm_disable_iopad(rinfo);
2664
2665 /* Set low current */
2666 radeon_pm_low_current(rinfo);
2667
2668 /* Prepare chip for power management */
2669 radeon_pm_setup_for_suspend(rinfo);
2670
2671 /* Reset the MDLL */
2672 OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) | MCKOA_RESET);
2673 (void)INPLL(MDLL_RDCKA);
2674 OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
2675 (void)INPLL(MDLL_RDCKA);
2676 }
2677
2678 /* Switch PCI power managment to D2. */
2679 for (;;) {
2680 pci_read_config_word(
2681 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2682 &pwr_cmd);
2683 if (pwr_cmd & 2)
2684 break;
2685 pci_write_config_word(
2686 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2687 (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
2688 mdelay(500);
2689 }
2690 } else {
2691 /* Switch back PCI powermanagment to D0 */
2692 mdelay(200);
2693 pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
2694 mdelay(500);
2695
2696 dbg_clk = INPLL(1);
2697
2698 /* Do we need that on M7 ? */
2699 if (rinfo->arch == RADEON_M6) {
2700 /* Restore the MDLL */
2701 OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
2702 (void)INPLL(MDLL_CKO);
2703 }
2704
2705 /* Restore some registers */
2706 radeon_pm_restore_regs(rinfo);
2707 }
2708}
2709
2710/*
2711 * Save the contents of the framebuffer when we go to sleep,
2712 * and restore it when we wake up again.
2713 */
2714
2715int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
2716{
2717 struct radeonfb_info *rinfo;
2718
2719 for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
2720 struct fb_fix_screeninfo fix;
2721 int nb;
2722 struct display *disp;
2723
2724 disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
2725
2726 switch (rinfo->arch) {
2727 case RADEON_M6:
2728 case RADEON_M7:
2729 case RADEON_M9:
2730 break;
2731 default:
2732 return PBOOK_SLEEP_REFUSE;
2733 }
2734
2735 radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
2736 nb = fb_display[fg_console].var.yres * fix.line_length;
2737
2738 switch (when) {
2739 case PBOOK_SLEEP_NOW:
2740 acquire_console_sem();
2741 disp->dispsw = &fbcon_dummy;
2742
2743 if (!noaccel) {
2744 /* Make sure engine is reset */
2745 radeon_engine_reset();
2746 radeon_engine_idle();
2747 }
2748
2749 /* Blank display and LCD */
2750 radeonfb_blank(VESA_POWERDOWN+1,
2751 (struct fb_info *)rinfo);
2752
2753 /* Sleep */
2754 rinfo->asleep = 1;
2755 radeon_set_suspend(rinfo, 1);
2756 release_console_sem();
2757
2758 break;
2759 case PBOOK_WAKE:
2760 acquire_console_sem();
2761 /* Wakeup */
2762 radeon_set_suspend(rinfo, 0);
2763
2764 if (!noaccel)
2765 radeon_engine_init(rinfo);
2766 rinfo->asleep = 0;
2767 radeon_set_dispsw(rinfo, disp);
2768 radeon_load_video_mode(rinfo, &disp->var);
2769 do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
2770 (struct fb_info *)rinfo);
2771
2772 radeonfb_blank(0, (struct fb_info *)rinfo);
2773 release_console_sem();
2774 printk("CLK_PIN_CNTL on wakeup was: %08x\n", dbg_clk);
2775 break;
2776 }
2777 }
2778
2779 return PBOOK_SLEEP_OK;
2780}
2781
2782#endif /* CONFIG_PMAC_PBOOK */
2783
2784static int radeonfb_pci_register (struct pci_dev *pdev,
2785 const struct pci_device_id *ent)
2786{
2787 struct radeonfb_info *rinfo;
2788 struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
2789 u32 tmp;
2790
2791 RTRACE("radeonfb_pci_register BEGIN\n");
2792
2793 /* Enable device in PCI config */
2794 if (pci_enable_device(pdev) != 0) {
2795 printk(KERN_ERR "radeonfb: Cannot enable PCI device\n");
2796 return -ENODEV;
2797 }
2798
2799 rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
2800 if (!rinfo) {
2801 printk ("radeonfb: could not allocate memory\n");
2802 return -ENODEV;
2803 }
2804
2805 memset (rinfo, 0, sizeof (struct radeonfb_info));
2806 //info = &rinfo->info;
2807 rinfo->pdev = pdev;
2808 strcpy(rinfo->name, rci->name);
2809 rinfo->arch = rci->arch;
2810
2811 /* Set base addrs */
2812 rinfo->fb_base_phys = pci_resource_start (pdev, 0);
2813 rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
2814
2815 /* request the mem regions */
2816 if (!request_mem_region (rinfo->fb_base_phys,
2817 pci_resource_len(pdev, 0), "radeonfb")) {
2818 printk ("radeonfb: cannot reserve FB region\n");
2819 kfree (rinfo);
2820 return -ENODEV;
2821 }
2822
2823 if (!request_mem_region (rinfo->mmio_base_phys,
2824 pci_resource_len(pdev, 2), "radeonfb")) {
2825 printk ("radeonfb: cannot reserve MMIO region\n");
2826 release_mem_region (rinfo->fb_base_phys,
2827 pci_resource_len(pdev, 0));
2828 kfree (rinfo);
2829 return -ENODEV;
2830 }
2831
2832 /* map the regions */
2833 rinfo->mmio_base = ioremap (rinfo->mmio_base_phys, RADEON_REGSIZE);
2834 if (!rinfo->mmio_base) {
2835 printk ("radeonfb: cannot map MMIO\n");
2836 release_mem_region (rinfo->mmio_base_phys,
2837 pci_resource_len(pdev, 2));
2838 release_mem_region (rinfo->fb_base_phys,
2839 pci_resource_len(pdev, 0));
2840 kfree (rinfo);
2841 return -ENODEV;
2842 }
2843
2844 rinfo->chipset = pdev->device;
2845
2846 switch (rinfo->arch) {
2847 case RADEON_R100:
2848 rinfo->hasCRTC2 = 0;
2849 break;
2850 default:
2851 /* all the rest have it */
2852 rinfo->hasCRTC2 = 1;
2853 break;
2854 }
2855#if 0
2856 if (rinfo->arch == RADEON_M7) {
2857 /*
2858 * Noticed some errors in accel with M7, will have to work these out...
2859 */
2860 noaccel = 1;
2861 }
2862#endif
2863 if (mirror)
2864 printk("radeonfb: mirroring display to CRT\n");
2865
2866 /* framebuffer size */
2867 tmp = INREG(CONFIG_MEMSIZE);
2868
2869 /* mem size is bits [28:0], mask off the rest */
2870 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
2871
2872 /* ram type */
2873 tmp = INREG(MEM_SDRAM_MODE_REG);
2874 switch ((MEM_CFG_TYPE & tmp) >> 30) {
2875 case 0:
2876 /* SDR SGRAM (2:1) */
2877 strcpy(rinfo->ram_type, "SDR SGRAM");
2878 rinfo->ram.ml = 4;
2879 rinfo->ram.mb = 4;
2880 rinfo->ram.trcd = 1;
2881 rinfo->ram.trp = 2;
2882 rinfo->ram.twr = 1;
2883 rinfo->ram.cl = 2;
2884 rinfo->ram.loop_latency = 16;
2885 rinfo->ram.rloop = 16;
2886
2887 break;
2888 case 1:
2889 /* DDR SGRAM */
2890 strcpy(rinfo->ram_type, "DDR SGRAM");
2891 rinfo->ram.ml = 4;
2892 rinfo->ram.mb = 4;
2893 rinfo->ram.trcd = 3;
2894 rinfo->ram.trp = 3;
2895 rinfo->ram.twr = 2;
2896 rinfo->ram.cl = 3;
2897 rinfo->ram.tr2w = 1;
2898 rinfo->ram.loop_latency = 16;
2899 rinfo->ram.rloop = 16;
2900
2901 break;
2902 default:
2903 /* 64-bit SDR SGRAM */
2904 strcpy(rinfo->ram_type, "SDR SGRAM 64");
2905 rinfo->ram.ml = 4;
2906 rinfo->ram.mb = 8;
2907 rinfo->ram.trcd = 3;
2908 rinfo->ram.trp = 3;
2909 rinfo->ram.twr = 1;
2910 rinfo->ram.cl = 3;
2911 rinfo->ram.tr2w = 1;
2912 rinfo->ram.loop_latency = 17;
2913 rinfo->ram.rloop = 17;
2914
2915 break;
2916 }
2917
2918 rinfo->bios_seg = radeon_find_rom(rinfo);
2919 radeon_get_pllinfo(rinfo, rinfo->bios_seg);
2920
2921 /*
2922 * Hack to get around some busted production M6's
2923 * reporting no ram
2924 */
2925 if (rinfo->video_ram == 0) {
2926 switch (pdev->device) {
2927 case PCI_DEVICE_ID_ATI_RADEON_LY:
2928 case PCI_DEVICE_ID_ATI_RADEON_LZ:
2929 rinfo->video_ram = 8192 * 1024;
2930 break;
2931 default:
2932 break;
2933 }
2934 }
2935
2936
2937 RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
2938
2939#if !defined(__powerpc__)
2940 radeon_get_moninfo(rinfo);
2941#else
2942 switch (pdev->device) {
2943 case PCI_DEVICE_ID_ATI_RADEON_LW:
2944 case PCI_DEVICE_ID_ATI_RADEON_LX:
2945 case PCI_DEVICE_ID_ATI_RADEON_LY:
2946 case PCI_DEVICE_ID_ATI_RADEON_LZ:
2947 rinfo->dviDisp_type = MT_LCD;
2948 break;
2949 default:
2950 radeon_get_moninfo(rinfo);
2951 break;
2952 }
2953#endif
2954
2955 radeon_get_EDID(rinfo);
2956
2957 if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
2958 (rinfo->crtDisp_type == MT_DFP)) {
2959 if (!radeon_get_dfpinfo(rinfo)) {
2960 iounmap(rinfo->mmio_base);
2961 release_mem_region (rinfo->mmio_base_phys,
2962 pci_resource_len(pdev, 2));
2963 release_mem_region (rinfo->fb_base_phys,
2964 pci_resource_len(pdev, 0));
2965 kfree (rinfo);
2966 return -ENODEV;
2967 }
2968 }
2969
2970 rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->video_ram);
2971 if (!rinfo->fb_base) {
2972 printk ("radeonfb: cannot map FB\n");
2973 iounmap(rinfo->mmio_base);
2974 release_mem_region (rinfo->mmio_base_phys,
2975 pci_resource_len(pdev, 2));
2976 release_mem_region (rinfo->fb_base_phys,
2977 pci_resource_len(pdev, 0));
2978 kfree (rinfo);
2979 return -ENODEV;
2980 }
2981
2982 /* I SHOULD FIX THAT CRAP ! I should probably mimmic XFree DRI
2983 * driver setup here.
2984 *
2985 * On PPC, OF based cards setup the internal memory
2986 * mapping in strange ways. We change it so that the
2987 * framebuffer is mapped at 0 and given half of the card's
2988 * address space (2Gb). AGP is mapped high (0xe0000000) and
2989 * can use up to 512Mb. Once DRI is fully implemented, we
2990 * will have to setup the PCI remapper to remap the agp_special_page
2991 * memory page somewhere between those regions so that the card
2992 * use a normal PCI bus master cycle to access the ring read ptr.
2993 * --BenH.
2994 */
2995#ifdef CONFIG_ALL_PPC
2996 if (rinfo->hasCRTC2)
2997 OUTREG(CRTC2_GEN_CNTL,
2998 (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
2999 OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) | CRTC_DISPLAY_DIS);
3000 OUTREG(MC_FB_LOCATION, 0x7fff0000);
3001 OUTREG(MC_AGP_LOCATION, 0xffffe000);
3002 OUTREG(DISPLAY_BASE_ADDR, 0x00000000);
3003 if (rinfo->hasCRTC2)
3004 OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0x00000000);
3005 OUTREG(SRC_OFFSET, 0x00000000);
3006 OUTREG(DST_OFFSET, 0x00000000);
3007 mdelay(10);
3008 OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) & ~CRTC_DISPLAY_DIS);
3009#endif /* CONFIG_ALL_PPC */
3010
3011 /* save current mode regs before we switch into the new one
3012 * so we can restore this upon __exit
3013 */
3014 radeon_save_state (rinfo, &rinfo->init_state);
3015
3016 /* set all the vital stuff */
3017 radeon_set_fbinfo (rinfo);
3018
3019 pci_set_drvdata(pdev, rinfo);
3020 rinfo->next = board_list;
3021 board_list = rinfo;
3022 ((struct fb_info *) rinfo)->device = &pdev->dev;
3023 if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
3024 printk ("radeonfb: could not register framebuffer\n");
3025 iounmap(rinfo->fb_base);
3026 iounmap(rinfo->mmio_base);
3027 release_mem_region (rinfo->mmio_base_phys,
3028 pci_resource_len(pdev, 2));
3029 release_mem_region (rinfo->fb_base_phys,
3030 pci_resource_len(pdev, 0));
3031 kfree (rinfo);
3032 return -ENODEV;
3033 }
3034
3035#ifdef CONFIG_MTRR
3036 rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
3037 rinfo->video_ram,
3038 MTRR_TYPE_WRCOMB, 1);
3039#endif
3040
3041#ifdef CONFIG_PMAC_BACKLIGHT
3042 if (rinfo->dviDisp_type == MT_LCD)
3043 register_backlight_controller(&radeon_backlight_controller,
3044 rinfo, "ati");
3045#endif
3046
3047#ifdef CONFIG_PMAC_PBOOK
3048 if (rinfo->dviDisp_type == MT_LCD) {
3049 rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
3050 pmu_register_sleep_notifier(&radeon_sleep_notifier);
3051 }
3052#endif
3053
3054 printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
3055 (rinfo->video_ram/(1024*1024)));
3056
3057 if (rinfo->hasCRTC2) {
3058 printk("radeonfb: DVI port %s monitor connected\n",
3059 GET_MON_NAME(rinfo->dviDisp_type));
3060 printk("radeonfb: CRT port %s monitor connected\n",
3061 GET_MON_NAME(rinfo->crtDisp_type));
3062 } else {
3063 printk("radeonfb: CRT port %s monitor connected\n",
3064 GET_MON_NAME(rinfo->crtDisp_type));
3065 }
3066
3067 RTRACE("radeonfb_pci_register END\n");
3068
3069 return 0;
3070}
3071
3072
3073
3074static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
3075{
3076 struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
3077
3078 if (!rinfo)
3079 return;
3080
3081 /* restore original state
3082 *
3083 * Doesn't quite work yet, possibly because of the PPC hacking
3084 * I do on startup, disable for now. --BenH
3085 */
3086 radeon_write_mode (rinfo, &rinfo->init_state);
3087
3088#ifdef CONFIG_MTRR
3089 if (rinfo->mtrr_hdl >= 0)
3090 mtrr_del(rinfo->mtrr_hdl, 0, 0);
3091#endif
3092
3093 unregister_framebuffer ((struct fb_info *) rinfo);
3094
3095 iounmap(rinfo->mmio_base);
3096 iounmap(rinfo->fb_base);
3097
3098 release_mem_region (rinfo->mmio_base_phys,
3099 pci_resource_len(pdev, 2));
3100 release_mem_region (rinfo->fb_base_phys,
3101 pci_resource_len(pdev, 0));
3102
3103 kfree (rinfo);
3104}
3105
3106
3107static struct pci_driver radeonfb_driver = {
3108 .name = "radeonfb",
3109 .id_table = radeonfb_pci_table,
3110 .probe = radeonfb_pci_register,
3111 .remove = __devexit_p(radeonfb_pci_unregister),
3112};
3113
3114#ifndef MODULE
3115static int __init radeonfb_old_setup (char *options)
3116{
3117 char *this_opt;
3118
3119 if (!options || !*options)
3120 return 0;
3121
3122 while ((this_opt = strsep (&options, ",")) != NULL) {
3123 if (!*this_opt)
3124 continue;
3125 if (!strncmp(this_opt, "noaccel", 7)) {
3126 noaccel = 1;
3127 } else if (!strncmp(this_opt, "mirror", 6)) {
3128 mirror = 1;
3129 } else if (!strncmp(this_opt, "dfp", 3)) {
3130 force_dfp = 1;
3131 } else if (!strncmp(this_opt, "panel_yres:", 11)) {
3132 panel_yres = simple_strtoul((this_opt+11), NULL, 0);
3133 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3134 nomtrr = 1;
3135 } else
3136 mode_option = this_opt;
3137 }
3138
3139 return 0;
3140}
3141#endif /* MODULE */
3142
3143static int __init radeonfb_old_init (void)
3144{
3145#ifndef MODULE
3146 char *option = NULL;
3147
3148 if (fb_get_options("radeonfb_old", &option))
3149 return -ENODEV;
3150 radeonfb_old_setup(option);
3151#endif
3152 return pci_register_driver (&radeonfb_driver);
3153}
3154
3155
3156static void __exit radeonfb_old_exit (void)
3157{
3158 pci_unregister_driver (&radeonfb_driver);
3159}
3160
3161module_init(radeonfb_old_init);
3162module_exit(radeonfb_old_exit);
3163
3164
3165MODULE_AUTHOR("Ani Joshi");
3166MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
3167MODULE_LICENSE("GPL");
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 8d5f35676f9a..4a292aae6eb2 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1378,7 +1378,7 @@ stifb_setup(char *options)
1378 int i; 1378 int i;
1379 1379
1380 if (!options || !*options) 1380 if (!options || !*options)
1381 return 0; 1381 return 1;
1382 1382
1383 if (strncmp(options, "off", 3) == 0) { 1383 if (strncmp(options, "off", 3) == 0) {
1384 stifb_disabled = 1; 1384 stifb_disabled = 1;
@@ -1393,7 +1393,7 @@ stifb_setup(char *options)
1393 stifb_bpp_pref[i] = simple_strtoul(options, &options, 10); 1393 stifb_bpp_pref[i] = simple_strtoul(options, &options, 10);
1394 } 1394 }
1395 } 1395 }
1396 return 0; 1396 return 1;
1397} 1397}
1398 1398
1399__setup("stifb=", stifb_setup); 1399__setup("stifb=", stifb_setup);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index f6e24ee85f07..5fc86ea20692 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -4,8 +4,9 @@
4 * Frame Buffer Device for ATI Imageon w100 (Wallaby) 4 * Frame Buffer Device for ATI Imageon w100 (Wallaby)
5 * 5 *
6 * Copyright (C) 2002, ATI Corp. 6 * Copyright (C) 2002, ATI Corp.
7 * Copyright (C) 2004-2005 Richard Purdie 7 * Copyright (C) 2004-2006 Richard Purdie
8 * Copyright (c) 2005 Ian Molton 8 * Copyright (c) 2005 Ian Molton
9 * Copyright (c) 2006 Alberto Mardegan
9 * 10 *
10 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> 11 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
11 * 12 *
@@ -14,6 +15,9 @@
14 * 15 *
15 * w32xx support by Ian Molton 16 * w32xx support by Ian Molton
16 * 17 *
18 * Hardware acceleration support by Alberto Mardegan
19 * <mardy@users.sourceforge.net>
20 *
17 * This program is free software; you can redistribute it and/or modify 21 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as 22 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation. 23 * published by the Free Software Foundation.
@@ -47,6 +51,7 @@ static void w100_set_dispregs(struct w100fb_par*);
47static void w100_update_enable(void); 51static void w100_update_enable(void);
48static void w100_update_disable(void); 52static void w100_update_disable(void);
49static void calc_hsync(struct w100fb_par *par); 53static void calc_hsync(struct w100fb_par *par);
54static void w100_init_graphic_engine(struct w100fb_par *par);
50struct w100_pll_info *w100_get_xtal_table(unsigned int freq); 55struct w100_pll_info *w100_get_xtal_table(unsigned int freq);
51 56
52/* Pseudo palette size */ 57/* Pseudo palette size */
@@ -248,6 +253,152 @@ static int w100fb_blank(int blank_mode, struct fb_info *info)
248} 253}
249 254
250 255
256static void w100_fifo_wait(int entries)
257{
258 union rbbm_status_u status;
259 int i;
260
261 for (i = 0; i < 2000000; i++) {
262 status.val = readl(remapped_regs + mmRBBM_STATUS);
263 if (status.f.cmdfifo_avail >= entries)
264 return;
265 udelay(1);
266 }
267 printk(KERN_ERR "w100fb: FIFO Timeout!\n");
268}
269
270
271static int w100fb_sync(struct fb_info *info)
272{
273 union rbbm_status_u status;
274 int i;
275
276 for (i = 0; i < 2000000; i++) {
277 status.val = readl(remapped_regs + mmRBBM_STATUS);
278 if (!status.f.gui_active)
279 return 0;
280 udelay(1);
281 }
282 printk(KERN_ERR "w100fb: Graphic engine timeout!\n");
283 return -EBUSY;
284}
285
286
287static void w100_init_graphic_engine(struct w100fb_par *par)
288{
289 union dp_gui_master_cntl_u gmc;
290 union dp_mix_u dp_mix;
291 union dp_datatype_u dp_datatype;
292 union dp_cntl_u dp_cntl;
293
294 w100_fifo_wait(4);
295 writel(W100_FB_BASE, remapped_regs + mmDST_OFFSET);
296 writel(par->xres, remapped_regs + mmDST_PITCH);
297 writel(W100_FB_BASE, remapped_regs + mmSRC_OFFSET);
298 writel(par->xres, remapped_regs + mmSRC_PITCH);
299
300 w100_fifo_wait(3);
301 writel(0, remapped_regs + mmSC_TOP_LEFT);
302 writel((par->yres << 16) | par->xres, remapped_regs + mmSC_BOTTOM_RIGHT);
303 writel(0x1fff1fff, remapped_regs + mmSRC_SC_BOTTOM_RIGHT);
304
305 w100_fifo_wait(4);
306 dp_cntl.val = 0;
307 dp_cntl.f.dst_x_dir = 1;
308 dp_cntl.f.dst_y_dir = 1;
309 dp_cntl.f.src_x_dir = 1;
310 dp_cntl.f.src_y_dir = 1;
311 dp_cntl.f.dst_major_x = 1;
312 dp_cntl.f.src_major_x = 1;
313 writel(dp_cntl.val, remapped_regs + mmDP_CNTL);
314
315 gmc.val = 0;
316 gmc.f.gmc_src_pitch_offset_cntl = 1;
317 gmc.f.gmc_dst_pitch_offset_cntl = 1;
318 gmc.f.gmc_src_clipping = 1;
319 gmc.f.gmc_dst_clipping = 1;
320 gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE;
321 gmc.f.gmc_dst_datatype = 3; /* from DstType_16Bpp_444 */
322 gmc.f.gmc_src_datatype = SRC_DATATYPE_EQU_DST;
323 gmc.f.gmc_byte_pix_order = 1;
324 gmc.f.gmc_default_sel = 0;
325 gmc.f.gmc_rop3 = ROP3_SRCCOPY;
326 gmc.f.gmc_dp_src_source = DP_SRC_MEM_RECTANGULAR;
327 gmc.f.gmc_clr_cmp_fcn_dis = 1;
328 gmc.f.gmc_wr_msk_dis = 1;
329 gmc.f.gmc_dp_op = DP_OP_ROP;
330 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
331
332 dp_datatype.val = dp_mix.val = 0;
333 dp_datatype.f.dp_dst_datatype = gmc.f.gmc_dst_datatype;
334 dp_datatype.f.dp_brush_datatype = gmc.f.gmc_brush_datatype;
335 dp_datatype.f.dp_src2_type = 0;
336 dp_datatype.f.dp_src2_datatype = gmc.f.gmc_src_datatype;
337 dp_datatype.f.dp_src_datatype = gmc.f.gmc_src_datatype;
338 dp_datatype.f.dp_byte_pix_order = gmc.f.gmc_byte_pix_order;
339 writel(dp_datatype.val, remapped_regs + mmDP_DATATYPE);
340
341 dp_mix.f.dp_src_source = gmc.f.gmc_dp_src_source;
342 dp_mix.f.dp_src2_source = 1;
343 dp_mix.f.dp_rop3 = gmc.f.gmc_rop3;
344 dp_mix.f.dp_op = gmc.f.gmc_dp_op;
345 writel(dp_mix.val, remapped_regs + mmDP_MIX);
346}
347
348
349static void w100fb_fillrect(struct fb_info *info,
350 const struct fb_fillrect *rect)
351{
352 union dp_gui_master_cntl_u gmc;
353
354 if (info->state != FBINFO_STATE_RUNNING)
355 return;
356 if (info->flags & FBINFO_HWACCEL_DISABLED) {
357 cfb_fillrect(info, rect);
358 return;
359 }
360
361 gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL);
362 gmc.f.gmc_rop3 = ROP3_PATCOPY;
363 gmc.f.gmc_brush_datatype = GMC_BRUSH_SOLID_COLOR;
364 w100_fifo_wait(2);
365 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
366 writel(rect->color, remapped_regs + mmDP_BRUSH_FRGD_CLR);
367
368 w100_fifo_wait(2);
369 writel((rect->dy << 16) | (rect->dx & 0xffff), remapped_regs + mmDST_Y_X);
370 writel((rect->width << 16) | (rect->height & 0xffff),
371 remapped_regs + mmDST_WIDTH_HEIGHT);
372}
373
374
375static void w100fb_copyarea(struct fb_info *info,
376 const struct fb_copyarea *area)
377{
378 u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
379 u32 h = area->height, w = area->width;
380 union dp_gui_master_cntl_u gmc;
381
382 if (info->state != FBINFO_STATE_RUNNING)
383 return;
384 if (info->flags & FBINFO_HWACCEL_DISABLED) {
385 cfb_copyarea(info, area);
386 return;
387 }
388
389 gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL);
390 gmc.f.gmc_rop3 = ROP3_SRCCOPY;
391 gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE;
392 w100_fifo_wait(1);
393 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
394
395 w100_fifo_wait(3);
396 writel((sy << 16) | (sx & 0xffff), remapped_regs + mmSRC_Y_X);
397 writel((dy << 16) | (dx & 0xffff), remapped_regs + mmDST_Y_X);
398 writel((w << 16) | (h & 0xffff), remapped_regs + mmDST_WIDTH_HEIGHT);
399}
400
401
251/* 402/*
252 * Change the resolution by calling the appropriate hardware functions 403 * Change the resolution by calling the appropriate hardware functions
253 */ 404 */
@@ -265,6 +416,7 @@ static void w100fb_activate_var(struct w100fb_par *par)
265 w100_init_lcd(par); 416 w100_init_lcd(par);
266 w100_set_dispregs(par); 417 w100_set_dispregs(par);
267 w100_update_enable(); 418 w100_update_enable();
419 w100_init_graphic_engine(par);
268 420
269 calc_hsync(par); 421 calc_hsync(par);
270 422
@@ -394,9 +546,10 @@ static struct fb_ops w100fb_ops = {
394 .fb_set_par = w100fb_set_par, 546 .fb_set_par = w100fb_set_par,
395 .fb_setcolreg = w100fb_setcolreg, 547 .fb_setcolreg = w100fb_setcolreg,
396 .fb_blank = w100fb_blank, 548 .fb_blank = w100fb_blank,
397 .fb_fillrect = cfb_fillrect, 549 .fb_fillrect = w100fb_fillrect,
398 .fb_copyarea = cfb_copyarea, 550 .fb_copyarea = w100fb_copyarea,
399 .fb_imageblit = cfb_imageblit, 551 .fb_imageblit = cfb_imageblit,
552 .fb_sync = w100fb_sync,
400}; 553};
401 554
402#ifdef CONFIG_PM 555#ifdef CONFIG_PM
@@ -543,7 +696,8 @@ int __init w100fb_probe(struct platform_device *pdev)
543 } 696 }
544 697
545 info->fbops = &w100fb_ops; 698 info->fbops = &w100fb_ops;
546 info->flags = FBINFO_DEFAULT; 699 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
700 FBINFO_HWACCEL_FILLRECT;
547 info->node = -1; 701 info->node = -1;
548 info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); 702 info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE);
549 info->screen_size = REMAPPED_FB_LEN; 703 info->screen_size = REMAPPED_FB_LEN;
diff --git a/drivers/video/w100fb.h b/drivers/video/w100fb.h
index 7a58a1e3e427..fffae7b4f6e9 100644
--- a/drivers/video/w100fb.h
+++ b/drivers/video/w100fb.h
@@ -122,15 +122,32 @@
122/* Block DISPLAY End: */ 122/* Block DISPLAY End: */
123 123
124/* Block GFX Start: */ 124/* Block GFX Start: */
125#define mmDST_OFFSET 0x1004
126#define mmDST_PITCH 0x1008
127#define mmDST_Y_X 0x1038
128#define mmDST_WIDTH_HEIGHT 0x1198
129#define mmDP_GUI_MASTER_CNTL 0x106C
125#define mmBRUSH_OFFSET 0x108C 130#define mmBRUSH_OFFSET 0x108C
126#define mmBRUSH_Y_X 0x1074 131#define mmBRUSH_Y_X 0x1074
132#define mmDP_BRUSH_FRGD_CLR 0x107C
133#define mmSRC_OFFSET 0x11AC
134#define mmSRC_PITCH 0x11B0
135#define mmSRC_Y_X 0x1034
127#define mmDEFAULT_PITCH_OFFSET 0x10A0 136#define mmDEFAULT_PITCH_OFFSET 0x10A0
128#define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8 137#define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8
129#define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC 138#define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC
139#define mmSC_TOP_LEFT 0x11BC
140#define mmSC_BOTTOM_RIGHT 0x11C0
141#define mmSRC_SC_BOTTOM_RIGHT 0x11C4
130#define mmGLOBAL_ALPHA 0x1210 142#define mmGLOBAL_ALPHA 0x1210
131#define mmFILTER_COEF 0x1214 143#define mmFILTER_COEF 0x1214
132#define mmMVC_CNTL_START 0x11E0 144#define mmMVC_CNTL_START 0x11E0
133#define mmE2_ARITHMETIC_CNTL 0x1220 145#define mmE2_ARITHMETIC_CNTL 0x1220
146#define mmDP_CNTL 0x11C8
147#define mmDP_CNTL_DST_DIR 0x11CC
148#define mmDP_DATATYPE 0x12C4
149#define mmDP_MIX 0x12C8
150#define mmDP_WRITE_MSK 0x12CC
134#define mmENG_CNTL 0x13E8 151#define mmENG_CNTL 0x13E8
135#define mmENG_PERF_CNT 0x13F0 152#define mmENG_PERF_CNT 0x13F0
136/* Block GFX End: */ 153/* Block GFX End: */
@@ -179,6 +196,7 @@
179/* Block RBBM Start: */ 196/* Block RBBM Start: */
180#define mmWAIT_UNTIL 0x1400 197#define mmWAIT_UNTIL 0x1400
181#define mmISYNC_CNTL 0x1404 198#define mmISYNC_CNTL 0x1404
199#define mmRBBM_STATUS 0x0140
182#define mmRBBM_CNTL 0x0144 200#define mmRBBM_CNTL 0x0144
183#define mmNQWAIT_UNTIL 0x0150 201#define mmNQWAIT_UNTIL 0x0150
184/* Block RBBM End: */ 202/* Block RBBM End: */
@@ -225,147 +243,147 @@
225/* Register structure definitions */ 243/* Register structure definitions */
226 244
227struct wrap_top_dir_t { 245struct wrap_top_dir_t {
228 unsigned long top_addr : 23; 246 u32 top_addr : 23;
229 unsigned long : 9; 247 u32 : 9;
230} __attribute__((packed)); 248} __attribute__((packed));
231 249
232union wrap_top_dir_u { 250union wrap_top_dir_u {
233 unsigned long val : 32; 251 u32 val : 32;
234 struct wrap_top_dir_t f; 252 struct wrap_top_dir_t f;
235} __attribute__((packed)); 253} __attribute__((packed));
236 254
237struct wrap_start_dir_t { 255struct wrap_start_dir_t {
238 unsigned long start_addr : 23; 256 u32 start_addr : 23;
239 unsigned long : 9; 257 u32 : 9;
240} __attribute__((packed)); 258} __attribute__((packed));
241 259
242union wrap_start_dir_u { 260union wrap_start_dir_u {
243 unsigned long val : 32; 261 u32 val : 32;
244 struct wrap_start_dir_t f; 262 struct wrap_start_dir_t f;
245} __attribute__((packed)); 263} __attribute__((packed));
246 264
247struct cif_cntl_t { 265struct cif_cntl_t {
248 unsigned long swap_reg : 2; 266 u32 swap_reg : 2;
249 unsigned long swap_fbuf_1 : 2; 267 u32 swap_fbuf_1 : 2;
250 unsigned long swap_fbuf_2 : 2; 268 u32 swap_fbuf_2 : 2;
251 unsigned long swap_fbuf_3 : 2; 269 u32 swap_fbuf_3 : 2;
252 unsigned long pmi_int_disable : 1; 270 u32 pmi_int_disable : 1;
253 unsigned long pmi_schmen_disable : 1; 271 u32 pmi_schmen_disable : 1;
254 unsigned long intb_oe : 1; 272 u32 intb_oe : 1;
255 unsigned long en_wait_to_compensate_dq_prop_dly : 1; 273 u32 en_wait_to_compensate_dq_prop_dly : 1;
256 unsigned long compensate_wait_rd_size : 2; 274 u32 compensate_wait_rd_size : 2;
257 unsigned long wait_asserted_timeout_val : 2; 275 u32 wait_asserted_timeout_val : 2;
258 unsigned long wait_masked_val : 2; 276 u32 wait_masked_val : 2;
259 unsigned long en_wait_timeout : 1; 277 u32 en_wait_timeout : 1;
260 unsigned long en_one_clk_setup_before_wait : 1; 278 u32 en_one_clk_setup_before_wait : 1;
261 unsigned long interrupt_active_high : 1; 279 u32 interrupt_active_high : 1;
262 unsigned long en_overwrite_straps : 1; 280 u32 en_overwrite_straps : 1;
263 unsigned long strap_wait_active_hi : 1; 281 u32 strap_wait_active_hi : 1;
264 unsigned long lat_busy_count : 2; 282 u32 lat_busy_count : 2;
265 unsigned long lat_rd_pm4_sclk_busy : 1; 283 u32 lat_rd_pm4_sclk_busy : 1;
266 unsigned long dis_system_bits : 1; 284 u32 dis_system_bits : 1;
267 unsigned long dis_mr : 1; 285 u32 dis_mr : 1;
268 unsigned long cif_spare_1 : 4; 286 u32 cif_spare_1 : 4;
269} __attribute__((packed)); 287} __attribute__((packed));
270 288
271union cif_cntl_u { 289union cif_cntl_u {
272 unsigned long val : 32; 290 u32 val : 32;
273 struct cif_cntl_t f; 291 struct cif_cntl_t f;
274} __attribute__((packed)); 292} __attribute__((packed));
275 293
276struct cfgreg_base_t { 294struct cfgreg_base_t {
277 unsigned long cfgreg_base : 24; 295 u32 cfgreg_base : 24;
278 unsigned long : 8; 296 u32 : 8;
279} __attribute__((packed)); 297} __attribute__((packed));
280 298
281union cfgreg_base_u { 299union cfgreg_base_u {
282 unsigned long val : 32; 300 u32 val : 32;
283 struct cfgreg_base_t f; 301 struct cfgreg_base_t f;
284} __attribute__((packed)); 302} __attribute__((packed));
285 303
286struct cif_io_t { 304struct cif_io_t {
287 unsigned long dq_srp : 1; 305 u32 dq_srp : 1;
288 unsigned long dq_srn : 1; 306 u32 dq_srn : 1;
289 unsigned long dq_sp : 4; 307 u32 dq_sp : 4;
290 unsigned long dq_sn : 4; 308 u32 dq_sn : 4;
291 unsigned long waitb_srp : 1; 309 u32 waitb_srp : 1;
292 unsigned long waitb_srn : 1; 310 u32 waitb_srn : 1;
293 unsigned long waitb_sp : 4; 311 u32 waitb_sp : 4;
294 unsigned long waitb_sn : 4; 312 u32 waitb_sn : 4;
295 unsigned long intb_srp : 1; 313 u32 intb_srp : 1;
296 unsigned long intb_srn : 1; 314 u32 intb_srn : 1;
297 unsigned long intb_sp : 4; 315 u32 intb_sp : 4;
298 unsigned long intb_sn : 4; 316 u32 intb_sn : 4;
299 unsigned long : 2; 317 u32 : 2;
300} __attribute__((packed)); 318} __attribute__((packed));
301 319
302union cif_io_u { 320union cif_io_u {
303 unsigned long val : 32; 321 u32 val : 32;
304 struct cif_io_t f; 322 struct cif_io_t f;
305} __attribute__((packed)); 323} __attribute__((packed));
306 324
307struct cif_read_dbg_t { 325struct cif_read_dbg_t {
308 unsigned long unpacker_pre_fetch_trig_gen : 2; 326 u32 unpacker_pre_fetch_trig_gen : 2;
309 unsigned long dly_second_rd_fetch_trig : 1; 327 u32 dly_second_rd_fetch_trig : 1;
310 unsigned long rst_rd_burst_id : 1; 328 u32 rst_rd_burst_id : 1;
311 unsigned long dis_rd_burst_id : 1; 329 u32 dis_rd_burst_id : 1;
312 unsigned long en_block_rd_when_packer_is_not_emp : 1; 330 u32 en_block_rd_when_packer_is_not_emp : 1;
313 unsigned long dis_pre_fetch_cntl_sm : 1; 331 u32 dis_pre_fetch_cntl_sm : 1;
314 unsigned long rbbm_chrncy_dis : 1; 332 u32 rbbm_chrncy_dis : 1;
315 unsigned long rbbm_rd_after_wr_lat : 2; 333 u32 rbbm_rd_after_wr_lat : 2;
316 unsigned long dis_be_during_rd : 1; 334 u32 dis_be_during_rd : 1;
317 unsigned long one_clk_invalidate_pulse : 1; 335 u32 one_clk_invalidate_pulse : 1;
318 unsigned long dis_chnl_priority : 1; 336 u32 dis_chnl_priority : 1;
319 unsigned long rst_read_path_a_pls : 1; 337 u32 rst_read_path_a_pls : 1;
320 unsigned long rst_read_path_b_pls : 1; 338 u32 rst_read_path_b_pls : 1;
321 unsigned long dis_reg_rd_fetch_trig : 1; 339 u32 dis_reg_rd_fetch_trig : 1;
322 unsigned long dis_rd_fetch_trig_from_ind_addr : 1; 340 u32 dis_rd_fetch_trig_from_ind_addr : 1;
323 unsigned long dis_rd_same_byte_to_trig_fetch : 1; 341 u32 dis_rd_same_byte_to_trig_fetch : 1;
324 unsigned long dis_dir_wrap : 1; 342 u32 dis_dir_wrap : 1;
325 unsigned long dis_ring_buf_to_force_dec : 1; 343 u32 dis_ring_buf_to_force_dec : 1;
326 unsigned long dis_addr_comp_in_16bit : 1; 344 u32 dis_addr_comp_in_16bit : 1;
327 unsigned long clr_w : 1; 345 u32 clr_w : 1;
328 unsigned long err_rd_tag_is_3 : 1; 346 u32 err_rd_tag_is_3 : 1;
329 unsigned long err_load_when_ful_a : 1; 347 u32 err_load_when_ful_a : 1;
330 unsigned long err_load_when_ful_b : 1; 348 u32 err_load_when_ful_b : 1;
331 unsigned long : 7; 349 u32 : 7;
332} __attribute__((packed)); 350} __attribute__((packed));
333 351
334union cif_read_dbg_u { 352union cif_read_dbg_u {
335 unsigned long val : 32; 353 u32 val : 32;
336 struct cif_read_dbg_t f; 354 struct cif_read_dbg_t f;
337} __attribute__((packed)); 355} __attribute__((packed));
338 356
339struct cif_write_dbg_t { 357struct cif_write_dbg_t {
340 unsigned long packer_timeout_count : 2; 358 u32 packer_timeout_count : 2;
341 unsigned long en_upper_load_cond : 1; 359 u32 en_upper_load_cond : 1;
342 unsigned long en_chnl_change_cond : 1; 360 u32 en_chnl_change_cond : 1;
343 unsigned long dis_addr_comp_cond : 1; 361 u32 dis_addr_comp_cond : 1;
344 unsigned long dis_load_same_byte_addr_cond : 1; 362 u32 dis_load_same_byte_addr_cond : 1;
345 unsigned long dis_timeout_cond : 1; 363 u32 dis_timeout_cond : 1;
346 unsigned long dis_timeout_during_rbbm : 1; 364 u32 dis_timeout_during_rbbm : 1;
347 unsigned long dis_packer_ful_during_rbbm_timeout : 1; 365 u32 dis_packer_ful_during_rbbm_timeout : 1;
348 unsigned long en_dword_split_to_rbbm : 1; 366 u32 en_dword_split_to_rbbm : 1;
349 unsigned long en_dummy_val : 1; 367 u32 en_dummy_val : 1;
350 unsigned long dummy_val_sel : 1; 368 u32 dummy_val_sel : 1;
351 unsigned long mask_pm4_wrptr_dec : 1; 369 u32 mask_pm4_wrptr_dec : 1;
352 unsigned long dis_mc_clean_cond : 1; 370 u32 dis_mc_clean_cond : 1;
353 unsigned long err_two_reqi_during_ful : 1; 371 u32 err_two_reqi_during_ful : 1;
354 unsigned long err_reqi_during_idle_clk : 1; 372 u32 err_reqi_during_idle_clk : 1;
355 unsigned long err_global : 1; 373 u32 err_global : 1;
356 unsigned long en_wr_buf_dbg_load : 1; 374 u32 en_wr_buf_dbg_load : 1;
357 unsigned long en_wr_buf_dbg_path : 1; 375 u32 en_wr_buf_dbg_path : 1;
358 unsigned long sel_wr_buf_byte : 3; 376 u32 sel_wr_buf_byte : 3;
359 unsigned long dis_rd_flush_wr : 1; 377 u32 dis_rd_flush_wr : 1;
360 unsigned long dis_packer_ful_cond : 1; 378 u32 dis_packer_ful_cond : 1;
361 unsigned long dis_invalidate_by_ops_chnl : 1; 379 u32 dis_invalidate_by_ops_chnl : 1;
362 unsigned long en_halt_when_reqi_err : 1; 380 u32 en_halt_when_reqi_err : 1;
363 unsigned long cif_spare_2 : 5; 381 u32 cif_spare_2 : 5;
364 unsigned long : 1; 382 u32 : 1;
365} __attribute__((packed)); 383} __attribute__((packed));
366 384
367union cif_write_dbg_u { 385union cif_write_dbg_u {
368 unsigned long val : 32; 386 u32 val : 32;
369 struct cif_write_dbg_t f; 387 struct cif_write_dbg_t f;
370} __attribute__((packed)); 388} __attribute__((packed));
371 389
@@ -403,327 +421,327 @@ union cpu_defaults_u {
403} __attribute__((packed)); 421} __attribute__((packed));
404 422
405struct crtc_total_t { 423struct crtc_total_t {
406 unsigned long crtc_h_total : 10; 424 u32 crtc_h_total : 10;
407 unsigned long : 6; 425 u32 : 6;
408 unsigned long crtc_v_total : 10; 426 u32 crtc_v_total : 10;
409 unsigned long : 6; 427 u32 : 6;
410} __attribute__((packed)); 428} __attribute__((packed));
411 429
412union crtc_total_u { 430union crtc_total_u {
413 unsigned long val : 32; 431 u32 val : 32;
414 struct crtc_total_t f; 432 struct crtc_total_t f;
415} __attribute__((packed)); 433} __attribute__((packed));
416 434
417struct crtc_ss_t { 435struct crtc_ss_t {
418 unsigned long ss_start : 10; 436 u32 ss_start : 10;
419 unsigned long : 6; 437 u32 : 6;
420 unsigned long ss_end : 10; 438 u32 ss_end : 10;
421 unsigned long : 2; 439 u32 : 2;
422 unsigned long ss_align : 1; 440 u32 ss_align : 1;
423 unsigned long ss_pol : 1; 441 u32 ss_pol : 1;
424 unsigned long ss_run_mode : 1; 442 u32 ss_run_mode : 1;
425 unsigned long ss_en : 1; 443 u32 ss_en : 1;
426} __attribute__((packed)); 444} __attribute__((packed));
427 445
428union crtc_ss_u { 446union crtc_ss_u {
429 unsigned long val : 32; 447 u32 val : 32;
430 struct crtc_ss_t f; 448 struct crtc_ss_t f;
431} __attribute__((packed)); 449} __attribute__((packed));
432 450
433struct active_h_disp_t { 451struct active_h_disp_t {
434 unsigned long active_h_start : 10; 452 u32 active_h_start : 10;
435 unsigned long : 6; 453 u32 : 6;
436 unsigned long active_h_end : 10; 454 u32 active_h_end : 10;
437 unsigned long : 6; 455 u32 : 6;
438} __attribute__((packed)); 456} __attribute__((packed));
439 457
440union active_h_disp_u { 458union active_h_disp_u {
441 unsigned long val : 32; 459 u32 val : 32;
442 struct active_h_disp_t f; 460 struct active_h_disp_t f;
443} __attribute__((packed)); 461} __attribute__((packed));
444 462
445struct active_v_disp_t { 463struct active_v_disp_t {
446 unsigned long active_v_start : 10; 464 u32 active_v_start : 10;
447 unsigned long : 6; 465 u32 : 6;
448 unsigned long active_v_end : 10; 466 u32 active_v_end : 10;
449 unsigned long : 6; 467 u32 : 6;
450} __attribute__((packed)); 468} __attribute__((packed));
451 469
452union active_v_disp_u { 470union active_v_disp_u {
453 unsigned long val : 32; 471 u32 val : 32;
454 struct active_v_disp_t f; 472 struct active_v_disp_t f;
455} __attribute__((packed)); 473} __attribute__((packed));
456 474
457struct graphic_h_disp_t { 475struct graphic_h_disp_t {
458 unsigned long graphic_h_start : 10; 476 u32 graphic_h_start : 10;
459 unsigned long : 6; 477 u32 : 6;
460 unsigned long graphic_h_end : 10; 478 u32 graphic_h_end : 10;
461 unsigned long : 6; 479 u32 : 6;
462} __attribute__((packed)); 480} __attribute__((packed));
463 481
464union graphic_h_disp_u { 482union graphic_h_disp_u {
465 unsigned long val : 32; 483 u32 val : 32;
466 struct graphic_h_disp_t f; 484 struct graphic_h_disp_t f;
467} __attribute__((packed)); 485} __attribute__((packed));
468 486
469struct graphic_v_disp_t { 487struct graphic_v_disp_t {
470 unsigned long graphic_v_start : 10; 488 u32 graphic_v_start : 10;
471 unsigned long : 6; 489 u32 : 6;
472 unsigned long graphic_v_end : 10; 490 u32 graphic_v_end : 10;
473 unsigned long : 6; 491 u32 : 6;
474} __attribute__((packed)); 492} __attribute__((packed));
475 493
476union graphic_v_disp_u{ 494union graphic_v_disp_u{
477 unsigned long val : 32; 495 u32 val : 32;
478 struct graphic_v_disp_t f; 496 struct graphic_v_disp_t f;
479} __attribute__((packed)); 497} __attribute__((packed));
480 498
481struct graphic_ctrl_t_w100 { 499struct graphic_ctrl_t_w100 {
482 unsigned long color_depth : 3; 500 u32 color_depth : 3;
483 unsigned long portrait_mode : 2; 501 u32 portrait_mode : 2;
484 unsigned long low_power_on : 1; 502 u32 low_power_on : 1;
485 unsigned long req_freq : 4; 503 u32 req_freq : 4;
486 unsigned long en_crtc : 1; 504 u32 en_crtc : 1;
487 unsigned long en_graphic_req : 1; 505 u32 en_graphic_req : 1;
488 unsigned long en_graphic_crtc : 1; 506 u32 en_graphic_crtc : 1;
489 unsigned long total_req_graphic : 9; 507 u32 total_req_graphic : 9;
490 unsigned long lcd_pclk_on : 1; 508 u32 lcd_pclk_on : 1;
491 unsigned long lcd_sclk_on : 1; 509 u32 lcd_sclk_on : 1;
492 unsigned long pclk_running : 1; 510 u32 pclk_running : 1;
493 unsigned long sclk_running : 1; 511 u32 sclk_running : 1;
494 unsigned long : 6; 512 u32 : 6;
495} __attribute__((packed)); 513} __attribute__((packed));
496 514
497struct graphic_ctrl_t_w32xx { 515struct graphic_ctrl_t_w32xx {
498 unsigned long color_depth : 3; 516 u32 color_depth : 3;
499 unsigned long portrait_mode : 2; 517 u32 portrait_mode : 2;
500 unsigned long low_power_on : 1; 518 u32 low_power_on : 1;
501 unsigned long req_freq : 4; 519 u32 req_freq : 4;
502 unsigned long en_crtc : 1; 520 u32 en_crtc : 1;
503 unsigned long en_graphic_req : 1; 521 u32 en_graphic_req : 1;
504 unsigned long en_graphic_crtc : 1; 522 u32 en_graphic_crtc : 1;
505 unsigned long total_req_graphic : 10; 523 u32 total_req_graphic : 10;
506 unsigned long lcd_pclk_on : 1; 524 u32 lcd_pclk_on : 1;
507 unsigned long lcd_sclk_on : 1; 525 u32 lcd_sclk_on : 1;
508 unsigned long pclk_running : 1; 526 u32 pclk_running : 1;
509 unsigned long sclk_running : 1; 527 u32 sclk_running : 1;
510 unsigned long : 5; 528 u32 : 5;
511} __attribute__((packed)); 529} __attribute__((packed));
512 530
513union graphic_ctrl_u { 531union graphic_ctrl_u {
514 unsigned long val : 32; 532 u32 val : 32;
515 struct graphic_ctrl_t_w100 f_w100; 533 struct graphic_ctrl_t_w100 f_w100;
516 struct graphic_ctrl_t_w32xx f_w32xx; 534 struct graphic_ctrl_t_w32xx f_w32xx;
517} __attribute__((packed)); 535} __attribute__((packed));
518 536
519struct video_ctrl_t { 537struct video_ctrl_t {
520 unsigned long video_mode : 1; 538 u32 video_mode : 1;
521 unsigned long keyer_en : 1; 539 u32 keyer_en : 1;
522 unsigned long en_video_req : 1; 540 u32 en_video_req : 1;
523 unsigned long en_graphic_req_video : 1; 541 u32 en_graphic_req_video : 1;
524 unsigned long en_video_crtc : 1; 542 u32 en_video_crtc : 1;
525 unsigned long video_hor_exp : 2; 543 u32 video_hor_exp : 2;
526 unsigned long video_ver_exp : 2; 544 u32 video_ver_exp : 2;
527 unsigned long uv_combine : 1; 545 u32 uv_combine : 1;
528 unsigned long total_req_video : 9; 546 u32 total_req_video : 9;
529 unsigned long video_ch_sel : 1; 547 u32 video_ch_sel : 1;
530 unsigned long video_portrait : 2; 548 u32 video_portrait : 2;
531 unsigned long yuv2rgb_en : 1; 549 u32 yuv2rgb_en : 1;
532 unsigned long yuv2rgb_option : 1; 550 u32 yuv2rgb_option : 1;
533 unsigned long video_inv_hor : 1; 551 u32 video_inv_hor : 1;
534 unsigned long video_inv_ver : 1; 552 u32 video_inv_ver : 1;
535 unsigned long gamma_sel : 2; 553 u32 gamma_sel : 2;
536 unsigned long dis_limit : 1; 554 u32 dis_limit : 1;
537 unsigned long en_uv_hblend : 1; 555 u32 en_uv_hblend : 1;
538 unsigned long rgb_gamma_sel : 2; 556 u32 rgb_gamma_sel : 2;
539} __attribute__((packed)); 557} __attribute__((packed));
540 558
541union video_ctrl_u { 559union video_ctrl_u {
542 unsigned long val : 32; 560 u32 val : 32;
543 struct video_ctrl_t f; 561 struct video_ctrl_t f;
544} __attribute__((packed)); 562} __attribute__((packed));
545 563
546struct disp_db_buf_cntl_rd_t { 564struct disp_db_buf_cntl_rd_t {
547 unsigned long en_db_buf : 1; 565 u32 en_db_buf : 1;
548 unsigned long update_db_buf_done : 1; 566 u32 update_db_buf_done : 1;
549 unsigned long db_buf_cntl : 6; 567 u32 db_buf_cntl : 6;
550 unsigned long : 24; 568 u32 : 24;
551} __attribute__((packed)); 569} __attribute__((packed));
552 570
553union disp_db_buf_cntl_rd_u { 571union disp_db_buf_cntl_rd_u {
554 unsigned long val : 32; 572 u32 val : 32;
555 struct disp_db_buf_cntl_rd_t f; 573 struct disp_db_buf_cntl_rd_t f;
556} __attribute__((packed)); 574} __attribute__((packed));
557 575
558struct disp_db_buf_cntl_wr_t { 576struct disp_db_buf_cntl_wr_t {
559 unsigned long en_db_buf : 1; 577 u32 en_db_buf : 1;
560 unsigned long update_db_buf : 1; 578 u32 update_db_buf : 1;
561 unsigned long db_buf_cntl : 6; 579 u32 db_buf_cntl : 6;
562 unsigned long : 24; 580 u32 : 24;
563} __attribute__((packed)); 581} __attribute__((packed));
564 582
565union disp_db_buf_cntl_wr_u { 583union disp_db_buf_cntl_wr_u {
566 unsigned long val : 32; 584 u32 val : 32;
567 struct disp_db_buf_cntl_wr_t f; 585 struct disp_db_buf_cntl_wr_t f;
568} __attribute__((packed)); 586} __attribute__((packed));
569 587
570struct gamma_value1_t { 588struct gamma_value1_t {
571 unsigned long gamma1 : 8; 589 u32 gamma1 : 8;
572 unsigned long gamma2 : 8; 590 u32 gamma2 : 8;
573 unsigned long gamma3 : 8; 591 u32 gamma3 : 8;
574 unsigned long gamma4 : 8; 592 u32 gamma4 : 8;
575} __attribute__((packed)); 593} __attribute__((packed));
576 594
577union gamma_value1_u { 595union gamma_value1_u {
578 unsigned long val : 32; 596 u32 val : 32;
579 struct gamma_value1_t f; 597 struct gamma_value1_t f;
580} __attribute__((packed)); 598} __attribute__((packed));
581 599
582struct gamma_value2_t { 600struct gamma_value2_t {
583 unsigned long gamma5 : 8; 601 u32 gamma5 : 8;
584 unsigned long gamma6 : 8; 602 u32 gamma6 : 8;
585 unsigned long gamma7 : 8; 603 u32 gamma7 : 8;
586 unsigned long gamma8 : 8; 604 u32 gamma8 : 8;
587} __attribute__((packed)); 605} __attribute__((packed));
588 606
589union gamma_value2_u { 607union gamma_value2_u {
590 unsigned long val : 32; 608 u32 val : 32;
591 struct gamma_value2_t f; 609 struct gamma_value2_t f;
592} __attribute__((packed)); 610} __attribute__((packed));
593 611
594struct gamma_slope_t { 612struct gamma_slope_t {
595 unsigned long slope1 : 3; 613 u32 slope1 : 3;
596 unsigned long slope2 : 3; 614 u32 slope2 : 3;
597 unsigned long slope3 : 3; 615 u32 slope3 : 3;
598 unsigned long slope4 : 3; 616 u32 slope4 : 3;
599 unsigned long slope5 : 3; 617 u32 slope5 : 3;
600 unsigned long slope6 : 3; 618 u32 slope6 : 3;
601 unsigned long slope7 : 3; 619 u32 slope7 : 3;
602 unsigned long slope8 : 3; 620 u32 slope8 : 3;
603 unsigned long : 8; 621 u32 : 8;
604} __attribute__((packed)); 622} __attribute__((packed));
605 623
606union gamma_slope_u { 624union gamma_slope_u {
607 unsigned long val : 32; 625 u32 val : 32;
608 struct gamma_slope_t f; 626 struct gamma_slope_t f;
609} __attribute__((packed)); 627} __attribute__((packed));
610 628
611struct mc_ext_mem_location_t { 629struct mc_ext_mem_location_t {
612 unsigned long mc_ext_mem_start : 16; 630 u32 mc_ext_mem_start : 16;
613 unsigned long mc_ext_mem_top : 16; 631 u32 mc_ext_mem_top : 16;
614} __attribute__((packed)); 632} __attribute__((packed));
615 633
616union mc_ext_mem_location_u { 634union mc_ext_mem_location_u {
617 unsigned long val : 32; 635 u32 val : 32;
618 struct mc_ext_mem_location_t f; 636 struct mc_ext_mem_location_t f;
619} __attribute__((packed)); 637} __attribute__((packed));
620 638
621struct mc_fb_location_t { 639struct mc_fb_location_t {
622 unsigned long mc_fb_start : 16; 640 u32 mc_fb_start : 16;
623 unsigned long mc_fb_top : 16; 641 u32 mc_fb_top : 16;
624} __attribute__((packed)); 642} __attribute__((packed));
625 643
626union mc_fb_location_u { 644union mc_fb_location_u {
627 unsigned long val : 32; 645 u32 val : 32;
628 struct mc_fb_location_t f; 646 struct mc_fb_location_t f;
629} __attribute__((packed)); 647} __attribute__((packed));
630 648
631struct clk_pin_cntl_t { 649struct clk_pin_cntl_t {
632 unsigned long osc_en : 1; 650 u32 osc_en : 1;
633 unsigned long osc_gain : 5; 651 u32 osc_gain : 5;
634 unsigned long dont_use_xtalin : 1; 652 u32 dont_use_xtalin : 1;
635 unsigned long xtalin_pm_en : 1; 653 u32 xtalin_pm_en : 1;
636 unsigned long xtalin_dbl_en : 1; 654 u32 xtalin_dbl_en : 1;
637 unsigned long : 7; 655 u32 : 7;
638 unsigned long cg_debug : 16; 656 u32 cg_debug : 16;
639} __attribute__((packed)); 657} __attribute__((packed));
640 658
641union clk_pin_cntl_u { 659union clk_pin_cntl_u {
642 unsigned long val : 32; 660 u32 val : 32;
643 struct clk_pin_cntl_t f; 661 struct clk_pin_cntl_t f;
644} __attribute__((packed)); 662} __attribute__((packed));
645 663
646struct pll_ref_fb_div_t { 664struct pll_ref_fb_div_t {
647 unsigned long pll_ref_div : 4; 665 u32 pll_ref_div : 4;
648 unsigned long : 4; 666 u32 : 4;
649 unsigned long pll_fb_div_int : 6; 667 u32 pll_fb_div_int : 6;
650 unsigned long : 2; 668 u32 : 2;
651 unsigned long pll_fb_div_frac : 3; 669 u32 pll_fb_div_frac : 3;
652 unsigned long : 1; 670 u32 : 1;
653 unsigned long pll_reset_time : 4; 671 u32 pll_reset_time : 4;
654 unsigned long pll_lock_time : 8; 672 u32 pll_lock_time : 8;
655} __attribute__((packed)); 673} __attribute__((packed));
656 674
657union pll_ref_fb_div_u { 675union pll_ref_fb_div_u {
658 unsigned long val : 32; 676 u32 val : 32;
659 struct pll_ref_fb_div_t f; 677 struct pll_ref_fb_div_t f;
660} __attribute__((packed)); 678} __attribute__((packed));
661 679
662struct pll_cntl_t { 680struct pll_cntl_t {
663 unsigned long pll_pwdn : 1; 681 u32 pll_pwdn : 1;
664 unsigned long pll_reset : 1; 682 u32 pll_reset : 1;
665 unsigned long pll_pm_en : 1; 683 u32 pll_pm_en : 1;
666 unsigned long pll_mode : 1; 684 u32 pll_mode : 1;
667 unsigned long pll_refclk_sel : 1; 685 u32 pll_refclk_sel : 1;
668 unsigned long pll_fbclk_sel : 1; 686 u32 pll_fbclk_sel : 1;
669 unsigned long pll_tcpoff : 1; 687 u32 pll_tcpoff : 1;
670 unsigned long pll_pcp : 3; 688 u32 pll_pcp : 3;
671 unsigned long pll_pvg : 3; 689 u32 pll_pvg : 3;
672 unsigned long pll_vcofr : 1; 690 u32 pll_vcofr : 1;
673 unsigned long pll_ioffset : 2; 691 u32 pll_ioffset : 2;
674 unsigned long pll_pecc_mode : 2; 692 u32 pll_pecc_mode : 2;
675 unsigned long pll_pecc_scon : 2; 693 u32 pll_pecc_scon : 2;
676 unsigned long pll_dactal : 4; 694 u32 pll_dactal : 4;
677 unsigned long pll_cp_clip : 2; 695 u32 pll_cp_clip : 2;
678 unsigned long pll_conf : 3; 696 u32 pll_conf : 3;
679 unsigned long pll_mbctrl : 2; 697 u32 pll_mbctrl : 2;
680 unsigned long pll_ring_off : 1; 698 u32 pll_ring_off : 1;
681} __attribute__((packed)); 699} __attribute__((packed));
682 700
683union pll_cntl_u { 701union pll_cntl_u {
684 unsigned long val : 32; 702 u32 val : 32;
685 struct pll_cntl_t f; 703 struct pll_cntl_t f;
686} __attribute__((packed)); 704} __attribute__((packed));
687 705
688struct sclk_cntl_t { 706struct sclk_cntl_t {
689 unsigned long sclk_src_sel : 2; 707 u32 sclk_src_sel : 2;
690 unsigned long : 2; 708 u32 : 2;
691 unsigned long sclk_post_div_fast : 4; 709 u32 sclk_post_div_fast : 4;
692 unsigned long sclk_clkon_hys : 3; 710 u32 sclk_clkon_hys : 3;
693 unsigned long sclk_post_div_slow : 4; 711 u32 sclk_post_div_slow : 4;
694 unsigned long disp_cg_ok2switch_en : 1; 712 u32 disp_cg_ok2switch_en : 1;
695 unsigned long sclk_force_reg : 1; 713 u32 sclk_force_reg : 1;
696 unsigned long sclk_force_disp : 1; 714 u32 sclk_force_disp : 1;
697 unsigned long sclk_force_mc : 1; 715 u32 sclk_force_mc : 1;
698 unsigned long sclk_force_extmc : 1; 716 u32 sclk_force_extmc : 1;
699 unsigned long sclk_force_cp : 1; 717 u32 sclk_force_cp : 1;
700 unsigned long sclk_force_e2 : 1; 718 u32 sclk_force_e2 : 1;
701 unsigned long sclk_force_e3 : 1; 719 u32 sclk_force_e3 : 1;
702 unsigned long sclk_force_idct : 1; 720 u32 sclk_force_idct : 1;
703 unsigned long sclk_force_bist : 1; 721 u32 sclk_force_bist : 1;
704 unsigned long busy_extend_cp : 1; 722 u32 busy_extend_cp : 1;
705 unsigned long busy_extend_e2 : 1; 723 u32 busy_extend_e2 : 1;
706 unsigned long busy_extend_e3 : 1; 724 u32 busy_extend_e3 : 1;
707 unsigned long busy_extend_idct : 1; 725 u32 busy_extend_idct : 1;
708 unsigned long : 3; 726 u32 : 3;
709} __attribute__((packed)); 727} __attribute__((packed));
710 728
711union sclk_cntl_u { 729union sclk_cntl_u {
712 unsigned long val : 32; 730 u32 val : 32;
713 struct sclk_cntl_t f; 731 struct sclk_cntl_t f;
714} __attribute__((packed)); 732} __attribute__((packed));
715 733
716struct pclk_cntl_t { 734struct pclk_cntl_t {
717 unsigned long pclk_src_sel : 2; 735 u32 pclk_src_sel : 2;
718 unsigned long : 2; 736 u32 : 2;
719 unsigned long pclk_post_div : 4; 737 u32 pclk_post_div : 4;
720 unsigned long : 8; 738 u32 : 8;
721 unsigned long pclk_force_disp : 1; 739 u32 pclk_force_disp : 1;
722 unsigned long : 15; 740 u32 : 15;
723} __attribute__((packed)); 741} __attribute__((packed));
724 742
725union pclk_cntl_u { 743union pclk_cntl_u {
726 unsigned long val : 32; 744 u32 val : 32;
727 struct pclk_cntl_t f; 745 struct pclk_cntl_t f;
728} __attribute__((packed)); 746} __attribute__((packed));
729 747
@@ -735,36 +753,176 @@ union pclk_cntl_u {
735#define TESTCLK_SRC_XTAL 0x06 753#define TESTCLK_SRC_XTAL 0x06
736 754
737struct clk_test_cntl_t { 755struct clk_test_cntl_t {
738 unsigned long testclk_sel : 4; 756 u32 testclk_sel : 4;
739 unsigned long : 3; 757 u32 : 3;
740 unsigned long start_check_freq : 1; 758 u32 start_check_freq : 1;
741 unsigned long tstcount_rst : 1; 759 u32 tstcount_rst : 1;
742 unsigned long : 15; 760 u32 : 15;
743 unsigned long test_count : 8; 761 u32 test_count : 8;
744} __attribute__((packed)); 762} __attribute__((packed));
745 763
746union clk_test_cntl_u { 764union clk_test_cntl_u {
747 unsigned long val : 32; 765 u32 val : 32;
748 struct clk_test_cntl_t f; 766 struct clk_test_cntl_t f;
749} __attribute__((packed)); 767} __attribute__((packed));
750 768
751struct pwrmgt_cntl_t { 769struct pwrmgt_cntl_t {
752 unsigned long pwm_enable : 1; 770 u32 pwm_enable : 1;
753 unsigned long : 1; 771 u32 : 1;
754 unsigned long pwm_mode_req : 2; 772 u32 pwm_mode_req : 2;
755 unsigned long pwm_wakeup_cond : 2; 773 u32 pwm_wakeup_cond : 2;
756 unsigned long pwm_fast_noml_hw_en : 1; 774 u32 pwm_fast_noml_hw_en : 1;
757 unsigned long pwm_noml_fast_hw_en : 1; 775 u32 pwm_noml_fast_hw_en : 1;
758 unsigned long pwm_fast_noml_cond : 4; 776 u32 pwm_fast_noml_cond : 4;
759 unsigned long pwm_noml_fast_cond : 4; 777 u32 pwm_noml_fast_cond : 4;
760 unsigned long pwm_idle_timer : 8; 778 u32 pwm_idle_timer : 8;
761 unsigned long pwm_busy_timer : 8; 779 u32 pwm_busy_timer : 8;
762} __attribute__((packed)); 780} __attribute__((packed));
763 781
764union pwrmgt_cntl_u { 782union pwrmgt_cntl_u {
765 unsigned long val : 32; 783 u32 val : 32;
766 struct pwrmgt_cntl_t f; 784 struct pwrmgt_cntl_t f;
767} __attribute__((packed)); 785} __attribute__((packed));
768 786
787#define SRC_DATATYPE_EQU_DST 3
788
789#define ROP3_SRCCOPY 0xcc
790#define ROP3_PATCOPY 0xf0
791
792#define GMC_BRUSH_SOLID_COLOR 13
793#define GMC_BRUSH_NONE 15
794
795#define DP_SRC_MEM_RECTANGULAR 2
796
797#define DP_OP_ROP 0
798
799struct dp_gui_master_cntl_t {
800 u32 gmc_src_pitch_offset_cntl : 1;
801 u32 gmc_dst_pitch_offset_cntl : 1;
802 u32 gmc_src_clipping : 1;
803 u32 gmc_dst_clipping : 1;
804 u32 gmc_brush_datatype : 4;
805 u32 gmc_dst_datatype : 4;
806 u32 gmc_src_datatype : 3;
807 u32 gmc_byte_pix_order : 1;
808 u32 gmc_default_sel : 1;
809 u32 gmc_rop3 : 8;
810 u32 gmc_dp_src_source : 3;
811 u32 gmc_clr_cmp_fcn_dis : 1;
812 u32 : 1;
813 u32 gmc_wr_msk_dis : 1;
814 u32 gmc_dp_op : 1;
815} __attribute__((packed));
816
817union dp_gui_master_cntl_u {
818 u32 val : 32;
819 struct dp_gui_master_cntl_t f;
820} __attribute__((packed));
821
822struct rbbm_status_t {
823 u32 cmdfifo_avail : 7;
824 u32 : 1;
825 u32 hirq_on_rbb : 1;
826 u32 cprq_on_rbb : 1;
827 u32 cfrq_on_rbb : 1;
828 u32 hirq_in_rtbuf : 1;
829 u32 cprq_in_rtbuf : 1;
830 u32 cfrq_in_rtbuf : 1;
831 u32 cf_pipe_busy : 1;
832 u32 eng_ev_busy : 1;
833 u32 cp_cmdstrm_busy : 1;
834 u32 e2_busy : 1;
835 u32 rb2d_busy : 1;
836 u32 rb3d_busy : 1;
837 u32 se_busy : 1;
838 u32 re_busy : 1;
839 u32 tam_busy : 1;
840 u32 tdm_busy : 1;
841 u32 pb_busy : 1;
842 u32 : 6;
843 u32 gui_active : 1;
844} __attribute__((packed));
845
846union rbbm_status_u {
847 u32 val : 32;
848 struct rbbm_status_t f;
849} __attribute__((packed));
850
851struct dp_datatype_t {
852 u32 dp_dst_datatype : 4;
853 u32 : 4;
854 u32 dp_brush_datatype : 4;
855 u32 dp_src2_type : 1;
856 u32 dp_src2_datatype : 3;
857 u32 dp_src_datatype : 3;
858 u32 : 11;
859 u32 dp_byte_pix_order : 1;
860 u32 : 1;
861} __attribute__((packed));
862
863union dp_datatype_u {
864 u32 val : 32;
865 struct dp_datatype_t f;
866} __attribute__((packed));
867
868struct dp_mix_t {
869 u32 : 8;
870 u32 dp_src_source : 3;
871 u32 dp_src2_source : 3;
872 u32 : 2;
873 u32 dp_rop3 : 8;
874 u32 dp_op : 1;
875 u32 : 7;
876} __attribute__((packed));
877
878union dp_mix_u {
879 u32 val : 32;
880 struct dp_mix_t f;
881} __attribute__((packed));
882
883struct eng_cntl_t {
884 u32 erc_reg_rd_ws : 1;
885 u32 erc_reg_wr_ws : 1;
886 u32 erc_idle_reg_wr : 1;
887 u32 dis_engine_triggers : 1;
888 u32 dis_rop_src_uses_dst_w_h : 1;
889 u32 dis_src_uses_dst_dirmaj : 1;
890 u32 : 6;
891 u32 force_3dclk_when_2dclk : 1;
892 u32 : 19;
893} __attribute__((packed));
894
895union eng_cntl_u {
896 u32 val : 32;
897 struct eng_cntl_t f;
898} __attribute__((packed));
899
900struct dp_cntl_t {
901 u32 dst_x_dir : 1;
902 u32 dst_y_dir : 1;
903 u32 src_x_dir : 1;
904 u32 src_y_dir : 1;
905 u32 dst_major_x : 1;
906 u32 src_major_x : 1;
907 u32 : 26;
908} __attribute__((packed));
909
910union dp_cntl_u {
911 u32 val : 32;
912 struct dp_cntl_t f;
913} __attribute__((packed));
914
915struct dp_cntl_dst_dir_t {
916 u32 : 15;
917 u32 dst_y_dir : 1;
918 u32 : 15;
919 u32 dst_x_dir : 1;
920} __attribute__((packed));
921
922union dp_cntl_dst_dir_u {
923 u32 val : 32;
924 struct dp_cntl_dst_dir_t f;
925} __attribute__((packed));
926
769#endif 927#endif
770 928
diff --git a/fs/Makefile b/fs/Makefile
index f3a4f7077175..83bf478e786b 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ 10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ 11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ 12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
13 ioprio.o pnode.o drop_caches.o splice.o 13 ioprio.o pnode.o drop_caches.o splice.o sync.o
14 14
15obj-$(CONFIG_INOTIFY) += inotify.o 15obj-$(CONFIG_INOTIFY) += inotify.o
16obj-$(CONFIG_EPOLL) += eventpoll.o 16obj-$(CONFIG_EPOLL) += eventpoll.o
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 4e1b849f912f..f3418f7a6e9d 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/smp_lock.h> 16#include <linux/smp_lock.h>
17#include <linux/devfs_fs_kernel.h> 17#include <linux/devfs_fs_kernel.h>
18#include <linux/seq_file.h>
18 19
19#include <linux/kobject.h> 20#include <linux/kobject.h>
20#include <linux/kobj_map.h> 21#include <linux/kobj_map.h>
@@ -27,8 +28,6 @@
27 28
28static struct kobj_map *cdev_map; 29static struct kobj_map *cdev_map;
29 30
30#define MAX_PROBE_HASH 255 /* random */
31
32static DEFINE_MUTEX(chrdevs_lock); 31static DEFINE_MUTEX(chrdevs_lock);
33 32
34static struct char_device_struct { 33static struct char_device_struct {
@@ -39,93 +38,29 @@ static struct char_device_struct {
39 char name[64]; 38 char name[64];
40 struct file_operations *fops; 39 struct file_operations *fops;
41 struct cdev *cdev; /* will die */ 40 struct cdev *cdev; /* will die */
42} *chrdevs[MAX_PROBE_HASH]; 41} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
43 42
44/* index in the above */ 43/* index in the above */
45static inline int major_to_index(int major) 44static inline int major_to_index(int major)
46{ 45{
47 return major % MAX_PROBE_HASH; 46 return major % CHRDEV_MAJOR_HASH_SIZE;
48}
49
50struct chrdev_info {
51 int index;
52 struct char_device_struct *cd;
53};
54
55void *get_next_chrdev(void *dev)
56{
57 struct chrdev_info *info;
58
59 if (dev == NULL) {
60 info = kmalloc(sizeof(*info), GFP_KERNEL);
61 if (!info)
62 goto out;
63 info->index=0;
64 info->cd = chrdevs[info->index];
65 if (info->cd)
66 goto out;
67 } else {
68 info = dev;
69 }
70
71 while (info->index < ARRAY_SIZE(chrdevs)) {
72 if (info->cd)
73 info->cd = info->cd->next;
74 if (info->cd)
75 goto out;
76 /*
77 * No devices on this chain, move to the next
78 */
79 info->index++;
80 info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
81 chrdevs[info->index] : NULL;
82 if (info->cd)
83 goto out;
84 }
85
86out:
87 return info;
88}
89
90void *acquire_chrdev_list(void)
91{
92 mutex_lock(&chrdevs_lock);
93 return get_next_chrdev(NULL);
94}
95
96void release_chrdev_list(void *dev)
97{
98 mutex_unlock(&chrdevs_lock);
99 kfree(dev);
100} 47}
101 48
49#ifdef CONFIG_PROC_FS
102 50
103int count_chrdev_list(void) 51void chrdev_show(struct seq_file *f, off_t offset)
104{ 52{
105 struct char_device_struct *cd; 53 struct char_device_struct *cd;
106 int i, count;
107
108 count = 0;
109 54
110 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { 55 if (offset < CHRDEV_MAJOR_HASH_SIZE) {
111 for (cd = chrdevs[i]; cd; cd = cd->next) 56 mutex_lock(&chrdevs_lock);
112 count++; 57 for (cd = chrdevs[offset]; cd; cd = cd->next)
58 seq_printf(f, "%3d %s\n", cd->major, cd->name);
59 mutex_unlock(&chrdevs_lock);
113 } 60 }
114
115 return count;
116} 61}
117 62
118int get_chrdev_info(void *dev, int *major, char **name) 63#endif /* CONFIG_PROC_FS */
119{
120 struct chrdev_info *info = dev;
121
122 if (info->cd == NULL)
123 return 1;
124
125 *major = info->cd->major;
126 *name = info->cd->name;
127 return 0;
128}
129 64
130/* 65/*
131 * Register a single major with a specified minor range. 66 * Register a single major with a specified minor range.
diff --git a/fs/dcache.c b/fs/dcache.c
index 19458d399502..940d188e5d14 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1101,6 +1101,32 @@ next:
1101} 1101}
1102 1102
1103/** 1103/**
1104 * d_hash_and_lookup - hash the qstr then search for a dentry
1105 * @dir: Directory to search in
1106 * @name: qstr of name we wish to find
1107 *
1108 * On hash failure or on lookup failure NULL is returned.
1109 */
1110struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
1111{
1112 struct dentry *dentry = NULL;
1113
1114 /*
1115 * Check for a fs-specific hash function. Note that we must
1116 * calculate the standard hash first, as the d_op->d_hash()
1117 * routine may choose to leave the hash value unchanged.
1118 */
1119 name->hash = full_name_hash(name->name, name->len);
1120 if (dir->d_op && dir->d_op->d_hash) {
1121 if (dir->d_op->d_hash(dir, name) < 0)
1122 goto out;
1123 }
1124 dentry = d_lookup(dir, name);
1125out:
1126 return dentry;
1127}
1128
1129/**
1104 * d_validate - verify dentry provided from insecure source 1130 * d_validate - verify dentry provided from insecure source
1105 * @dentry: The dentry alleged to be valid child of @dparent 1131 * @dentry: The dentry alleged to be valid child of @dparent
1106 * @dparent: The parent dentry (known to be valid) 1132 * @dparent: The parent dentry (known to be valid)
@@ -1172,11 +1198,11 @@ void d_delete(struct dentry * dentry)
1172 spin_lock(&dentry->d_lock); 1198 spin_lock(&dentry->d_lock);
1173 isdir = S_ISDIR(dentry->d_inode->i_mode); 1199 isdir = S_ISDIR(dentry->d_inode->i_mode);
1174 if (atomic_read(&dentry->d_count) == 1) { 1200 if (atomic_read(&dentry->d_count) == 1) {
1175 /* remove this and other inotify debug checks after 2.6.18 */
1176 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1177
1178 dentry_iput(dentry); 1201 dentry_iput(dentry);
1179 fsnotify_nameremove(dentry, isdir); 1202 fsnotify_nameremove(dentry, isdir);
1203
1204 /* remove this and other inotify debug checks after 2.6.18 */
1205 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1180 return; 1206 return;
1181 } 1207 }
1182 1208
@@ -1616,26 +1642,12 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)
1616 struct dentry * dentry; 1642 struct dentry * dentry;
1617 ino_t ino = 0; 1643 ino_t ino = 0;
1618 1644
1619 /* 1645 dentry = d_hash_and_lookup(dir, name);
1620 * Check for a fs-specific hash function. Note that we must 1646 if (dentry) {
1621 * calculate the standard hash first, as the d_op->d_hash()
1622 * routine may choose to leave the hash value unchanged.
1623 */
1624 name->hash = full_name_hash(name->name, name->len);
1625 if (dir->d_op && dir->d_op->d_hash)
1626 {
1627 if (dir->d_op->d_hash(dir, name) != 0)
1628 goto out;
1629 }
1630
1631 dentry = d_lookup(dir, name);
1632 if (dentry)
1633 {
1634 if (dentry->d_inode) 1647 if (dentry->d_inode)
1635 ino = dentry->d_inode->i_ino; 1648 ino = dentry->d_inode->i_ino;
1636 dput(dentry); 1649 dput(dentry);
1637 } 1650 }
1638out:
1639 return ino; 1651 return ino;
1640} 1652}
1641 1653
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index 2ba20cdb5baa..5e6363be246f 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -216,10 +216,10 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
216static struct inode_operations hppfs_file_iops = { 216static struct inode_operations hppfs_file_iops = {
217}; 217};
218 218
219static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 219static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
220 loff_t *ppos, int is_user) 220 loff_t *ppos, int is_user)
221{ 221{
222 ssize_t (*read)(struct file *, char *, size_t, loff_t *); 222 ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
223 ssize_t n; 223 ssize_t n;
224 224
225 read = file->f_dentry->d_inode->i_fop->read; 225 read = file->f_dentry->d_inode->i_fop->read;
@@ -236,7 +236,7 @@ static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
236 return n; 236 return n;
237} 237}
238 238
239static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count) 239static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
240{ 240{
241 ssize_t n; 241 ssize_t n;
242 int cur, err; 242 int cur, err;
@@ -274,7 +274,7 @@ static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
274 return n; 274 return n;
275} 275}
276 276
277static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 277static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
278 loff_t *ppos) 278 loff_t *ppos)
279{ 279{
280 struct hppfs_private *hppfs = file->private_data; 280 struct hppfs_private *hppfs = file->private_data;
@@ -313,12 +313,12 @@ static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
313 return(count); 313 return(count);
314} 314}
315 315
316static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 316static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
317 loff_t *ppos) 317 loff_t *ppos)
318{ 318{
319 struct hppfs_private *data = file->private_data; 319 struct hppfs_private *data = file->private_data;
320 struct file *proc_file = data->proc_file; 320 struct file *proc_file = data->proc_file;
321 ssize_t (*write)(struct file *, const char *, size_t, loff_t *); 321 ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
322 int err; 322 int err;
323 323
324 write = proc_file->f_dentry->d_inode->i_fop->write; 324 write = proc_file->f_dentry->d_inode->i_fop->write;
@@ -658,7 +658,7 @@ static struct super_operations hppfs_sbops = {
658 .statfs = hppfs_statfs, 658 .statfs = hppfs_statfs,
659}; 659};
660 660
661static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen) 661static int hppfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
662{ 662{
663 struct file *proc_file; 663 struct file *proc_file;
664 struct dentry *proc_dentry; 664 struct dentry *proc_dentry;
diff --git a/fs/locks.c b/fs/locks.c
index 4d9e71d43e7e..dda83d6cd48b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -168,18 +168,9 @@ static void locks_release_private(struct file_lock *fl)
168/* Free a lock which is not in use. */ 168/* Free a lock which is not in use. */
169static void locks_free_lock(struct file_lock *fl) 169static void locks_free_lock(struct file_lock *fl)
170{ 170{
171 if (fl == NULL) { 171 BUG_ON(waitqueue_active(&fl->fl_wait));
172 BUG(); 172 BUG_ON(!list_empty(&fl->fl_block));
173 return; 173 BUG_ON(!list_empty(&fl->fl_link));
174 }
175 if (waitqueue_active(&fl->fl_wait))
176 panic("Attempting to free lock with active wait queue");
177
178 if (!list_empty(&fl->fl_block))
179 panic("Attempting to free lock with active block list");
180
181 if (!list_empty(&fl->fl_link))
182 panic("Attempting to free lock on active lock list");
183 174
184 locks_release_private(fl); 175 locks_release_private(fl);
185 kmem_cache_free(filelock_cache, fl); 176 kmem_cache_free(filelock_cache, fl);
@@ -735,8 +726,9 @@ EXPORT_SYMBOL(posix_locks_deadlock);
735 * at the head of the list, but that's secret knowledge known only to 726 * at the head of the list, but that's secret knowledge known only to
736 * flock_lock_file and posix_lock_file. 727 * flock_lock_file and posix_lock_file.
737 */ 728 */
738static int flock_lock_file(struct file *filp, struct file_lock *new_fl) 729static int flock_lock_file(struct file *filp, struct file_lock *request)
739{ 730{
731 struct file_lock *new_fl = NULL;
740 struct file_lock **before; 732 struct file_lock **before;
741 struct inode * inode = filp->f_dentry->d_inode; 733 struct inode * inode = filp->f_dentry->d_inode;
742 int error = 0; 734 int error = 0;
@@ -751,17 +743,19 @@ static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
751 continue; 743 continue;
752 if (filp != fl->fl_file) 744 if (filp != fl->fl_file)
753 continue; 745 continue;
754 if (new_fl->fl_type == fl->fl_type) 746 if (request->fl_type == fl->fl_type)
755 goto out; 747 goto out;
756 found = 1; 748 found = 1;
757 locks_delete_lock(before); 749 locks_delete_lock(before);
758 break; 750 break;
759 } 751 }
760 unlock_kernel();
761 752
762 if (new_fl->fl_type == F_UNLCK) 753 if (request->fl_type == F_UNLCK)
763 return 0; 754 goto out;
764 755
756 new_fl = locks_alloc_lock();
757 if (new_fl == NULL)
758 goto out;
765 /* 759 /*
766 * If a higher-priority process was blocked on the old file lock, 760 * If a higher-priority process was blocked on the old file lock,
767 * give it the opportunity to lock the file. 761 * give it the opportunity to lock the file.
@@ -769,26 +763,27 @@ static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
769 if (found) 763 if (found)
770 cond_resched(); 764 cond_resched();
771 765
772 lock_kernel();
773 for_each_lock(inode, before) { 766 for_each_lock(inode, before) {
774 struct file_lock *fl = *before; 767 struct file_lock *fl = *before;
775 if (IS_POSIX(fl)) 768 if (IS_POSIX(fl))
776 break; 769 break;
777 if (IS_LEASE(fl)) 770 if (IS_LEASE(fl))
778 continue; 771 continue;
779 if (!flock_locks_conflict(new_fl, fl)) 772 if (!flock_locks_conflict(request, fl))
780 continue; 773 continue;
781 error = -EAGAIN; 774 error = -EAGAIN;
782 if (new_fl->fl_flags & FL_SLEEP) { 775 if (request->fl_flags & FL_SLEEP)
783 locks_insert_block(fl, new_fl); 776 locks_insert_block(fl, request);
784 }
785 goto out; 777 goto out;
786 } 778 }
779 locks_copy_lock(new_fl, request);
787 locks_insert_lock(&inode->i_flock, new_fl); 780 locks_insert_lock(&inode->i_flock, new_fl);
788 error = 0; 781 new_fl = NULL;
789 782
790out: 783out:
791 unlock_kernel(); 784 unlock_kernel();
785 if (new_fl)
786 locks_free_lock(new_fl);
792 return error; 787 return error;
793} 788}
794 789
@@ -1569,9 +1564,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1569 error = flock_lock_file_wait(filp, lock); 1564 error = flock_lock_file_wait(filp, lock);
1570 1565
1571 out_free: 1566 out_free:
1572 if (list_empty(&lock->fl_link)) { 1567 locks_free_lock(lock);
1573 locks_free_lock(lock);
1574 }
1575 1568
1576 out_putf: 1569 out_putf:
1577 fput(filp); 1570 fput(filp);
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 626a367bcd81..5b76ccd19e3f 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -12,14 +12,6 @@
12#include <linux/msdos_fs.h> 12#include <linux/msdos_fs.h>
13#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
14 14
15/* MS-DOS "device special files" */
16static const unsigned char *reserved_names[] = {
17 "CON ", "PRN ", "NUL ", "AUX ",
18 "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ",
19 "COM1 ", "COM2 ", "COM3 ", "COM4 ",
20 NULL
21};
22
23/* Characters that are undesirable in an MS-DOS file name */ 15/* Characters that are undesirable in an MS-DOS file name */
24static unsigned char bad_chars[] = "*?<>|\""; 16static unsigned char bad_chars[] = "*?<>|\"";
25static unsigned char bad_if_strict_pc[] = "+=,; "; 17static unsigned char bad_if_strict_pc[] = "+=,; ";
@@ -40,7 +32,6 @@ static int msdos_format_name(const unsigned char *name, int len,
40 */ 32 */
41{ 33{
42 unsigned char *walk; 34 unsigned char *walk;
43 const unsigned char **reserved;
44 unsigned char c; 35 unsigned char c;
45 int space; 36 int space;
46 37
@@ -127,11 +118,7 @@ static int msdos_format_name(const unsigned char *name, int len,
127 } 118 }
128 while (walk - res < MSDOS_NAME) 119 while (walk - res < MSDOS_NAME)
129 *walk++ = ' '; 120 *walk++ = ' ';
130 if (!opts->atari) 121
131 /* GEMDOS is less stupid and has no reserved names */
132 for (reserved = reserved_names; *reserved; reserved++)
133 if (!strncmp(res, *reserved, 8))
134 return -EINVAL;
135 return 0; 122 return 0;
136} 123}
137 124
diff --git a/fs/namei.c b/fs/namei.c
index 22f6e8d16aa8..96723ae83c89 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1254,7 +1254,7 @@ out:
1254 return dentry; 1254 return dentry;
1255} 1255}
1256 1256
1257struct dentry * lookup_hash(struct nameidata *nd) 1257static struct dentry *lookup_hash(struct nameidata *nd)
1258{ 1258{
1259 return __lookup_hash(&nd->last, nd->dentry, nd); 1259 return __lookup_hash(&nd->last, nd->dentry, nd);
1260} 1260}
@@ -2697,7 +2697,6 @@ EXPORT_SYMBOL(follow_up);
2697EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2697EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
2698EXPORT_SYMBOL(getname); 2698EXPORT_SYMBOL(getname);
2699EXPORT_SYMBOL(lock_rename); 2699EXPORT_SYMBOL(lock_rename);
2700EXPORT_SYMBOL(lookup_hash);
2701EXPORT_SYMBOL(lookup_one_len); 2700EXPORT_SYMBOL(lookup_one_len);
2702EXPORT_SYMBOL(page_follow_link_light); 2701EXPORT_SYMBOL(page_follow_link_light);
2703EXPORT_SYMBOL(page_put_link); 2702EXPORT_SYMBOL(page_put_link);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8f1f49ceebec..a3a3eecef689 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -534,12 +534,15 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
534 534
535/* If the process being read is separated by chroot from the reading process, 535/* If the process being read is separated by chroot from the reading process,
536 * don't let the reader access the threads. 536 * don't let the reader access the threads.
537 *
538 * note: this does dput(root) and mntput(vfsmnt) on exit.
537 */ 539 */
538static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt) 540static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
539{ 541{
540 struct dentry *de, *base; 542 struct dentry *de, *base;
541 struct vfsmount *our_vfsmnt, *mnt; 543 struct vfsmount *our_vfsmnt, *mnt;
542 int res = 0; 544 int res = 0;
545
543 read_lock(&current->fs->lock); 546 read_lock(&current->fs->lock);
544 our_vfsmnt = mntget(current->fs->rootmnt); 547 our_vfsmnt = mntget(current->fs->rootmnt);
545 base = dget(current->fs->root); 548 base = dget(current->fs->root);
@@ -549,11 +552,11 @@ static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
549 de = root; 552 de = root;
550 mnt = vfsmnt; 553 mnt = vfsmnt;
551 554
552 while (vfsmnt != our_vfsmnt) { 555 while (mnt != our_vfsmnt) {
553 if (vfsmnt == vfsmnt->mnt_parent) 556 if (mnt == mnt->mnt_parent)
554 goto out; 557 goto out;
555 de = vfsmnt->mnt_mountpoint; 558 de = mnt->mnt_mountpoint;
556 vfsmnt = vfsmnt->mnt_parent; 559 mnt = mnt->mnt_parent;
557 } 560 }
558 561
559 if (!is_subdir(de, base)) 562 if (!is_subdir(de, base))
@@ -564,7 +567,7 @@ exit:
564 dput(base); 567 dput(base);
565 mntput(our_vfsmnt); 568 mntput(our_vfsmnt);
566 dput(root); 569 dput(root);
567 mntput(mnt); 570 mntput(vfsmnt);
568 return res; 571 return res;
569out: 572out:
570 spin_unlock(&vfsmount_lock); 573 spin_unlock(&vfsmount_lock);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index ef5a3323f4b5..5c10ea157425 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -249,144 +249,60 @@ static int cpuinfo_open(struct inode *inode, struct file *file)
249 return seq_open(file, &cpuinfo_op); 249 return seq_open(file, &cpuinfo_op);
250} 250}
251 251
252enum devinfo_states { 252static struct file_operations proc_cpuinfo_operations = {
253 CHR_HDR, 253 .open = cpuinfo_open,
254 CHR_LIST, 254 .read = seq_read,
255 BLK_HDR, 255 .llseek = seq_lseek,
256 BLK_LIST, 256 .release = seq_release,
257 DEVINFO_DONE
258};
259
260struct devinfo_state {
261 void *chrdev;
262 void *blkdev;
263 unsigned int num_records;
264 unsigned int cur_record;
265 enum devinfo_states state;
266}; 257};
267 258
268static void *devinfo_start(struct seq_file *f, loff_t *pos) 259static int devinfo_show(struct seq_file *f, void *v)
269{ 260{
270 struct devinfo_state *info = f->private; 261 int i = *(loff_t *) v;
271 262
272 if (*pos) { 263 if (i < CHRDEV_MAJOR_HASH_SIZE) {
273 if ((info) && (*pos <= info->num_records)) 264 if (i == 0)
274 return info; 265 seq_printf(f, "Character devices:\n");
275 return NULL; 266 chrdev_show(f, i);
267 } else {
268 i -= CHRDEV_MAJOR_HASH_SIZE;
269 if (i == 0)
270 seq_printf(f, "\nBlock devices:\n");
271 blkdev_show(f, i);
276 } 272 }
277 info = kmalloc(sizeof(*info), GFP_KERNEL); 273 return 0;
278 f->private = info;
279 info->chrdev = acquire_chrdev_list();
280 info->blkdev = acquire_blkdev_list();
281 info->state = CHR_HDR;
282 info->num_records = count_chrdev_list();
283 info->num_records += count_blkdev_list();
284 info->num_records += 2; /* Character and Block headers */
285 *pos = 1;
286 info->cur_record = *pos;
287 return info;
288} 274}
289 275
290static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) 276static void *devinfo_start(struct seq_file *f, loff_t *pos)
291{ 277{
292 int idummy; 278 if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
293 char *ndummy; 279 return pos;
294 struct devinfo_state *info = f->private; 280 return NULL;
295
296 switch (info->state) {
297 case CHR_HDR:
298 info->state = CHR_LIST;
299 (*pos)++;
300 /*fallthrough*/
301 case CHR_LIST:
302 if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
303 /*
304 * The character dev list is complete
305 */
306 info->state = BLK_HDR;
307 } else {
308 info->chrdev = get_next_chrdev(info->chrdev);
309 }
310 (*pos)++;
311 break;
312 case BLK_HDR:
313 info->state = BLK_LIST;
314 (*pos)++;
315 /*fallthrough*/
316 case BLK_LIST:
317 if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
318 /*
319 * The block dev list is complete
320 */
321 info->state = DEVINFO_DONE;
322 } else {
323 info->blkdev = get_next_blkdev(info->blkdev);
324 }
325 (*pos)++;
326 break;
327 case DEVINFO_DONE:
328 (*pos)++;
329 info->cur_record = *pos;
330 info = NULL;
331 break;
332 default:
333 break;
334 }
335 if (info)
336 info->cur_record = *pos;
337 return info;
338} 281}
339 282
340static void devinfo_stop(struct seq_file *f, void *v) 283static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
341{ 284{
342 struct devinfo_state *info = f->private; 285 (*pos)++;
343 286 if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
344 if (info) { 287 return NULL;
345 release_chrdev_list(info->chrdev); 288 return pos;
346 release_blkdev_list(info->blkdev);
347 f->private = NULL;
348 kfree(info);
349 }
350} 289}
351 290
352static int devinfo_show(struct seq_file *f, void *arg) 291static void devinfo_stop(struct seq_file *f, void *v)
353{ 292{
354 int major; 293 /* Nothing to do */
355 char *name;
356 struct devinfo_state *info = f->private;
357
358 switch(info->state) {
359 case CHR_HDR:
360 seq_printf(f,"Character devices:\n");
361 /* fallthrough */
362 case CHR_LIST:
363 if (!get_chrdev_info(info->chrdev,&major,&name))
364 seq_printf(f,"%3d %s\n",major,name);
365 break;
366 case BLK_HDR:
367 seq_printf(f,"\nBlock devices:\n");
368 /* fallthrough */
369 case BLK_LIST:
370 if (!get_blkdev_info(info->blkdev,&major,&name))
371 seq_printf(f,"%3d %s\n",major,name);
372 break;
373 default:
374 break;
375 }
376
377 return 0;
378} 294}
379 295
380static struct seq_operations devinfo_op = { 296static struct seq_operations devinfo_ops = {
381 .start = devinfo_start, 297 .start = devinfo_start,
382 .next = devinfo_next, 298 .next = devinfo_next,
383 .stop = devinfo_stop, 299 .stop = devinfo_stop,
384 .show = devinfo_show, 300 .show = devinfo_show
385}; 301};
386 302
387static int devinfo_open(struct inode *inode, struct file *file) 303static int devinfo_open(struct inode *inode, struct file *filp)
388{ 304{
389 return seq_open(file, &devinfo_op); 305 return seq_open(filp, &devinfo_ops);
390} 306}
391 307
392static struct file_operations proc_devinfo_operations = { 308static struct file_operations proc_devinfo_operations = {
@@ -396,13 +312,6 @@ static struct file_operations proc_devinfo_operations = {
396 .release = seq_release, 312 .release = seq_release,
397}; 313};
398 314
399static struct file_operations proc_cpuinfo_operations = {
400 .open = cpuinfo_open,
401 .read = seq_read,
402 .llseek = seq_lseek,
403 .release = seq_release,
404};
405
406extern struct seq_operations vmstat_op; 315extern struct seq_operations vmstat_op;
407static int vmstat_open(struct inode *inode, struct file *file) 316static int vmstat_open(struct inode *inode, struct file *file)
408{ 317{
diff --git a/fs/select.c b/fs/select.c
index b3a3a1326af6..071660fa7b01 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -314,7 +314,7 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
314 int ret, size, max_fdset; 314 int ret, size, max_fdset;
315 struct fdtable *fdt; 315 struct fdtable *fdt;
316 /* Allocate small arguments on the stack to save memory and be faster */ 316 /* Allocate small arguments on the stack to save memory and be faster */
317 char stack_fds[SELECT_STACK_ALLOC]; 317 long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
318 318
319 ret = -EINVAL; 319 ret = -EINVAL;
320 if (n < 0) 320 if (n < 0)
@@ -639,8 +639,10 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
639 struct poll_list *walk; 639 struct poll_list *walk;
640 struct fdtable *fdt; 640 struct fdtable *fdt;
641 int max_fdset; 641 int max_fdset;
642 /* Allocate small arguments on the stack to save memory and be faster */ 642 /* Allocate small arguments on the stack to save memory and be
643 char stack_pps[POLL_STACK_ALLOC]; 643 faster - use long to make sure the buffer is aligned properly
644 on 64 bit archs to avoid unaligned access */
645 long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
644 struct poll_list *stack_pp = NULL; 646 struct poll_list *stack_pp = NULL;
645 647
646 /* Do a sanity check on nfds ... */ 648 /* Do a sanity check on nfds ... */
diff --git a/fs/sync.c b/fs/sync.c
new file mode 100644
index 000000000000..8616006d2094
--- /dev/null
+++ b/fs/sync.c
@@ -0,0 +1,164 @@
1/*
2 * High-level sync()-related operations
3 */
4
5#include <linux/kernel.h>
6#include <linux/file.h>
7#include <linux/fs.h>
8#include <linux/module.h>
9#include <linux/writeback.h>
10#include <linux/syscalls.h>
11#include <linux/linkage.h>
12#include <linux/pagemap.h>
13
14#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
15 SYNC_FILE_RANGE_WAIT_AFTER)
16
17/*
18 * sys_sync_file_range() permits finely controlled syncing over a segment of
19 * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is
20 * zero then sys_sync_file_range() will operate from offset out to EOF.
21 *
22 * The flag bits are:
23 *
24 * SYNC_FILE_RANGE_WAIT_BEFORE: wait upon writeout of all pages in the range
25 * before performing the write.
26 *
27 * SYNC_FILE_RANGE_WRITE: initiate writeout of all those dirty pages in the
28 * range which are not presently under writeback.
29 *
30 * SYNC_FILE_RANGE_WAIT_AFTER: wait upon writeout of all pages in the range
31 * after performing the write.
32 *
33 * Useful combinations of the flag bits are:
34 *
35 * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE: ensures that all pages
36 * in the range which were dirty on entry to sys_sync_file_range() are placed
37 * under writeout. This is a start-write-for-data-integrity operation.
38 *
39 * SYNC_FILE_RANGE_WRITE: start writeout of all dirty pages in the range which
40 * are not presently under writeout. This is an asynchronous flush-to-disk
41 * operation. Not suitable for data integrity operations.
42 *
43 * SYNC_FILE_RANGE_WAIT_BEFORE (or SYNC_FILE_RANGE_WAIT_AFTER): wait for
44 * completion of writeout of all pages in the range. This will be used after an
45 * earlier SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE operation to wait
46 * for that operation to complete and to return the result.
47 *
48 * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER:
49 * a traditional sync() operation. This is a write-for-data-integrity operation
50 * which will ensure that all pages in the range which were dirty on entry to
51 * sys_sync_file_range() are committed to disk.
52 *
53 *
54 * SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any
55 * I/O errors or ENOSPC conditions and will return those to the caller, after
56 * clearing the EIO and ENOSPC flags in the address_space.
57 *
58 * It should be noted that none of these operations write out the file's
59 * metadata. So unless the application is strictly performing overwrites of
60 * already-instantiated disk blocks, there are no guarantees here that the data
61 * will be available after a crash.
62 */
63asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
64 int flags)
65{
66 int ret;
67 struct file *file;
68 loff_t endbyte; /* inclusive */
69 int fput_needed;
70 umode_t i_mode;
71
72 ret = -EINVAL;
73 if (flags & ~VALID_FLAGS)
74 goto out;
75
76 endbyte = offset + nbytes;
77
78 if ((s64)offset < 0)
79 goto out;
80 if ((s64)endbyte < 0)
81 goto out;
82 if (endbyte < offset)
83 goto out;
84
85 if (sizeof(pgoff_t) == 4) {
86 if (offset >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
87 /*
88 * The range starts outside a 32 bit machine's
89 * pagecache addressing capabilities. Let it "succeed"
90 */
91 ret = 0;
92 goto out;
93 }
94 if (endbyte >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
95 /*
96 * Out to EOF
97 */
98 nbytes = 0;
99 }
100 }
101
102 if (nbytes == 0)
103 endbyte = -1;
104 else
105 endbyte--; /* inclusive */
106
107 ret = -EBADF;
108 file = fget_light(fd, &fput_needed);
109 if (!file)
110 goto out;
111
112 i_mode = file->f_dentry->d_inode->i_mode;
113 ret = -ESPIPE;
114 if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
115 !S_ISLNK(i_mode))
116 goto out_put;
117
118 ret = do_sync_file_range(file, offset, endbyte, flags);
119out_put:
120 fput_light(file, fput_needed);
121out:
122 return ret;
123}
124
125/*
126 * `endbyte' is inclusive
127 */
128int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte,
129 int flags)
130{
131 int ret;
132 struct address_space *mapping;
133
134 mapping = file->f_mapping;
135 if (!mapping) {
136 ret = -EINVAL;
137 goto out;
138 }
139
140 ret = 0;
141 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
142 ret = wait_on_page_writeback_range(mapping,
143 offset >> PAGE_CACHE_SHIFT,
144 endbyte >> PAGE_CACHE_SHIFT);
145 if (ret < 0)
146 goto out;
147 }
148
149 if (flags & SYNC_FILE_RANGE_WRITE) {
150 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
151 WB_SYNC_NONE);
152 if (ret < 0)
153 goto out;
154 }
155
156 if (flags & SYNC_FILE_RANGE_WAIT_AFTER) {
157 ret = wait_on_page_writeback_range(mapping,
158 offset >> PAGE_CACHE_SHIFT,
159 endbyte >> PAGE_CACHE_SHIFT);
160 }
161out:
162 return ret;
163}
164EXPORT_SYMBOL_GPL(do_sync_file_range);
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index ef46939c0c1a..a56cec3be5f0 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -185,24 +185,6 @@ static int vfat_valid_longname(const unsigned char *name, unsigned int len)
185 return -EINVAL; 185 return -EINVAL;
186 if (len >= 256) 186 if (len >= 256)
187 return -ENAMETOOLONG; 187 return -ENAMETOOLONG;
188
189 /* MS-DOS "device special files" */
190 if (len == 3 || (len > 3 && name[3] == '.')) { /* basename == 3 */
191 if (!strnicmp(name, "aux", 3) ||
192 !strnicmp(name, "con", 3) ||
193 !strnicmp(name, "nul", 3) ||
194 !strnicmp(name, "prn", 3))
195 return -EINVAL;
196 }
197 if (len == 4 || (len > 4 && name[4] == '.')) { /* basename == 4 */
198 /* "com1", "com2", ... */
199 if ('1' <= name[3] && name[3] <= '9') {
200 if (!strnicmp(name, "com", 3) ||
201 !strnicmp(name, "lpt", 3))
202 return -EINVAL;
203 }
204 }
205
206 return 0; 188 return 0;
207} 189}
208 190
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
index 0b43495d24b4..94cb4982af82 100644
--- a/include/asm-arm/arch-pxa/sharpsl.h
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -27,6 +27,8 @@ struct corgits_machinfo {
27 */ 27 */
28struct corgibl_machinfo { 28struct corgibl_machinfo {
29 int max_intensity; 29 int max_intensity;
30 int default_intensity;
31 int limit_mask;
30 void (*set_bl_intensity)(int intensity); 32 void (*set_bl_intensity)(int intensity);
31}; 33};
32extern void corgibl_limit_intensity(int limit); 34extern void corgibl_limit_intensity(int limit);
diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h
index de4614840c2c..9291c24f5819 100644
--- a/include/asm-generic/local.h
+++ b/include/asm-generic/local.h
@@ -7,8 +7,15 @@
7#include <asm/atomic.h> 7#include <asm/atomic.h>
8#include <asm/types.h> 8#include <asm/types.h>
9 9
10/* An unsigned long type for operations which are atomic for a single 10/*
11 * CPU. Usually used in combination with per-cpu variables. */ 11 * A signed long type for operations which are atomic for a single CPU.
12 * Usually used in combination with per-cpu variables.
13 *
14 * This is the default implementation, which uses atomic_long_t. Which is
15 * rather pointless. The whole point behind local_t is that some processors
16 * can perform atomic adds and subtracts in a manner which is atomic wrt IRQs
17 * running on this CPU. local_t allows exploitation of such capabilities.
18 */
12 19
13/* Implement in terms of atomics. */ 20/* Implement in terms of atomics. */
14 21
@@ -20,7 +27,7 @@ typedef struct
20 27
21#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } 28#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
22 29
23#define local_read(l) ((unsigned long)atomic_long_read(&(l)->a)) 30#define local_read(l) atomic_long_read(&(l)->a)
24#define local_set(l,i) atomic_long_set((&(l)->a),(i)) 31#define local_set(l,i) atomic_long_set((&(l)->a),(i))
25#define local_inc(l) atomic_long_inc(&(l)->a) 32#define local_inc(l) atomic_long_inc(&(l)->a)
26#define local_dec(l) atomic_long_dec(&(l)->a) 33#define local_dec(l) atomic_long_dec(&(l)->a)
diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h
index 40c6d1f86598..29c6ac34e236 100644
--- a/include/asm-generic/mutex-dec.h
+++ b/include/asm-generic/mutex-dec.h
@@ -17,13 +17,14 @@
17 * it wasn't 1 originally. This function MUST leave the value lower than 17 * it wasn't 1 originally. This function MUST leave the value lower than
18 * 1 even when the "1" assertion wasn't true. 18 * 1 even when the "1" assertion wasn't true.
19 */ 19 */
20#define __mutex_fastpath_lock(count, fail_fn) \ 20static inline void
21do { \ 21__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
22 if (unlikely(atomic_dec_return(count) < 0)) \ 22{
23 fail_fn(count); \ 23 if (unlikely(atomic_dec_return(count) < 0))
24 else \ 24 fail_fn(count);
25 smp_mb(); \ 25 else
26} while (0) 26 smp_mb();
27}
27 28
28/** 29/**
29 * __mutex_fastpath_lock_retval - try to take the lock by moving the count 30 * __mutex_fastpath_lock_retval - try to take the lock by moving the count
@@ -36,7 +37,7 @@ do { \
36 * or anything the slow path function returns. 37 * or anything the slow path function returns.
37 */ 38 */
38static inline int 39static inline int
39__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) 40__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
40{ 41{
41 if (unlikely(atomic_dec_return(count) < 0)) 42 if (unlikely(atomic_dec_return(count) < 0))
42 return fail_fn(count); 43 return fail_fn(count);
@@ -59,12 +60,13 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
59 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs 60 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
60 * to return 0 otherwise. 61 * to return 0 otherwise.
61 */ 62 */
62#define __mutex_fastpath_unlock(count, fail_fn) \ 63static inline void
63do { \ 64__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
64 smp_mb(); \ 65{
65 if (unlikely(atomic_inc_return(count) <= 0)) \ 66 smp_mb();
66 fail_fn(count); \ 67 if (unlikely(atomic_inc_return(count) <= 0))
67} while (0) 68 fail_fn(count);
69}
68 70
69#define __mutex_slowpath_needs_to_unlock() 1 71#define __mutex_slowpath_needs_to_unlock() 1
70 72
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
index 1d24f47e6c48..32a2100c1aeb 100644
--- a/include/asm-generic/mutex-xchg.h
+++ b/include/asm-generic/mutex-xchg.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Generic implementation of the mutex fastpath, based on xchg(). 4 * Generic implementation of the mutex fastpath, based on xchg().
5 * 5 *
6 * NOTE: An xchg based implementation is less optimal than an atomic 6 * NOTE: An xchg based implementation might be less optimal than an atomic
7 * decrement/increment based implementation. If your architecture 7 * decrement/increment based implementation. If your architecture
8 * has a reasonable atomic dec/inc then you should probably use 8 * has a reasonable atomic dec/inc then you should probably use
9 * asm-generic/mutex-dec.h instead, or you could open-code an 9 * asm-generic/mutex-dec.h instead, or you could open-code an
@@ -22,14 +22,14 @@
22 * wasn't 1 originally. This function MUST leave the value lower than 1 22 * wasn't 1 originally. This function MUST leave the value lower than 1
23 * even when the "1" assertion wasn't true. 23 * even when the "1" assertion wasn't true.
24 */ 24 */
25#define __mutex_fastpath_lock(count, fail_fn) \ 25static inline void
26do { \ 26__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
27 if (unlikely(atomic_xchg(count, 0) != 1)) \ 27{
28 fail_fn(count); \ 28 if (unlikely(atomic_xchg(count, 0) != 1))
29 else \ 29 fail_fn(count);
30 smp_mb(); \ 30 else
31} while (0) 31 smp_mb();
32 32}
33 33
34/** 34/**
35 * __mutex_fastpath_lock_retval - try to take the lock by moving the count 35 * __mutex_fastpath_lock_retval - try to take the lock by moving the count
@@ -42,7 +42,7 @@ do { \
42 * or anything the slow path function returns 42 * or anything the slow path function returns
43 */ 43 */
44static inline int 44static inline int
45__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) 45__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
46{ 46{
47 if (unlikely(atomic_xchg(count, 0) != 1)) 47 if (unlikely(atomic_xchg(count, 0) != 1))
48 return fail_fn(count); 48 return fail_fn(count);
@@ -64,12 +64,13 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
64 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs 64 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
65 * to return 0 otherwise. 65 * to return 0 otherwise.
66 */ 66 */
67#define __mutex_fastpath_unlock(count, fail_fn) \ 67static inline void
68do { \ 68__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
69 smp_mb(); \ 69{
70 if (unlikely(atomic_xchg(count, 1) != 0)) \ 70 smp_mb();
71 fail_fn(count); \ 71 if (unlikely(atomic_xchg(count, 1) != 0))
72} while (0) 72 fail_fn(count);
73}
73 74
74#define __mutex_slowpath_needs_to_unlock() 0 75#define __mutex_slowpath_needs_to_unlock() 0
75 76
diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
index 03185cef8e0a..5e4a35af2921 100644
--- a/include/asm-i386/apicdef.h
+++ b/include/asm-i386/apicdef.h
@@ -37,6 +37,7 @@
37#define APIC_SPIV_FOCUS_DISABLED (1<<9) 37#define APIC_SPIV_FOCUS_DISABLED (1<<9)
38#define APIC_SPIV_APIC_ENABLED (1<<8) 38#define APIC_SPIV_APIC_ENABLED (1<<8)
39#define APIC_ISR 0x100 39#define APIC_ISR 0x100
40#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */
40#define APIC_TMR 0x180 41#define APIC_TMR 0x180
41#define APIC_IRR 0x200 42#define APIC_IRR 0x200
42#define APIC_ESR 0x280 43#define APIC_ESR 0x280
diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h
index 79727afb94c9..03403045c182 100644
--- a/include/asm-i386/floppy.h
+++ b/include/asm-i386/floppy.h
@@ -56,7 +56,6 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
56 register unsigned char st; 56 register unsigned char st;
57 57
58#undef TRACE_FLPY_INT 58#undef TRACE_FLPY_INT
59#define NO_FLOPPY_ASSEMBLER
60 59
61#ifdef TRACE_FLPY_INT 60#ifdef TRACE_FLPY_INT
62 static int calls=0; 61 static int calls=0;
@@ -71,38 +70,6 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
71 bytes = virtual_dma_count; 70 bytes = virtual_dma_count;
72#endif 71#endif
73 72
74#ifndef NO_FLOPPY_ASSEMBLER
75 __asm__ (
76 "testl %1,%1"
77 "je 3f"
78"1: inb %w4,%b0"
79 "andb $160,%b0"
80 "cmpb $160,%b0"
81 "jne 2f"
82 "incw %w4"
83 "testl %3,%3"
84 "jne 4f"
85 "inb %w4,%b0"
86 "movb %0,(%2)"
87 "jmp 5f"
88"4: movb (%2),%0"
89 "outb %b0,%w4"
90"5: decw %w4"
91 "outb %0,$0x80"
92 "decl %1"
93 "incl %2"
94 "testl %1,%1"
95 "jne 1b"
96"3: inb %w4,%b0"
97"2: "
98 : "=a" ((char) st),
99 "=c" ((long) virtual_dma_count),
100 "=S" ((long) virtual_dma_addr)
101 : "b" ((long) virtual_dma_mode),
102 "d" ((short) virtual_dma_port+4),
103 "1" ((long) virtual_dma_count),
104 "2" ((long) virtual_dma_addr));
105#else
106 { 73 {
107 register int lcount; 74 register int lcount;
108 register char *lptr; 75 register char *lptr;
@@ -122,7 +89,6 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
122 virtual_dma_addr = lptr; 89 virtual_dma_addr = lptr;
123 st = inb(virtual_dma_port+4); 90 st = inb(virtual_dma_port+4);
124 } 91 }
125#endif
126 92
127#ifdef TRACE_FLPY_INT 93#ifdef TRACE_FLPY_INT
128 calls++; 94 calls++;
diff --git a/include/asm-i386/local.h b/include/asm-i386/local.h
index 0177da80dde3..e67fa08260fe 100644
--- a/include/asm-i386/local.h
+++ b/include/asm-i386/local.h
@@ -5,7 +5,7 @@
5 5
6typedef struct 6typedef struct
7{ 7{
8 volatile unsigned long counter; 8 volatile long counter;
9} local_t; 9} local_t;
10 10
11#define LOCAL_INIT(i) { (i) } 11#define LOCAL_INIT(i) { (i) }
@@ -29,7 +29,7 @@ static __inline__ void local_dec(local_t *v)
29 :"m" (v->counter)); 29 :"m" (v->counter));
30} 30}
31 31
32static __inline__ void local_add(unsigned long i, local_t *v) 32static __inline__ void local_add(long i, local_t *v)
33{ 33{
34 __asm__ __volatile__( 34 __asm__ __volatile__(
35 "addl %1,%0" 35 "addl %1,%0"
@@ -37,7 +37,7 @@ static __inline__ void local_add(unsigned long i, local_t *v)
37 :"ir" (i), "m" (v->counter)); 37 :"ir" (i), "m" (v->counter));
38} 38}
39 39
40static __inline__ void local_sub(unsigned long i, local_t *v) 40static __inline__ void local_sub(long i, local_t *v)
41{ 41{
42 __asm__ __volatile__( 42 __asm__ __volatile__(
43 "subl %1,%0" 43 "subl %1,%0"
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 789e9bdd0a40..2e7f3e257fdd 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -319,8 +319,9 @@
319#define __NR_set_robust_list 311 319#define __NR_set_robust_list 311
320#define __NR_get_robust_list 312 320#define __NR_get_robust_list 312
321#define __NR_sys_splice 313 321#define __NR_sys_splice 313
322#define __NR_sys_sync_file_range 314
322 323
323#define NR_syscalls 314 324#define NR_syscalls 315
324 325
325/* 326/*
326 * user-visible error numbers are in the range -1 - -128: see 327 * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 65f5a7b2646b..d075725bf444 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -365,8 +365,11 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
365 * powers of 2 writes until it reaches sufficient alignment). 365 * powers of 2 writes until it reaches sufficient alignment).
366 * 366 *
367 * Based on this we disable the IP header alignment in network drivers. 367 * Based on this we disable the IP header alignment in network drivers.
368 * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining
369 * cacheline alignment of buffers.
368 */ 370 */
369#define NET_IP_ALIGN 0 371#define NET_IP_ALIGN 0
372#define NET_SKB_PAD L1_CACHE_BYTES
370#endif 373#endif
371 374
372#define arch_align_stack(x) (x) 375#define arch_align_stack(x) (x)
diff --git a/include/asm-s390/percpu.h b/include/asm-s390/percpu.h
index e10ed87094f0..436d216601e5 100644
--- a/include/asm-s390/percpu.h
+++ b/include/asm-s390/percpu.h
@@ -46,7 +46,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
46#define percpu_modcopy(pcpudst, src, size) \ 46#define percpu_modcopy(pcpudst, src, size) \
47do { \ 47do { \
48 unsigned int __i; \ 48 unsigned int __i; \
49 for_each_cpu(__i) \ 49 for_each_possible_cpu(__i) \
50 memcpy((pcpudst)+__per_cpu_offset[__i], \ 50 memcpy((pcpudst)+__per_cpu_offset[__i], \
51 (src), (size)); \ 51 (src), (size)); \
52} while (0) 52} while (0)
diff --git a/include/asm-um/desc.h b/include/asm-um/desc.h
index ac1d2a20d178..4ec34a51b62c 100644
--- a/include/asm-um/desc.h
+++ b/include/asm-um/desc.h
@@ -1,6 +1,16 @@
1#ifndef __UM_DESC_H 1#ifndef __UM_DESC_H
2#define __UM_DESC_H 2#define __UM_DESC_H
3 3
4#include "asm/arch/desc.h" 4/* Taken from asm-i386/desc.h, it's the only thing we need. The rest wouldn't
5 * compile, and has never been used. */
6#define LDT_empty(info) (\
7 (info)->base_addr == 0 && \
8 (info)->limit == 0 && \
9 (info)->contents == 0 && \
10 (info)->read_exec_only == 1 && \
11 (info)->seg_32bit == 0 && \
12 (info)->limit_in_pages == 0 && \
13 (info)->seg_not_present == 1 && \
14 (info)->useable == 0 )
5 15
6#endif 16#endif
diff --git a/include/asm-um/host_ldt-i386.h b/include/asm-um/host_ldt-i386.h
new file mode 100644
index 000000000000..b27cb0a9dd30
--- /dev/null
+++ b/include/asm-um/host_ldt-i386.h
@@ -0,0 +1,34 @@
1#ifndef __ASM_HOST_LDT_I386_H
2#define __ASM_HOST_LDT_I386_H
3
4#include "asm/arch/ldt.h"
5
6/*
7 * macros stolen from include/asm-i386/desc.h
8 */
9#define LDT_entry_a(info) \
10 ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
11
12#define LDT_entry_b(info) \
13 (((info)->base_addr & 0xff000000) | \
14 (((info)->base_addr & 0x00ff0000) >> 16) | \
15 ((info)->limit & 0xf0000) | \
16 (((info)->read_exec_only ^ 1) << 9) | \
17 ((info)->contents << 10) | \
18 (((info)->seg_not_present ^ 1) << 15) | \
19 ((info)->seg_32bit << 22) | \
20 ((info)->limit_in_pages << 23) | \
21 ((info)->useable << 20) | \
22 0x7000)
23
24#define LDT_empty(info) (\
25 (info)->base_addr == 0 && \
26 (info)->limit == 0 && \
27 (info)->contents == 0 && \
28 (info)->read_exec_only == 1 && \
29 (info)->seg_32bit == 0 && \
30 (info)->limit_in_pages == 0 && \
31 (info)->seg_not_present == 1 && \
32 (info)->useable == 0 )
33
34#endif
diff --git a/include/asm-um/ldt-x86_64.h b/include/asm-um/host_ldt-x86_64.h
index 96b35aada79a..74a63f7d9a90 100644
--- a/include/asm-um/ldt-x86_64.h
+++ b/include/asm-um/host_ldt-x86_64.h
@@ -1,43 +1,8 @@
1/* 1#ifndef __ASM_HOST_LDT_X86_64_H
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH 2#define __ASM_HOST_LDT_X86_64_H
3 * Licensed under the GPL
4 *
5 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
6 */
7 3
8#ifndef __ASM_LDT_X86_64_H
9#define __ASM_LDT_X86_64_H
10
11#include "asm/semaphore.h"
12#include "asm/arch/ldt.h" 4#include "asm/arch/ldt.h"
13 5
14struct mmu_context_skas;
15extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19
20#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
22#define LDT_ENTRIES_PER_PAGE \
23 (PAGE_SIZE/LDT_ENTRY_SIZE)
24#define LDT_DIRECT_ENTRIES \
25 ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
26
27struct ldt_entry {
28 __u32 a;
29 __u32 b;
30};
31
32typedef struct uml_ldt {
33 int entry_count;
34 struct semaphore semaphore;
35 union {
36 struct ldt_entry * pages[LDT_PAGES_MAX];
37 struct ldt_entry entries[LDT_DIRECT_ENTRIES];
38 } u;
39} uml_ldt_t;
40
41/* 6/*
42 * macros stolen from include/asm-x86_64/desc.h 7 * macros stolen from include/asm-x86_64/desc.h
43 */ 8 */
diff --git a/include/asm-um/ldt-i386.h b/include/asm-um/ldt-i386.h
deleted file mode 100644
index 175722a91164..000000000000
--- a/include/asm-um/ldt-i386.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Licensed under the GPL
4 *
5 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
6 */
7
8#ifndef __ASM_LDT_I386_H
9#define __ASM_LDT_I386_H
10
11#include "asm/semaphore.h"
12#include "asm/arch/ldt.h"
13
14struct mmu_context_skas;
15extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19
20#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
22#define LDT_ENTRIES_PER_PAGE \
23 (PAGE_SIZE/LDT_ENTRY_SIZE)
24#define LDT_DIRECT_ENTRIES \
25 ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
26
27struct ldt_entry {
28 __u32 a;
29 __u32 b;
30};
31
32typedef struct uml_ldt {
33 int entry_count;
34 struct semaphore semaphore;
35 union {
36 struct ldt_entry * pages[LDT_PAGES_MAX];
37 struct ldt_entry entries[LDT_DIRECT_ENTRIES];
38 } u;
39} uml_ldt_t;
40
41/*
42 * macros stolen from include/asm-i386/desc.h
43 */
44#define LDT_entry_a(info) \
45 ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
46
47#define LDT_entry_b(info) \
48 (((info)->base_addr & 0xff000000) | \
49 (((info)->base_addr & 0x00ff0000) >> 16) | \
50 ((info)->limit & 0xf0000) | \
51 (((info)->read_exec_only ^ 1) << 9) | \
52 ((info)->contents << 10) | \
53 (((info)->seg_not_present ^ 1) << 15) | \
54 ((info)->seg_32bit << 22) | \
55 ((info)->limit_in_pages << 23) | \
56 ((info)->useable << 20) | \
57 0x7000)
58
59#define LDT_empty(info) (\
60 (info)->base_addr == 0 && \
61 (info)->limit == 0 && \
62 (info)->contents == 0 && \
63 (info)->read_exec_only == 1 && \
64 (info)->seg_32bit == 0 && \
65 (info)->limit_in_pages == 0 && \
66 (info)->seg_not_present == 1 && \
67 (info)->useable == 0 )
68
69#endif
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
new file mode 100644
index 000000000000..96f82a456ce6
--- /dev/null
+++ b/include/asm-um/ldt.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Licensed under the GPL
4 *
5 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
6 */
7
8#ifndef __ASM_LDT_H
9#define __ASM_LDT_H
10
11#include "asm/semaphore.h"
12#include "asm/host_ldt.h"
13
14struct mmu_context_skas;
15extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19
20#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
22#define LDT_ENTRIES_PER_PAGE \
23 (PAGE_SIZE/LDT_ENTRY_SIZE)
24#define LDT_DIRECT_ENTRIES \
25 ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
26
27struct ldt_entry {
28 __u32 a;
29 __u32 b;
30};
31
32typedef struct uml_ldt {
33 int entry_count;
34 struct semaphore semaphore;
35 union {
36 struct ldt_entry * pages[LDT_PAGES_MAX];
37 struct ldt_entry entries[LDT_DIRECT_ENTRIES];
38 } u;
39} uml_ldt_t;
40
41#endif
diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
index 4108a579eb92..595f1c3e1e40 100644
--- a/include/asm-um/processor-i386.h
+++ b/include/asm-um/processor-i386.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -6,21 +6,48 @@
6#ifndef __UM_PROCESSOR_I386_H 6#ifndef __UM_PROCESSOR_I386_H
7#define __UM_PROCESSOR_I386_H 7#define __UM_PROCESSOR_I386_H
8 8
9#include "linux/string.h"
10#include "asm/host_ldt.h"
11#include "asm/segment.h"
12
9extern int host_has_xmm; 13extern int host_has_xmm;
10extern int host_has_cmov; 14extern int host_has_cmov;
11 15
12/* include faultinfo structure */ 16/* include faultinfo structure */
13#include "sysdep/faultinfo.h" 17#include "sysdep/faultinfo.h"
14 18
19struct uml_tls_struct {
20 struct user_desc tls;
21 unsigned flushed:1;
22 unsigned present:1;
23};
24
15struct arch_thread { 25struct arch_thread {
26 struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
16 unsigned long debugregs[8]; 27 unsigned long debugregs[8];
17 int debugregs_seq; 28 int debugregs_seq;
18 struct faultinfo faultinfo; 29 struct faultinfo faultinfo;
19}; 30};
20 31
21#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ 32#define INIT_ARCH_THREAD { \
22 .debugregs_seq = 0, \ 33 .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \
23 .faultinfo = { 0, 0, 0 } } 34 { .present = 0, .flushed = 0 } }, \
35 .debugregs = { [ 0 ... 7 ] = 0 }, \
36 .debugregs_seq = 0, \
37 .faultinfo = { 0, 0, 0 } \
38}
39
40static inline void arch_flush_thread(struct arch_thread *thread)
41{
42 /* Clear any TLS still hanging */
43 memset(&thread->tls_array, 0, sizeof(thread->tls_array));
44}
45
46static inline void arch_copy_thread(struct arch_thread *from,
47 struct arch_thread *to)
48{
49 memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array));
50}
24 51
25#include "asm/arch/user.h" 52#include "asm/arch/user.h"
26 53
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index e1e1255a1d36..10609af376c0 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -28,6 +28,15 @@ extern inline void rep_nop(void)
28 .debugregs_seq = 0, \ 28 .debugregs_seq = 0, \
29 .faultinfo = { 0, 0, 0 } } 29 .faultinfo = { 0, 0, 0 } }
30 30
31static inline void arch_flush_thread(struct arch_thread *thread)
32{
33}
34
35static inline void arch_copy_thread(struct arch_thread *from,
36 struct arch_thread *to)
37{
38}
39
31#include "asm/arch/user.h" 40#include "asm/arch/user.h"
32 41
33#define current_text_addr() \ 42#define current_text_addr() \
diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
index 46599ac44037..503484305e67 100644
--- a/include/asm-um/ptrace-generic.h
+++ b/include/asm-um/ptrace-generic.h
@@ -28,7 +28,7 @@ struct pt_regs {
28 union uml_pt_regs regs; 28 union uml_pt_regs regs;
29}; 29};
30 30
31#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS } 31#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
32 32
33#define PT_REGS_IP(r) UPT_IP(&(r)->regs) 33#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
34#define PT_REGS_SP(r) UPT_SP(&(r)->regs) 34#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
@@ -60,17 +60,9 @@ extern void show_regs(struct pt_regs *regs);
60extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs, 60extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
61 int error_code); 61 int error_code);
62 62
63#endif 63extern int arch_copy_tls(struct task_struct *new);
64extern void clear_flushed_tls(struct task_struct *task);
64 65
65#endif 66#endif
66 67
67/* 68#endif
68 * Overrides for Emacs so that we follow Linus's tabbing style.
69 * Emacs will notice this stuff at the end of the file and automatically
70 * adjust the settings for this buffer only. This must remain at the end
71 * of the file.
72 * ---------------------------------------------------------------------------
73 * Local variables:
74 * c-file-style: "linux"
75 * End:
76 */
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index fe882b9d917e..30656c962d74 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -8,8 +8,11 @@
8 8
9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
10 10
11#include "linux/compiler.h"
11#include "sysdep/ptrace.h" 12#include "sysdep/ptrace.h"
12#include "asm/ptrace-generic.h" 13#include "asm/ptrace-generic.h"
14#include "asm/host_ldt.h"
15#include "choose-mode.h"
13 16
14#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) 17#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
15#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) 18#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
@@ -38,15 +41,31 @@
38 41
39#define user_mode(r) UPT_IS_USER(&(r)->regs) 42#define user_mode(r) UPT_IS_USER(&(r)->regs)
40 43
41#endif 44extern int ptrace_get_thread_area(struct task_struct *child, int idx,
45 struct user_desc __user *user_desc);
42 46
43/* 47extern int ptrace_set_thread_area(struct task_struct *child, int idx,
44 * Overrides for Emacs so that we follow Linus's tabbing style. 48 struct user_desc __user *user_desc);
45 * Emacs will notice this stuff at the end of the file and automatically 49
46 * adjust the settings for this buffer only. This must remain at the end 50extern int do_set_thread_area_skas(struct user_desc *info);
47 * of the file. 51extern int do_get_thread_area_skas(struct user_desc *info);
48 * --------------------------------------------------------------------------- 52
49 * Local variables: 53extern int do_set_thread_area_tt(struct user_desc *info);
50 * c-file-style: "linux" 54extern int do_get_thread_area_tt(struct user_desc *info);
51 * End: 55
52 */ 56extern int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to);
57extern int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to);
58
59static inline int do_get_thread_area(struct user_desc *info)
60{
61 return CHOOSE_MODE_PROC(do_get_thread_area_tt, do_get_thread_area_skas, info);
62}
63
64static inline int do_set_thread_area(struct user_desc *info)
65{
66 return CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, info);
67}
68
69struct task_struct;
70
71#endif
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index be51219a8ffe..c894e68b1f96 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -8,6 +8,8 @@
8#define __UM_PTRACE_X86_64_H 8#define __UM_PTRACE_X86_64_H
9 9
10#include "linux/compiler.h" 10#include "linux/compiler.h"
11#include "asm/errno.h"
12#include "asm/host_ldt.h"
11 13
12#define signal_fault signal_fault_x86_64 14#define signal_fault signal_fault_x86_64
13#define __FRAME_OFFSETS /* Needed to get the R* macros */ 15#define __FRAME_OFFSETS /* Needed to get the R* macros */
@@ -63,15 +65,26 @@ void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
63 65
64#define profile_pc(regs) PT_REGS_IP(regs) 66#define profile_pc(regs) PT_REGS_IP(regs)
65 67
66#endif 68static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
69 struct user_desc __user *user_desc)
70{
71 return -ENOSYS;
72}
67 73
68/* 74static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
69 * Overrides for Emacs so that we follow Linus's tabbing style. 75 struct user_desc __user *user_desc)
70 * Emacs will notice this stuff at the end of the file and automatically 76{
71 * adjust the settings for this buffer only. This must remain at the end 77 return -ENOSYS;
72 * of the file. 78}
73 * --------------------------------------------------------------------------- 79
74 * Local variables: 80static inline void arch_switch_to_tt(struct task_struct *from,
75 * c-file-style: "linux" 81 struct task_struct *to)
76 * End: 82{
77 */ 83}
84
85static inline void arch_switch_to_skas(struct task_struct *from,
86 struct task_struct *to)
87{
88}
89
90#endif
diff --git a/include/asm-um/segment.h b/include/asm-um/segment.h
index 55e40301f625..45183fcd10b6 100644
--- a/include/asm-um/segment.h
+++ b/include/asm-um/segment.h
@@ -1,4 +1,10 @@
1#ifndef __UM_SEGMENT_H 1#ifndef __UM_SEGMENT_H
2#define __UM_SEGMENT_H 2#define __UM_SEGMENT_H
3 3
4extern int host_gdt_entry_tls_min;
5
6#define GDT_ENTRY_TLS_ENTRIES 3
7#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min
8#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
9
4#endif 10#endif
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index 17b6b07c4332..f166b9837c6a 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -27,14 +27,14 @@ struct thread_info {
27 27
28#define INIT_THREAD_INFO(tsk) \ 28#define INIT_THREAD_INFO(tsk) \
29{ \ 29{ \
30 task: &tsk, \ 30 .task = &tsk, \
31 exec_domain: &default_exec_domain, \ 31 .exec_domain = &default_exec_domain, \
32 flags: 0, \ 32 .flags = 0, \
33 cpu: 0, \ 33 .cpu = 0, \
34 preempt_count: 1, \ 34 .preempt_count = 1, \
35 addr_limit: KERNEL_DS, \ 35 .addr_limit = KERNEL_DS, \
36 restart_block: { \ 36 .restart_block = { \
37 fn: do_no_restart_syscall, \ 37 .fn = do_no_restart_syscall, \
38 }, \ 38 }, \
39} 39}
40 40
diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
index 4e460d6f5ac8..bea5a015f667 100644
--- a/include/asm-um/uaccess.h
+++ b/include/asm-um/uaccess.h
@@ -57,7 +57,7 @@
57({ \ 57({ \
58 const __typeof__((*(ptr))) __user *private_ptr = (ptr); \ 58 const __typeof__((*(ptr))) __user *private_ptr = (ptr); \
59 (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \ 59 (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
60 __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \ 60 __get_user(x, private_ptr) : ((x) = (__typeof__(*ptr))0, -EFAULT)); \
61}) 61})
62 62
63#define __put_user(x, ptr) \ 63#define __put_user(x, ptr) \
diff --git a/include/asm-x86_64/local.h b/include/asm-x86_64/local.h
index bf148037d4e5..cd17945bf218 100644
--- a/include/asm-x86_64/local.h
+++ b/include/asm-x86_64/local.h
@@ -5,7 +5,7 @@
5 5
6typedef struct 6typedef struct
7{ 7{
8 volatile unsigned long counter; 8 volatile long counter;
9} local_t; 9} local_t;
10 10
11#define LOCAL_INIT(i) { (i) } 11#define LOCAL_INIT(i) { (i) }
@@ -13,7 +13,7 @@ typedef struct
13#define local_read(v) ((v)->counter) 13#define local_read(v) ((v)->counter)
14#define local_set(v,i) (((v)->counter) = (i)) 14#define local_set(v,i) (((v)->counter) = (i))
15 15
16static __inline__ void local_inc(local_t *v) 16static inline void local_inc(local_t *v)
17{ 17{
18 __asm__ __volatile__( 18 __asm__ __volatile__(
19 "incq %0" 19 "incq %0"
@@ -21,7 +21,7 @@ static __inline__ void local_inc(local_t *v)
21 :"m" (v->counter)); 21 :"m" (v->counter));
22} 22}
23 23
24static __inline__ void local_dec(local_t *v) 24static inline void local_dec(local_t *v)
25{ 25{
26 __asm__ __volatile__( 26 __asm__ __volatile__(
27 "decq %0" 27 "decq %0"
@@ -29,7 +29,7 @@ static __inline__ void local_dec(local_t *v)
29 :"m" (v->counter)); 29 :"m" (v->counter));
30} 30}
31 31
32static __inline__ void local_add(unsigned int i, local_t *v) 32static inline void local_add(long i, local_t *v)
33{ 33{
34 __asm__ __volatile__( 34 __asm__ __volatile__(
35 "addq %1,%0" 35 "addq %1,%0"
@@ -37,7 +37,7 @@ static __inline__ void local_add(unsigned int i, local_t *v)
37 :"ir" (i), "m" (v->counter)); 37 :"ir" (i), "m" (v->counter));
38} 38}
39 39
40static __inline__ void local_sub(unsigned int i, local_t *v) 40static inline void local_sub(long i, local_t *v)
41{ 41{
42 __asm__ __volatile__( 42 __asm__ __volatile__(
43 "subq %1,%0" 43 "subq %1,%0"
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index bb9e54322322..75e91f5b6a04 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -19,20 +19,25 @@ struct fb_info;
19struct backlight_properties { 19struct backlight_properties {
20 /* Owner module */ 20 /* Owner module */
21 struct module *owner; 21 struct module *owner;
22 /* Get the backlight power status (0: full on, 1..3: power saving 22
23 modes; 4: full off), see FB_BLANK_XXX */ 23 /* Notify the backlight driver some property has changed */
24 int (*get_power)(struct backlight_device *); 24 int (*update_status)(struct backlight_device *);
25 /* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */ 25 /* Return the current backlight brightness (accounting for power,
26 int (*set_power)(struct backlight_device *, int power); 26 fb_blank etc.) */
27 /* Maximal value for brightness (read-only) */
28 int max_brightness;
29 /* Get current backlight brightness */
30 int (*get_brightness)(struct backlight_device *); 27 int (*get_brightness)(struct backlight_device *);
31 /* Set backlight brightness (0..max_brightness) */
32 int (*set_brightness)(struct backlight_device *, int brightness);
33 /* Check if given framebuffer device is the one bound to this backlight; 28 /* Check if given framebuffer device is the one bound to this backlight;
34 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ 29 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
35 int (*check_fb)(struct fb_info *); 30 int (*check_fb)(struct fb_info *);
31
32 /* Current User requested brightness (0 - max_brightness) */
33 int brightness;
34 /* Maximal value for brightness (read-only) */
35 int max_brightness;
36 /* Current FB Power mode (0: full on, 1..3: power saving
37 modes; 4: full off), see FB_BLANK_XXX */
38 int power;
39 /* FB Blanking active? (values as for power) */
40 int fb_blank;
36}; 41};
37 42
38struct backlight_device { 43struct backlight_device {
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index d10bd30c337e..836325ee0931 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -275,6 +275,7 @@ extern void d_move(struct dentry *, struct dentry *);
275/* appendix may either be NULL or be used for transname suffixes */ 275/* appendix may either be NULL or be used for transname suffixes */
276extern struct dentry * d_lookup(struct dentry *, struct qstr *); 276extern struct dentry * d_lookup(struct dentry *, struct qstr *);
277extern struct dentry * __d_lookup(struct dentry *, struct qstr *); 277extern struct dentry * __d_lookup(struct dentry *, struct qstr *);
278extern struct dentry * d_hash_and_lookup(struct dentry *, struct qstr *);
278 279
279/* validate "insecure" dentry pointer */ 280/* validate "insecure" dentry pointer */
280extern int d_validate(struct dentry *, struct dentry *); 281extern int d_validate(struct dentry *, struct dentry *);
diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h
index b2913bba35d8..e8e747139b9a 100644
--- a/include/linux/fadvise.h
+++ b/include/linux/fadvise.h
@@ -18,10 +18,4 @@
18#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ 18#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
19#endif 19#endif
20 20
21/*
22 * Linux-specific fadvise() extensions:
23 */
24#define LINUX_FADV_ASYNC_WRITE 32 /* Start writeout on range */
25#define LINUX_FADV_WRITE_WAIT 33 /* Wait upon writeout to range */
26
27#endif /* FADVISE_H_INCLUDED */ 21#endif /* FADVISE_H_INCLUDED */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d03fadfcafe3..315d89740ddf 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -839,12 +839,10 @@ struct fb_info {
839#define FB_LEFT_POS(bpp) (32 - bpp) 839#define FB_LEFT_POS(bpp) (32 - bpp)
840#define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) 840#define FB_SHIFT_HIGH(val, bits) ((val) >> (bits))
841#define FB_SHIFT_LOW(val, bits) ((val) << (bits)) 841#define FB_SHIFT_LOW(val, bits) ((val) << (bits))
842#define FB_BIT_NR(b) (7 - (b))
843#else 842#else
844#define FB_LEFT_POS(bpp) (0) 843#define FB_LEFT_POS(bpp) (0)
845#define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) 844#define FB_SHIFT_HIGH(val, bits) ((val) << (bits))
846#define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) 845#define FB_SHIFT_LOW(val, bits) ((val) >> (bits))
847#define FB_BIT_NR(b) (b)
848#endif 846#endif
849 847
850 /* 848 /*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 20fa5f6d7269..4ed7e602d703 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -757,6 +757,13 @@ extern void send_sigio(struct fown_struct *fown, int fd, int band);
757extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); 757extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
758extern int fcntl_getlease(struct file *filp); 758extern int fcntl_getlease(struct file *filp);
759 759
760/* fs/sync.c */
761#define SYNC_FILE_RANGE_WAIT_BEFORE 1
762#define SYNC_FILE_RANGE_WRITE 2
763#define SYNC_FILE_RANGE_WAIT_AFTER 4
764extern int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte,
765 int flags);
766
760/* fs/locks.c */ 767/* fs/locks.c */
761extern void locks_init_lock(struct file_lock *); 768extern void locks_init_lock(struct file_lock *);
762extern void locks_copy_lock(struct file_lock *, struct file_lock *); 769extern void locks_copy_lock(struct file_lock *, struct file_lock *);
@@ -1413,6 +1420,7 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *);
1413#endif 1420#endif
1414 1421
1415/* fs/char_dev.c */ 1422/* fs/char_dev.c */
1423#define CHRDEV_MAJOR_HASH_SIZE 255
1416extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); 1424extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
1417extern int register_chrdev_region(dev_t, unsigned, const char *); 1425extern int register_chrdev_region(dev_t, unsigned, const char *);
1418extern int register_chrdev(unsigned int, const char *, 1426extern int register_chrdev(unsigned int, const char *,
@@ -1420,25 +1428,17 @@ extern int register_chrdev(unsigned int, const char *,
1420extern int unregister_chrdev(unsigned int, const char *); 1428extern int unregister_chrdev(unsigned int, const char *);
1421extern void unregister_chrdev_region(dev_t, unsigned); 1429extern void unregister_chrdev_region(dev_t, unsigned);
1422extern int chrdev_open(struct inode *, struct file *); 1430extern int chrdev_open(struct inode *, struct file *);
1423extern int get_chrdev_list(char *); 1431extern void chrdev_show(struct seq_file *,off_t);
1424extern void *acquire_chrdev_list(void);
1425extern int count_chrdev_list(void);
1426extern void *get_next_chrdev(void *);
1427extern int get_chrdev_info(void *, int *, char **);
1428extern void release_chrdev_list(void *);
1429 1432
1430/* fs/block_dev.c */ 1433/* fs/block_dev.c */
1434#define BLKDEV_MAJOR_HASH_SIZE 255
1431#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ 1435#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
1432extern const char *__bdevname(dev_t, char *buffer); 1436extern const char *__bdevname(dev_t, char *buffer);
1433extern const char *bdevname(struct block_device *bdev, char *buffer); 1437extern const char *bdevname(struct block_device *bdev, char *buffer);
1434extern struct block_device *lookup_bdev(const char *); 1438extern struct block_device *lookup_bdev(const char *);
1435extern struct block_device *open_bdev_excl(const char *, int, void *); 1439extern struct block_device *open_bdev_excl(const char *, int, void *);
1436extern void close_bdev_excl(struct block_device *); 1440extern void close_bdev_excl(struct block_device *);
1437extern void *acquire_blkdev_list(void); 1441extern void blkdev_show(struct seq_file *,off_t);
1438extern int count_blkdev_list(void);
1439extern void *get_next_blkdev(void *);
1440extern int get_blkdev_info(void *, int *, char **);
1441extern void release_blkdev_list(void *);
1442 1442
1443extern void init_special_inode(struct inode *, umode_t, dev_t); 1443extern void init_special_inode(struct inode *, umode_t, dev_t);
1444 1444
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 93830158348e..b20939287613 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -58,6 +58,19 @@ struct hrtimer {
58}; 58};
59 59
60/** 60/**
61 * struct hrtimer_sleeper - simple sleeper structure
62 *
63 * @timer: embedded timer structure
64 * @task: task to wake up
65 *
66 * task is set to NULL, when the timer expires.
67 */
68struct hrtimer_sleeper {
69 struct hrtimer timer;
70 struct task_struct *task;
71};
72
73/**
61 * struct hrtimer_base - the timer base for a specific clock 74 * struct hrtimer_base - the timer base for a specific clock
62 * 75 *
63 * @index: clock type index for per_cpu support when moving a timer 76 * @index: clock type index for per_cpu support when moving a timer
@@ -127,6 +140,9 @@ extern long hrtimer_nanosleep(struct timespec *rqtp,
127 const enum hrtimer_mode mode, 140 const enum hrtimer_mode mode,
128 const clockid_t clockid); 141 const clockid_t clockid);
129 142
143extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
144 struct task_struct *tsk);
145
130/* Soft interrupt function to run the hrtimer queues: */ 146/* Soft interrupt function to run the hrtimer queues: */
131extern void hrtimer_run_queues(void); 147extern void hrtimer_run_queues(void);
132 148
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index 53571288a9fc..6d9c7e4da472 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -82,6 +82,13 @@ struct ipmi_smi_handlers
82{ 82{
83 struct module *owner; 83 struct module *owner;
84 84
85 /* The low-level interface cannot start sending messages to
86 the upper layer until this function is called. This may
87 not be NULL, the lower layer must take the interface from
88 this call. */
89 int (*start_processing)(void *send_info,
90 ipmi_smi_t new_intf);
91
85 /* Called to enqueue an SMI message to be sent. This 92 /* Called to enqueue an SMI message to be sent. This
86 operation is not allowed to fail. If an error occurs, it 93 operation is not allowed to fail. If an error occurs, it
87 should report back the error in a received message. It may 94 should report back the error in a received message. It may
@@ -157,13 +164,16 @@ static inline void ipmi_demangle_device_id(unsigned char *data,
157} 164}
158 165
159/* Add a low-level interface to the IPMI driver. Note that if the 166/* Add a low-level interface to the IPMI driver. Note that if the
160 interface doesn't know its slave address, it should pass in zero. */ 167 interface doesn't know its slave address, it should pass in zero.
168 The low-level interface should not deliver any messages to the
169 upper layer until the start_processing() function in the handlers
170 is called, and the lower layer must get the interface from that
171 call. */
161int ipmi_register_smi(struct ipmi_smi_handlers *handlers, 172int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
162 void *send_info, 173 void *send_info,
163 struct ipmi_device_id *device_id, 174 struct ipmi_device_id *device_id,
164 struct device *dev, 175 struct device *dev,
165 unsigned char slave_addr, 176 unsigned char slave_addr);
166 ipmi_smi_t *intf);
167 177
168/* 178/*
169 * Remove a low-level interface from the IPMI driver. This will 179 * Remove a low-level interface from the IPMI driver. This will
diff --git a/include/linux/leds.h b/include/linux/leds.h
new file mode 100644
index 000000000000..4617e75903b0
--- /dev/null
+++ b/include/linux/leds.h
@@ -0,0 +1,111 @@
1/*
2 * Driver model for leds and led triggers
3 *
4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
5 * Copyright (C) 2005 Richard Purdie <rpurdie@openedhand.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#ifndef __LINUX_LEDS_H_INCLUDED
13#define __LINUX_LEDS_H_INCLUDED
14
15struct device;
16struct class_device;
17/*
18 * LED Core
19 */
20
21enum led_brightness {
22 LED_OFF = 0,
23 LED_HALF = 127,
24 LED_FULL = 255,
25};
26
27struct led_classdev {
28 const char *name;
29 int brightness;
30 int flags;
31#define LED_SUSPENDED (1 << 0)
32
33 /* A function to set the brightness of the led */
34 void (*brightness_set)(struct led_classdev *led_cdev,
35 enum led_brightness brightness);
36
37 struct class_device *class_dev;
38 /* LED Device linked list */
39 struct list_head node;
40
41 /* Trigger data */
42 char *default_trigger;
43#ifdef CONFIG_LEDS_TRIGGERS
44 rwlock_t trigger_lock;
45 /* Protects the trigger data below */
46
47 struct led_trigger *trigger;
48 struct list_head trig_list;
49 void *trigger_data;
50#endif
51};
52
53extern int led_classdev_register(struct device *parent,
54 struct led_classdev *led_cdev);
55extern void led_classdev_unregister(struct led_classdev *led_cdev);
56extern void led_classdev_suspend(struct led_classdev *led_cdev);
57extern void led_classdev_resume(struct led_classdev *led_cdev);
58
59/*
60 * LED Triggers
61 */
62#ifdef CONFIG_LEDS_TRIGGERS
63
64#define TRIG_NAME_MAX 50
65
66struct led_trigger {
67 /* Trigger Properties */
68 const char *name;
69 void (*activate)(struct led_classdev *led_cdev);
70 void (*deactivate)(struct led_classdev *led_cdev);
71
72 /* LEDs under control by this trigger (for simple triggers) */
73 rwlock_t leddev_list_lock;
74 struct list_head led_cdevs;
75
76 /* Link to next registered trigger */
77 struct list_head next_trig;
78};
79
80/* Registration functions for complex triggers */
81extern int led_trigger_register(struct led_trigger *trigger);
82extern void led_trigger_unregister(struct led_trigger *trigger);
83
84/* Registration functions for simple triggers */
85#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x;
86#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x;
87extern void led_trigger_register_simple(const char *name,
88 struct led_trigger **trigger);
89extern void led_trigger_unregister_simple(struct led_trigger *trigger);
90extern void led_trigger_event(struct led_trigger *trigger,
91 enum led_brightness event);
92
93#else
94
95/* Triggers aren't active - null macros */
96#define DEFINE_LED_TRIGGER(x)
97#define DEFINE_LED_TRIGGER_GLOBAL(x)
98#define led_trigger_register_simple(x, y) do {} while(0)
99#define led_trigger_unregister_simple(x) do {} while(0)
100#define led_trigger_event(x, y) do {} while(0)
101
102#endif
103
104/* Trigger specific functions */
105#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
106extern void ledtrig_ide_activity(void);
107#else
108#define ledtrig_ide_activity() do {} while(0)
109#endif
110
111#endif /* __LINUX_LEDS_H_INCLUDED */
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 7d09962c3c0b..ff0a64073ebc 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -12,7 +12,7 @@ extern void migrate_page_copy(struct page *, struct page *);
12extern int migrate_page_remove_references(struct page *, struct page *, int); 12extern int migrate_page_remove_references(struct page *, struct page *, int);
13extern int migrate_pages(struct list_head *l, struct list_head *t, 13extern int migrate_pages(struct list_head *l, struct list_head *t,
14 struct list_head *moved, struct list_head *failed); 14 struct list_head *moved, struct list_head *failed);
15int migrate_pages_to(struct list_head *pagelist, 15extern int migrate_pages_to(struct list_head *pagelist,
16 struct vm_area_struct *vma, int dest); 16 struct vm_area_struct *vma, int dest);
17extern int fail_migrate_page(struct page *, struct page *); 17extern int fail_migrate_page(struct page *, struct page *);
18 18
@@ -26,6 +26,9 @@ static inline int putback_lru_pages(struct list_head *l) { return 0; }
26static inline int migrate_pages(struct list_head *l, struct list_head *t, 26static inline int migrate_pages(struct list_head *l, struct list_head *t,
27 struct list_head *moved, struct list_head *failed) { return -ENOSYS; } 27 struct list_head *moved, struct list_head *failed) { return -ENOSYS; }
28 28
29static inline int migrate_pages_to(struct list_head *pagelist,
30 struct vm_area_struct *vma, int dest) { return 0; }
31
29static inline int migrate_prep(void) { return -ENOSYS; } 32static inline int migrate_prep(void) { return -ENOSYS; }
30 33
31/* Possible settings for the migrate_page() method in address_operations */ 34/* Possible settings for the migrate_page() method in address_operations */
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index f46afec6fbf8..72fc68c5ee96 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -10,7 +10,7 @@
10#ifndef __MTD_TRANS_H__ 10#ifndef __MTD_TRANS_H__
11#define __MTD_TRANS_H__ 11#define __MTD_TRANS_H__
12 12
13#include <asm/semaphore.h> 13#include <linux/mutex.h>
14 14
15struct hd_geometry; 15struct hd_geometry;
16struct mtd_info; 16struct mtd_info;
@@ -22,7 +22,7 @@ struct mtd_blktrans_dev {
22 struct mtd_blktrans_ops *tr; 22 struct mtd_blktrans_ops *tr;
23 struct list_head list; 23 struct list_head list;
24 struct mtd_info *mtd; 24 struct mtd_info *mtd;
25 struct semaphore sem; 25 struct mutex lock;
26 int devnum; 26 int devnum;
27 int blksize; 27 int blksize;
28 unsigned long size; 28 unsigned long size;
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index 386a52cf8b1b..9addd073bf15 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -15,7 +15,7 @@
15#define __MTD_DOC2000_H__ 15#define __MTD_DOC2000_H__
16 16
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <asm/semaphore.h> 18#include <linux/mutex.h>
19 19
20#define DoC_Sig1 0 20#define DoC_Sig1 0
21#define DoC_Sig2 1 21#define DoC_Sig2 1
@@ -187,7 +187,7 @@ struct DiskOnChip {
187 int numchips; 187 int numchips;
188 struct Nand *chips; 188 struct Nand *chips;
189 struct mtd_info *nextdoc; 189 struct mtd_info *nextdoc;
190 struct semaphore lock; 190 struct mutex lock;
191}; 191};
192 192
193int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); 193int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]);
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h
index 0268125a6271..d7eaa40e5ab0 100644
--- a/include/linux/mtd/inftl.h
+++ b/include/linux/mtd/inftl.h
@@ -52,6 +52,11 @@ struct INFTLrecord {
52int INFTL_mount(struct INFTLrecord *s); 52int INFTL_mount(struct INFTLrecord *s);
53int INFTL_formatblock(struct INFTLrecord *s, int block); 53int INFTL_formatblock(struct INFTLrecord *s, int block);
54 54
55extern char inftlmountrev[];
56
57void INFTL_dumptables(struct INFTLrecord *s);
58void INFTL_dumpVUchains(struct INFTLrecord *s);
59
55#endif /* __KERNEL__ */ 60#endif /* __KERNEL__ */
56 61
57#endif /* __MTD_INFTL_H__ */ 62#endif /* __MTD_INFTL_H__ */
diff --git a/include/linux/namei.h b/include/linux/namei.h
index e6698013e4d0..58cb3d3d44b4 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -75,7 +75,6 @@ extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
75extern void release_open_intent(struct nameidata *); 75extern void release_open_intent(struct nameidata *);
76 76
77extern struct dentry * lookup_one_len(const char *, struct dentry *, int); 77extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
78extern __deprecated_for_modules struct dentry * lookup_hash(struct nameidata *);
79 78
80extern int follow_down(struct vfsmount **, struct dentry **); 79extern int follow_down(struct vfsmount **, struct dentry **);
81extern int follow_up(struct vfsmount **, struct dentry **); 80extern int follow_up(struct vfsmount **, struct dentry **);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 950dc55e5192..40ccf8cc4239 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -598,20 +598,7 @@ DECLARE_PER_CPU(struct softnet_data,softnet_data);
598 598
599#define HAVE_NETIF_QUEUE 599#define HAVE_NETIF_QUEUE
600 600
601static inline void __netif_schedule(struct net_device *dev) 601extern void __netif_schedule(struct net_device *dev);
602{
603 if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
604 unsigned long flags;
605 struct softnet_data *sd;
606
607 local_irq_save(flags);
608 sd = &__get_cpu_var(softnet_data);
609 dev->next_sched = sd->output_queue;
610 sd->output_queue = dev;
611 raise_softirq_irqoff(NET_TX_SOFTIRQ);
612 local_irq_restore(flags);
613 }
614}
615 602
616static inline void netif_schedule(struct net_device *dev) 603static inline void netif_schedule(struct net_device *dev)
617{ 604{
@@ -675,13 +662,7 @@ static inline void dev_kfree_skb_irq(struct sk_buff *skb)
675/* Use this variant in places where it could be invoked 662/* Use this variant in places where it could be invoked
676 * either from interrupt or non-interrupt context. 663 * either from interrupt or non-interrupt context.
677 */ 664 */
678static inline void dev_kfree_skb_any(struct sk_buff *skb) 665extern void dev_kfree_skb_any(struct sk_buff *skb);
679{
680 if (in_irq() || irqs_disabled())
681 dev_kfree_skb_irq(skb);
682 else
683 dev_kfree_skb(skb);
684}
685 666
686#define HAVE_NETIF_RX 1 667#define HAVE_NETIF_RX 1
687extern int netif_rx(struct sk_buff *skb); 668extern int netif_rx(struct sk_buff *skb);
@@ -768,22 +749,9 @@ static inline int netif_device_present(struct net_device *dev)
768 return test_bit(__LINK_STATE_PRESENT, &dev->state); 749 return test_bit(__LINK_STATE_PRESENT, &dev->state);
769} 750}
770 751
771static inline void netif_device_detach(struct net_device *dev) 752extern void netif_device_detach(struct net_device *dev);
772{
773 if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
774 netif_running(dev)) {
775 netif_stop_queue(dev);
776 }
777}
778 753
779static inline void netif_device_attach(struct net_device *dev) 754extern void netif_device_attach(struct net_device *dev);
780{
781 if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
782 netif_running(dev)) {
783 netif_wake_queue(dev);
784 __netdev_watchdog_up(dev);
785 }
786}
787 755
788/* 756/*
789 * Network interface message level settings 757 * Network interface message level settings
@@ -851,20 +819,7 @@ static inline int netif_rx_schedule_prep(struct net_device *dev)
851 * already been called and returned 1. 819 * already been called and returned 1.
852 */ 820 */
853 821
854static inline void __netif_rx_schedule(struct net_device *dev) 822extern void __netif_rx_schedule(struct net_device *dev);
855{
856 unsigned long flags;
857
858 local_irq_save(flags);
859 dev_hold(dev);
860 list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
861 if (dev->quota < 0)
862 dev->quota += dev->weight;
863 else
864 dev->quota = dev->weight;
865 __raise_softirq_irqoff(NET_RX_SOFTIRQ);
866 local_irq_restore(flags);
867}
868 823
869/* Try to reschedule poll. Called by irq handler. */ 824/* Try to reschedule poll. Called by irq handler. */
870 825
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 839f0b3c23aa..9539efd4f7e6 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -72,8 +72,8 @@ extern struct page * find_get_page(struct address_space *mapping,
72 unsigned long index); 72 unsigned long index);
73extern struct page * find_lock_page(struct address_space *mapping, 73extern struct page * find_lock_page(struct address_space *mapping,
74 unsigned long index); 74 unsigned long index);
75extern struct page * find_trylock_page(struct address_space *mapping, 75extern __deprecated_for_modules struct page * find_trylock_page(
76 unsigned long index); 76 struct address_space *mapping, unsigned long index);
77extern struct page * find_or_create_page(struct address_space *mapping, 77extern struct page * find_or_create_page(struct address_space *mapping,
78 unsigned long index, gfp_t gfp_mask); 78 unsigned long index, gfp_t gfp_mask);
79unsigned find_get_pages(struct address_space *mapping, pgoff_t start, 79unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 5b9082cc600f..29960b03bef7 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -1,6 +1,8 @@
1#ifndef _LINUX_PID_H 1#ifndef _LINUX_PID_H
2#define _LINUX_PID_H 2#define _LINUX_PID_H
3 3
4#include <linux/rcupdate.h>
5
4enum pid_type 6enum pid_type
5{ 7{
6 PIDTYPE_PID, 8 PIDTYPE_PID,
@@ -9,45 +11,109 @@ enum pid_type
9 PIDTYPE_MAX 11 PIDTYPE_MAX
10}; 12};
11 13
14/*
15 * What is struct pid?
16 *
17 * A struct pid is the kernel's internal notion of a process identifier.
18 * It refers to individual tasks, process groups, and sessions. While
19 * there are processes attached to it the struct pid lives in a hash
20 * table, so it and then the processes that it refers to can be found
21 * quickly from the numeric pid value. The attached processes may be
22 * quickly accessed by following pointers from struct pid.
23 *
24 * Storing pid_t values in the kernel and refering to them later has a
25 * problem. The process originally with that pid may have exited and the
26 * pid allocator wrapped, and another process could have come along
27 * and been assigned that pid.
28 *
29 * Referring to user space processes by holding a reference to struct
30 * task_struct has a problem. When the user space process exits
31 * the now useless task_struct is still kept. A task_struct plus a
32 * stack consumes around 10K of low kernel memory. More precisely
33 * this is THREAD_SIZE + sizeof(struct task_struct). By comparison
34 * a struct pid is about 64 bytes.
35 *
36 * Holding a reference to struct pid solves both of these problems.
37 * It is small so holding a reference does not consume a lot of
38 * resources, and since a new struct pid is allocated when the numeric
39 * pid value is reused we don't mistakenly refer to new processes.
40 */
41
12struct pid 42struct pid
13{ 43{
44 atomic_t count;
14 /* Try to keep pid_chain in the same cacheline as nr for find_pid */ 45 /* Try to keep pid_chain in the same cacheline as nr for find_pid */
15 int nr; 46 int nr;
16 struct hlist_node pid_chain; 47 struct hlist_node pid_chain;
17 /* list of pids with the same nr, only one of them is in the hash */ 48 /* lists of tasks that use this pid */
18 struct list_head pid_list; 49 struct hlist_head tasks[PIDTYPE_MAX];
50 struct rcu_head rcu;
19}; 51};
20 52
21#define pid_task(elem, type) \ 53struct pid_link
22 list_entry(elem, struct task_struct, pids[type].pid_list) 54{
55 struct hlist_node node;
56 struct pid *pid;
57};
58
59static inline struct pid *get_pid(struct pid *pid)
60{
61 if (pid)
62 atomic_inc(&pid->count);
63 return pid;
64}
65
66extern void FASTCALL(put_pid(struct pid *pid));
67extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type));
68extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
69 enum pid_type));
23 70
24/* 71/*
25 * attach_pid() and detach_pid() must be called with the tasklist_lock 72 * attach_pid() and detach_pid() must be called with the tasklist_lock
26 * write-held. 73 * write-held.
27 */ 74 */
28extern int FASTCALL(attach_pid(struct task_struct *task, enum pid_type type, int nr)); 75extern int FASTCALL(attach_pid(struct task_struct *task,
76 enum pid_type type, int nr));
29 77
30extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type)); 78extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
31 79
32/* 80/*
33 * look up a PID in the hash table. Must be called with the tasklist_lock 81 * look up a PID in the hash table. Must be called with the tasklist_lock
34 * held. 82 * or rcu_read_lock() held.
83 */
84extern struct pid *FASTCALL(find_pid(int nr));
85
86/*
87 * Lookup a PID in the hash table, and return with it's count elevated.
35 */ 88 */
36extern struct pid *FASTCALL(find_pid(enum pid_type, int)); 89extern struct pid *find_get_pid(int nr);
37 90
38extern int alloc_pidmap(void); 91extern struct pid *alloc_pid(void);
39extern void FASTCALL(free_pidmap(int)); 92extern void FASTCALL(free_pid(struct pid *pid));
40 93
94#define pid_next(task, type) \
95 ((task)->pids[(type)].node.next)
96
97#define pid_next_task(task, type) \
98 hlist_entry(pid_next(task, type), struct task_struct, \
99 pids[(type)].node)
100
101
102/* We could use hlist_for_each_entry_rcu here but it takes more arguments
103 * than the do_each_task_pid/while_each_task_pid. So we roll our own
104 * to preserve the existing interface.
105 */
41#define do_each_task_pid(who, type, task) \ 106#define do_each_task_pid(who, type, task) \
42 if ((task = find_task_by_pid_type(type, who))) { \ 107 if ((task = find_task_by_pid_type(type, who))) { \
43 prefetch((task)->pids[type].pid_list.next); \ 108 prefetch(pid_next(task, type)); \
44 do { 109 do {
45 110
46#define while_each_task_pid(who, type, task) \ 111#define while_each_task_pid(who, type, task) \
47 } while (task = pid_task((task)->pids[type].pid_list.next,\ 112 } while (pid_next(task, type) && ({ \
48 type), \ 113 task = pid_next_task(task, type); \
49 prefetch((task)->pids[type].pid_list.next), \ 114 rcu_dereference(task); \
50 hlist_unhashed(&(task)->pids[type].pid_chain)); \ 115 prefetch(pid_next(task, type)); \
51 } \ 116 1; }) ); \
117 }
52 118
53#endif /* _LINUX_PID_H */ 119#endif /* _LINUX_PID_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index d04186d8cc68..541f4828f5e7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -100,6 +100,7 @@ DECLARE_PER_CPU(unsigned long, process_counts);
100extern int nr_processes(void); 100extern int nr_processes(void);
101extern unsigned long nr_running(void); 101extern unsigned long nr_running(void);
102extern unsigned long nr_uninterruptible(void); 102extern unsigned long nr_uninterruptible(void);
103extern unsigned long nr_active(void);
103extern unsigned long nr_iowait(void); 104extern unsigned long nr_iowait(void);
104 105
105#include <linux/time.h> 106#include <linux/time.h>
@@ -483,6 +484,7 @@ struct signal_struct {
483#define MAX_PRIO (MAX_RT_PRIO + 40) 484#define MAX_PRIO (MAX_RT_PRIO + 40)
484 485
485#define rt_task(p) (unlikely((p)->prio < MAX_RT_PRIO)) 486#define rt_task(p) (unlikely((p)->prio < MAX_RT_PRIO))
487#define batch_task(p) (unlikely((p)->policy == SCHED_BATCH))
486 488
487/* 489/*
488 * Some day this will be a full-fledged user tracking system.. 490 * Some day this will be a full-fledged user tracking system..
@@ -683,6 +685,13 @@ static inline void prefetch_stack(struct task_struct *t) { }
683struct audit_context; /* See audit.c */ 685struct audit_context; /* See audit.c */
684struct mempolicy; 686struct mempolicy;
685 687
688enum sleep_type {
689 SLEEP_NORMAL,
690 SLEEP_NONINTERACTIVE,
691 SLEEP_INTERACTIVE,
692 SLEEP_INTERRUPTED,
693};
694
686struct task_struct { 695struct task_struct {
687 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 696 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
688 struct thread_info *thread_info; 697 struct thread_info *thread_info;
@@ -705,7 +714,7 @@ struct task_struct {
705 unsigned long sleep_avg; 714 unsigned long sleep_avg;
706 unsigned long long timestamp, last_ran; 715 unsigned long long timestamp, last_ran;
707 unsigned long long sched_time; /* sched_clock time spent running */ 716 unsigned long long sched_time; /* sched_clock time spent running */
708 int activated; 717 enum sleep_type sleep_type;
709 718
710 unsigned long policy; 719 unsigned long policy;
711 cpumask_t cpus_allowed; 720 cpumask_t cpus_allowed;
@@ -751,7 +760,7 @@ struct task_struct {
751 struct task_struct *group_leader; /* threadgroup leader */ 760 struct task_struct *group_leader; /* threadgroup leader */
752 761
753 /* PID/PID hash table linkage. */ 762 /* PID/PID hash table linkage. */
754 struct pid pids[PIDTYPE_MAX]; 763 struct pid_link pids[PIDTYPE_MAX];
755 struct list_head thread_group; 764 struct list_head thread_group;
756 765
757 struct completion *vfork_done; /* for vfork() */ 766 struct completion *vfork_done; /* for vfork() */
@@ -890,18 +899,19 @@ static inline pid_t process_group(struct task_struct *tsk)
890 */ 899 */
891static inline int pid_alive(struct task_struct *p) 900static inline int pid_alive(struct task_struct *p)
892{ 901{
893 return p->pids[PIDTYPE_PID].nr != 0; 902 return p->pids[PIDTYPE_PID].pid != NULL;
894} 903}
895 904
896extern void free_task(struct task_struct *tsk); 905extern void free_task(struct task_struct *tsk);
897#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) 906#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
898 907
899extern void __put_task_struct_cb(struct rcu_head *rhp); 908extern void __put_task_struct_cb(struct rcu_head *rhp);
909extern void __put_task_struct(struct task_struct *t);
900 910
901static inline void put_task_struct(struct task_struct *t) 911static inline void put_task_struct(struct task_struct *t)
902{ 912{
903 if (atomic_dec_and_test(&t->usage)) 913 if (atomic_dec_and_test(&t->usage))
904 call_rcu(&t->rcu, __put_task_struct_cb); 914 __put_task_struct(t);
905} 915}
906 916
907/* 917/*
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 613b9513f8b9..c4619a428d9b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -941,6 +941,25 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
941#define NET_IP_ALIGN 2 941#define NET_IP_ALIGN 2
942#endif 942#endif
943 943
944/*
945 * The networking layer reserves some headroom in skb data (via
946 * dev_alloc_skb). This is used to avoid having to reallocate skb data when
947 * the header has to grow. In the default case, if the header has to grow
948 * 16 bytes or less we avoid the reallocation.
949 *
950 * Unfortunately this headroom changes the DMA alignment of the resulting
951 * network packet. As for NET_IP_ALIGN, this unaligned DMA is expensive
952 * on some architectures. An architecture can override this value,
953 * perhaps setting it to a cacheline in size (since that will maintain
954 * cacheline alignment of the DMA). It must be a power of 2.
955 *
956 * Various parts of the networking layer expect at least 16 bytes of
957 * headroom, you should not reduce this.
958 */
959#ifndef NET_SKB_PAD
960#define NET_SKB_PAD 16
961#endif
962
944extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); 963extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
945 964
946static inline void __skb_trim(struct sk_buff *skb, unsigned int len) 965static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
@@ -1030,9 +1049,9 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
1030static inline struct sk_buff *__dev_alloc_skb(unsigned int length, 1049static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
1031 gfp_t gfp_mask) 1050 gfp_t gfp_mask)
1032{ 1051{
1033 struct sk_buff *skb = alloc_skb(length + 16, gfp_mask); 1052 struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
1034 if (likely(skb)) 1053 if (likely(skb))
1035 skb_reserve(skb, 16); 1054 skb_reserve(skb, NET_SKB_PAD);
1036 return skb; 1055 return skb;
1037} 1056}
1038#else 1057#else
@@ -1070,13 +1089,15 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
1070 */ 1089 */
1071static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) 1090static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
1072{ 1091{
1073 int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb); 1092 int delta = (headroom > NET_SKB_PAD ? headroom : NET_SKB_PAD) -
1093 skb_headroom(skb);
1074 1094
1075 if (delta < 0) 1095 if (delta < 0)
1076 delta = 0; 1096 delta = 0;
1077 1097
1078 if (delta || skb_cloned(skb)) 1098 if (delta || skb_cloned(skb))
1079 return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC); 1099 return pskb_expand_head(skb, (delta + (NET_SKB_PAD-1)) &
1100 ~(NET_SKB_PAD-1), 0, GFP_ATOMIC);
1080 return 0; 1101 return 0;
1081} 1102}
1082 1103
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e78ffc7d5b56..5717147596b6 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -571,5 +571,7 @@ asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
571asmlinkage long sys_unshare(unsigned long unshare_flags); 571asmlinkage long sys_unshare(unsigned long unshare_flags);
572asmlinkage long sys_splice(int fdin, int fdout, size_t len, 572asmlinkage long sys_splice(int fdin, int fdout, size_t len,
573 unsigned int flags); 573 unsigned int flags);
574asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
575 int flags);
574 576
575#endif 577#endif
diff --git a/include/linux/timer.h b/include/linux/timer.h
index b5caabca553c..0a485beba9f5 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -6,7 +6,7 @@
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/stddef.h> 7#include <linux/stddef.h>
8 8
9struct timer_base_s; 9struct tvec_t_base_s;
10 10
11struct timer_list { 11struct timer_list {
12 struct list_head entry; 12 struct list_head entry;
@@ -15,16 +15,16 @@ struct timer_list {
15 void (*function)(unsigned long); 15 void (*function)(unsigned long);
16 unsigned long data; 16 unsigned long data;
17 17
18 struct timer_base_s *base; 18 struct tvec_t_base_s *base;
19}; 19};
20 20
21extern struct timer_base_s __init_timer_base; 21extern struct tvec_t_base_s boot_tvec_bases;
22 22
23#define TIMER_INITIALIZER(_function, _expires, _data) { \ 23#define TIMER_INITIALIZER(_function, _expires, _data) { \
24 .function = (_function), \ 24 .function = (_function), \
25 .expires = (_expires), \ 25 .expires = (_expires), \
26 .data = (_data), \ 26 .data = (_data), \
27 .base = &__init_timer_base, \ 27 .base = &boot_tvec_bases, \
28 } 28 }
29 29
30#define DEFINE_TIMER(_name, _function, _expires, _data) \ 30#define DEFINE_TIMER(_name, _function, _expires, _data) \
diff --git a/include/linux/tiocl.h b/include/linux/tiocl.h
index 2c9e847f6ed1..4756862c4ed4 100644
--- a/include/linux/tiocl.h
+++ b/include/linux/tiocl.h
@@ -34,5 +34,6 @@ struct tiocl_selection {
34#define TIOCL_SCROLLCONSOLE 13 /* scroll console */ 34#define TIOCL_SCROLLCONSOLE 13 /* scroll console */
35#define TIOCL_BLANKSCREEN 14 /* keep screen blank even if a key is pressed */ 35#define TIOCL_BLANKSCREEN 14 /* keep screen blank even if a key is pressed */
36#define TIOCL_BLANKEDSCREEN 15 /* return which vt was blanked */ 36#define TIOCL_BLANKEDSCREEN 15 /* return which vt was blanked */
37#define TIOCL_GETKMSGREDIRECT 17 /* get the vt the kernel messages are restricted to */
37 38
38#endif /* _LINUX_TIOCL_H */ 39#endif /* _LINUX_TIOCL_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9418f4d1afbb..3c989db8a7aa 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -405,9 +405,6 @@ extern int tcp_disconnect(struct sock *sk, int flags);
405 405
406extern void tcp_unhash(struct sock *sk); 406extern void tcp_unhash(struct sock *sk);
407 407
408extern int tcp_v4_hash_connecting(struct sock *sk);
409
410
411/* From syncookies.c */ 408/* From syncookies.c */
412extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, 409extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
413 struct ip_options *opt); 410 struct ip_options *opt);
diff --git a/kernel/acct.c b/kernel/acct.c
index 065d8b4e51ef..b327f4d20104 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -449,8 +449,8 @@ static void do_acct_process(long exitcode, struct file *file)
449 /* calculate run_time in nsec*/ 449 /* calculate run_time in nsec*/
450 do_posix_clock_monotonic_gettime(&uptime); 450 do_posix_clock_monotonic_gettime(&uptime);
451 run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec; 451 run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec;
452 run_time -= (u64)current->start_time.tv_sec*NSEC_PER_SEC 452 run_time -= (u64)current->group_leader->start_time.tv_sec * NSEC_PER_SEC
453 + current->start_time.tv_nsec; 453 + current->group_leader->start_time.tv_nsec;
454 /* convert nsec -> AHZ */ 454 /* convert nsec -> AHZ */
455 elapsed = nsec_to_AHZ(run_time); 455 elapsed = nsec_to_AHZ(run_time);
456#if ACCT_VERSION==3 456#if ACCT_VERSION==3
@@ -469,10 +469,10 @@ static void do_acct_process(long exitcode, struct file *file)
469#endif 469#endif
470 do_div(elapsed, AHZ); 470 do_div(elapsed, AHZ);
471 ac.ac_btime = xtime.tv_sec - elapsed; 471 ac.ac_btime = xtime.tv_sec - elapsed;
472 jiffies = cputime_to_jiffies(cputime_add(current->group_leader->utime, 472 jiffies = cputime_to_jiffies(cputime_add(current->utime,
473 current->signal->utime)); 473 current->signal->utime));
474 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies)); 474 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies));
475 jiffies = cputime_to_jiffies(cputime_add(current->group_leader->stime, 475 jiffies = cputime_to_jiffies(cputime_add(current->stime,
476 current->signal->stime)); 476 current->signal->stime));
477 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies)); 477 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies));
478 /* we really need to bite the bullet and change layout */ 478 /* we really need to bite the bullet and change layout */
@@ -522,9 +522,9 @@ static void do_acct_process(long exitcode, struct file *file)
522 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ 522 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
523 ac.ac_rw = encode_comp_t(ac.ac_io / 1024); 523 ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
524 ac.ac_minflt = encode_comp_t(current->signal->min_flt + 524 ac.ac_minflt = encode_comp_t(current->signal->min_flt +
525 current->group_leader->min_flt); 525 current->min_flt);
526 ac.ac_majflt = encode_comp_t(current->signal->maj_flt + 526 ac.ac_majflt = encode_comp_t(current->signal->maj_flt +
527 current->group_leader->maj_flt); 527 current->maj_flt);
528 ac.ac_swaps = encode_comp_t(0); 528 ac.ac_swaps = encode_comp_t(0);
529 ac.ac_exitcode = exitcode; 529 ac.ac_exitcode = exitcode;
530 530
diff --git a/kernel/audit.c b/kernel/audit.c
index 04fe2e301b61..c8ccbd09048f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -578,7 +578,7 @@ static int __init audit_enable(char *str)
578 audit_initialized ? "" : " (after initialization)"); 578 audit_initialized ? "" : " (after initialization)");
579 if (audit_initialized) 579 if (audit_initialized)
580 audit_enabled = audit_default; 580 audit_enabled = audit_default;
581 return 0; 581 return 1;
582} 582}
583 583
584__setup("audit=", audit_enable); 584__setup("audit=", audit_enable);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 18aea1bd1284..72248d1b9e3f 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -616,12 +616,10 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
616 * current->cpuset if a task has its memory placement changed. 616 * current->cpuset if a task has its memory placement changed.
617 * Do not call this routine if in_interrupt(). 617 * Do not call this routine if in_interrupt().
618 * 618 *
619 * Call without callback_mutex or task_lock() held. May be called 619 * Call without callback_mutex or task_lock() held. May be
620 * with or without manage_mutex held. Doesn't need task_lock to guard 620 * called with or without manage_mutex held. Thanks in part to
621 * against another task changing a non-NULL cpuset pointer to NULL, 621 * 'the_top_cpuset_hack', the tasks cpuset pointer will never
622 * as that is only done by a task on itself, and if the current task 622 * be NULL. This routine also might acquire callback_mutex and
623 * is here, it is not simultaneously in the exit code NULL'ing its
624 * cpuset pointer. This routine also might acquire callback_mutex and
625 * current->mm->mmap_sem during call. 623 * current->mm->mmap_sem during call.
626 * 624 *
627 * Reading current->cpuset->mems_generation doesn't need task_lock 625 * Reading current->cpuset->mems_generation doesn't need task_lock
@@ -836,6 +834,55 @@ static int update_cpumask(struct cpuset *cs, char *buf)
836} 834}
837 835
838/* 836/*
837 * cpuset_migrate_mm
838 *
839 * Migrate memory region from one set of nodes to another.
840 *
841 * Temporarilly set tasks mems_allowed to target nodes of migration,
842 * so that the migration code can allocate pages on these nodes.
843 *
844 * Call holding manage_mutex, so our current->cpuset won't change
845 * during this call, as manage_mutex holds off any attach_task()
846 * calls. Therefore we don't need to take task_lock around the
847 * call to guarantee_online_mems(), as we know no one is changing
848 * our tasks cpuset.
849 *
850 * Hold callback_mutex around the two modifications of our tasks
851 * mems_allowed to synchronize with cpuset_mems_allowed().
852 *
853 * While the mm_struct we are migrating is typically from some
854 * other task, the task_struct mems_allowed that we are hacking
855 * is for our current task, which must allocate new pages for that
856 * migrating memory region.
857 *
858 * We call cpuset_update_task_memory_state() before hacking
859 * our tasks mems_allowed, so that we are assured of being in
860 * sync with our tasks cpuset, and in particular, callbacks to
861 * cpuset_update_task_memory_state() from nested page allocations
862 * won't see any mismatch of our cpuset and task mems_generation
863 * values, so won't overwrite our hacked tasks mems_allowed
864 * nodemask.
865 */
866
867static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
868 const nodemask_t *to)
869{
870 struct task_struct *tsk = current;
871
872 cpuset_update_task_memory_state();
873
874 mutex_lock(&callback_mutex);
875 tsk->mems_allowed = *to;
876 mutex_unlock(&callback_mutex);
877
878 do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL);
879
880 mutex_lock(&callback_mutex);
881 guarantee_online_mems(tsk->cpuset, &tsk->mems_allowed);
882 mutex_unlock(&callback_mutex);
883}
884
885/*
839 * Handle user request to change the 'mems' memory placement 886 * Handle user request to change the 'mems' memory placement
840 * of a cpuset. Needs to validate the request, update the 887 * of a cpuset. Needs to validate the request, update the
841 * cpusets mems_allowed and mems_generation, and for each 888 * cpusets mems_allowed and mems_generation, and for each
@@ -947,10 +994,8 @@ static int update_nodemask(struct cpuset *cs, char *buf)
947 struct mm_struct *mm = mmarray[i]; 994 struct mm_struct *mm = mmarray[i];
948 995
949 mpol_rebind_mm(mm, &cs->mems_allowed); 996 mpol_rebind_mm(mm, &cs->mems_allowed);
950 if (migrate) { 997 if (migrate)
951 do_migrate_pages(mm, &oldmem, &cs->mems_allowed, 998 cpuset_migrate_mm(mm, &oldmem, &cs->mems_allowed);
952 MPOL_MF_MOVE_ALL);
953 }
954 mmput(mm); 999 mmput(mm);
955 } 1000 }
956 1001
@@ -1185,11 +1230,11 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
1185 mm = get_task_mm(tsk); 1230 mm = get_task_mm(tsk);
1186 if (mm) { 1231 if (mm) {
1187 mpol_rebind_mm(mm, &to); 1232 mpol_rebind_mm(mm, &to);
1233 if (is_memory_migrate(cs))
1234 cpuset_migrate_mm(mm, &from, &to);
1188 mmput(mm); 1235 mmput(mm);
1189 } 1236 }
1190 1237
1191 if (is_memory_migrate(cs))
1192 do_migrate_pages(tsk->mm, &from, &to, MPOL_MF_MOVE_ALL);
1193 put_task_struct(tsk); 1238 put_task_struct(tsk);
1194 synchronize_rcu(); 1239 synchronize_rcu();
1195 if (atomic_dec_and_test(&oldcs->count)) 1240 if (atomic_dec_and_test(&oldcs->count))
diff --git a/kernel/exit.c b/kernel/exit.c
index bc0ec674d3f4..6c2eeb8f6390 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -127,6 +127,11 @@ static void __exit_signal(struct task_struct *tsk)
127 } 127 }
128} 128}
129 129
130static void delayed_put_task_struct(struct rcu_head *rhp)
131{
132 put_task_struct(container_of(rhp, struct task_struct, rcu));
133}
134
130void release_task(struct task_struct * p) 135void release_task(struct task_struct * p)
131{ 136{
132 int zap_leader; 137 int zap_leader;
@@ -168,7 +173,7 @@ repeat:
168 spin_unlock(&p->proc_lock); 173 spin_unlock(&p->proc_lock);
169 proc_pid_flush(proc_dentry); 174 proc_pid_flush(proc_dentry);
170 release_thread(p); 175 release_thread(p);
171 put_task_struct(p); 176 call_rcu(&p->rcu, delayed_put_task_struct);
172 177
173 p = leader; 178 p = leader;
174 if (unlikely(zap_leader)) 179 if (unlikely(zap_leader))
diff --git a/kernel/fork.c b/kernel/fork.c
index b3f7a1bb5e55..3384eb89cb1c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -108,10 +108,8 @@ void free_task(struct task_struct *tsk)
108} 108}
109EXPORT_SYMBOL(free_task); 109EXPORT_SYMBOL(free_task);
110 110
111void __put_task_struct_cb(struct rcu_head *rhp) 111void __put_task_struct(struct task_struct *tsk)
112{ 112{
113 struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
114
115 WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE))); 113 WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
116 WARN_ON(atomic_read(&tsk->usage)); 114 WARN_ON(atomic_read(&tsk->usage));
117 WARN_ON(tsk == current); 115 WARN_ON(tsk == current);
@@ -126,6 +124,12 @@ void __put_task_struct_cb(struct rcu_head *rhp)
126 free_task(tsk); 124 free_task(tsk);
127} 125}
128 126
127void __put_task_struct_cb(struct rcu_head *rhp)
128{
129 struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
130 __put_task_struct(tsk);
131}
132
129void __init fork_init(unsigned long mempages) 133void __init fork_init(unsigned long mempages)
130{ 134{
131#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR 135#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
@@ -721,7 +725,7 @@ out_release:
721 free_fdset (new_fdt->open_fds, new_fdt->max_fdset); 725 free_fdset (new_fdt->open_fds, new_fdt->max_fdset);
722 free_fd_array(new_fdt->fd, new_fdt->max_fds); 726 free_fd_array(new_fdt->fd, new_fdt->max_fds);
723 kmem_cache_free(files_cachep, newf); 727 kmem_cache_free(files_cachep, newf);
724 goto out; 728 return NULL;
725} 729}
726 730
727static int copy_files(unsigned long clone_flags, struct task_struct * tsk) 731static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
@@ -1311,17 +1315,19 @@ long do_fork(unsigned long clone_flags,
1311{ 1315{
1312 struct task_struct *p; 1316 struct task_struct *p;
1313 int trace = 0; 1317 int trace = 0;
1314 long pid = alloc_pidmap(); 1318 struct pid *pid = alloc_pid();
1319 long nr;
1315 1320
1316 if (pid < 0) 1321 if (!pid)
1317 return -EAGAIN; 1322 return -EAGAIN;
1323 nr = pid->nr;
1318 if (unlikely(current->ptrace)) { 1324 if (unlikely(current->ptrace)) {
1319 trace = fork_traceflag (clone_flags); 1325 trace = fork_traceflag (clone_flags);
1320 if (trace) 1326 if (trace)
1321 clone_flags |= CLONE_PTRACE; 1327 clone_flags |= CLONE_PTRACE;
1322 } 1328 }
1323 1329
1324 p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid); 1330 p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, nr);
1325 /* 1331 /*
1326 * Do this prior waking up the new thread - the thread pointer 1332 * Do this prior waking up the new thread - the thread pointer
1327 * might get invalid after that point, if the thread exits quickly. 1333 * might get invalid after that point, if the thread exits quickly.
@@ -1348,7 +1354,7 @@ long do_fork(unsigned long clone_flags,
1348 p->state = TASK_STOPPED; 1354 p->state = TASK_STOPPED;
1349 1355
1350 if (unlikely (trace)) { 1356 if (unlikely (trace)) {
1351 current->ptrace_message = pid; 1357 current->ptrace_message = nr;
1352 ptrace_notify ((trace << 8) | SIGTRAP); 1358 ptrace_notify ((trace << 8) | SIGTRAP);
1353 } 1359 }
1354 1360
@@ -1358,10 +1364,10 @@ long do_fork(unsigned long clone_flags,
1358 ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); 1364 ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
1359 } 1365 }
1360 } else { 1366 } else {
1361 free_pidmap(pid); 1367 free_pid(pid);
1362 pid = PTR_ERR(p); 1368 nr = PTR_ERR(p);
1363 } 1369 }
1364 return pid; 1370 return nr;
1365} 1371}
1366 1372
1367#ifndef ARCH_MIN_MMSTRUCT_ALIGN 1373#ifndef ARCH_MIN_MMSTRUCT_ALIGN
diff --git a/kernel/futex.c b/kernel/futex.c
index 9c9b2b6b22dd..5699c512057b 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1039,9 +1039,11 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
1039 unsigned long timeout = MAX_SCHEDULE_TIMEOUT; 1039 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
1040 int val2 = 0; 1040 int val2 = 0;
1041 1041
1042 if ((op == FUTEX_WAIT) && utime) { 1042 if (utime && (op == FUTEX_WAIT)) {
1043 if (copy_from_user(&t, utime, sizeof(t)) != 0) 1043 if (copy_from_user(&t, utime, sizeof(t)) != 0)
1044 return -EFAULT; 1044 return -EFAULT;
1045 if (!timespec_valid(&t))
1046 return -EINVAL;
1045 timeout = timespec_to_jiffies(&t) + 1; 1047 timeout = timespec_to_jiffies(&t) + 1;
1046 } 1048 }
1047 /* 1049 /*
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 54274fc85321..1ab6a0ea3d14 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -129,9 +129,11 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
129 unsigned long timeout = MAX_SCHEDULE_TIMEOUT; 129 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
130 int val2 = 0; 130 int val2 = 0;
131 131
132 if ((op == FUTEX_WAIT) && utime) { 132 if (utime && (op == FUTEX_WAIT)) {
133 if (get_compat_timespec(&t, utime)) 133 if (get_compat_timespec(&t, utime))
134 return -EFAULT; 134 return -EFAULT;
135 if (!timespec_valid(&t))
136 return -EINVAL;
135 timeout = timespec_to_jiffies(&t) + 1; 137 timeout = timespec_to_jiffies(&t) + 1;
136 } 138 }
137 if (op >= FUTEX_REQUEUE) 139 if (op >= FUTEX_REQUEUE)
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 0237a556eb1f..f181ff4dd32e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -606,6 +606,9 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base)
606{ 606{
607 struct rb_node *node; 607 struct rb_node *node;
608 608
609 if (!base->first)
610 return;
611
609 if (base->get_softirq_time) 612 if (base->get_softirq_time)
610 base->softirq_time = base->get_softirq_time(); 613 base->softirq_time = base->get_softirq_time();
611 614
@@ -655,29 +658,28 @@ void hrtimer_run_queues(void)
655/* 658/*
656 * Sleep related functions: 659 * Sleep related functions:
657 */ 660 */
658 661static int hrtimer_wakeup(struct hrtimer *timer)
659struct sleep_hrtimer {
660 struct hrtimer timer;
661 struct task_struct *task;
662 int expired;
663};
664
665static int nanosleep_wakeup(struct hrtimer *timer)
666{ 662{
667 struct sleep_hrtimer *t = 663 struct hrtimer_sleeper *t =
668 container_of(timer, struct sleep_hrtimer, timer); 664 container_of(timer, struct hrtimer_sleeper, timer);
665 struct task_struct *task = t->task;
669 666
670 t->expired = 1; 667 t->task = NULL;
671 wake_up_process(t->task); 668 if (task)
669 wake_up_process(task);
672 670
673 return HRTIMER_NORESTART; 671 return HRTIMER_NORESTART;
674} 672}
675 673
676static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) 674void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, task_t *task)
677{ 675{
678 t->timer.function = nanosleep_wakeup; 676 sl->timer.function = hrtimer_wakeup;
679 t->task = current; 677 sl->task = task;
680 t->expired = 0; 678}
679
680static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
681{
682 hrtimer_init_sleeper(t, current);
681 683
682 do { 684 do {
683 set_current_state(TASK_INTERRUPTIBLE); 685 set_current_state(TASK_INTERRUPTIBLE);
@@ -685,18 +687,17 @@ static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode)
685 687
686 schedule(); 688 schedule();
687 689
688 if (unlikely(!t->expired)) { 690 hrtimer_cancel(&t->timer);
689 hrtimer_cancel(&t->timer); 691 mode = HRTIMER_ABS;
690 mode = HRTIMER_ABS; 692
691 } 693 } while (t->task && !signal_pending(current));
692 } while (!t->expired && !signal_pending(current));
693 694
694 return t->expired; 695 return t->task == NULL;
695} 696}
696 697
697static long __sched nanosleep_restart(struct restart_block *restart) 698static long __sched nanosleep_restart(struct restart_block *restart)
698{ 699{
699 struct sleep_hrtimer t; 700 struct hrtimer_sleeper t;
700 struct timespec __user *rmtp; 701 struct timespec __user *rmtp;
701 struct timespec tu; 702 struct timespec tu;
702 ktime_t time; 703 ktime_t time;
@@ -729,7 +730,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
729 const enum hrtimer_mode mode, const clockid_t clockid) 730 const enum hrtimer_mode mode, const clockid_t clockid)
730{ 731{
731 struct restart_block *restart; 732 struct restart_block *restart;
732 struct sleep_hrtimer t; 733 struct hrtimer_sleeper t;
733 struct timespec tu; 734 struct timespec tu;
734 ktime_t rem; 735 ktime_t rem;
735 736
diff --git a/kernel/module.c b/kernel/module.c
index bd088a7c1499..d24deb0dbbc9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1254,6 +1254,7 @@ static inline int license_is_gpl_compatible(const char *license)
1254 || strcmp(license, "GPL v2") == 0 1254 || strcmp(license, "GPL v2") == 0
1255 || strcmp(license, "GPL and additional rights") == 0 1255 || strcmp(license, "GPL and additional rights") == 0
1256 || strcmp(license, "Dual BSD/GPL") == 0 1256 || strcmp(license, "Dual BSD/GPL") == 0
1257 || strcmp(license, "Dual MIT/GPL") == 0
1257 || strcmp(license, "Dual MPL/GPL") == 0); 1258 || strcmp(license, "Dual MPL/GPL") == 0);
1258} 1259}
1259 1260
diff --git a/kernel/pid.c b/kernel/pid.c
index a9f2dfd006d2..eeb836b65ca4 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -28,8 +28,9 @@
28#include <linux/hash.h> 28#include <linux/hash.h>
29 29
30#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift) 30#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
31static struct hlist_head *pid_hash[PIDTYPE_MAX]; 31static struct hlist_head *pid_hash;
32static int pidhash_shift; 32static int pidhash_shift;
33static kmem_cache_t *pid_cachep;
33 34
34int pid_max = PID_MAX_DEFAULT; 35int pid_max = PID_MAX_DEFAULT;
35int last_pid; 36int last_pid;
@@ -60,9 +61,22 @@ typedef struct pidmap {
60static pidmap_t pidmap_array[PIDMAP_ENTRIES] = 61static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
61 { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } }; 62 { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };
62 63
64/*
65 * Note: disable interrupts while the pidmap_lock is held as an
66 * interrupt might come in and do read_lock(&tasklist_lock).
67 *
68 * If we don't disable interrupts there is a nasty deadlock between
69 * detach_pid()->free_pid() and another cpu that does
70 * spin_lock(&pidmap_lock) followed by an interrupt routine that does
71 * read_lock(&tasklist_lock);
72 *
73 * After we clean up the tasklist_lock and know there are no
74 * irq handlers that take it we can leave the interrupts enabled.
75 * For now it is easier to be safe than to prove it can't happen.
76 */
63static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); 77static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
64 78
65fastcall void free_pidmap(int pid) 79static fastcall void free_pidmap(int pid)
66{ 80{
67 pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE; 81 pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE;
68 int offset = pid & BITS_PER_PAGE_MASK; 82 int offset = pid & BITS_PER_PAGE_MASK;
@@ -71,7 +85,7 @@ fastcall void free_pidmap(int pid)
71 atomic_inc(&map->nr_free); 85 atomic_inc(&map->nr_free);
72} 86}
73 87
74int alloc_pidmap(void) 88static int alloc_pidmap(void)
75{ 89{
76 int i, offset, max_scan, pid, last = last_pid; 90 int i, offset, max_scan, pid, last = last_pid;
77 pidmap_t *map; 91 pidmap_t *map;
@@ -89,12 +103,12 @@ int alloc_pidmap(void)
89 * Free the page if someone raced with us 103 * Free the page if someone raced with us
90 * installing it: 104 * installing it:
91 */ 105 */
92 spin_lock(&pidmap_lock); 106 spin_lock_irq(&pidmap_lock);
93 if (map->page) 107 if (map->page)
94 free_page(page); 108 free_page(page);
95 else 109 else
96 map->page = (void *)page; 110 map->page = (void *)page;
97 spin_unlock(&pidmap_lock); 111 spin_unlock_irq(&pidmap_lock);
98 if (unlikely(!map->page)) 112 if (unlikely(!map->page))
99 break; 113 break;
100 } 114 }
@@ -131,13 +145,73 @@ int alloc_pidmap(void)
131 return -1; 145 return -1;
132} 146}
133 147
134struct pid * fastcall find_pid(enum pid_type type, int nr) 148fastcall void put_pid(struct pid *pid)
149{
150 if (!pid)
151 return;
152 if ((atomic_read(&pid->count) == 1) ||
153 atomic_dec_and_test(&pid->count))
154 kmem_cache_free(pid_cachep, pid);
155}
156
157static void delayed_put_pid(struct rcu_head *rhp)
158{
159 struct pid *pid = container_of(rhp, struct pid, rcu);
160 put_pid(pid);
161}
162
163fastcall void free_pid(struct pid *pid)
164{
165 /* We can be called with write_lock_irq(&tasklist_lock) held */
166 unsigned long flags;
167
168 spin_lock_irqsave(&pidmap_lock, flags);
169 hlist_del_rcu(&pid->pid_chain);
170 spin_unlock_irqrestore(&pidmap_lock, flags);
171
172 free_pidmap(pid->nr);
173 call_rcu(&pid->rcu, delayed_put_pid);
174}
175
176struct pid *alloc_pid(void)
177{
178 struct pid *pid;
179 enum pid_type type;
180 int nr = -1;
181
182 pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);
183 if (!pid)
184 goto out;
185
186 nr = alloc_pidmap();
187 if (nr < 0)
188 goto out_free;
189
190 atomic_set(&pid->count, 1);
191 pid->nr = nr;
192 for (type = 0; type < PIDTYPE_MAX; ++type)
193 INIT_HLIST_HEAD(&pid->tasks[type]);
194
195 spin_lock_irq(&pidmap_lock);
196 hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]);
197 spin_unlock_irq(&pidmap_lock);
198
199out:
200 return pid;
201
202out_free:
203 kmem_cache_free(pid_cachep, pid);
204 pid = NULL;
205 goto out;
206}
207
208struct pid * fastcall find_pid(int nr)
135{ 209{
136 struct hlist_node *elem; 210 struct hlist_node *elem;
137 struct pid *pid; 211 struct pid *pid;
138 212
139 hlist_for_each_entry_rcu(pid, elem, 213 hlist_for_each_entry_rcu(pid, elem,
140 &pid_hash[type][pid_hashfn(nr)], pid_chain) { 214 &pid_hash[pid_hashfn(nr)], pid_chain) {
141 if (pid->nr == nr) 215 if (pid->nr == nr)
142 return pid; 216 return pid;
143 } 217 }
@@ -146,77 +220,82 @@ struct pid * fastcall find_pid(enum pid_type type, int nr)
146 220
147int fastcall attach_pid(task_t *task, enum pid_type type, int nr) 221int fastcall attach_pid(task_t *task, enum pid_type type, int nr)
148{ 222{
149 struct pid *pid, *task_pid; 223 struct pid_link *link;
150 224 struct pid *pid;
151 task_pid = &task->pids[type]; 225
152 pid = find_pid(type, nr); 226 WARN_ON(!task->pid); /* to be removed soon */
153 task_pid->nr = nr; 227 WARN_ON(!nr); /* to be removed soon */
154 if (pid == NULL) { 228
155 INIT_LIST_HEAD(&task_pid->pid_list); 229 link = &task->pids[type];
156 hlist_add_head_rcu(&task_pid->pid_chain, 230 link->pid = pid = find_pid(nr);
157 &pid_hash[type][pid_hashfn(nr)]); 231 hlist_add_head_rcu(&link->node, &pid->tasks[type]);
158 } else {
159 INIT_HLIST_NODE(&task_pid->pid_chain);
160 list_add_tail_rcu(&task_pid->pid_list, &pid->pid_list);
161 }
162 232
163 return 0; 233 return 0;
164} 234}
165 235
166static fastcall int __detach_pid(task_t *task, enum pid_type type) 236void fastcall detach_pid(task_t *task, enum pid_type type)
167{ 237{
168 struct pid *pid, *pid_next; 238 struct pid_link *link;
169 int nr = 0; 239 struct pid *pid;
240 int tmp;
170 241
171 pid = &task->pids[type]; 242 link = &task->pids[type];
172 if (!hlist_unhashed(&pid->pid_chain)) { 243 pid = link->pid;
173 244
174 if (list_empty(&pid->pid_list)) { 245 hlist_del_rcu(&link->node);
175 nr = pid->nr; 246 link->pid = NULL;
176 hlist_del_rcu(&pid->pid_chain);
177 } else {
178 pid_next = list_entry(pid->pid_list.next,
179 struct pid, pid_list);
180 /* insert next pid from pid_list to hash */
181 hlist_replace_rcu(&pid->pid_chain,
182 &pid_next->pid_chain);
183 }
184 }
185 247
186 list_del_rcu(&pid->pid_list); 248 for (tmp = PIDTYPE_MAX; --tmp >= 0; )
187 pid->nr = 0; 249 if (!hlist_empty(&pid->tasks[tmp]))
250 return;
188 251
189 return nr; 252 free_pid(pid);
190} 253}
191 254
192void fastcall detach_pid(task_t *task, enum pid_type type) 255struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
193{ 256{
194 int tmp, nr; 257 struct task_struct *result = NULL;
258 if (pid) {
259 struct hlist_node *first;
260 first = rcu_dereference(pid->tasks[type].first);
261 if (first)
262 result = hlist_entry(first, struct task_struct, pids[(type)].node);
263 }
264 return result;
265}
195 266
196 nr = __detach_pid(task, type); 267/*
197 if (!nr) 268 * Must be called under rcu_read_lock() or with tasklist_lock read-held.
198 return; 269 */
270task_t *find_task_by_pid_type(int type, int nr)
271{
272 return pid_task(find_pid(nr), type);
273}
199 274
200 for (tmp = PIDTYPE_MAX; --tmp >= 0; ) 275EXPORT_SYMBOL(find_task_by_pid_type);
201 if (tmp != type && find_pid(tmp, nr))
202 return;
203 276
204 free_pidmap(nr); 277struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
278{
279 struct task_struct *result;
280 rcu_read_lock();
281 result = pid_task(pid, type);
282 if (result)
283 get_task_struct(result);
284 rcu_read_unlock();
285 return result;
205} 286}
206 287
207task_t *find_task_by_pid_type(int type, int nr) 288struct pid *find_get_pid(pid_t nr)
208{ 289{
209 struct pid *pid; 290 struct pid *pid;
210 291
211 pid = find_pid(type, nr); 292 rcu_read_lock();
212 if (!pid) 293 pid = get_pid(find_pid(nr));
213 return NULL; 294 rcu_read_unlock();
214 295
215 return pid_task(&pid->pid_list, type); 296 return pid;
216} 297}
217 298
218EXPORT_SYMBOL(find_task_by_pid_type);
219
220/* 299/*
221 * The pid hash table is scaled according to the amount of memory in the 300 * The pid hash table is scaled according to the amount of memory in the
222 * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or 301 * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or
@@ -224,7 +303,7 @@ EXPORT_SYMBOL(find_task_by_pid_type);
224 */ 303 */
225void __init pidhash_init(void) 304void __init pidhash_init(void)
226{ 305{
227 int i, j, pidhash_size; 306 int i, pidhash_size;
228 unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT); 307 unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT);
229 308
230 pidhash_shift = max(4, fls(megabytes * 4)); 309 pidhash_shift = max(4, fls(megabytes * 4));
@@ -233,16 +312,13 @@ void __init pidhash_init(void)
233 312
234 printk("PID hash table entries: %d (order: %d, %Zd bytes)\n", 313 printk("PID hash table entries: %d (order: %d, %Zd bytes)\n",
235 pidhash_size, pidhash_shift, 314 pidhash_size, pidhash_shift,
236 PIDTYPE_MAX * pidhash_size * sizeof(struct hlist_head)); 315 pidhash_size * sizeof(struct hlist_head));
237 316
238 for (i = 0; i < PIDTYPE_MAX; i++) { 317 pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash)));
239 pid_hash[i] = alloc_bootmem(pidhash_size * 318 if (!pid_hash)
240 sizeof(*(pid_hash[i]))); 319 panic("Could not alloc pidhash!\n");
241 if (!pid_hash[i]) 320 for (i = 0; i < pidhash_size; i++)
242 panic("Could not alloc pidhash!\n"); 321 INIT_HLIST_HEAD(&pid_hash[i]);
243 for (j = 0; j < pidhash_size; j++)
244 INIT_HLIST_HEAD(&pid_hash[i][j]);
245 }
246} 322}
247 323
248void __init pidmap_init(void) 324void __init pidmap_init(void)
@@ -251,4 +327,8 @@ void __init pidmap_init(void)
251 /* Reserve PID 0. We never call free_pidmap(0) */ 327 /* Reserve PID 0. We never call free_pidmap(0) */
252 set_bit(0, pidmap_array->page); 328 set_bit(0, pidmap_array->page);
253 atomic_dec(&pidmap_array->nr_free); 329 atomic_dec(&pidmap_array->nr_free);
330
331 pid_cachep = kmem_cache_create("pid", sizeof(struct pid),
332 __alignof__(struct pid),
333 SLAB_PANIC, NULL, NULL);
254} 334}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 8ac7c35fad77..b2a5f671d6cd 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -26,8 +26,7 @@ static inline int freezeable(struct task_struct * p)
26 (p->flags & PF_NOFREEZE) || 26 (p->flags & PF_NOFREEZE) ||
27 (p->exit_state == EXIT_ZOMBIE) || 27 (p->exit_state == EXIT_ZOMBIE) ||
28 (p->exit_state == EXIT_DEAD) || 28 (p->exit_state == EXIT_DEAD) ||
29 (p->state == TASK_STOPPED) || 29 (p->state == TASK_STOPPED))
30 (p->state == TASK_TRACED))
31 return 0; 30 return 0;
32 return 1; 31 return 1;
33} 32}
diff --git a/kernel/sched.c b/kernel/sched.c
index a9ecac398bb9..dd153d6f8a04 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -667,9 +667,13 @@ static int effective_prio(task_t *p)
667/* 667/*
668 * __activate_task - move a task to the runqueue. 668 * __activate_task - move a task to the runqueue.
669 */ 669 */
670static inline void __activate_task(task_t *p, runqueue_t *rq) 670static void __activate_task(task_t *p, runqueue_t *rq)
671{ 671{
672 enqueue_task(p, rq->active); 672 prio_array_t *target = rq->active;
673
674 if (batch_task(p))
675 target = rq->expired;
676 enqueue_task(p, target);
673 rq->nr_running++; 677 rq->nr_running++;
674} 678}
675 679
@@ -688,7 +692,7 @@ static int recalc_task_prio(task_t *p, unsigned long long now)
688 unsigned long long __sleep_time = now - p->timestamp; 692 unsigned long long __sleep_time = now - p->timestamp;
689 unsigned long sleep_time; 693 unsigned long sleep_time;
690 694
691 if (unlikely(p->policy == SCHED_BATCH)) 695 if (batch_task(p))
692 sleep_time = 0; 696 sleep_time = 0;
693 else { 697 else {
694 if (__sleep_time > NS_MAX_SLEEP_AVG) 698 if (__sleep_time > NS_MAX_SLEEP_AVG)
@@ -700,21 +704,25 @@ static int recalc_task_prio(task_t *p, unsigned long long now)
700 if (likely(sleep_time > 0)) { 704 if (likely(sleep_time > 0)) {
701 /* 705 /*
702 * User tasks that sleep a long time are categorised as 706 * User tasks that sleep a long time are categorised as
703 * idle and will get just interactive status to stay active & 707 * idle. They will only have their sleep_avg increased to a
704 * prevent them suddenly becoming cpu hogs and starving 708 * level that makes them just interactive priority to stay
705 * other processes. 709 * active yet prevent them suddenly becoming cpu hogs and
710 * starving other processes.
706 */ 711 */
707 if (p->mm && p->activated != -1 && 712 if (p->mm && sleep_time > INTERACTIVE_SLEEP(p)) {
708 sleep_time > INTERACTIVE_SLEEP(p)) { 713 unsigned long ceiling;
709 p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG - 714
710 DEF_TIMESLICE); 715 ceiling = JIFFIES_TO_NS(MAX_SLEEP_AVG -
716 DEF_TIMESLICE);
717 if (p->sleep_avg < ceiling)
718 p->sleep_avg = ceiling;
711 } else { 719 } else {
712 /* 720 /*
713 * Tasks waking from uninterruptible sleep are 721 * Tasks waking from uninterruptible sleep are
714 * limited in their sleep_avg rise as they 722 * limited in their sleep_avg rise as they
715 * are likely to be waiting on I/O 723 * are likely to be waiting on I/O
716 */ 724 */
717 if (p->activated == -1 && p->mm) { 725 if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) {
718 if (p->sleep_avg >= INTERACTIVE_SLEEP(p)) 726 if (p->sleep_avg >= INTERACTIVE_SLEEP(p))
719 sleep_time = 0; 727 sleep_time = 0;
720 else if (p->sleep_avg + sleep_time >= 728 else if (p->sleep_avg + sleep_time >=
@@ -769,7 +777,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
769 * This checks to make sure it's not an uninterruptible task 777 * This checks to make sure it's not an uninterruptible task
770 * that is now waking up. 778 * that is now waking up.
771 */ 779 */
772 if (!p->activated) { 780 if (p->sleep_type == SLEEP_NORMAL) {
773 /* 781 /*
774 * Tasks which were woken up by interrupts (ie. hw events) 782 * Tasks which were woken up by interrupts (ie. hw events)
775 * are most likely of interactive nature. So we give them 783 * are most likely of interactive nature. So we give them
@@ -778,13 +786,13 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
778 * on a CPU, first time around: 786 * on a CPU, first time around:
779 */ 787 */
780 if (in_interrupt()) 788 if (in_interrupt())
781 p->activated = 2; 789 p->sleep_type = SLEEP_INTERRUPTED;
782 else { 790 else {
783 /* 791 /*
784 * Normal first-time wakeups get a credit too for 792 * Normal first-time wakeups get a credit too for
785 * on-runqueue time, but it will be weighted down: 793 * on-runqueue time, but it will be weighted down:
786 */ 794 */
787 p->activated = 1; 795 p->sleep_type = SLEEP_INTERACTIVE;
788 } 796 }
789 } 797 }
790 p->timestamp = now; 798 p->timestamp = now;
@@ -1272,19 +1280,19 @@ out_activate:
1272 * Tasks on involuntary sleep don't earn 1280 * Tasks on involuntary sleep don't earn
1273 * sleep_avg beyond just interactive state. 1281 * sleep_avg beyond just interactive state.
1274 */ 1282 */
1275 p->activated = -1; 1283 p->sleep_type = SLEEP_NONINTERACTIVE;
1276 } 1284 } else
1277 1285
1278 /* 1286 /*
1279 * Tasks that have marked their sleep as noninteractive get 1287 * Tasks that have marked their sleep as noninteractive get
1280 * woken up without updating their sleep average. (i.e. their 1288 * woken up with their sleep average not weighted in an
1281 * sleep is handled in a priority-neutral manner, no priority 1289 * interactive way.
1282 * boost and no penalty.)
1283 */ 1290 */
1284 if (old_state & TASK_NONINTERACTIVE) 1291 if (old_state & TASK_NONINTERACTIVE)
1285 __activate_task(p, rq); 1292 p->sleep_type = SLEEP_NONINTERACTIVE;
1286 else 1293
1287 activate_task(p, rq, cpu == this_cpu); 1294
1295 activate_task(p, rq, cpu == this_cpu);
1288 /* 1296 /*
1289 * Sync wakeups (i.e. those types of wakeups where the waker 1297 * Sync wakeups (i.e. those types of wakeups where the waker
1290 * has indicated that it will leave the CPU in short order) 1298 * has indicated that it will leave the CPU in short order)
@@ -1658,6 +1666,21 @@ unsigned long nr_iowait(void)
1658 return sum; 1666 return sum;
1659} 1667}
1660 1668
1669unsigned long nr_active(void)
1670{
1671 unsigned long i, running = 0, uninterruptible = 0;
1672
1673 for_each_online_cpu(i) {
1674 running += cpu_rq(i)->nr_running;
1675 uninterruptible += cpu_rq(i)->nr_uninterruptible;
1676 }
1677
1678 if (unlikely((long)uninterruptible < 0))
1679 uninterruptible = 0;
1680
1681 return running + uninterruptible;
1682}
1683
1661#ifdef CONFIG_SMP 1684#ifdef CONFIG_SMP
1662 1685
1663/* 1686/*
@@ -2860,6 +2883,12 @@ EXPORT_SYMBOL(sub_preempt_count);
2860 2883
2861#endif 2884#endif
2862 2885
2886static inline int interactive_sleep(enum sleep_type sleep_type)
2887{
2888 return (sleep_type == SLEEP_INTERACTIVE ||
2889 sleep_type == SLEEP_INTERRUPTED);
2890}
2891
2863/* 2892/*
2864 * schedule() is the main scheduler function. 2893 * schedule() is the main scheduler function.
2865 */ 2894 */
@@ -2983,12 +3012,12 @@ go_idle:
2983 queue = array->queue + idx; 3012 queue = array->queue + idx;
2984 next = list_entry(queue->next, task_t, run_list); 3013 next = list_entry(queue->next, task_t, run_list);
2985 3014
2986 if (!rt_task(next) && next->activated > 0) { 3015 if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
2987 unsigned long long delta = now - next->timestamp; 3016 unsigned long long delta = now - next->timestamp;
2988 if (unlikely((long long)(now - next->timestamp) < 0)) 3017 if (unlikely((long long)(now - next->timestamp) < 0))
2989 delta = 0; 3018 delta = 0;
2990 3019
2991 if (next->activated == 1) 3020 if (next->sleep_type == SLEEP_INTERACTIVE)
2992 delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; 3021 delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
2993 3022
2994 array = next->array; 3023 array = next->array;
@@ -2998,10 +3027,9 @@ go_idle:
2998 dequeue_task(next, array); 3027 dequeue_task(next, array);
2999 next->prio = new_prio; 3028 next->prio = new_prio;
3000 enqueue_task(next, array); 3029 enqueue_task(next, array);
3001 } else 3030 }
3002 requeue_task(next, array);
3003 } 3031 }
3004 next->activated = 0; 3032 next->sleep_type = SLEEP_NORMAL;
3005switch_tasks: 3033switch_tasks:
3006 if (next == rq->idle) 3034 if (next == rq->idle)
3007 schedstat_inc(rq, sched_goidle); 3035 schedstat_inc(rq, sched_goidle);
diff --git a/kernel/signal.c b/kernel/signal.c
index 4922928d91f6..92025b108791 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1560,6 +1560,7 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
1560 /* Let the debugger run. */ 1560 /* Let the debugger run. */
1561 set_current_state(TASK_TRACED); 1561 set_current_state(TASK_TRACED);
1562 spin_unlock_irq(&current->sighand->siglock); 1562 spin_unlock_irq(&current->sighand->siglock);
1563 try_to_freeze();
1563 read_lock(&tasklist_lock); 1564 read_lock(&tasklist_lock);
1564 if (likely(current->ptrace & PT_PTRACED) && 1565 if (likely(current->ptrace & PT_PTRACED) &&
1565 likely(current->parent != current->real_parent || 1566 likely(current->parent != current->real_parent ||
diff --git a/kernel/sys.c b/kernel/sys.c
index 7ef7f6054c28..0b6ec0e7936f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1372,18 +1372,29 @@ asmlinkage long sys_getsid(pid_t pid)
1372asmlinkage long sys_setsid(void) 1372asmlinkage long sys_setsid(void)
1373{ 1373{
1374 struct task_struct *group_leader = current->group_leader; 1374 struct task_struct *group_leader = current->group_leader;
1375 struct pid *pid; 1375 pid_t session;
1376 int err = -EPERM; 1376 int err = -EPERM;
1377 1377
1378 mutex_lock(&tty_mutex); 1378 mutex_lock(&tty_mutex);
1379 write_lock_irq(&tasklist_lock); 1379 write_lock_irq(&tasklist_lock);
1380 1380
1381 pid = find_pid(PIDTYPE_PGID, group_leader->pid); 1381 /* Fail if I am already a session leader */
1382 if (pid) 1382 if (group_leader->signal->leader)
1383 goto out;
1384
1385 session = group_leader->pid;
1386 /* Fail if a process group id already exists that equals the
1387 * proposed session id.
1388 *
1389 * Don't check if session id == 1 because kernel threads use this
1390 * session id and so the check will always fail and make it so
1391 * init cannot successfully call setsid.
1392 */
1393 if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
1383 goto out; 1394 goto out;
1384 1395
1385 group_leader->signal->leader = 1; 1396 group_leader->signal->leader = 1;
1386 __set_special_pids(group_leader->pid, group_leader->pid); 1397 __set_special_pids(session, session);
1387 group_leader->signal->tty = NULL; 1398 group_leader->signal->tty = NULL;
1388 group_leader->signal->tty_old_pgrp = 0; 1399 group_leader->signal->tty_old_pgrp = 0;
1389 err = process_group(group_leader); 1400 err = process_group(group_leader);
diff --git a/kernel/timer.c b/kernel/timer.c
index ab189dd187cb..6b812c04737b 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -54,7 +54,6 @@ EXPORT_SYMBOL(jiffies_64);
54/* 54/*
55 * per-CPU timer vector definitions: 55 * per-CPU timer vector definitions:
56 */ 56 */
57
58#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6) 57#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6)
59#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8) 58#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8)
60#define TVN_SIZE (1 << TVN_BITS) 59#define TVN_SIZE (1 << TVN_BITS)
@@ -62,11 +61,6 @@ EXPORT_SYMBOL(jiffies_64);
62#define TVN_MASK (TVN_SIZE - 1) 61#define TVN_MASK (TVN_SIZE - 1)
63#define TVR_MASK (TVR_SIZE - 1) 62#define TVR_MASK (TVR_SIZE - 1)
64 63
65struct timer_base_s {
66 spinlock_t lock;
67 struct timer_list *running_timer;
68};
69
70typedef struct tvec_s { 64typedef struct tvec_s {
71 struct list_head vec[TVN_SIZE]; 65 struct list_head vec[TVN_SIZE];
72} tvec_t; 66} tvec_t;
@@ -76,7 +70,8 @@ typedef struct tvec_root_s {
76} tvec_root_t; 70} tvec_root_t;
77 71
78struct tvec_t_base_s { 72struct tvec_t_base_s {
79 struct timer_base_s t_base; 73 spinlock_t lock;
74 struct timer_list *running_timer;
80 unsigned long timer_jiffies; 75 unsigned long timer_jiffies;
81 tvec_root_t tv1; 76 tvec_root_t tv1;
82 tvec_t tv2; 77 tvec_t tv2;
@@ -87,13 +82,14 @@ struct tvec_t_base_s {
87 82
88typedef struct tvec_t_base_s tvec_base_t; 83typedef struct tvec_t_base_s tvec_base_t;
89static DEFINE_PER_CPU(tvec_base_t *, tvec_bases); 84static DEFINE_PER_CPU(tvec_base_t *, tvec_bases);
90static tvec_base_t boot_tvec_bases; 85tvec_base_t boot_tvec_bases;
86EXPORT_SYMBOL(boot_tvec_bases);
91 87
92static inline void set_running_timer(tvec_base_t *base, 88static inline void set_running_timer(tvec_base_t *base,
93 struct timer_list *timer) 89 struct timer_list *timer)
94{ 90{
95#ifdef CONFIG_SMP 91#ifdef CONFIG_SMP
96 base->t_base.running_timer = timer; 92 base->running_timer = timer;
97#endif 93#endif
98} 94}
99 95
@@ -139,15 +135,6 @@ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
139 list_add_tail(&timer->entry, vec); 135 list_add_tail(&timer->entry, vec);
140} 136}
141 137
142typedef struct timer_base_s timer_base_t;
143/*
144 * Used by TIMER_INITIALIZER, we can't use per_cpu(tvec_bases)
145 * at compile time, and we need timer->base to lock the timer.
146 */
147timer_base_t __init_timer_base
148 ____cacheline_aligned_in_smp = { .lock = SPIN_LOCK_UNLOCKED };
149EXPORT_SYMBOL(__init_timer_base);
150
151/*** 138/***
152 * init_timer - initialize a timer. 139 * init_timer - initialize a timer.
153 * @timer: the timer to be initialized 140 * @timer: the timer to be initialized
@@ -158,7 +145,7 @@ EXPORT_SYMBOL(__init_timer_base);
158void fastcall init_timer(struct timer_list *timer) 145void fastcall init_timer(struct timer_list *timer)
159{ 146{
160 timer->entry.next = NULL; 147 timer->entry.next = NULL;
161 timer->base = &per_cpu(tvec_bases, raw_smp_processor_id())->t_base; 148 timer->base = per_cpu(tvec_bases, raw_smp_processor_id());
162} 149}
163EXPORT_SYMBOL(init_timer); 150EXPORT_SYMBOL(init_timer);
164 151
@@ -174,7 +161,7 @@ static inline void detach_timer(struct timer_list *timer,
174} 161}
175 162
176/* 163/*
177 * We are using hashed locking: holding per_cpu(tvec_bases).t_base.lock 164 * We are using hashed locking: holding per_cpu(tvec_bases).lock
178 * means that all timers which are tied to this base via timer->base are 165 * means that all timers which are tied to this base via timer->base are
179 * locked, and the base itself is locked too. 166 * locked, and the base itself is locked too.
180 * 167 *
@@ -185,10 +172,10 @@ static inline void detach_timer(struct timer_list *timer,
185 * possible to set timer->base = NULL and drop the lock: the timer remains 172 * possible to set timer->base = NULL and drop the lock: the timer remains
186 * locked. 173 * locked.
187 */ 174 */
188static timer_base_t *lock_timer_base(struct timer_list *timer, 175static tvec_base_t *lock_timer_base(struct timer_list *timer,
189 unsigned long *flags) 176 unsigned long *flags)
190{ 177{
191 timer_base_t *base; 178 tvec_base_t *base;
192 179
193 for (;;) { 180 for (;;) {
194 base = timer->base; 181 base = timer->base;
@@ -205,8 +192,7 @@ static timer_base_t *lock_timer_base(struct timer_list *timer,
205 192
206int __mod_timer(struct timer_list *timer, unsigned long expires) 193int __mod_timer(struct timer_list *timer, unsigned long expires)
207{ 194{
208 timer_base_t *base; 195 tvec_base_t *base, *new_base;
209 tvec_base_t *new_base;
210 unsigned long flags; 196 unsigned long flags;
211 int ret = 0; 197 int ret = 0;
212 198
@@ -221,7 +207,7 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
221 207
222 new_base = __get_cpu_var(tvec_bases); 208 new_base = __get_cpu_var(tvec_bases);
223 209
224 if (base != &new_base->t_base) { 210 if (base != new_base) {
225 /* 211 /*
226 * We are trying to schedule the timer on the local CPU. 212 * We are trying to schedule the timer on the local CPU.
227 * However we can't change timer's base while it is running, 213 * However we can't change timer's base while it is running,
@@ -229,21 +215,19 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
229 * handler yet has not finished. This also guarantees that 215 * handler yet has not finished. This also guarantees that
230 * the timer is serialized wrt itself. 216 * the timer is serialized wrt itself.
231 */ 217 */
232 if (unlikely(base->running_timer == timer)) { 218 if (likely(base->running_timer != timer)) {
233 /* The timer remains on a former base */
234 new_base = container_of(base, tvec_base_t, t_base);
235 } else {
236 /* See the comment in lock_timer_base() */ 219 /* See the comment in lock_timer_base() */
237 timer->base = NULL; 220 timer->base = NULL;
238 spin_unlock(&base->lock); 221 spin_unlock(&base->lock);
239 spin_lock(&new_base->t_base.lock); 222 base = new_base;
240 timer->base = &new_base->t_base; 223 spin_lock(&base->lock);
224 timer->base = base;
241 } 225 }
242 } 226 }
243 227
244 timer->expires = expires; 228 timer->expires = expires;
245 internal_add_timer(new_base, timer); 229 internal_add_timer(base, timer);
246 spin_unlock_irqrestore(&new_base->t_base.lock, flags); 230 spin_unlock_irqrestore(&base->lock, flags);
247 231
248 return ret; 232 return ret;
249} 233}
@@ -263,10 +247,10 @@ void add_timer_on(struct timer_list *timer, int cpu)
263 unsigned long flags; 247 unsigned long flags;
264 248
265 BUG_ON(timer_pending(timer) || !timer->function); 249 BUG_ON(timer_pending(timer) || !timer->function);
266 spin_lock_irqsave(&base->t_base.lock, flags); 250 spin_lock_irqsave(&base->lock, flags);
267 timer->base = &base->t_base; 251 timer->base = base;
268 internal_add_timer(base, timer); 252 internal_add_timer(base, timer);
269 spin_unlock_irqrestore(&base->t_base.lock, flags); 253 spin_unlock_irqrestore(&base->lock, flags);
270} 254}
271 255
272 256
@@ -319,7 +303,7 @@ EXPORT_SYMBOL(mod_timer);
319 */ 303 */
320int del_timer(struct timer_list *timer) 304int del_timer(struct timer_list *timer)
321{ 305{
322 timer_base_t *base; 306 tvec_base_t *base;
323 unsigned long flags; 307 unsigned long flags;
324 int ret = 0; 308 int ret = 0;
325 309
@@ -346,7 +330,7 @@ EXPORT_SYMBOL(del_timer);
346 */ 330 */
347int try_to_del_timer_sync(struct timer_list *timer) 331int try_to_del_timer_sync(struct timer_list *timer)
348{ 332{
349 timer_base_t *base; 333 tvec_base_t *base;
350 unsigned long flags; 334 unsigned long flags;
351 int ret = -1; 335 int ret = -1;
352 336
@@ -410,7 +394,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
410 struct timer_list *tmp; 394 struct timer_list *tmp;
411 395
412 tmp = list_entry(curr, struct timer_list, entry); 396 tmp = list_entry(curr, struct timer_list, entry);
413 BUG_ON(tmp->base != &base->t_base); 397 BUG_ON(tmp->base != base);
414 curr = curr->next; 398 curr = curr->next;
415 internal_add_timer(base, tmp); 399 internal_add_timer(base, tmp);
416 } 400 }
@@ -432,7 +416,7 @@ static inline void __run_timers(tvec_base_t *base)
432{ 416{
433 struct timer_list *timer; 417 struct timer_list *timer;
434 418
435 spin_lock_irq(&base->t_base.lock); 419 spin_lock_irq(&base->lock);
436 while (time_after_eq(jiffies, base->timer_jiffies)) { 420 while (time_after_eq(jiffies, base->timer_jiffies)) {
437 struct list_head work_list = LIST_HEAD_INIT(work_list); 421 struct list_head work_list = LIST_HEAD_INIT(work_list);
438 struct list_head *head = &work_list; 422 struct list_head *head = &work_list;
@@ -458,7 +442,7 @@ static inline void __run_timers(tvec_base_t *base)
458 442
459 set_running_timer(base, timer); 443 set_running_timer(base, timer);
460 detach_timer(timer, 1); 444 detach_timer(timer, 1);
461 spin_unlock_irq(&base->t_base.lock); 445 spin_unlock_irq(&base->lock);
462 { 446 {
463 int preempt_count = preempt_count(); 447 int preempt_count = preempt_count();
464 fn(data); 448 fn(data);
@@ -471,11 +455,11 @@ static inline void __run_timers(tvec_base_t *base)
471 BUG(); 455 BUG();
472 } 456 }
473 } 457 }
474 spin_lock_irq(&base->t_base.lock); 458 spin_lock_irq(&base->lock);
475 } 459 }
476 } 460 }
477 set_running_timer(base, NULL); 461 set_running_timer(base, NULL);
478 spin_unlock_irq(&base->t_base.lock); 462 spin_unlock_irq(&base->lock);
479} 463}
480 464
481#ifdef CONFIG_NO_IDLE_HZ 465#ifdef CONFIG_NO_IDLE_HZ
@@ -506,7 +490,7 @@ unsigned long next_timer_interrupt(void)
506 hr_expires += jiffies; 490 hr_expires += jiffies;
507 491
508 base = __get_cpu_var(tvec_bases); 492 base = __get_cpu_var(tvec_bases);
509 spin_lock(&base->t_base.lock); 493 spin_lock(&base->lock);
510 expires = base->timer_jiffies + (LONG_MAX >> 1); 494 expires = base->timer_jiffies + (LONG_MAX >> 1);
511 list = NULL; 495 list = NULL;
512 496
@@ -554,7 +538,7 @@ found:
554 expires = nte->expires; 538 expires = nte->expires;
555 } 539 }
556 } 540 }
557 spin_unlock(&base->t_base.lock); 541 spin_unlock(&base->lock);
558 542
559 if (time_before(hr_expires, expires)) 543 if (time_before(hr_expires, expires))
560 return hr_expires; 544 return hr_expires;
@@ -841,7 +825,7 @@ void update_process_times(int user_tick)
841 */ 825 */
842static unsigned long count_active_tasks(void) 826static unsigned long count_active_tasks(void)
843{ 827{
844 return (nr_running() + nr_uninterruptible()) * FIXED_1; 828 return nr_active() * FIXED_1;
845} 829}
846 830
847/* 831/*
@@ -1262,7 +1246,7 @@ static int __devinit init_timers_cpu(int cpu)
1262 } 1246 }
1263 per_cpu(tvec_bases, cpu) = base; 1247 per_cpu(tvec_bases, cpu) = base;
1264 } 1248 }
1265 spin_lock_init(&base->t_base.lock); 1249 spin_lock_init(&base->lock);
1266 for (j = 0; j < TVN_SIZE; j++) { 1250 for (j = 0; j < TVN_SIZE; j++) {
1267 INIT_LIST_HEAD(base->tv5.vec + j); 1251 INIT_LIST_HEAD(base->tv5.vec + j);
1268 INIT_LIST_HEAD(base->tv4.vec + j); 1252 INIT_LIST_HEAD(base->tv4.vec + j);
@@ -1284,7 +1268,7 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
1284 while (!list_empty(head)) { 1268 while (!list_empty(head)) {
1285 timer = list_entry(head->next, struct timer_list, entry); 1269 timer = list_entry(head->next, struct timer_list, entry);
1286 detach_timer(timer, 0); 1270 detach_timer(timer, 0);
1287 timer->base = &new_base->t_base; 1271 timer->base = new_base;
1288 internal_add_timer(new_base, timer); 1272 internal_add_timer(new_base, timer);
1289 } 1273 }
1290} 1274}
@@ -1300,11 +1284,11 @@ static void __devinit migrate_timers(int cpu)
1300 new_base = get_cpu_var(tvec_bases); 1284 new_base = get_cpu_var(tvec_bases);
1301 1285
1302 local_irq_disable(); 1286 local_irq_disable();
1303 spin_lock(&new_base->t_base.lock); 1287 spin_lock(&new_base->lock);
1304 spin_lock(&old_base->t_base.lock); 1288 spin_lock(&old_base->lock);
1289
1290 BUG_ON(old_base->running_timer);
1305 1291
1306 if (old_base->t_base.running_timer)
1307 BUG();
1308 for (i = 0; i < TVR_SIZE; i++) 1292 for (i = 0; i < TVR_SIZE; i++)
1309 migrate_timer_list(new_base, old_base->tv1.vec + i); 1293 migrate_timer_list(new_base, old_base->tv1.vec + i);
1310 for (i = 0; i < TVN_SIZE; i++) { 1294 for (i = 0; i < TVN_SIZE; i++) {
@@ -1314,8 +1298,8 @@ static void __devinit migrate_timers(int cpu)
1314 migrate_timer_list(new_base, old_base->tv5.vec + i); 1298 migrate_timer_list(new_base, old_base->tv5.vec + i);
1315 } 1299 }
1316 1300
1317 spin_unlock(&old_base->t_base.lock); 1301 spin_unlock(&old_base->lock);
1318 spin_unlock(&new_base->t_base.lock); 1302 spin_unlock(&new_base->lock);
1319 local_irq_enable(); 1303 local_irq_enable();
1320 put_cpu_var(tvec_bases); 1304 put_cpu_var(tvec_bases);
1321} 1305}
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 907c39257ca0..0a03357a1f8e 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -35,17 +35,6 @@
35 * 35 *
36 * LINUX_FADV_ASYNC_WRITE: push some or all of the dirty pages at the disk. 36 * LINUX_FADV_ASYNC_WRITE: push some or all of the dirty pages at the disk.
37 * 37 *
38 * LINUX_FADV_WRITE_WAIT, LINUX_FADV_ASYNC_WRITE: push all of the currently
39 * dirty pages at the disk.
40 *
41 * LINUX_FADV_WRITE_WAIT, LINUX_FADV_ASYNC_WRITE, LINUX_FADV_WRITE_WAIT: push
42 * all of the currently dirty pages at the disk, wait until they have been
43 * written.
44 *
45 * It should be noted that none of these operations write out the file's
46 * metadata. So unless the application is strictly performing overwrites of
47 * already-instantiated disk blocks, there are no guarantees here that the data
48 * will be available after a crash.
49 */ 38 */
50asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) 39asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
51{ 40{
@@ -129,15 +118,6 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
129 invalidate_mapping_pages(mapping, start_index, 118 invalidate_mapping_pages(mapping, start_index,
130 end_index); 119 end_index);
131 break; 120 break;
132 case LINUX_FADV_ASYNC_WRITE:
133 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
134 WB_SYNC_NONE);
135 break;
136 case LINUX_FADV_WRITE_WAIT:
137 ret = wait_on_page_writeback_range(mapping,
138 offset >> PAGE_CACHE_SHIFT,
139 endbyte >> PAGE_CACHE_SHIFT);
140 break;
141 default: 121 default:
142 ret = -EINVAL; 122 ret = -EINVAL;
143 } 123 }
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ebad6bbb3501..832f676ca038 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -334,6 +334,7 @@ static unsigned long set_max_huge_pages(unsigned long count)
334 return nr_huge_pages; 334 return nr_huge_pages;
335 335
336 spin_lock(&hugetlb_lock); 336 spin_lock(&hugetlb_lock);
337 count = max(count, reserved_huge_pages);
337 try_to_free_low(count); 338 try_to_free_low(count);
338 while (count < nr_huge_pages) { 339 while (count < nr_huge_pages) {
339 struct page *page = dequeue_huge_page(NULL, 0); 340 struct page *page = dequeue_huge_page(NULL, 0);
@@ -697,9 +698,10 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
697 pfn_offset = (vaddr & ~HPAGE_MASK) >> PAGE_SHIFT; 698 pfn_offset = (vaddr & ~HPAGE_MASK) >> PAGE_SHIFT;
698 page = pte_page(*pte); 699 page = pte_page(*pte);
699same_page: 700same_page:
700 get_page(page); 701 if (pages) {
701 if (pages) 702 get_page(page);
702 pages[i] = page + pfn_offset; 703 pages[i] = page + pfn_offset;
704 }
703 705
704 if (vmas) 706 if (vmas)
705 vmas[i] = vma; 707 vmas[i] = vma;
diff --git a/mm/memory.c b/mm/memory.c
index 8d8f52569f32..0ec7bc644271 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -87,7 +87,7 @@ int randomize_va_space __read_mostly = 1;
87static int __init disable_randmaps(char *s) 87static int __init disable_randmaps(char *s)
88{ 88{
89 randomize_va_space = 0; 89 randomize_va_space = 0;
90 return 0; 90 return 1;
91} 91}
92__setup("norandmaps", disable_randmaps); 92__setup("norandmaps", disable_randmaps);
93 93
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 39aa9d129612..e5fd5385f0cc 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -397,18 +397,24 @@ void free_swap_and_cache(swp_entry_t entry)
397 397
398 p = swap_info_get(entry); 398 p = swap_info_get(entry);
399 if (p) { 399 if (p) {
400 if (swap_entry_free(p, swp_offset(entry)) == 1) 400 if (swap_entry_free(p, swp_offset(entry)) == 1) {
401 page = find_trylock_page(&swapper_space, entry.val); 401 page = find_get_page(&swapper_space, entry.val);
402 if (page && unlikely(TestSetPageLocked(page))) {
403 page_cache_release(page);
404 page = NULL;
405 }
406 }
402 spin_unlock(&swap_lock); 407 spin_unlock(&swap_lock);
403 } 408 }
404 if (page) { 409 if (page) {
405 int one_user; 410 int one_user;
406 411
407 BUG_ON(PagePrivate(page)); 412 BUG_ON(PagePrivate(page));
408 page_cache_get(page);
409 one_user = (page_count(page) == 2); 413 one_user = (page_count(page) == 2);
410 /* Only cache user (+us), or swap space full? Free it! */ 414 /* Only cache user (+us), or swap space full? Free it! */
411 if (!PageWriteback(page) && (one_user || vm_swap_full())) { 415 /* Also recheck PageSwapCache after page is locked (above) */
416 if (PageSwapCache(page) && !PageWriteback(page) &&
417 (one_user || vm_swap_full())) {
412 delete_from_swap_cache(page); 418 delete_from_swap_cache(page);
413 SetPageDirty(page); 419 SetPageDirty(page);
414 } 420 }
diff --git a/net/core/dev.c b/net/core/dev.c
index a3ab11f34153..434220d093aa 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1080,6 +1080,70 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
1080 rcu_read_unlock(); 1080 rcu_read_unlock();
1081} 1081}
1082 1082
1083
1084void __netif_schedule(struct net_device *dev)
1085{
1086 if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
1087 unsigned long flags;
1088 struct softnet_data *sd;
1089
1090 local_irq_save(flags);
1091 sd = &__get_cpu_var(softnet_data);
1092 dev->next_sched = sd->output_queue;
1093 sd->output_queue = dev;
1094 raise_softirq_irqoff(NET_TX_SOFTIRQ);
1095 local_irq_restore(flags);
1096 }
1097}
1098EXPORT_SYMBOL(__netif_schedule);
1099
1100void __netif_rx_schedule(struct net_device *dev)
1101{
1102 unsigned long flags;
1103
1104 local_irq_save(flags);
1105 dev_hold(dev);
1106 list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
1107 if (dev->quota < 0)
1108 dev->quota += dev->weight;
1109 else
1110 dev->quota = dev->weight;
1111 __raise_softirq_irqoff(NET_RX_SOFTIRQ);
1112 local_irq_restore(flags);
1113}
1114EXPORT_SYMBOL(__netif_rx_schedule);
1115
1116void dev_kfree_skb_any(struct sk_buff *skb)
1117{
1118 if (in_irq() || irqs_disabled())
1119 dev_kfree_skb_irq(skb);
1120 else
1121 dev_kfree_skb(skb);
1122}
1123EXPORT_SYMBOL(dev_kfree_skb_any);
1124
1125
1126/* Hot-plugging. */
1127void netif_device_detach(struct net_device *dev)
1128{
1129 if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
1130 netif_running(dev)) {
1131 netif_stop_queue(dev);
1132 }
1133}
1134EXPORT_SYMBOL(netif_device_detach);
1135
1136void netif_device_attach(struct net_device *dev)
1137{
1138 if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
1139 netif_running(dev)) {
1140 netif_wake_queue(dev);
1141 __netdev_watchdog_up(dev);
1142 }
1143}
1144EXPORT_SYMBOL(netif_device_attach);
1145
1146
1083/* 1147/*
1084 * Invalidate hardware checksum when packet is to be mangled, and 1148 * Invalidate hardware checksum when packet is to be mangled, and
1085 * complete checksum manually on outgoing path. 1149 * complete checksum manually on outgoing path.
diff --git a/net/core/sock.c b/net/core/sock.c
index a96ea7dd0fc1..ed2afdb9ea2d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -385,7 +385,21 @@ set_sndbuf:
385 val = sysctl_rmem_max; 385 val = sysctl_rmem_max;
386set_rcvbuf: 386set_rcvbuf:
387 sk->sk_userlocks |= SOCK_RCVBUF_LOCK; 387 sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
388 /* FIXME: is this lower bound the right one? */ 388 /*
389 * We double it on the way in to account for
390 * "struct sk_buff" etc. overhead. Applications
391 * assume that the SO_RCVBUF setting they make will
392 * allow that much actual data to be received on that
393 * socket.
394 *
395 * Applications are unaware that "struct sk_buff" and
396 * other overheads allocate from the receive buffer
397 * during socket buffer allocation.
398 *
399 * And after considering the possible alternatives,
400 * returning the value we actually used in getsockopt
401 * is the most desirable behavior.
402 */
389 if ((val * 2) < SOCK_MIN_RCVBUF) 403 if ((val * 2) < SOCK_MIN_RCVBUF)
390 sk->sk_rcvbuf = SOCK_MIN_RCVBUF; 404 sk->sk_rcvbuf = SOCK_MIN_RCVBUF;
391 else 405 else
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index e3dd30d36c8a..b39e2a597889 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -204,7 +204,7 @@ static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
204 if (rc) { 204 if (rc) {
205 kfree(opt->dccpop_sc->dccpoc_val); 205 kfree(opt->dccpop_sc->dccpoc_val);
206 kfree(opt->dccpop_sc); 206 kfree(opt->dccpop_sc);
207 opt->dccpop_sc = 0; 207 opt->dccpop_sc = NULL;
208 return rc; 208 return rc;
209 } 209 }
210 210
@@ -322,7 +322,7 @@ static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
322 opt->dccpop_type = type == DCCPO_CHANGE_L ? DCCPO_CONFIRM_R : 322 opt->dccpop_type = type == DCCPO_CHANGE_L ? DCCPO_CONFIRM_R :
323 DCCPO_CONFIRM_L; 323 DCCPO_CONFIRM_L;
324 opt->dccpop_feat = feature; 324 opt->dccpop_feat = feature;
325 opt->dccpop_val = 0; 325 opt->dccpop_val = NULL;
326 opt->dccpop_len = 0; 326 opt->dccpop_len = 0;
327 327
328 /* change feature */ 328 /* change feature */
@@ -523,7 +523,7 @@ int dccp_feat_clone(struct sock *oldsk, struct sock *newsk)
523 * once... 523 * once...
524 */ 524 */
525 /* the master socket no longer needs to worry about confirms */ 525 /* the master socket no longer needs to worry about confirms */
526 opt->dccpop_sc = 0; /* it's not a memleak---new socket has it */ 526 opt->dccpop_sc = NULL; /* it's not a memleak---new socket has it */
527 527
528 /* reset state for a new socket */ 528 /* reset state for a new socket */
529 opt->dccpop_conf = 0; 529 opt->dccpop_conf = 0;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index d2ae9893ca17..a26ff9f44576 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -620,7 +620,7 @@ int dn_dev_set_default(struct net_device *dev, int force)
620 } 620 }
621 write_unlock(&dndev_lock); 621 write_unlock(&dndev_lock);
622 if (old) 622 if (old)
623 dev_put(dev); 623 dev_put(old);
624 return rv; 624 return rv;
625} 625}
626 626