aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@kernel.bkbits.net>2005-03-31 13:45:22 -0800
committerDavid S. Miller <davem@kernel.bkbits.net>2005-03-31 13:45:22 -0800
commitc168f9a4f1bcb46516e7fc11b72325eedfe1803a (patch)
treee7ad798c3e8a62a9b556d0d2776c31177d23c55e
parentf4b9bfe34026406a19d58626b14f1a86454adf30 (diff)
parentf937b476f5353acc37be22a2f59c7b0f2fc77c8e (diff)
downloadhistory-c168f9a4f1bcb46516e7fc11b72325eedfe1803a.tar.gz
Merge davem@sunset.davemloft.net:/home/davem/src/BK/sparc-2.6
into kernel.bkbits.net:/home/davem/sparc-2.6
-rw-r--r--Documentation/SubmittingDrivers7
-rw-r--r--Documentation/cpusets.txt8
-rw-r--r--Documentation/kernel-docs.txt7
-rw-r--r--Documentation/oops-tracing.txt32
-rw-r--r--Documentation/sysrq.txt2
-rw-r--r--arch/frv/kernel/setup.c3
-rw-r--r--arch/i386/kernel/cpu/common.c11
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c456
-rw-r--r--arch/i386/kernel/entry.S130
-rw-r--r--arch/i386/kernel/head.S2
-rw-r--r--arch/i386/kernel/kprobes.c19
-rw-r--r--arch/i386/kernel/process.c29
-rw-r--r--arch/i386/kernel/smp.c2
-rw-r--r--arch/i386/kernel/traps.c45
-rw-r--r--arch/m32r/kernel/setup.c31
-rw-r--r--arch/m32r/mm/discontig.c1
-rw-r--r--arch/ppc/Kconfig2
-rw-r--r--arch/ppc/boot/simple/mpc52xx_tty.c30
-rw-r--r--arch/ppc/kernel/entry.S91
-rw-r--r--arch/ppc/kernel/head_44x.S77
-rw-r--r--arch/ppc/kernel/head_4xx.S44
-rw-r--r--arch/ppc/kernel/head_booke.h139
-rw-r--r--arch/ppc/kernel/head_e500.S81
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c18
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c19
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c21
-rw-r--r--arch/ppc/platforms/Makefile2
-rw-r--r--arch/ppc/platforms/lite5200.c87
-rw-r--r--arch/ppc/platforms/lite5200.h2
-rw-r--r--arch/ppc/platforms/pmac_backlight.c80
-rw-r--r--arch/ppc/syslib/Makefile3
-rw-r--r--arch/ppc/syslib/cpm2_pic.c94
-rw-r--r--arch/ppc/syslib/cpm2_pic.h3
-rw-r--r--arch/ppc/syslib/m8260_setup.c8
-rw-r--r--arch/ppc/syslib/mpc52xx_devices.c318
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c2
-rw-r--r--arch/ppc/syslib/mpc52xx_pic.c4
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c42
-rw-r--r--arch/ppc/syslib/mpc52xx_sys.c38
-rw-r--r--arch/ppc/syslib/mpc85xx_sys.c8
-rw-r--r--arch/ppc64/Kconfig17
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c40
-rw-r--r--arch/ppc64/kernel/kprobes.c15
-rw-r--r--arch/ppc64/kernel/lmb.c26
-rw-r--r--arch/ppc64/kernel/prom.c15
-rw-r--r--arch/ppc64/kernel/prom_init.c137
-rw-r--r--arch/ppc64/kernel/ptrace.c3
-rw-r--r--arch/ppc64/kernel/setup.c20
-rw-r--r--arch/ppc64/mm/hash_utils.c23
-rw-r--r--arch/ppc64/mm/numa.c46
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sparc64/kernel/kprobes.c18
-rw-r--r--arch/um/Kconfig.debug2
-rw-r--r--arch/um/drivers/chan_kern.c5
-rw-r--r--arch/um/drivers/line.c2
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h16
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h16
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h6
-rw-r--r--arch/um/include/sysdep-x86_64/syscalls.h5
-rw-r--r--arch/um/kernel/sigio_user.c29
-rw-r--r--arch/um/kernel/skas/uaccess.c3
-rw-r--r--arch/um/kernel/sys_call_table.c15
-rw-r--r--arch/um/kernel/um_arch.c2
-rw-r--r--arch/x86_64/ia32/sys_ia32.c1
-rw-r--r--arch/x86_64/kernel/kprobes.c160
-rw-r--r--arch/x86_64/kernel/process.c41
-rw-r--r--arch/x86_64/kernel/smp.c5
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c1
-rw-r--r--drivers/block/ll_rw_blk.c2
-rw-r--r--drivers/block/rd.c4
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/mem.c31
-rw-r--r--drivers/char/rio/riocmd.c67
-rw-r--r--drivers/char/sx.c60
-rw-r--r--drivers/char/sysrq.c23
-rw-r--r--drivers/char/vt.c18
-rw-r--r--drivers/media/dvb/frontends/cx24110.c28
-rw-r--r--drivers/media/video/zr36050.c2
-rw-r--r--drivers/parport/parport_pc.c8
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/mpc52xx_uart.c189
-rw-r--r--drivers/video/Kconfig31
-rw-r--r--drivers/video/Makefile14
-rw-r--r--drivers/video/asiliantfb.c2
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c27
-rw-r--r--drivers/video/aty/radeon_accel.c28
-rw-r--r--drivers/video/aty/radeon_base.c67
-rw-r--r--drivers/video/aty/radeon_i2c.c6
-rw-r--r--drivers/video/aty/radeon_monitor.c33
-rw-r--r--drivers/video/aty/radeon_pm.c41
-rw-r--r--drivers/video/aty/radeonfb.h146
-rw-r--r--drivers/video/chipsfb.c2
-rw-r--r--drivers/video/cirrusfb.c2
-rw-r--r--drivers/video/console/bitblit.c11
-rw-r--r--drivers/video/console/fbcon.c86
-rw-r--r--drivers/video/console/fbcon.h8
-rw-r--r--drivers/video/console/mdacon.c4
-rw-r--r--drivers/video/console/sticore.c9
-rw-r--r--drivers/video/cyber2000fb.c2
-rw-r--r--drivers/video/fbmem.c9
-rw-r--r--drivers/video/fbmon.c23
-rw-r--r--drivers/video/igafb.c3
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/intelfb/intelfbdrv.c2
-rw-r--r--drivers/video/kyro/fbdev.c2
-rw-r--r--drivers/video/macmodes.c9
-rw-r--r--drivers/video/matrox/matroxfb_accel.c14
-rw-r--r--drivers/video/matrox/matroxfb_base.h4
-rw-r--r--drivers/video/modedb.c4
-rw-r--r--drivers/video/neofb.c38
-rw-r--r--drivers/video/nvidia/nv_accel.c72
-rw-r--r--drivers/video/nvidia/nv_dma.h10
-rw-r--r--drivers/video/nvidia/nv_hw.c11
-rw-r--r--drivers/video/nvidia/nv_i2c.c2
-rw-r--r--drivers/video/nvidia/nv_local.h13
-rw-r--r--drivers/video/nvidia/nv_of.c1
-rw-r--r--drivers/video/nvidia/nv_proto.h2
-rw-r--r--drivers/video/nvidia/nv_setup.c10
-rw-r--r--drivers/video/nvidia/nvidia.c35
-rw-r--r--drivers/video/pm2fb.c4
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/pxafb.c3
-rw-r--r--drivers/video/radeonfb.c2
-rw-r--r--drivers/video/riva/fbdev.c6
-rw-r--r--drivers/video/s1d13xxxfb.c772
-rw-r--r--drivers/video/sa1100fb.c3
-rw-r--r--drivers/video/savage/savagefb_driver.c3
-rw-r--r--drivers/video/sis/sis_main.c4
-rw-r--r--drivers/video/sstfb.c2
-rw-r--r--drivers/video/tdfxfb.c2
-rw-r--r--drivers/video/tgafb.c2
-rw-r--r--drivers/video/tridentfb.c4
-rw-r--r--drivers/video/vga16fb.c24
-rw-r--r--drivers/video/w100fb.c6
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/fs-writeback.c4
-rw-r--r--fs/hostfs/hostfs_kern.c20
-rw-r--r--fs/hugetlbfs/inode.c2
-rw-r--r--fs/inode.c7
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfsd/nfs4acl.c40
-rw-r--r--fs/nfsd/nfs4callback.c2
-rw-r--r--fs/nfsd/nfs4proc.c60
-rw-r--r--fs/nfsd/nfs4state.c103
-rw-r--r--fs/nfsd/nfs4xdr.c5
-rw-r--r--fs/nfsd/vfs.c7
-rw-r--r--fs/ramfs/inode.c4
-rw-r--r--fs/sysfs/inode.c2
-rw-r--r--include/asm-arm/atomic.h1
-rw-r--r--include/asm-arm/ipc.h30
-rw-r--r--include/asm-arm26/ipc.h29
-rw-r--r--include/asm-cris/ipc.h36
-rw-r--r--include/asm-frv/ipc.h34
-rw-r--r--include/asm-generic/ipc.h31
-rw-r--r--include/asm-h8300/ipc.h32
-rw-r--r--include/asm-i386/desc.h4
-rw-r--r--include/asm-i386/ipc.h33
-rw-r--r--include/asm-i386/processor.h12
-rw-r--r--include/asm-i386/seccomp.h16
-rw-r--r--include/asm-i386/segment.h5
-rw-r--r--include/asm-m32r/ipc.h36
-rw-r--r--include/asm-m32r/spinlock.h6
-rw-r--r--include/asm-m68k/ipc.h32
-rw-r--r--include/asm-m68knommu/ipc.h2
-rw-r--r--include/asm-mips/ipc.h34
-rw-r--r--include/asm-ppc/cpm2.h2
-rw-r--r--include/asm-ppc/ipc.h30
-rw-r--r--include/asm-ppc/irq.h169
-rw-r--r--include/asm-ppc/mpc52xx.h113
-rw-r--r--include/asm-ppc/mpc85xx.h49
-rw-r--r--include/asm-ppc/ppc_sys.h2
-rw-r--r--include/asm-ppc64/ipc.h35
-rw-r--r--include/asm-ppc64/lmb.h1
-rw-r--r--include/asm-ppc64/seccomp.h21
-rw-r--r--include/asm-ppc64/thread_info.h4
-rw-r--r--include/asm-s390/ipc.h41
-rw-r--r--include/asm-sh/ipc.h33
-rw-r--r--include/asm-sh64/ipc.h7
-rw-r--r--include/asm-sparc/ipc.h33
-rw-r--r--include/asm-sparc64/ipc.h34
-rw-r--r--include/asm-v850/ipc.h32
-rw-r--r--include/asm-x86_64/ipc.h6
-rw-r--r--include/asm-x86_64/msr.h12
-rw-r--r--include/asm-x86_64/seccomp.h24
-rw-r--r--include/asm-x86_64/unistd.h2
-rw-r--r--include/linux/backing-dev.h41
-rw-r--r--include/linux/console.h1
-rw-r--r--include/linux/fb.h4
-rw-r--r--include/linux/seccomp.h1
-rw-r--r--include/linux/sunrpc/svcauth.h14
-rw-r--r--include/video/s1d13xxxfb.h166
-rw-r--r--include/video/trident.h2
-rw-r--r--kernel/cpuset.c4
-rw-r--r--kernel/printk.c18
-rw-r--r--kernel/rcupdate.c6
-rw-r--r--kernel/sched.c2
-rw-r--r--kernel/seccomp.c32
-rw-r--r--mm/filemap.c6
-rw-r--r--mm/nommu.c7
-rw-r--r--mm/page-writeback.c6
-rw-r--r--mm/page_alloc.c5
-rw-r--r--mm/readahead.c1
-rw-r--r--mm/shmem.c4
-rw-r--r--mm/swap_state.c2
205 files changed, 4180 insertions, 2156 deletions
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index 2630629d7ab56d..de3b252e717d0f 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -118,13 +118,18 @@ Linux kernel mailing list:
linux-kernel@vger.kernel.org
[mail majordomo@vger.kernel.org to subscribe]
+Linux Device Drivers, Third Edition (covers 2.6.10):
+ http://lwn.net/Kernel/LDD3/ (free version)
+
Kernel traffic:
Weekly summary of kernel list activity (much easier to read)
http://www.kerneltraffic.org/kernel-traffic/
LWN.net:
Weekly summary of kernel development activity - http://lwn.net/
- 2.6 driver porting information:
+ 2.6 API changes:
+ http://lwn.net/Articles/2.6-kernel-api/
+ Porting drivers from prior kernels to 2.6:
http://lwn.net/Articles/driver-porting/
KernelTrap:
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 488792243d15b9..1ad26d2c20ae61 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -261,6 +261,14 @@ that has had all its allowed CPUs or Memory Nodes taken offline. User
code should reconfigure cpusets to only refer to online CPUs and Memory
Nodes when using hotplug to add or remove such resources.
+There is a second exception to the above. GFP_ATOMIC requests are
+kernel internal allocations that must be satisfied, immediately.
+The kernel may drop some request, in rare cases even panic, if a
+GFP_ATOMIC alloc fails. If the request cannot be satisfied within
+the current tasks cpuset, then we relax the cpuset, and look for
+memory anywhere we can find it. It's better to violate the cpuset
+than stress the kernel.
+
To start a new job that is to be contained within a cpuset, the steps are:
1) mkdir /dev/cpuset
diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt
index cffca06ad4cefd..cb89fb3b61efd2 100644
--- a/Documentation/kernel-docs.txt
+++ b/Documentation/kernel-docs.txt
@@ -39,6 +39,13 @@
ON-LINE DOCS:
+ * Title: "Linux Device Drivers, Third Edition"
+ Author: Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman
+ URL: http://lwn.net/Kernel/LDD3/
+ Description: A 600-page book covering the (2.6.10) driver
+ programming API and kernel hacking in general. Available under the
+ Creative Commons Attribution-ShareAlike 2.0 license.
+
* Title: "The Linux Kernel"
Author: David A. Rusling.
URL: http://www.tldp.org/LDP/tlk/tlk.html
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index 53b58a6ace67ec..da711028e5f712 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -1,23 +1,22 @@
+NOTE: ksymoops is useless on 2.6. Please use the Oops in its original format
+(from dmesg, etc). Ignore any references in this or other docs to "decoding
+the Oops" or "running it through ksymoops". If you post an Oops fron 2.6 that
+has been run through ksymoops, people will just tell you to repost it.
+
Quick Summary
-------------
-Install ksymoops from
-ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops
-Read the ksymoops man page.
-ksymoops < the_oops.txt
-
-and send the output the maintainer of the kernel area that seems to be
-involved with the problem, not to the ksymoops maintainer. Don't worry
-too much about getting the wrong person. If you are unsure send it to
-the person responsible for the code relevant to what you were doing.
-If it occurs repeatably try and describe how to recreate it. Thats
-worth even more than the oops
+Find the Oops and send it to the maintainer of the kernel area that seems to be
+involved with the problem. Don't worry too much about getting the wrong person.
+If you are unsure send it to the person responsible for the code relevant to
+what you were doing. If it occurs repeatably try and describe how to recreate
+it. That's worth even more than the oops.
If you are totally stumped as to whom to send the report, send it to
linux-kernel@vger.kernel.org. Thanks for your help in making Linux as
stable as humanly possible.
-Where is the_oops.txt?
+Where is the Oops?
----------------------
Normally the Oops text is read from the kernel buffers by klogd and
@@ -43,15 +42,14 @@ the disk is not available then you have three options :-
them yourself. Search kernel archives for kmsgdump, lkcd and
oops+smram.
-No matter how you capture the log output, feed the resulting file to
-ksymoops along with /proc/ksyms and /proc/modules that applied at the
-time of the crash. /var/log/ksymoops can be useful to capture the
-latter, man ksymoops for details.
-
Full Information
----------------
+NOTE: the message from Linus below applies to 2.4 kernel. I have preserved it
+for historical reasons, and because some of the information in it still
+applies. Especially, please ignore any references to ksymoops.
+
From: Linus Torvalds <torvalds@osdl.org>
How to track down an Oops.. [originally a mail to linux-kernel]
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index a1d3ec6292a995..f98c2e31c143e6 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -92,6 +92,8 @@ On all - write a character to /proc/sysrq-trigger. eg:
it so that only emergency messages like PANICs or OOPSes would
make it to your console.)
+'f' - Will call oom_kill to kill a memory hog process
+
'e' - Send a SIGTERM to all processes, except for init.
'i' - Send a SIGKILL to all processes, except for init.
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 9ba4979188a820..ef6865f0b9792a 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -65,9 +65,6 @@ static void __init setup_uclinux_memory(void);
#ifdef CONFIG_CONSOLE
extern struct consw *conswitchp;
-#ifdef CONFIG_FRAMEBUFFER
-extern struct consw fb_con;
-#endif
#endif
#ifdef CONFIG_MB93090_MB00
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 190e3feeba6d5c..ebd5d8247faaee 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -21,6 +21,9 @@
DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
+DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
+EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
+
static int cachesize_override __initdata = -1;
static int disable_x86_fxsr __initdata = 0;
static int disable_x86_serial_nr __initdata = 1;
@@ -546,6 +549,7 @@ void __init cpu_init (void)
int cpu = smp_processor_id();
struct tss_struct * t = &per_cpu(init_tss, cpu);
struct thread_struct *thread = &current->thread;
+ __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
if (cpu_test_and_set(cpu, cpu_initialized)) {
printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
@@ -568,6 +572,13 @@ void __init cpu_init (void)
*/
memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
GDT_SIZE);
+
+ /* Set up GDT entry for 16bit stack */
+ *(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
+ ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
+ ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
+ (CPU_16BIT_STACK_SIZE - 1);
+
cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
cpu_gdt_descr[cpu].address =
(unsigned long)&per_cpu(cpu_gdt_table, cpu);
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index d7c8f7b9f72a57..7d1d350bf87e8c 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -1,5 +1,18 @@
+/*
+ * Routines to indentify caches on Intel CPU.
+ *
+ * Changes:
+ * Venkatesh Pallipadi : Adding cache identification through cpuid(4)
+ */
+
#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/compiler.h>
+#include <linux/cpu.h>
+
#include <asm/processor.h>
+#include <asm/smp.h>
#define LVL_1_INST 1
#define LVL_1_DATA 2
@@ -58,10 +71,142 @@ static struct _cache_table cache_table[] __initdata =
{ 0x00, 0, 0}
};
+
+enum _cache_type
+{
+ CACHE_TYPE_NULL = 0,
+ CACHE_TYPE_DATA = 1,
+ CACHE_TYPE_INST = 2,
+ CACHE_TYPE_UNIFIED = 3
+};
+
+union _cpuid4_leaf_eax {
+ struct {
+ enum _cache_type type:5;
+ unsigned int level:3;
+ unsigned int is_self_initializing:1;
+ unsigned int is_fully_associative:1;
+ unsigned int reserved:4;
+ unsigned int num_threads_sharing:12;
+ unsigned int num_cores_on_die:6;
+ } split;
+ u32 full;
+};
+
+union _cpuid4_leaf_ebx {
+ struct {
+ unsigned int coherency_line_size:12;
+ unsigned int physical_line_partition:10;
+ unsigned int ways_of_associativity:10;
+ } split;
+ u32 full;
+};
+
+union _cpuid4_leaf_ecx {
+ struct {
+ unsigned int number_of_sets:32;
+ } split;
+ u32 full;
+};
+
+struct _cpuid4_info {
+ union _cpuid4_leaf_eax eax;
+ union _cpuid4_leaf_ebx ebx;
+ union _cpuid4_leaf_ecx ecx;
+ unsigned long size;
+ cpumask_t shared_cpu_map;
+};
+
+#define MAX_CACHE_LEAVES 4
+static unsigned short __devinitdata num_cache_leaves;
+
+static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+{
+ unsigned int eax, ebx, ecx, edx;
+ union _cpuid4_leaf_eax cache_eax;
+
+ cpuid_count(4, index, &eax, &ebx, &ecx, &edx);
+ cache_eax.full = eax;
+ if (cache_eax.split.type == CACHE_TYPE_NULL)
+ return -1;
+
+ this_leaf->eax.full = eax;
+ this_leaf->ebx.full = ebx;
+ this_leaf->ecx.full = ecx;
+ this_leaf->size = (this_leaf->ecx.split.number_of_sets + 1) *
+ (this_leaf->ebx.split.coherency_line_size + 1) *
+ (this_leaf->ebx.split.physical_line_partition + 1) *
+ (this_leaf->ebx.split.ways_of_associativity + 1);
+ return 0;
+}
+
+static int __init find_num_cache_leaves(void)
+{
+ unsigned int eax, ebx, ecx, edx;
+ union _cpuid4_leaf_eax cache_eax;
+ int i;
+ int retval;
+
+ retval = MAX_CACHE_LEAVES;
+ /* Do cpuid(4) loop to find out num_cache_leaves */
+ for (i = 0; i < MAX_CACHE_LEAVES; i++) {
+ cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
+ cache_eax.full = eax;
+ if (cache_eax.split.type == CACHE_TYPE_NULL) {
+ retval = i;
+ break;
+ }
+ }
+ return retval;
+}
+
unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
{
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+ unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
+ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
+
+ if (c->cpuid_level > 4) {
+ static int is_initialized;
+
+ if (is_initialized == 0) {
+ /* Init num_cache_leaves from boot CPU */
+ num_cache_leaves = find_num_cache_leaves();
+ is_initialized++;
+ }
+
+ /*
+ * Whenever possible use cpuid(4), deterministic cache
+ * parameters cpuid leaf to find the cache details
+ */
+ for (i = 0; i < num_cache_leaves; i++) {
+ struct _cpuid4_info this_leaf;
+
+ int retval;
+ retval = cpuid4_cache_lookup(i, &this_leaf);
+ if (retval >= 0) {
+ switch(this_leaf.eax.split.level) {
+ case 1:
+ if (this_leaf.eax.split.type ==
+ CACHE_TYPE_DATA)
+ new_l1d = this_leaf.size/1024;
+ else if (this_leaf.eax.split.type ==
+ CACHE_TYPE_INST)
+ new_l1i = this_leaf.size/1024;
+ break;
+ case 2:
+ new_l2 = this_leaf.size/1024;
+ break;
+ case 3:
+ new_l3 = this_leaf.size/1024;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
if (c->cpuid_level > 1) {
/* supports eax=2 call */
int i, j, n;
@@ -114,6 +259,18 @@ unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
}
}
+ if (new_l1d)
+ l1d = new_l1d;
+
+ if (new_l1i)
+ l1i = new_l1i;
+
+ if (new_l2)
+ l2 = new_l2;
+
+ if (new_l3)
+ l3 = new_l3;
+
if ( trace )
printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
else if ( l1i )
@@ -138,3 +295,302 @@ unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
return l2;
}
+
+/* pointer to _cpuid4_info array (for each cache leaf) */
+static struct _cpuid4_info *cpuid4_info[NR_CPUS];
+#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
+
+#ifdef CONFIG_SMP
+static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+{
+ struct _cpuid4_info *this_leaf;
+ unsigned long num_threads_sharing;
+
+ this_leaf = CPUID4_INFO_IDX(cpu, index);
+ num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
+
+ if (num_threads_sharing == 1)
+ cpu_set(cpu, this_leaf->shared_cpu_map);
+ else if (num_threads_sharing == smp_num_siblings)
+ this_leaf->shared_cpu_map = cpu_sibling_map[cpu];
+ else
+ printk(KERN_INFO "Number of CPUs sharing cache didn't match "
+ "any known set of CPUs\n");
+}
+#else
+static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
+#endif
+
+static void free_cache_attributes(unsigned int cpu)
+{
+ kfree(cpuid4_info[cpu]);
+ cpuid4_info[cpu] = NULL;
+}
+
+static int __devinit detect_cache_attributes(unsigned int cpu)
+{
+ struct _cpuid4_info *this_leaf;
+ unsigned long j;
+ int retval;
+
+ if (num_cache_leaves == 0)
+ return -ENOENT;
+
+ cpuid4_info[cpu] = kmalloc(
+ sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
+ if (unlikely(cpuid4_info[cpu] == NULL))
+ return -ENOMEM;
+ memset(cpuid4_info[cpu], 0,
+ sizeof(struct _cpuid4_info) * num_cache_leaves);
+
+ /* Do cpuid and store the results */
+ for (j = 0; j < num_cache_leaves; j++) {
+ this_leaf = CPUID4_INFO_IDX(cpu, j);
+ retval = cpuid4_cache_lookup(j, this_leaf);
+ if (unlikely(retval < 0))
+ goto err_out;
+ cache_shared_cpu_map_setup(cpu, j);
+ }
+ return 0;
+
+err_out:
+ free_cache_attributes(cpu);
+ return -ENOMEM;
+}
+
+#ifdef CONFIG_SYSFS
+
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
+
+/* pointer to kobject for cpuX/cache */
+static struct kobject * cache_kobject[NR_CPUS];
+
+struct _index_kobject {
+ struct kobject kobj;
+ unsigned int cpu;
+ unsigned short index;
+};
+
+/* pointer to array of kobjects for cpuX/cache/indexY */
+static struct _index_kobject *index_kobject[NR_CPUS];
+#define INDEX_KOBJECT_PTR(x,y) (&((index_kobject[x])[y]))
+
+#define show_one_plus(file_name, object, val) \
+static ssize_t show_##file_name \
+ (struct _cpuid4_info *this_leaf, char *buf) \
+{ \
+ return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
+}
+
+show_one_plus(level, eax.split.level, 0);
+show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
+show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
+show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
+show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
+
+static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
+{
+ return sprintf (buf, "%luK\n", this_leaf->size / 1024);
+}
+
+static ssize_t show_shared_cpu_map(struct _cpuid4_info *this_leaf, char *buf)
+{
+ char mask_str[NR_CPUS];
+ cpumask_scnprintf(mask_str, NR_CPUS, this_leaf->shared_cpu_map);
+ return sprintf(buf, "%s\n", mask_str);
+}
+
+static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
+ switch(this_leaf->eax.split.type) {
+ case CACHE_TYPE_DATA:
+ return sprintf(buf, "Data\n");
+ break;
+ case CACHE_TYPE_INST:
+ return sprintf(buf, "Instruction\n");
+ break;
+ case CACHE_TYPE_UNIFIED:
+ return sprintf(buf, "Unified\n");
+ break;
+ default:
+ return sprintf(buf, "Unknown\n");
+ break;
+ }
+}
+
+struct _cache_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct _cpuid4_info *, char *);
+ ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
+};
+
+#define define_one_ro(_name) \
+static struct _cache_attr _name = \
+ __ATTR(_name, 0444, show_##_name, NULL)
+
+define_one_ro(level);
+define_one_ro(type);
+define_one_ro(coherency_line_size);
+define_one_ro(physical_line_partition);
+define_one_ro(ways_of_associativity);
+define_one_ro(number_of_sets);
+define_one_ro(size);
+define_one_ro(shared_cpu_map);
+
+static struct attribute * default_attrs[] = {
+ &type.attr,
+ &level.attr,
+ &coherency_line_size.attr,
+ &physical_line_partition.attr,
+ &ways_of_associativity.attr,
+ &number_of_sets.attr,
+ &size.attr,
+ &shared_cpu_map.attr,
+ NULL
+};
+
+#define to_object(k) container_of(k, struct _index_kobject, kobj)
+#define to_attr(a) container_of(a, struct _cache_attr, attr)
+
+static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
+{
+ struct _cache_attr *fattr = to_attr(attr);
+ struct _index_kobject *this_leaf = to_object(kobj);
+ ssize_t ret;
+
+ ret = fattr->show ?
+ fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
+ buf) :
+ 0;
+ return ret;
+}
+
+static ssize_t store(struct kobject * kobj, struct attribute * attr,
+ const char * buf, size_t count)
+{
+ return 0;
+}
+
+static struct sysfs_ops sysfs_ops = {
+ .show = show,
+ .store = store,
+};
+
+static struct kobj_type ktype_cache = {
+ .sysfs_ops = &sysfs_ops,
+ .default_attrs = default_attrs,
+};
+
+static struct kobj_type ktype_percpu_entry = {
+ .sysfs_ops = &sysfs_ops,
+};
+
+static void cpuid4_cache_sysfs_exit(unsigned int cpu)
+{
+ kfree(cache_kobject[cpu]);
+ kfree(index_kobject[cpu]);
+ cache_kobject[cpu] = NULL;
+ index_kobject[cpu] = NULL;
+ free_cache_attributes(cpu);
+}
+
+static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
+{
+
+ if (num_cache_leaves == 0)
+ return -ENOENT;
+
+ detect_cache_attributes(cpu);
+ if (cpuid4_info[cpu] == NULL)
+ return -ENOENT;
+
+ /* Allocate all required memory */
+ cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL);
+ if (unlikely(cache_kobject[cpu] == NULL))
+ goto err_out;
+ memset(cache_kobject[cpu], 0, sizeof(struct kobject));
+
+ index_kobject[cpu] = kmalloc(
+ sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
+ if (unlikely(index_kobject[cpu] == NULL))
+ goto err_out;
+ memset(index_kobject[cpu], 0,
+ sizeof(struct _index_kobject) * num_cache_leaves);
+
+ return 0;
+
+err_out:
+ cpuid4_cache_sysfs_exit(cpu);
+ return -ENOMEM;
+}
+
+/* Add/Remove cache interface for CPU device */
+static int __devinit cache_add_dev(struct sys_device * sys_dev)
+{
+ unsigned int cpu = sys_dev->id;
+ unsigned long i, j;
+ struct _index_kobject *this_object;
+ int retval = 0;
+
+ retval = cpuid4_cache_sysfs_init(cpu);
+ if (unlikely(retval < 0))
+ return retval;
+
+ cache_kobject[cpu]->parent = &sys_dev->kobj;
+ kobject_set_name(cache_kobject[cpu], "%s", "cache");
+ cache_kobject[cpu]->ktype = &ktype_percpu_entry;
+ retval = kobject_register(cache_kobject[cpu]);
+
+ for (i = 0; i < num_cache_leaves; i++) {
+ this_object = INDEX_KOBJECT_PTR(cpu,i);
+ this_object->cpu = cpu;
+ this_object->index = i;
+ this_object->kobj.parent = cache_kobject[cpu];
+ kobject_set_name(&(this_object->kobj), "index%1lu", i);
+ this_object->kobj.ktype = &ktype_cache;
+ retval = kobject_register(&(this_object->kobj));
+ if (unlikely(retval)) {
+ for (j = 0; j < i; j++) {
+ kobject_unregister(
+ &(INDEX_KOBJECT_PTR(cpu,j)->kobj));
+ }
+ kobject_unregister(cache_kobject[cpu]);
+ cpuid4_cache_sysfs_exit(cpu);
+ break;
+ }
+ }
+ return retval;
+}
+
+static int __devexit cache_remove_dev(struct sys_device * sys_dev)
+{
+ unsigned int cpu = sys_dev->id;
+ unsigned long i;
+
+ for (i = 0; i < num_cache_leaves; i++)
+ kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
+ kobject_unregister(cache_kobject[cpu]);
+ cpuid4_cache_sysfs_exit(cpu);
+ return 0;
+}
+
+static struct sysdev_driver cache_sysdev_driver = {
+ .add = cache_add_dev,
+ .remove = __devexit_p(cache_remove_dev),
+};
+
+/* Register/Unregister the cpu_cache driver */
+static int __devinit cache_register_driver(void)
+{
+ if (num_cache_leaves == 0)
+ return 0;
+
+ return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver);
+}
+
+device_initcall(cache_register_driver);
+
+#endif
+
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 87aad70d373021..1e45ff292bc99d 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -47,6 +47,7 @@
#include <asm/segment.h>
#include <asm/smp.h>
#include <asm/page.h>
+#include <asm/desc.h>
#include "irq_vectors.h"
#define nr_syscalls ((syscall_table_size)/4)
@@ -78,7 +79,7 @@ VM_MASK = 0x00020000
#define preempt_stop cli
#else
#define preempt_stop
-#define resume_kernel restore_all
+#define resume_kernel restore_nocheck
#endif
#define SAVE_ALL \
@@ -122,24 +123,6 @@ VM_MASK = 0x00020000
.previous
-#define RESTORE_ALL \
- RESTORE_REGS \
- addl $4, %esp; \
-1: iret; \
-.section .fixup,"ax"; \
-2: sti; \
- movl $(__USER_DS), %edx; \
- movl %edx, %ds; \
- movl %edx, %es; \
- movl $11,%eax; \
- call do_exit; \
-.previous; \
-.section __ex_table,"a";\
- .align 4; \
- .long 1b,2b; \
-.previous
-
-
ENTRY(ret_from_fork)
pushl %eax
call schedule_tail
@@ -163,7 +146,7 @@ ret_from_intr:
movl EFLAGS(%esp), %eax # mix EFLAGS and CS
movb CS(%esp), %al
testl $(VM_MASK | 3), %eax
- jz resume_kernel # returning to kernel or vm86-space
+ jz resume_kernel
ENTRY(resume_userspace)
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
@@ -178,7 +161,7 @@ ENTRY(resume_userspace)
ENTRY(resume_kernel)
cli
cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
- jnz restore_all
+ jnz restore_nocheck
need_resched:
movl TI_flags(%ebp), %ecx # need_resched set ?
testb $_TIF_NEED_RESCHED, %cl
@@ -259,8 +242,56 @@ syscall_exit:
movl TI_flags(%ebp), %ecx
testw $_TIF_ALLWORK_MASK, %cx # current->work
jne syscall_exit_work
+
restore_all:
- RESTORE_ALL
+ movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
+ movb OLDSS(%esp), %ah
+ movb CS(%esp), %al
+ andl $(VM_MASK | (4 << 8) | 3), %eax
+ cmpl $((4 << 8) | 3), %eax
+ je ldt_ss # returning to user-space with LDT SS
+restore_nocheck:
+ RESTORE_REGS
+ addl $4, %esp
+1: iret
+.section .fixup,"ax"
+iret_exc:
+ sti
+ movl $__USER_DS, %edx
+ movl %edx, %ds
+ movl %edx, %es
+ movl $11,%eax
+ call do_exit
+.previous
+.section __ex_table,"a"
+ .align 4
+ .long 1b,iret_exc
+.previous
+
+ldt_ss:
+ larl OLDSS(%esp), %eax
+ jnz restore_nocheck
+ testl $0x00400000, %eax # returning to 32bit stack?
+ jnz restore_nocheck # allright, normal return
+ /* If returning to userspace with 16bit stack,
+ * try to fix the higher word of ESP, as the CPU
+ * won't restore it.
+ * This is an "official" bug of all the x86-compatible
+ * CPUs, which we can try to work around to make
+ * dosemu and wine happy. */
+ subl $8, %esp # reserve space for switch16 pointer
+ cli
+ movl %esp, %eax
+ /* Set up the 16bit stack frame with switch32 pointer on top,
+ * and a switch16 pointer on top of the current frame. */
+ call setup_x86_bogus_stack
+ RESTORE_REGS
+ lss 20+4(%esp), %esp # switch to 16bit stack
+1: iret
+.section __ex_table,"a"
+ .align 4
+ .long 1b,iret_exc
+.previous
# perform work that needs to be done immediately before resumption
ALIGN
@@ -336,6 +367,27 @@ syscall_badsys:
movl $-ENOSYS,EAX(%esp)
jmp resume_userspace
+#define FIXUP_ESPFIX_STACK \
+ movl %esp, %eax; \
+ /* switch to 32bit stack using the pointer on top of 16bit stack */ \
+ lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \
+ /* copy data from 16bit stack to 32bit stack */ \
+ call fixup_x86_bogus_stack; \
+ /* put ESP to the proper location */ \
+ movl %eax, %esp;
+#define UNWIND_ESPFIX_STACK \
+ pushl %eax; \
+ movl %ss, %eax; \
+ /* see if on 16bit stack */ \
+ cmpw $__ESPFIX_SS, %ax; \
+ jne 28f; \
+ movl $__KERNEL_DS, %edx; \
+ movl %edx, %ds; \
+ movl %edx, %es; \
+ /* switch to 32bit stack */ \
+ FIXUP_ESPFIX_STACK \
+28: popl %eax;
+
/*
* Build the entry stubs and pointer table with
* some assembler magic.
@@ -390,7 +442,9 @@ error_code:
pushl %ecx
pushl %ebx
cld
- movl %es, %ecx
+ pushl %es
+ UNWIND_ESPFIX_STACK
+ popl %ecx
movl ES(%esp), %edi # get the function address
movl ORIG_EAX(%esp), %edx # get the error code
movl %eax, ORIG_EAX(%esp)
@@ -472,6 +526,11 @@ debug_stack_correct:
* fault happened on the sysenter path.
*/
ENTRY(nmi)
+ pushl %eax
+ movl %ss, %eax
+ cmpw $__ESPFIX_SS, %ax
+ popl %eax
+ je nmi_16bit_stack
cmpl $sysenter_entry,(%esp)
je nmi_stack_fixup
pushl %eax
@@ -491,7 +550,7 @@ nmi_stack_correct:
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer
call do_nmi
- RESTORE_ALL
+ jmp restore_all
nmi_stack_fixup:
FIX_STACK(12,nmi_stack_correct, 1)
@@ -507,6 +566,29 @@ nmi_debug_stack_fixup:
FIX_STACK(24,nmi_stack_correct, 1)
jmp nmi_stack_correct
+nmi_16bit_stack:
+ /* create the pointer to lss back */
+ pushl %ss
+ pushl %esp
+ movzwl %sp, %esp
+ addw $4, (%esp)
+ /* copy the iret frame of 12 bytes */
+ .rept 3
+ pushl 16(%esp)
+ .endr
+ pushl %eax
+ SAVE_ALL
+ FIXUP_ESPFIX_STACK # %eax == %esp
+ xorl %edx,%edx # zero error code
+ call do_nmi
+ RESTORE_REGS
+ lss 12+4(%esp), %esp # back to 16bit stack
+1: iret
+.section __ex_table,"a"
+ .align 4
+ .long 1b,iret_exc
+.previous
+
ENTRY(int3)
pushl $-1 # mark this as an int
SAVE_ALL
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index ea1ef3a32ec5bc..d273fd74619211 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -512,7 +512,7 @@ ENTRY(cpu_gdt_table)
.quad 0x00009a0000000000 /* 0xc0 APM CS 16 code (16 bit) */
.quad 0x0040920000000000 /* 0xc8 APM DS data */
- .quad 0x0000000000000000 /* 0xd0 - unused */
+ .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */
.quad 0x0000000000000000 /* 0xd8 - unused */
.quad 0x0000000000000000 /* 0xe0 - unused */
.quad 0x0000000000000000 /* 0xe8 - unused */
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index f74b755704c4c0..67168165924346 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -84,7 +84,11 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
regs->eflags |= TF_MASK;
regs->eflags &= ~IF_MASK;
- regs->eip = (unsigned long)&p->ainsn.insn;
+ /*single step inline if the instruction is an int3*/
+ if (p->opcode == BREAKPOINT_INSTRUCTION)
+ regs->eip = (unsigned long)p->addr;
+ else
+ regs->eip = (unsigned long)&p->ainsn.insn;
}
/*
@@ -117,6 +121,12 @@ static int kprobe_handler(struct pt_regs *regs)
Disarm the probe we just hit, and ignore it. */
p = get_kprobe(addr);
if (p) {
+ if (kprobe_status == KPROBE_HIT_SS) {
+ regs->eflags &= ~TF_MASK;
+ regs->eflags |= kprobe_saved_eflags;
+ unlock_kprobes();
+ goto no_kprobe;
+ }
disarm_kprobe(p, regs);
ret = 1;
} else {
@@ -159,17 +169,16 @@ static int kprobe_handler(struct pt_regs *regs)
if (is_IF_modifier(p->opcode))
kprobe_saved_eflags &= ~IF_MASK;
- if (p->pre_handler(p, regs)) {
+ if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */
return 1;
- }
- ss_probe:
+ss_probe:
prepare_singlestep(p, regs);
kprobe_status = KPROBE_HIT_SS;
return 1;
- no_kprobe:
+no_kprobe:
preempt_enable_no_resched();
return ret;
}
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 90cfff176251e1..c36fedf40e9580 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -73,7 +73,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
-static cpumask_t cpu_idle_map;
+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
void disable_hlt(void)
{
@@ -146,15 +146,14 @@ static void poll_idle (void)
*/
void cpu_idle (void)
{
- int cpu = _smp_processor_id();
-
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched()) {
void (*idle)(void);
- if (cpu_isset(cpu, cpu_idle_map))
- cpu_clear(cpu, cpu_idle_map);
+ if (__get_cpu_var(cpu_idle_state))
+ __get_cpu_var(cpu_idle_state) = 0;
+
rmb();
idle = pm_idle;
@@ -170,16 +169,28 @@ void cpu_idle (void)
void cpu_idle_wait(void)
{
- int cpu;
+ unsigned int cpu, this_cpu = get_cpu();
cpumask_t map;
- for_each_online_cpu(cpu)
- cpu_set(cpu, cpu_idle_map);
+ set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
+ put_cpu();
+
+ cpus_clear(map);
+ for_each_online_cpu(cpu) {
+ per_cpu(cpu_idle_state, cpu) = 1;
+ cpu_set(cpu, map);
+ }
+
+ __get_cpu_var(cpu_idle_state) = 0;
wmb();
do {
ssleep(1);
- cpus_and(map, cpu_idle_map, cpu_online_map);
+ for_each_online_cpu(cpu) {
+ if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
+ cpu_clear(cpu, map);
+ }
+ cpus_and(map, map, cpu_online_map);
} while (!cpus_empty(map));
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 0ac1d19c7739f0..6223c33ac91cc6 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -188,7 +188,7 @@ void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
local_irq_restore(flags);
}
-inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
+void send_IPI_mask_sequence(cpumask_t mask, int vector)
{
unsigned long cfg, flags;
unsigned int query_cpu;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 7b5b97f209b7f3..6c0e383915b6a0 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -887,6 +887,51 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
#endif
}
+fastcall void setup_x86_bogus_stack(unsigned char * stk)
+{
+ unsigned long *switch16_ptr, *switch32_ptr;
+ struct pt_regs *regs;
+ unsigned long stack_top, stack_bot;
+ unsigned short iret_frame16_off;
+ int cpu = smp_processor_id();
+ /* reserve the space on 32bit stack for the magic switch16 pointer */
+ memmove(stk, stk + 8, sizeof(struct pt_regs));
+ switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs));
+ regs = (struct pt_regs *)stk;
+ /* now the switch32 on 16bit stack */
+ stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu);
+ stack_top = stack_bot + CPU_16BIT_STACK_SIZE;
+ switch32_ptr = (unsigned long *)(stack_top - 8);
+ iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20;
+ /* copy iret frame on 16bit stack */
+ memcpy((void *)(stack_bot + iret_frame16_off), &regs->eip, 20);
+ /* fill in the switch pointers */
+ switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off;
+ switch16_ptr[1] = __ESPFIX_SS;
+ switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) +
+ 8 - CPU_16BIT_STACK_SIZE;
+ switch32_ptr[1] = __KERNEL_DS;
+}
+
+fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp)
+{
+ unsigned long *switch32_ptr;
+ unsigned char *stack16, *stack32;
+ unsigned long stack_top, stack_bot;
+ int len;
+ int cpu = smp_processor_id();
+ stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu);
+ stack_top = stack_bot + CPU_16BIT_STACK_SIZE;
+ switch32_ptr = (unsigned long *)(stack_top - 8);
+ /* copy the data from 16bit stack to 32bit stack */
+ len = CPU_16BIT_STACK_SIZE - 8 - sp;
+ stack16 = (unsigned char *)(stack_bot + sp);
+ stack32 = (unsigned char *)
+ (switch32_ptr[0] + CPU_16BIT_STACK_SIZE - 8 - len);
+ memcpy(stack32, stack16, len);
+ return stack32;
+}
+
/*
* 'math_state_restore()' saves the current math information in the
* old math state array, and gets the new ones from the current task
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index fb03be1a0c94c2..4826cd6e40e8ee 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -7,8 +7,6 @@
* Hitoshi Yamamoto
*/
-/* $Id$ */
-
#include <linux/config.h>
#include <linux/init.h>
#include <linux/stddef.h>
@@ -24,6 +22,9 @@
#include <linux/seq_file.h>
#include <linux/timex.h>
#include <linux/tty.h>
+#include <linux/cpu.h>
+#include <linux/nodemask.h>
+
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/io.h>
@@ -52,7 +53,7 @@ struct cpuinfo_m32r boot_cpu_data;
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start; /* starting block # of image */
+extern int rd_image_start; /* starting block # of image */
#endif
#if defined(CONFIG_VGA_CONSOLE)
@@ -273,6 +274,21 @@ void __init setup_arch(char **cmdline_p)
paging_init();
}
+static struct cpu cpu[NR_CPUS];
+
+static int __init topology_init(void)
+{
+ int cpu_id;
+
+ for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++)
+ if (cpu_possible(cpu_id))
+ register_cpu(&cpu[cpu_id], cpu_id, NULL);
+
+ return 0;
+}
+
+subsys_initcall(topology_init);
+
#ifdef CONFIG_PROC_FS
/*
* Get CPU information for use by the procfs.
@@ -285,7 +301,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_SMP
if (!cpu_online(cpu))
return 0;
-#endif /* CONFIG_SMP */
+#endif /* CONFIG_SMP */
seq_printf(m, "processor\t: %ld\n", cpu);
@@ -359,7 +375,7 @@ struct seq_operations cpuinfo_op = {
stop: c_stop,
show: show_cpuinfo,
};
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_PROC_FS */
unsigned long cpu_initialized __initdata = 0;
@@ -399,7 +415,6 @@ void __init cpu_init (void)
#endif
/* Set up ICUIMASK */
- outl(0x00070000, M32R_ICU_IMASK_PORTL); /* imask=111 */
+ outl(0x00070000, M32R_ICU_IMASK_PORTL); /* imask=111 */
}
-#endif /* defined(CONFIG_CHIP_VDEC2) ... */
-
+#endif /* defined(CONFIG_CHIP_VDEC2) ... */
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
index bf3104a1590878..1d1a01e54b3fa2 100644
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -11,6 +11,7 @@
#include <linux/bootmem.h>
#include <linux/mmzone.h>
#include <linux/initrd.h>
+#include <linux/nodemask.h>
#include <asm/setup.h>
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 930103cf2b3394..59995a4308683d 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -816,7 +816,7 @@ config MPC10X_BRIDGE
config FSL_OCP
bool
- depends on MPC10X_BRIDGE || PPC_MPC52xx
+ depends on MPC10X_BRIDGE
default y
config MPC10X_OPENPIC
diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c
index 5bf4f0c7932234..3acc6b7c0727cc 100644
--- a/arch/ppc/boot/simple/mpc52xx_tty.c
+++ b/arch/ppc/boot/simple/mpc52xx_tty.c
@@ -20,32 +20,31 @@
#include <asm/io.h>
#include <asm/time.h>
-#if MPC52xx_PF_CONSOLE_PORT == 0
-#define MPC52xx_CONSOLE MPC52xx_PSC1
-#define MPC52xx_PSC_CONFIG_SHIFT 0
-#elif MPC52xx_PF_CONSOLE_PORT == 1
-#define MPC52xx_CONSOLE MPC52xx_PSC2
-#define MPC52xx_PSC_CONFIG_SHIFT 4
-#elif MPC52xx_PF_CONSOLE_PORT == 2
-#define MPC52xx_CONSOLE MPC52xx_PSC3
-#define MPC52xx_PSC_CONFIG_SHIFT 8
+
+#ifdef MPC52xx_PF_CONSOLE_PORT
+#define MPC52xx_CONSOLE MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT)
+#define MPC52xx_PSC_CONFIG_SHIFT ((MPC52xx_PF_CONSOLE_PORT-1)<<2)
#else
#error "MPC52xx_PF_CONSOLE_PORT not defined"
#endif
static struct mpc52xx_psc __iomem *psc =
- (struct mpc52xx_psc __iomem *) MPC52xx_CONSOLE;
+ (struct mpc52xx_psc __iomem *) MPC52xx_PA(MPC52xx_CONSOLE);
/* The decrementer counts at the system bus clock frequency
* divided by four. The most accurate time base is connected to the
- * rtc. We read the decrementer change during one rtc tick (one second)
- * and multiply by 4 to get the system bus clock frequency.
+ * rtc. We read the decrementer change during one rtc tick
+ * and multiply by 4 to get the system bus clock frequency. Since a
+ * rtc tick is one seconds, and that's pretty long, we change the rtc
+ * dividers temporarly to set them 64x faster ;)
*/
static int
mpc52xx_ipbfreq(void)
{
- struct mpc52xx_rtc __iomem *rtc = (struct mpc52xx_rtc __iomem *)MPC52xx_RTC;
- struct mpc52xx_cdm __iomem *cdm = (struct mpc52xx_cdm __iomem *)MPC52xx_CDM;
+ struct mpc52xx_rtc __iomem *rtc =
+ (struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET);
+ struct mpc52xx_cdm __iomem *cdm =
+ (struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET);
int current_time, previous_time;
int tbl_start, tbl_end;
int xlbfreq, ipbfreq;
@@ -68,7 +67,8 @@ mpc52xx_ipbfreq(void)
unsigned long
serial_init(int ignored, void *ignored2)
{
- struct mpc52xx_gpio __iomem *gpio = (struct mpc52xx_gpio __iomem *)MPC52xx_GPIO;
+ struct mpc52xx_gpio __iomem *gpio =
+ (struct mpc52xx_gpio __iomem *) MPC52xx_PA(MPC52xx_GPIO_OFFSET);
int divisor;
int mode1;
int mode2;
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 370ee2a59c1f57..035217d6c0f115 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -45,40 +45,37 @@
#endif
#ifdef CONFIG_BOOKE
-#define COR r8 /* Critical Offset Register (COR) */
-#define BOOKE_LOAD_COR lis COR,crit_save@ha
-#define BOOKE_REST_COR mfspr COR,SPRN_SPRG2
-#define BOOKE_SAVE_COR mtspr SPRN_SPRG2,COR
-#else
-#define COR 0
-#define BOOKE_LOAD_COR
-#define BOOKE_REST_COR
-#define BOOKE_SAVE_COR
-#endif
-
-#ifdef CONFIG_BOOKE
+#include "head_booke.h"
.globl mcheck_transfer_to_handler
mcheck_transfer_to_handler:
- mtspr SPRN_SPRG6W,r8
- lis r8,mcheck_save@ha
- lwz r0,mcheck_r10@l(r8)
+ mtspr MCHECK_SPRG,r8
+ BOOKE_LOAD_MCHECK_STACK
+ lwz r0,GPR10-INT_FRAME_SIZE(r8)
stw r0,GPR10(r11)
- lwz r0,mcheck_r11@l(r8)
+ lwz r0,GPR11-INT_FRAME_SIZE(r8)
stw r0,GPR11(r11)
- mfspr r8,SPRN_SPRG6R
+ mfspr r8,MCHECK_SPRG
b transfer_to_handler_full
+
+ .globl crit_transfer_to_handler
+crit_transfer_to_handler:
+ mtspr CRIT_SPRG,r8
+ BOOKE_LOAD_CRIT_STACK
+ lwz r0,GPR10-INT_FRAME_SIZE(r8)
+ stw r0,GPR10(r11)
+ lwz r0,GPR11-INT_FRAME_SIZE(r8)
+ stw r0,GPR11(r11)
+ mfspr r8,CRIT_SPRG
+ /* fall through */
#endif
-#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+#ifdef CONFIG_40x
.globl crit_transfer_to_handler
crit_transfer_to_handler:
- BOOKE_SAVE_COR
- BOOKE_LOAD_COR
- lwz r0,crit_r10@l(COR)
+ lwz r0,crit_r10@l(0)
stw r0,GPR10(r11)
- lwz r0,crit_r11@l(COR)
+ lwz r0,crit_r11@l(0)
stw r0,GPR11(r11)
- BOOKE_REST_COR
/* fall through */
#endif
@@ -724,8 +721,6 @@ exc_exit_restart_end:
* We have to restore various SPRs that may have been in use at the
* time of the critical interrupt.
*
- * Note that SPRG6 is used for machine check on CONFIG_BOOKE parts and
- * thus not saved in the critical handler
*/
.globl ret_from_crit_exc
ret_from_crit_exc:
@@ -770,32 +765,9 @@ ret_from_crit_exc:
mtspr SPRN_CSRR1,r12
lwz r9,GPR9(r1)
lwz r12,GPR12(r1)
- BOOKE_SAVE_COR
- BOOKE_LOAD_COR
- lwz r10,crit_sprg0@l(COR)
- mtspr SPRN_SPRG0,r10
- lwz r10,crit_sprg1@l(COR)
- mtspr SPRN_SPRG1,r10
- lwz r10,crit_sprg4@l(COR)
- mtspr SPRN_SPRG4,r10
- lwz r10,crit_sprg5@l(COR)
- mtspr SPRN_SPRG5,r10
-#ifdef CONFIG_40x
- lwz r10,crit_sprg6@l(COR)
- mtspr SPRN_SPRG6,r10
-#endif
- lwz r10,crit_sprg7@l(COR)
- mtspr SPRN_SPRG7,r10
- lwz r10,crit_srr0@l(COR)
- mtspr SPRN_SRR0,r10
- lwz r10,crit_srr1@l(COR)
- mtspr SPRN_SRR1,r10
- lwz r10,crit_pid@l(COR)
- mtspr SPRN_PID,r10
lwz r10,GPR10(r1)
lwz r11,GPR11(r1)
lwz r1,GPR1(r1)
- BOOKE_REST_COR
PPC405_ERR77_SYNC
rfci
b . /* prevent prefetch past rfci */
@@ -839,32 +811,9 @@ ret_from_mcheck_exc:
mtspr SPRN_MCSRR1,r12
lwz r9,GPR9(r1)
lwz r12,GPR12(r1)
- mtspr SPRN_SPRG6W,r8
- lis r8,mcheck_save@ha
- lwz r10,mcheck_sprg0@l(r8)
- mtspr SPRN_SPRG0,r10
- lwz r10,mcheck_sprg1@l(r8)
- mtspr SPRN_SPRG1,r10
- lwz r10,mcheck_sprg4@l(r8)
- mtspr SPRN_SPRG4,r10
- lwz r10,mcheck_sprg5@l(r8)
- mtspr SPRN_SPRG5,r10
- lwz r10,mcheck_sprg7@l(r8)
- mtspr SPRN_SPRG7,r10
- lwz r10,mcheck_srr0@l(r8)
- mtspr SPRN_SRR0,r10
- lwz r10,mcheck_srr1@l(r8)
- mtspr SPRN_SRR1,r10
- lwz r10,mcheck_csrr0@l(r8)
- mtspr SPRN_CSRR0,r10
- lwz r10,mcheck_csrr1@l(r8)
- mtspr SPRN_CSRR1,r10
- lwz r10,mcheck_pid@l(r8)
- mtspr SPRN_PID,r10
lwz r10,GPR10(r1)
lwz r11,GPR11(r1)
lwz r1,GPR1(r1)
- mfspr r8,SPRN_SPRG6R
RFMCI
#endif /* CONFIG_BOOKE */
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index e61f3be049feb7..9ed8165a3d6c62 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -728,78 +728,13 @@ _GLOBAL(empty_zero_page)
_GLOBAL(swapper_pg_dir)
.space 8192
+/* Reserved 4k for the critical exception stack & 4k for the machine
+ * check stack per CPU for kernel mode exceptions */
.section .bss
-/* Stack for handling critical exceptions from kernel mode */
-critical_stack_bottom:
- .space 4096
-critical_stack_top:
- .previous
-
-/* Stack for handling machine check exceptions from kernel mode */
-mcheck_stack_bottom:
- .space 4096
-mcheck_stack_top:
- .previous
-
-/*
- * This area is used for temporarily saving registers during the
- * critical and machine check exception prologs. It must always
- * follow the page aligned allocations, so it starts on a page
- * boundary, ensuring that all crit_save areas are in a single
- * page.
- */
-
-/* crit_save */
-_GLOBAL(crit_save)
- .space 4
-_GLOBAL(crit_r10)
- .space 4
-_GLOBAL(crit_r11)
- .space 4
-_GLOBAL(crit_sprg0)
- .space 4
-_GLOBAL(crit_sprg1)
- .space 4
-_GLOBAL(crit_sprg4)
- .space 4
-_GLOBAL(crit_sprg5)
- .space 4
-_GLOBAL(crit_sprg7)
- .space 4
-_GLOBAL(crit_pid)
- .space 4
-_GLOBAL(crit_srr0)
- .space 4
-_GLOBAL(crit_srr1)
- .space 4
-
-/* mcheck_save */
-_GLOBAL(mcheck_save)
- .space 4
-_GLOBAL(mcheck_r10)
- .space 4
-_GLOBAL(mcheck_r11)
- .space 4
-_GLOBAL(mcheck_sprg0)
- .space 4
-_GLOBAL(mcheck_sprg1)
- .space 4
-_GLOBAL(mcheck_sprg4)
- .space 4
-_GLOBAL(mcheck_sprg5)
- .space 4
-_GLOBAL(mcheck_sprg7)
- .space 4
-_GLOBAL(mcheck_pid)
- .space 4
-_GLOBAL(mcheck_srr0)
- .space 4
-_GLOBAL(mcheck_srr1)
- .space 4
-_GLOBAL(mcheck_csrr0)
- .space 4
-_GLOBAL(mcheck_csrr1)
- .space 4
+ .align 12
+exception_stack_bottom:
+ .space BOOKE_EXCEPTION_STACK_SIZE
+_GLOBAL(exception_stack_top)
/*
* This space gets a copy of optional info passed to us by the bootstrap
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
index dd23e90ac81667..6f5d380e234503 100644
--- a/arch/ppc/kernel/head_4xx.S
+++ b/arch/ppc/kernel/head_4xx.S
@@ -95,24 +95,6 @@ _GLOBAL(crit_r10)
.space 4
_GLOBAL(crit_r11)
.space 4
-_GLOBAL(crit_sprg0)
- .space 4
-_GLOBAL(crit_sprg1)
- .space 4
-_GLOBAL(crit_sprg4)
- .space 4
-_GLOBAL(crit_sprg5)
- .space 4
-_GLOBAL(crit_sprg6)
- .space 4
-_GLOBAL(crit_sprg7)
- .space 4
-_GLOBAL(crit_pid)
- .space 4
-_GLOBAL(crit_srr0)
- .space 4
-_GLOBAL(crit_srr1)
- .space 4
/*
* Exception vector entry code. This code runs with address translation
@@ -165,24 +147,6 @@ _GLOBAL(crit_srr1)
#define CRITICAL_EXCEPTION_PROLOG \
stw r10,crit_r10@l(0); /* save two registers to work with */\
stw r11,crit_r11@l(0); \
- mfspr r10,SPRN_SPRG0; \
- stw r10,crit_sprg0@l(0); \
- mfspr r10,SPRN_SPRG1; \
- stw r10,crit_sprg1@l(0); \
- mfspr r10,SPRN_SPRG4; \
- stw r10,crit_sprg4@l(0); \
- mfspr r10,SPRN_SPRG5; \
- stw r10,crit_sprg5@l(0); \
- mfspr r10,SPRN_SPRG6; \
- stw r10,crit_sprg6@l(0); \
- mfspr r10,SPRN_SPRG7; \
- stw r10,crit_sprg7@l(0); \
- mfspr r10,SPRN_PID; \
- stw r10,crit_pid@l(0); \
- mfspr r10,SPRN_SRR0; \
- stw r10,crit_srr0@l(0); \
- mfspr r10,SPRN_SRR1; \
- stw r10,crit_srr1@l(0); \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
@@ -221,9 +185,6 @@ _GLOBAL(crit_srr1)
* r11 saved in crit_r11 and in stack frame,
* now phys stack/exception frame pointer
* r12 saved in stack frame, now saved SRR2
- * SPRG0,1,4,5,6,7 saved in crit_sprg0,1,4,5,6,7
- * PID saved in crit_pid
- * SRR0,1 saved in crit_srr0,1
* CR saved in stack frame, CR0.EQ = !SRR3.PR
* LR, DEAR, ESR in stack frame
* r1 saved in stack frame, now virt stack/excframe pointer
@@ -1030,10 +991,11 @@ _GLOBAL(swapper_pg_dir)
/* Stack for handling critical exceptions from kernel mode */
.section .bss
-critical_stack_bottom:
+ .align 12
+exception_stack_bottom:
.space 4096
critical_stack_top:
- .previous
+_GLOBAL(exception_stack_top)
/* This space gets a copy of optional info passed to us by the bootstrap
* which is used to pass parameters into the kernel like root=/dev/sda1, etc.
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index b69813a9f9e93f..884dac916bce77 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -22,7 +22,7 @@
lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
addi r1,r1,THREAD_SIZE; \
1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
- tophys(r11,r1); \
+ mr r11,r1; \
stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \
stw r9,GPR9(r11); \
@@ -42,45 +42,71 @@
SAVE_4GPRS(3, r11); \
SAVE_2GPRS(7, r11)
+/* To handle the additional exception priority levels on 40x and Book-E
+ * processors we allocate a 4k stack per additional priority level. The various
+ * head_xxx.S files allocate space (exception_stack_top) for each priority's
+ * stack times the number of CPUs
+ *
+ * On 40x critical is the only additional level
+ * On 44x/e500 we have critical and machine check
+ *
+ * Additionally we reserve a SPRG for each priority level so we can free up a
+ * GPR to use as the base for indirect access to the exception stacks. This
+ * is necessary since the MMU is always on, for Book-E parts, and the stacks
+ * are offset from KERNELBASE.
+ *
+ */
+#define BOOKE_EXCEPTION_STACK_SIZE (8192)
+
+/* CRIT_SPRG only used in critical exception handling */
+#define CRIT_SPRG SPRN_SPRG2
+/* MCHECK_SPRG only used in critical exception handling */
+#define MCHECK_SPRG SPRN_SPRG6W
+
+#define MCHECK_STACK_TOP (exception_stack_top - 4096)
+#define CRIT_STACK_TOP (exception_stack_top)
+
+#ifdef CONFIG_SMP
+#define BOOKE_LOAD_CRIT_STACK \
+ mfspr r8,SPRN_PIR; \
+ mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
+ neg r8,r8; \
+ addis r8,r8,CRIT_STACK_TOP@ha; \
+ addi r8,r8,CRIT_STACK_TOP@l
+#define BOOKE_LOAD_MCHECK_STACK \
+ mfspr r8,SPRN_PIR; \
+ mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
+ neg r8,r8; \
+ addis r8,r8,MCHECK_STACK_TOP@ha; \
+ addi r8,r8,MCHECK_STACK_TOP@l
+#else
+#define BOOKE_LOAD_CRIT_STACK \
+ lis r8,CRIT_STACK_TOP@h; \
+ ori r8,r8,CRIT_STACK_TOP@l
+#define BOOKE_LOAD_MCHECK_STACK \
+ lis r8,MCHECK_STACK_TOP@h; \
+ ori r8,r8,MCHECK_STACK_TOP@l
+#endif
+
/*
* Exception prolog for critical exceptions. This is a little different
* from the normal exception prolog above since a critical exception
* can potentially occur at any point during normal exception processing.
* Thus we cannot use the same SPRG registers as the normal prolog above.
- * Instead we use a couple of words of memory at low physical addresses.
- * This is OK since we don't support SMP on these processors. For Book E
- * processors, we also have a reserved register (SPRG2) that is only used
- * in critical exceptions so we can free up a GPR to use as the base for
- * indirect access to the critical exception save area. This is necessary
- * since the MMU is always on and the save area is offset from KERNELBASE.
+ * Instead we use a portion of the critical exception stack at low physical
+ * addresses.
*/
+
#define CRITICAL_EXCEPTION_PROLOG \
- mtspr SPRN_SPRG2,r8; /* SPRG2 only used in criticals */ \
- lis r8,crit_save@ha; \
- stw r10,crit_r10@l(r8); \
- stw r11,crit_r11@l(r8); \
- mfspr r10,SPRN_SPRG0; \
- stw r10,crit_sprg0@l(r8); \
- mfspr r10,SPRN_SPRG1; \
- stw r10,crit_sprg1@l(r8); \
- mfspr r10,SPRN_SPRG4R; \
- stw r10,crit_sprg4@l(r8); \
- mfspr r10,SPRN_SPRG5R; \
- stw r10,crit_sprg5@l(r8); \
- mfspr r10,SPRN_SPRG7R; \
- stw r10,crit_sprg7@l(r8); \
- mfspr r10,SPRN_PID; \
- stw r10,crit_pid@l(r8); \
- mfspr r10,SPRN_SRR0; \
- stw r10,crit_srr0@l(r8); \
- mfspr r10,SPRN_SRR1; \
- stw r10,crit_srr1@l(r8); \
- mfspr r8,SPRN_SPRG2; /* SPRG2 only used in criticals */ \
+ mtspr CRIT_SPRG,r8; \
+ BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
+ stw r10,GPR10-INT_FRAME_SIZE(r8); \
+ stw r11,GPR11-INT_FRAME_SIZE(r8); \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
- lis r11,critical_stack_top@h; \
- ori r11,r11,critical_stack_top@l; \
+ mr r11,r8; \
+ mfspr r8,CRIT_SPRG; \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
@@ -100,7 +126,7 @@
stw r1,GPR1(r11); \
mfspr r9,SPRN_CSRR1; \
stw r1,0(r11); \
- tovirt(r1,r11); \
+ mr r1,r11; \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \
SAVE_4GPRS(3, r11); \
@@ -109,43 +135,18 @@
/*
* Exception prolog for machine check exceptions. This is similar to
* the critical exception prolog, except that machine check exceptions
- * have their own save area. For Book E processors, we also have a
- * reserved register (SPRG6) that is only used in machine check exceptions
- * so we can free up a GPR to use as the base for indirect access to the
- * machine check exception save area. This is necessary since the MMU
- * is always on and the save area is offset from KERNELBASE.
+ * have their stack.
*/
#define MCHECK_EXCEPTION_PROLOG \
- mtspr SPRN_SPRG6W,r8; /* SPRG6 used in machine checks */ \
- lis r8,mcheck_save@ha; \
- stw r10,mcheck_r10@l(r8); \
- stw r11,mcheck_r11@l(r8); \
- mfspr r10,SPRN_SPRG0; \
- stw r10,mcheck_sprg0@l(r8); \
- mfspr r10,SPRN_SPRG1; \
- stw r10,mcheck_sprg1@l(r8); \
- mfspr r10,SPRN_SPRG4R; \
- stw r10,mcheck_sprg4@l(r8); \
- mfspr r10,SPRN_SPRG5R; \
- stw r10,mcheck_sprg5@l(r8); \
- mfspr r10,SPRN_SPRG7R; \
- stw r10,mcheck_sprg7@l(r8); \
- mfspr r10,SPRN_PID; \
- stw r10,mcheck_pid@l(r8); \
- mfspr r10,SPRN_SRR0; \
- stw r10,mcheck_srr0@l(r8); \
- mfspr r10,SPRN_SRR1; \
- stw r10,mcheck_srr1@l(r8); \
- mfspr r10,SPRN_CSRR0; \
- stw r10,mcheck_csrr0@l(r8); \
- mfspr r10,SPRN_CSRR1; \
- stw r10,mcheck_csrr1@l(r8); \
- mfspr r8,SPRN_SPRG6R; /* SPRG6 used in machine checks */ \
+ mtspr MCHECK_SPRG,r8; \
+ BOOKE_LOAD_MCHECK_STACK; /* r8 points to the mcheck stack */\
+ stw r10,GPR10-INT_FRAME_SIZE(r8); \
+ stw r11,GPR11-INT_FRAME_SIZE(r8); \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_MCSRR1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
- lis r11,mcheck_stack_top@h; \
- ori r11,r11,mcheck_stack_top@l; \
+ mr r11,r8; \
+ mfspr r8,MCHECK_SPRG; \
beq 1f; \
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
@@ -165,7 +166,7 @@
stw r1,GPR1(r11); \
mfspr r9,SPRN_MCSRR1; \
stw r1,0(r11); \
- tovirt(r1,r11); \
+ mr r1,r11; \
rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
stw r0,GPR0(r11); \
SAVE_4GPRS(3, r11); \
@@ -289,11 +290,11 @@ label:
mtspr SPRN_CSRR1,r9; \
lwz r9,GPR9(r11); \
lwz r12,GPR12(r11); \
- mtspr SPRN_SPRG2,r8; /* SPRG2 only used in criticals */ \
- lis r8,crit_save@ha; \
- lwz r10,crit_r10@l(r8); \
- lwz r11,crit_r11@l(r8); \
- mfspr r8,SPRN_SPRG2; \
+ mtspr CRIT_SPRG,r8; \
+ BOOKE_LOAD_CRIT_STACK; /* r8 points to the crit stack */ \
+ lwz r10,GPR10-INT_FRAME_SIZE(r8); \
+ lwz r11,GPR11-INT_FRAME_SIZE(r8); \
+ mfspr r8,CRIT_SPRG; \
\
rfci; \
b .; \
diff --git a/arch/ppc/kernel/head_e500.S b/arch/ppc/kernel/head_e500.S
index d83353d5eab563..e478de5a92d32c 100644
--- a/arch/ppc/kernel/head_e500.S
+++ b/arch/ppc/kernel/head_e500.S
@@ -33,6 +33,7 @@
*/
#include <linux/config.h>
+#include <linux/threads.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/mmu.h>
@@ -789,8 +790,6 @@ load_up_spe:
SYNC
rfi
-
-
/*
* SPE unavailable trap from kernel - print a message, but let
* the task use SPE in the kernel until it returns to user mode.
@@ -929,78 +928,13 @@ _GLOBAL(empty_zero_page)
_GLOBAL(swapper_pg_dir)
.space 4096
+/* Reserved 4k for the critical exception stack & 4k for the machine
+ * check stack per CPU for kernel mode exceptions */
.section .bss
-/* Stack for handling critical exceptions from kernel mode */
-critical_stack_bottom:
- .space 4096
-critical_stack_top:
- .previous
-
-/* Stack for handling machine check exceptions from kernel mode */
-mcheck_stack_bottom:
- .space 4096
-mcheck_stack_top:
- .previous
-
-/*
- * This area is used for temporarily saving registers during the
- * critical and machine check exception prologs. It must always
- * follow the page aligned allocations, so it starts on a page
- * boundary, ensuring that all crit_save areas are in a single
- * page.
- */
-
-/* crit_save */
-_GLOBAL(crit_save)
- .space 4
-_GLOBAL(crit_r10)
- .space 4
-_GLOBAL(crit_r11)
- .space 4
-_GLOBAL(crit_sprg0)
- .space 4
-_GLOBAL(crit_sprg1)
- .space 4
-_GLOBAL(crit_sprg4)
- .space 4
-_GLOBAL(crit_sprg5)
- .space 4
-_GLOBAL(crit_sprg7)
- .space 4
-_GLOBAL(crit_pid)
- .space 4
-_GLOBAL(crit_srr0)
- .space 4
-_GLOBAL(crit_srr1)
- .space 4
-
-/* mcheck_save */
-_GLOBAL(mcheck_save)
- .space 4
-_GLOBAL(mcheck_r10)
- .space 4
-_GLOBAL(mcheck_r11)
- .space 4
-_GLOBAL(mcheck_sprg0)
- .space 4
-_GLOBAL(mcheck_sprg1)
- .space 4
-_GLOBAL(mcheck_sprg4)
- .space 4
-_GLOBAL(mcheck_sprg5)
- .space 4
-_GLOBAL(mcheck_sprg7)
- .space 4
-_GLOBAL(mcheck_pid)
- .space 4
-_GLOBAL(mcheck_srr0)
- .space 4
-_GLOBAL(mcheck_srr1)
- .space 4
-_GLOBAL(mcheck_csrr0)
- .space 4
-_GLOBAL(mcheck_csrr1)
- .space 4
+ .align 12
+exception_stack_bottom:
+ .space BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
+_GLOBAL(exception_stack_top)
/*
* This space gets a copy of optional info passed to us by the bootstrap
@@ -1016,4 +950,3 @@ _GLOBAL(cmd_line)
abatron_pteptrs:
.space 8
-
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 513c5ecdcd4f5a..761b8c7b25d275 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -135,25 +135,11 @@ static struct irqaction cpm2_irqaction = {
static void __init
mpc8560_ads_init_IRQ(void)
{
- int i;
- volatile cpm2_map_t *immap = cpm2_immr;
-
/* Setup OpenPIC */
mpc85xx_ads_init_IRQ();
- /* disable all CPM interupts */
- immap->im_intctl.ic_simrh = 0x0;
- immap->im_intctl.ic_simrl = 0x0;
-
- for (i = CPM_IRQ_OFFSET; i < (NR_CPM_INTS + CPM_IRQ_OFFSET); i++)
- irq_desc[i].handler = &cpm2_pic;
-
- /* Initialize the default interrupt mapping priorities,
- * in case the boot rom changed something on us.
- */
- immap->im_intctl.ic_sicr = 0;
- immap->im_intctl.ic_scprrh = 0x05309770;
- immap->im_intctl.ic_scprrl = 0x05309770;
+ /* Setup CPM2 PIC */
+ cpm2_init_IRQ();
setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 5e80b9dc4ed4f3..6c020d67ad7044 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -181,10 +181,6 @@ void __init
mpc85xx_cds_init_IRQ(void)
{
bd_t *binfo = (bd_t *) __res;
-#ifdef CONFIG_CPM2
- volatile cpm2_map_t *immap = cpm2_immr;
- int i;
-#endif
/* Determine the Physical Address of the OpenPIC regs */
phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
@@ -203,19 +199,8 @@ mpc85xx_cds_init_IRQ(void)
openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
#ifdef CONFIG_CPM2
- /* disable all CPM interupts */
- immap->im_intctl.ic_simrh = 0x0;
- immap->im_intctl.ic_simrl = 0x0;
-
- for (i = CPM_IRQ_OFFSET; i < (NR_CPM_INTS + CPM_IRQ_OFFSET); i++)
- irq_desc[i].handler = &cpm2_pic;
-
- /* Initialize the default interrupt mapping priorities,
- * in case the boot rom changed something on us.
- */
- immap->im_intctl.ic_sicr = 0;
- immap->im_intctl.ic_scprrh = 0x05309770;
- immap->im_intctl.ic_scprrl = 0x05309770;
+ /* Setup CPM2 PIC */
+ cpm2_init_IRQ();
setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
#endif
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 6184b533035a12..bc95836e417c51 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -201,7 +201,6 @@ static void __init
gp3_init_IRQ(void)
{
int i;
- volatile cpm2_map_t *immap = cpm2_immr;
bd_t *binfo = (bd_t *) __res;
/*
@@ -227,24 +226,8 @@ gp3_init_IRQ(void)
*/
openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
- /*
- * Setup CPM2 PIC
- */
-
- /* disable all CPM interupts */
- immap->im_intctl.ic_simrh = 0x0;
- immap->im_intctl.ic_simrl = 0x0;
-
- for (i = CPM_IRQ_OFFSET; i < (NR_CPM_INTS + CPM_IRQ_OFFSET); i++)
- irq_desc[i].handler = &cpm2_pic;
-
- /*
- * Initialize the default interrupt mapping priorities,
- * in case the boot rom changed something on us.
- */
- immap->im_intctl.ic_sicr = 0;
- immap->im_intctl.ic_scprrh = 0x05309770;
- immap->im_intctl.ic_scprrl = 0x05309770;
+ /* Setup CPM2 PIC */
+ cpm2_init_IRQ();
setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 7bc10c88c8240f..5488a053f4155f 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -45,7 +45,7 @@ obj-$(CONFIG_RADSTONE_PPC7D) += radstone_ppc7d.o
obj-$(CONFIG_SANDPOINT) += sandpoint.o
obj-$(CONFIG_SBC82xx) += sbc82xx.o
obj-$(CONFIG_SPRUCE) += spruce.o
-obj-$(CONFIG_LITE5200) += lite5200.o mpc5200.o
+obj-$(CONFIG_LITE5200) += lite5200.o
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index 77fa7545bb0a56..b604cf8b3cae91 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -13,7 +13,7 @@
* Dale Farnsworth <dale.farnsworth@mvista.com> and
* Wolfgang Denk <wd@denx.de>
*
- * Copyright 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright 2004-2005 Sylvain Munaut <tnt@246tNt.com>
* Copyright 2003 Motorola Inc.
* Copyright 2003 MontaVista Software Inc.
* Copyright 2003 DENX Software Engineering (wd@denx.de)
@@ -29,11 +29,12 @@
#include <linux/kdev_t.h>
#include <linux/root_dev.h>
#include <linux/console.h>
+#include <linux/module.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
-#include <asm/ocp.h>
#include <asm/mpc52xx.h>
+#include <asm/ppc_sys.h>
#include <syslib/mpc52xx_pci.h>
@@ -46,33 +47,19 @@ EXPORT_SYMBOL(__res); /* For modules */
/* ======================================================================== */
-/* OCP device definition */
-/* For board/shared resources like PSCs */
+/* Platform specific code */
/* ======================================================================== */
-/* Be sure not to load conficting devices : e.g. loading the UART drivers for
- * PSC1 and then also loading a AC97 for this same PSC.
- * For details about how to create an entry, look in the doc of the concerned
- * driver ( eg drivers/serial/mpc52xx_uart.c for the PSC in uart mode )
- */
-
-static struct ocp_def board_ocp[] = {
- {
- .vendor = OCP_VENDOR_FREESCALE,
- .function = OCP_FUNC_PSC_UART,
- .index = 0,
- .paddr = MPC52xx_PSC1,
- .irq = MPC52xx_PSC1_IRQ,
- .pm = OCP_CPM_NA,
- },
- { /* Terminating entry */
- .vendor = OCP_VENDOR_INVALID
- }
-};
+/* Supported PSC function in "preference" order */
+struct mpc52xx_psc_func mpc52xx_psc_functions[] = {
+ { .id = 0,
+ .func = "uart",
+ },
+ { .id = -1, /* End entry */
+ .func = NULL,
+ }
+ };
-/* ======================================================================== */
-/* Platform specific code */
-/* ======================================================================== */
static int
lite5200_show_cpuinfo(struct seq_file *m)
@@ -92,21 +79,47 @@ lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
static void __init
lite5200_setup_cpu(void)
{
+ struct mpc52xx_cdm __iomem *cdm;
+ struct mpc52xx_gpio __iomem *gpio;
struct mpc52xx_intr __iomem *intr;
struct mpc52xx_xlb __iomem *xlb;
+ u32 port_config;
u32 intr_ctrl;
/* Map zones */
- xlb = ioremap(MPC52xx_XLB,sizeof(struct mpc52xx_xlb));
- intr = ioremap(MPC52xx_INTR,sizeof(struct mpc52xx_intr));
+ cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
+ gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
+ xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
+ intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
- if (!xlb || !intr) {
- printk("lite5200.c: Error while mapping XLB/INTR during "
+ if (!cdm || !gpio || !xlb || !intr) {
+ printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during"
"lite5200_setup_cpu\n");
goto unmap_regs;
}
+ /* Use internal 48 Mhz */
+ out_8(&cdm->ext_48mhz_en, 0x00);
+ out_8(&cdm->fd_enable, 0x01);
+ if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
+ out_be16(&cdm->fd_counters, 0x0001);
+ else
+ out_be16(&cdm->fd_counters, 0x5555);
+
+ /* Get port mux config */
+ port_config = in_be32(&gpio->port_config);
+
+ /* 48Mhz internal, pin is GPIO */
+ port_config &= ~0x00800000;
+
+ /* USB port */
+ port_config &= ~0x00007000; /* Differential mode - USB1 only */
+ port_config |= 0x00001000;
+
+ /* Commit port config */
+ out_be32(&gpio->port_config, port_config);
+
/* Configure the XLB Arbiter */
out_be32(&xlb->master_pri_enable, 0xff);
out_be32(&xlb->master_priority, 0x11111111);
@@ -124,6 +137,8 @@ lite5200_setup_cpu(void)
/* Unmap reg zone */
unmap_regs:
+ if (cdm) iounmap(cdm);
+ if (gpio) iounmap(gpio);
if (xlb) iounmap(xlb);
if (intr) iounmap(intr);
}
@@ -131,9 +146,6 @@ unmap_regs:
static void __init
lite5200_setup_arch(void)
{
- /* Add board OCP definitions */
- mpc52xx_add_board_devices(board_ocp);
-
/* CPU & Port mux setup */
lite5200_setup_cpu();
@@ -176,6 +188,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
}
}
+ /* PPC Sys identification */
+ identify_ppc_sys_by_id(mfspr(SPRN_SVR));
+
/* BAT setup */
mpc52xx_set_bat();
@@ -184,7 +199,11 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
isa_mem_base = 0;
/* Powersave */
- powersave_nap = 1; /* We allow this platform to NAP */
+ /* This is provided as an example on how to do it. But you
+ need to be aware that NAP disable bus snoop and that may
+ be required for some devices to work properly, like USB ... */
+ /* powersave_nap = 1; */
+
/* Setup the ppc_md struct */
ppc_md.setup_arch = lite5200_setup_arch;
diff --git a/arch/ppc/platforms/lite5200.h b/arch/ppc/platforms/lite5200.h
index 833134b19c791e..c1de2aa47175f6 100644
--- a/arch/ppc/platforms/lite5200.h
+++ b/arch/ppc/platforms/lite5200.h
@@ -17,7 +17,7 @@
#define __PLATFORMS_LITE5200_H__
/* Serial port used for low-level debug */
-#define MPC52xx_PF_CONSOLE_PORT 0 /* PSC1 */
+#define MPC52xx_PF_CONSOLE_PORT 1 /* PSC1 */
#endif /* __PLATFORMS_LITE5200_H__ */
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
index e0c797f59ac997..ed2b1cebc19ae3 100644
--- a/arch/ppc/platforms/pmac_backlight.c
+++ b/arch/ppc/platforms/pmac_backlight.c
@@ -12,6 +12,7 @@
#include <linux/stddef.h>
#include <linux/reboot.h>
#include <linux/nvram.h>
+#include <linux/console.h>
#include <asm/sections.h>
#include <asm/ptrace.h>
#include <asm/io.h>
@@ -25,14 +26,19 @@
#include <linux/adb.h>
#include <linux/pmu.h>
-static struct backlight_controller *backlighter = NULL;
-static void* backlighter_data = NULL;
-static int backlight_autosave = 0;
+static struct backlight_controller *backlighter;
+static void* backlighter_data;
+static int backlight_autosave;
static int backlight_level = BACKLIGHT_MAX;
static int backlight_enabled = 1;
+static int backlight_req_level = -1;
+static int backlight_req_enable = -1;
-void __pmac
-register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type)
+static void backlight_callback(void *);
+static DECLARE_WORK(backlight_work, backlight_callback, NULL);
+
+void __pmac register_backlight_controller(struct backlight_controller *ctrler,
+ void *data, char *type)
{
struct device_node* bk_node;
char *prop;
@@ -83,16 +89,18 @@ register_backlight_controller(struct backlight_controller *ctrler, void *data, c
backlight_level = req.reply[0] >> 4;
}
#endif
+ acquire_console_sem();
if (!backlighter->set_enable(1, backlight_level, data))
backlight_enabled = 1;
+ release_console_sem();
- printk(KERN_INFO "Registered \"%s\" backlight controller, level: %d/15\n",
- type, backlight_level);
+ printk(KERN_INFO "Registered \"%s\" backlight controller,"
+ "level: %d/15\n", type, backlight_level);
}
EXPORT_SYMBOL(register_backlight_controller);
-void __pmac
-unregister_backlight_controller(struct backlight_controller *ctrler, void *data)
+void __pmac unregister_backlight_controller(struct backlight_controller
+ *ctrler, void *data)
{
/* We keep the current backlight level (for now) */
if (ctrler == backlighter && data == backlighter_data)
@@ -100,22 +108,32 @@ unregister_backlight_controller(struct backlight_controller *ctrler, void *data)
}
EXPORT_SYMBOL(unregister_backlight_controller);
-int __pmac
-set_backlight_enable(int enable)
+static int __pmac __set_backlight_enable(int enable)
{
int rc;
if (!backlighter)
return -ENODEV;
- rc = backlighter->set_enable(enable, backlight_level, backlighter_data);
+ acquire_console_sem();
+ rc = backlighter->set_enable(enable, backlight_level,
+ backlighter_data);
if (!rc)
backlight_enabled = enable;
+ release_console_sem();
return rc;
}
+int __pmac set_backlight_enable(int enable)
+{
+ if (!backlighter)
+ return -ENODEV;
+ backlight_req_enable = enable;
+ schedule_work(&backlight_work);
+ return 0;
+}
+
EXPORT_SYMBOL(set_backlight_enable);
-int __pmac
-get_backlight_enable(void)
+int __pmac get_backlight_enable(void)
{
if (!backlighter)
return -ENODEV;
@@ -123,8 +141,7 @@ get_backlight_enable(void)
}
EXPORT_SYMBOL(get_backlight_enable);
-int __pmac
-set_backlight_level(int level)
+static int __pmac __set_backlight_level(int level)
{
int rc = 0;
@@ -134,10 +151,12 @@ set_backlight_level(int level)
level = BACKLIGHT_OFF;
if (level > BACKLIGHT_MAX)
level = BACKLIGHT_MAX;
+ acquire_console_sem();
if (backlight_enabled)
rc = backlighter->set_level(level, backlighter_data);
if (!rc)
backlight_level = level;
+ release_console_sem();
if (!rc && !backlight_autosave) {
level <<=1;
if (level & 0x10)
@@ -146,13 +165,38 @@ set_backlight_level(int level)
}
return rc;
}
+int __pmac set_backlight_level(int level)
+{
+ if (!backlighter)
+ return -ENODEV;
+ backlight_req_level = level;
+ schedule_work(&backlight_work);
+ return 0;
+}
+
EXPORT_SYMBOL(set_backlight_level);
-int __pmac
-get_backlight_level(void)
+int __pmac get_backlight_level(void)
{
if (!backlighter)
return -ENODEV;
return backlight_level;
}
EXPORT_SYMBOL(get_backlight_level);
+
+static void backlight_callback(void *dummy)
+{
+ int level, enable;
+
+ do {
+ level = backlight_req_level;
+ enable = backlight_req_enable;
+ mb();
+
+ if (level >= 0)
+ __set_backlight_level(level);
+ if (enable >= 0)
+ __set_backlight_enable(enable);
+ } while(cmpxchg(&backlight_req_level, level, -1) != level ||
+ cmpxchg(&backlight_req_enable, enable, -1) != enable);
+}
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 830d00da5db0bc..dd418ea3426c70 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -108,7 +108,8 @@ ifeq ($(CONFIG_83xx),y)
obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o
endif
obj-$(CONFIG_MPC8555_CDS) += todc_time.o
-obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o
+obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o \
+ mpc52xx_sys.o mpc52xx_devices.o ppc_sys.o
ifeq ($(CONFIG_PPC_MPC52xx),y)
obj-$(CONFIG_PCI) += mpc52xx_pci.o
endif
diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c
index bd8335b84d93af..954b07fc1df391 100644
--- a/arch/ppc/syslib/cpm2_pic.c
+++ b/arch/ppc/syslib/cpm2_pic.c
@@ -32,15 +32,17 @@ static u_char irq_to_siureg[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
+/* bit numbers do not match the docs, these are precomputed so the bit for
+ * a given irq is (1 << irq_to_siubit[irq]) */
static u_char irq_to_siubit[] = {
- 31, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30,
- 29, 30, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 31,
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 15, 14, 13, 12, 11, 10, 9, 8,
- 7, 6, 5, 4, 3, 2, 1, 0
+ 0, 15, 14, 13, 12, 11, 10, 9,
+ 8, 7, 6, 5, 4, 3, 2, 1,
+ 2, 1, 15, 14, 13, 12, 11, 10,
+ 9, 8, 7, 6, 5, 4, 3, 0,
+ 31, 30, 29, 28, 27, 26, 25, 24,
+ 23, 22, 21, 20, 19, 18, 17, 16,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
};
static void cpm2_mask_irq(unsigned int irq_nr)
@@ -48,11 +50,13 @@ static void cpm2_mask_irq(unsigned int irq_nr)
int bit, word;
volatile uint *simr;
+ irq_nr -= CPM_IRQ_OFFSET;
+
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
simr = &(cpm2_immr->im_intctl.ic_simrh);
- ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+ ppc_cached_irq_mask[word] &= ~(1 << bit);
simr[word] = ppc_cached_irq_mask[word];
}
@@ -61,11 +65,13 @@ static void cpm2_unmask_irq(unsigned int irq_nr)
int bit, word;
volatile uint *simr;
+ irq_nr -= CPM_IRQ_OFFSET;
+
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
simr = &(cpm2_immr->im_intctl.ic_simrh);
- ppc_cached_irq_mask[word] |= (1 << (31 - bit));
+ ppc_cached_irq_mask[word] |= 1 << bit;
simr[word] = ppc_cached_irq_mask[word];
}
@@ -74,14 +80,16 @@ static void cpm2_mask_and_ack(unsigned int irq_nr)
int bit, word;
volatile uint *simr, *sipnr;
+ irq_nr -= CPM_IRQ_OFFSET;
+
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
simr = &(cpm2_immr->im_intctl.ic_simrh);
sipnr = &(cpm2_immr->im_intctl.ic_sipnrh);
- ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+ ppc_cached_irq_mask[word] &= ~(1 << bit);
simr[word] = ppc_cached_irq_mask[word];
- sipnr[word] = 1 << (31 - bit);
+ sipnr[word] = 1 << bit;
}
static void cpm2_end_irq(unsigned int irq_nr)
@@ -92,29 +100,25 @@ static void cpm2_end_irq(unsigned int irq_nr)
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
&& irq_desc[irq_nr].action) {
+ irq_nr -= CPM_IRQ_OFFSET;
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
simr = &(cpm2_immr->im_intctl.ic_simrh);
- ppc_cached_irq_mask[word] |= (1 << (31 - bit));
+ ppc_cached_irq_mask[word] |= 1 << bit;
simr[word] = ppc_cached_irq_mask[word];
}
}
-struct hw_interrupt_type cpm2_pic = {
- " CPM2 SIU ",
- NULL,
- NULL,
- cpm2_unmask_irq,
- cpm2_mask_irq,
- cpm2_mask_and_ack,
- cpm2_end_irq,
- 0
+static struct hw_interrupt_type cpm2_pic = {
+ .typename = " CPM2 SIU ",
+ .enable = cpm2_unmask_irq,
+ .disable = cpm2_mask_irq,
+ .ack = cpm2_mask_and_ack,
+ .end = cpm2_end_irq,
};
-
-int
-cpm2_get_irq(struct pt_regs *regs)
+int cpm2_get_irq(struct pt_regs *regs)
{
int irq;
unsigned long bits;
@@ -126,5 +130,43 @@ cpm2_get_irq(struct pt_regs *regs)
if (irq == 0)
return(-1);
- return irq;
+ return irq+CPM_IRQ_OFFSET;
+}
+
+void cpm2_init_IRQ(void)
+{
+ int i;
+
+ /* Clear the CPM IRQ controller, in case it has any bits set
+ * from the bootloader
+ */
+
+ /* Mask out everything */
+ cpm2_immr->im_intctl.ic_simrh = 0x00000000;
+ cpm2_immr->im_intctl.ic_simrl = 0x00000000;
+ wmb();
+
+ /* Ack everything */
+ cpm2_immr->im_intctl.ic_sipnrh = 0xffffffff;
+ cpm2_immr->im_intctl.ic_sipnrl = 0xffffffff;
+ wmb();
+
+ /* Dummy read of the vector */
+ i = cpm2_immr->im_intctl.ic_sivec;
+ rmb();
+
+ /* Initialize the default interrupt mapping priorities,
+ * in case the boot rom changed something on us.
+ */
+ cpm2_immr->im_intctl.ic_sicr = 0;
+ cpm2_immr->im_intctl.ic_scprrh = 0x05309770;
+ cpm2_immr->im_intctl.ic_scprrl = 0x05309770;
+
+
+ /* Enable chaining to OpenPIC, and make everything level
+ */
+ for (i = 0; i < NR_CPM_INTS; i++) {
+ irq_desc[i+CPM_IRQ_OFFSET].handler = &cpm2_pic;
+ irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL;
+ }
}
diff --git a/arch/ppc/syslib/cpm2_pic.h b/arch/ppc/syslib/cpm2_pic.h
index d05003b091f531..97cab8f13a1a0c 100644
--- a/arch/ppc/syslib/cpm2_pic.h
+++ b/arch/ppc/syslib/cpm2_pic.h
@@ -1,7 +1,8 @@
#ifndef _PPC_KERNEL_CPM2_H
#define _PPC_KERNEL_CPM2_H
-extern struct hw_interrupt_type cpm2_pic;
extern int cpm2_get_irq(struct pt_regs *regs);
+extern void cpm2_init_IRQ(void);
+
#endif /* _PPC_KERNEL_CPM2_H */
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index f3c12a51bf3e08..23ea3f694de206 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -167,18 +167,12 @@ m8260_show_cpuinfo(struct seq_file *m)
static void __init
m8260_init_IRQ(void)
{
- int i;
-
- for ( i = 0 ; i < NR_SIU_INTS ; i++ )
- irq_desc[i].handler = &cpm2_pic;
+ cpm2_init_IRQ();
/* Initialize the default interrupt mapping priorities,
* in case the boot rom changed something on us.
*/
- cpm2_immr->im_intctl.ic_sicr = 0;
cpm2_immr->im_intctl.ic_siprr = 0x05309770;
- cpm2_immr->im_intctl.ic_scprrh = 0x05309770;
- cpm2_immr->im_intctl.ic_scprrl = 0x05309770;
}
/*
diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c
new file mode 100644
index 00000000000000..ad5182efca1dd3
--- /dev/null
+++ b/arch/ppc/syslib/mpc52xx_devices.c
@@ -0,0 +1,318 @@
+/*
+ * arch/ppc/syslib/mpc52xx_devices.c
+ *
+ * Freescale MPC52xx device descriptions
+ *
+ *
+ * Maintainer : Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/fsl_devices.h>
+#include <linux/resource.h>
+#include <asm/mpc52xx.h>
+#include <asm/ppc_sys.h>
+
+
+static u64 mpc52xx_dma_mask = 0xffffffffULL;
+
+static struct fsl_i2c_platform_data mpc52xx_fsl_i2c_pdata = {
+ .device_flags = FSL_I2C_DEV_CLOCK_5200,
+};
+
+
+/* We use relative offsets for IORESOURCE_MEM to be independent from the
+ * MBAR location at compile time
+ */
+
+/* TODO Add the BestComm initiator channel to the device definitions,
+ possibly using IORESOURCE_DMA. But that's when BestComm is ready ... */
+
+struct platform_device ppc_sys_platform_devices[] = {
+ [MPC52xx_MSCAN1] = {
+ .name = "mpc52xx-mscan",
+ .id = 0,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x0900,
+ .end = 0x097f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_MSCAN1_IRQ,
+ .end = MPC52xx_MSCAN1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_MSCAN2] = {
+ .name = "mpc52xx-mscan",
+ .id = 1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x0980,
+ .end = 0x09ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_MSCAN2_IRQ,
+ .end = MPC52xx_MSCAN2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_SPI] = {
+ .name = "mpc52xx-spi",
+ .id = -1,
+ .num_resources = 3,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x0f00,
+ .end = 0x0f1f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "modf",
+ .start = MPC52xx_SPI_MODF_IRQ,
+ .end = MPC52xx_SPI_MODF_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "spif",
+ .start = MPC52xx_SPI_SPIF_IRQ,
+ .end = MPC52xx_SPI_SPIF_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_USB] = {
+ .name = "ppc-soc-ohci",
+ .id = -1,
+ .num_resources = 2,
+ .dev.dma_mask = &mpc52xx_dma_mask,
+ .dev.coherent_dma_mask = 0xffffffffULL,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x1000,
+ .end = 0x10ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_USB_IRQ,
+ .end = MPC52xx_USB_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_BDLC] = {
+ .name = "mpc52xx-bdlc",
+ .id = -1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x1300,
+ .end = 0x130f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_BDLC_IRQ,
+ .end = MPC52xx_BDLC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_PSC1] = {
+ .name = "mpc52xx-psc",
+ .id = 0,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x2000,
+ .end = 0x209f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_PSC1_IRQ,
+ .end = MPC52xx_PSC1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_PSC2] = {
+ .name = "mpc52xx-psc",
+ .id = 1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x2200,
+ .end = 0x229f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_PSC2_IRQ,
+ .end = MPC52xx_PSC2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_PSC3] = {
+ .name = "mpc52xx-psc",
+ .id = 2,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x2400,
+ .end = 0x249f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_PSC3_IRQ,
+ .end = MPC52xx_PSC3_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_PSC4] = {
+ .name = "mpc52xx-psc",
+ .id = 3,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x2600,
+ .end = 0x269f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_PSC4_IRQ,
+ .end = MPC52xx_PSC4_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_PSC5] = {
+ .name = "mpc52xx-psc",
+ .id = 4,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x2800,
+ .end = 0x289f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_PSC5_IRQ,
+ .end = MPC52xx_PSC5_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_PSC6] = {
+ .name = "mpc52xx-psc",
+ .id = 5,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x2c00,
+ .end = 0x2c9f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_PSC6_IRQ,
+ .end = MPC52xx_PSC6_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_FEC] = {
+ .name = "mpc52xx-fec",
+ .id = -1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x3000,
+ .end = 0x33ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_FEC_IRQ,
+ .end = MPC52xx_FEC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_ATA] = {
+ .name = "mpc52xx-ata",
+ .id = -1,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x3a00,
+ .end = 0x3aff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_ATA_IRQ,
+ .end = MPC52xx_ATA_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_I2C1] = {
+ .name = "fsl-i2c",
+ .id = 0,
+ .dev.platform_data = &mpc52xx_fsl_i2c_pdata,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x3d00,
+ .end = 0x3d1f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_I2C1_IRQ,
+ .end = MPC52xx_I2C1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+ [MPC52xx_I2C2] = {
+ .name = "fsl-i2c",
+ .id = 1,
+ .dev.platform_data = &mpc52xx_fsl_i2c_pdata,
+ .num_resources = 2,
+ .resource = (struct resource[]) {
+ {
+ .start = 0x3d40,
+ .end = 0x3d5f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MPC52xx_I2C2_IRQ,
+ .end = MPC52xx_I2C2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ },
+ },
+};
+
+
+static int __init mach_mpc52xx_fixup(struct platform_device *pdev)
+{
+ ppc_sys_fixup_mem_resource(pdev, MPC52xx_MBAR);
+ return 0;
+}
+
+static int __init mach_mpc52xx_init(void)
+{
+ ppc_sys_device_fixup = mach_mpc52xx_fixup;
+ return 0;
+}
+
+postcore_initcall(mach_mpc52xx_init);
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 347be33954cd5a..c723efd954a6a0 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -183,7 +183,7 @@ mpc52xx_find_bridges(void)
pci_assign_all_busses = 1;
- pci_regs = ioremap(MPC52xx_PCI, sizeof(struct mpc52xx_pci));
+ pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
if (!pci_regs)
return;
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c
index 1c5838f9d292a8..4c4497e62517da 100644
--- a/arch/ppc/syslib/mpc52xx_pic.c
+++ b/arch/ppc/syslib/mpc52xx_pic.c
@@ -180,8 +180,8 @@ mpc52xx_init_irq(void)
u32 intr_ctrl;
/* Remap the necessary zones */
- intr = ioremap(MPC52xx_INTR, sizeof(struct mpc52xx_intr));
- sdma = ioremap(MPC52xx_SDMA, sizeof(struct mpc52xx_sdma));
+ intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
+ sdma = ioremap(MPC52xx_PA(MPC52xx_SDMA_OFFSET), MPC52xx_SDMA_SIZE);
if ((intr==NULL) || (sdma==NULL))
panic("Can't ioremap PIC/SDMA register for init_irq !");
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index c0ecb24210c392..bb2374585a7b9d 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -23,7 +23,6 @@
#include <asm/time.h>
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
-#include <asm/ocp.h>
#include <asm/pgtable.h>
#include <asm/ppcboot.h>
@@ -39,18 +38,14 @@ static int core_mult[] = { /* CPU Frequency multiplier, taken */
void
mpc52xx_restart(char *cmd)
{
- struct mpc52xx_gpt __iomem *gpt0 =
- (struct mpc52xx_gpt __iomem *) MPC52xx_GPTx(0);
+ struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
local_irq_disable();
/* Turn on the watchdog and wait for it to expire. It effectively
does a reset */
- if (gpt0 != NULL) {
- out_be32(&gpt0->count, 0x000000ff);
- out_be32(&gpt0->mode, 0x00009004);
- } else
- printk(KERN_ERR "mpc52xx_restart: Unable to ioremap GPT0 registers, -> looping ...");
+ out_be32(&gpt0->count, 0x000000ff);
+ out_be32(&gpt0->mode, 0x00009004);
while (1);
}
@@ -96,9 +91,7 @@ mpc52xx_map_io(void)
#ifdef CONFIG_SERIAL_TEXT_DEBUG
-#ifdef MPC52xx_PF_CONSOLE_PORT
-#define MPC52xx_CONSOLE MPC52xx_PSCx(MPC52xx_PF_CONSOLE_PORT)
-#else
+#ifndef MPC52xx_PF_CONSOLE_PORT
#error "mpc52xx PSC for console not selected"
#endif
@@ -114,8 +107,9 @@ void
mpc52xx_progress(char *s, unsigned short hex)
{
char c;
- struct mpc52xx_psc __iomem *psc =
- (struct mpc52xx_psc __iomem *)MPC52xx_CONSOLE;
+ struct mpc52xx_psc __iomem *psc;
+
+ psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));
while ((c = *s++) != 0) {
if (c == '\n')
@@ -144,7 +138,7 @@ mpc52xx_find_end_of_memory(void)
u32 sdram_config_0, sdram_config_1;
/* Temp BAT2 mapping active when this is called ! */
- mmap_ctl = (struct mpc52xx_mmap_ctl __iomem *) MPC52xx_MMAP_CTL;
+ mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);
sdram_config_0 = in_be32(&mmap_ctl->sdram0);
sdram_config_1 = in_be32(&mmap_ctl->sdram1);
@@ -174,8 +168,8 @@ mpc52xx_calibrate_decr(void)
struct mpc52xx_rtc __iomem *rtc;
struct mpc52xx_cdm __iomem *cdm;
- rtc = ioremap(MPC52xx_RTC, sizeof(struct mpc52xx_rtc));
- cdm = ioremap(MPC52xx_CDM, sizeof(struct mpc52xx_cdm));
+ rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);
+ cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
if ((rtc==NULL) || (cdm==NULL))
panic("Can't ioremap RTC/CDM while computing bus freq");
@@ -222,11 +216,15 @@ mpc52xx_calibrate_decr(void)
tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
}
+int mpc52xx_match_psc_function(int psc_idx, const char *func)
+{
+ struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
-void __init
-mpc52xx_add_board_devices(struct ocp_def board_ocp[]) {
- while (board_ocp->vendor != OCP_VENDOR_INVALID)
- if(ocp_add_one_device(board_ocp++))
- printk("mpc5200-ocp: Failed to add board device !\n");
-}
+ while ((cf->id != -1) && (cf->func != NULL)) {
+ if ((cf->id == psc_idx) && !strcmp(cf->func,func))
+ return 1;
+ cf++;
+ }
+ return 0;
+}
diff --git a/arch/ppc/syslib/mpc52xx_sys.c b/arch/ppc/syslib/mpc52xx_sys.c
new file mode 100644
index 00000000000000..9a0f90aa8aac8e
--- /dev/null
+++ b/arch/ppc/syslib/mpc52xx_sys.c
@@ -0,0 +1,38 @@
+/*
+ * arch/ppc/syslib/mpc52xx_sys.c
+ *
+ * Freescale MPC52xx system descriptions
+ *
+ *
+ * Maintainer : Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <asm/ppc_sys.h>
+
+struct ppc_sys_spec *cur_ppc_sys_spec;
+struct ppc_sys_spec ppc_sys_specs[] = {
+ {
+ .ppc_sys_name = "5200",
+ .mask = 0xffff0000,
+ .value = 0x80110000,
+ .num_devices = 15,
+ .device_list = (enum ppc_sys_devices[])
+ {
+ MPC52xx_MSCAN1, MPC52xx_MSCAN2, MPC52xx_SPI,
+ MPC52xx_USB, MPC52xx_BDLC, MPC52xx_PSC1, MPC52xx_PSC2,
+ MPC52xx_PSC3, MPC52xx_PSC4, MPC52xx_PSC5, MPC52xx_PSC6,
+ MPC52xx_FEC, MPC52xx_ATA, MPC52xx_I2C1, MPC52xx_I2C2,
+ },
+ },
+ { /* default match */
+ .ppc_sys_name = "",
+ .mask = 0x00000000,
+ .value = 0x00000000,
+ },
+};
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
index 389c509d858231..d806a92a9401be 100644
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -80,7 +80,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8555",
.mask = 0xFFFF0000,
.value = 0x80710000,
- .num_devices = 20,
+ .num_devices = 19,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -88,7 +88,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_PERFMON, MPC85xx_DUART,
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3,
- MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
+ MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
MPC85xx_CPM_USB,
},
@@ -97,7 +97,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8555E",
.mask = 0xFFFF0000,
.value = 0x80790000,
- .num_devices = 21,
+ .num_devices = 20,
.device_list = (enum ppc_sys_devices[])
{
MPC85xx_TSEC1, MPC85xx_TSEC2, MPC85xx_IIC1,
@@ -105,7 +105,7 @@ struct ppc_sys_spec ppc_sys_specs[] = {
MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
MPC85xx_CPM_SPI, MPC85xx_CPM_I2C, MPC85xx_CPM_SCC1,
MPC85xx_CPM_SCC2, MPC85xx_CPM_SCC3,
- MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2, MPC85xx_CPM_FCC3,
+ MPC85xx_CPM_FCC1, MPC85xx_CPM_FCC2,
MPC85xx_CPM_SMC1, MPC85xx_CPM_SMC2,
MPC85xx_CPM_USB,
},
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index eeb9c2ec911822..15c4a1455caee7 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -278,6 +278,23 @@ config LPARCFG
Provide system capacity information via human readable
<key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
endmenu
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index 3db6ef3fed53b3..da20120f226175 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -285,7 +285,7 @@ static unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
return mem_blocks;
}
-static void __init iSeries_parse_cmdline(void)
+static void __init iSeries_get_cmdline(void)
{
char *p, *q;
@@ -305,6 +305,8 @@ static void __init iSeries_parse_cmdline(void)
static void __init iSeries_init_early(void)
{
+ extern unsigned long memory_limit;
+
DBG(" -> iSeries_init_early()\n");
ppcdbg_initialize();
@@ -352,6 +354,31 @@ static void __init iSeries_init_early(void)
*/
build_iSeries_Memory_Map();
+ iSeries_get_cmdline();
+
+ /* Save unparsed command line copy for /proc/cmdline */
+ strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+
+ /* Parse early parameters, in particular mem=x */
+ parse_early_param();
+
+ if (memory_limit) {
+ if (memory_limit < systemcfg->physicalMemorySize)
+ systemcfg->physicalMemorySize = memory_limit;
+ else {
+ printk("Ignoring mem=%lu >= ram_top.\n", memory_limit);
+ memory_limit = 0;
+ }
+ }
+
+ /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */
+ iSeries_bolt_kernel(0, systemcfg->physicalMemorySize);
+
+ lmb_init();
+ lmb_add(0, systemcfg->physicalMemorySize);
+ lmb_analyze();
+ lmb_reserve(0, __pa(klimit));
+
/* Initialize machine-dependency vectors */
#ifdef CONFIG_SMP
smp_init_iSeries();
@@ -377,9 +404,6 @@ static void __init iSeries_init_early(void)
initrd_start = initrd_end = 0;
#endif /* CONFIG_BLK_DEV_INITRD */
-
- iSeries_parse_cmdline();
-
DBG(" <- iSeries_init_early()\n");
}
@@ -540,14 +564,6 @@ static void __init build_iSeries_Memory_Map(void)
* nextPhysChunk
*/
systemcfg->physicalMemorySize = chunk_to_addr(nextPhysChunk);
-
- /* Bolt kernel mappings for all of memory */
- iSeries_bolt_kernel(0, systemcfg->physicalMemorySize);
-
- lmb_init();
- lmb_add(0, systemcfg->physicalMemorySize);
- lmb_analyze(); /* ?? */
- lmb_reserve(0, __pa(klimit));
}
/*
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 4f5c16d4cc6dd6..103daaf735734e 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -71,7 +71,11 @@ static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
regs->msr |= MSR_SE;
- regs->nip = (unsigned long)&p->ainsn.insn;
+ /*single step inline if it a breakpoint instruction*/
+ if (p->opcode == BREAKPOINT_INSTRUCTION)
+ regs->nip = (unsigned long)p->addr;
+ else
+ regs->nip = (unsigned long)&p->ainsn.insn;
}
static inline int kprobe_handler(struct pt_regs *regs)
@@ -86,6 +90,12 @@ static inline int kprobe_handler(struct pt_regs *regs)
Disarm the probe we just hit, and ignore it. */
p = get_kprobe(addr);
if (p) {
+ if (kprobe_status == KPROBE_HIT_SS) {
+ regs->msr &= ~MSR_SE;
+ regs->msr |= kprobe_saved_msr;
+ unlock_kprobes();
+ goto no_kprobe;
+ }
disarm_kprobe(p, regs);
ret = 1;
} else {
@@ -128,10 +138,9 @@ static inline int kprobe_handler(struct pt_regs *regs)
kprobe_status = KPROBE_HIT_ACTIVE;
current_kprobe = p;
kprobe_saved_msr = regs->msr;
- if (p->pre_handler(p, regs)) {
+ if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */
return 1;
- }
ss_probe:
prepare_singlestep(p, regs);
diff --git a/arch/ppc64/kernel/lmb.c b/arch/ppc64/kernel/lmb.c
index 56d7ba87fe608d..d6c6bd03d2a42c 100644
--- a/arch/ppc64/kernel/lmb.c
+++ b/arch/ppc64/kernel/lmb.c
@@ -344,3 +344,29 @@ lmb_abs_to_phys(unsigned long aa)
return pa;
}
+
+/*
+ * Truncate the lmb list to memory_limit if it's set
+ * You must call lmb_analyze() after this.
+ */
+void __init lmb_enforce_memory_limit(void)
+{
+ extern unsigned long memory_limit;
+ unsigned long i, limit;
+ struct lmb_region *mem = &(lmb.memory);
+
+ if (! memory_limit)
+ return;
+
+ limit = memory_limit;
+ for (i = 0; i < mem->cnt; i++) {
+ if (limit > mem->region[i].size) {
+ limit -= mem->region[i].size;
+ continue;
+ }
+
+ mem->region[i].size = limit;
+ mem->cnt = i + 1;
+ break;
+ }
+}
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 3e3c40f248cb9c..1a5f59b769b915 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -912,6 +912,8 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
const char *full_path, void *data)
{
u32 *prop;
+ u64 *prop64;
+ extern unsigned long memory_limit, tce_alloc_start, tce_alloc_end;
if (strcmp(full_path, "/chosen") != 0)
return 0;
@@ -928,6 +930,18 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
iommu_force_on = 1;
+ prop64 = (u64*)get_flat_dt_prop(node, "linux,memory-limit", NULL);
+ if (prop64)
+ memory_limit = *prop64;
+
+ prop64 = (u64*)get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+ if (prop64)
+ tce_alloc_start = *prop64;
+
+ prop64 = (u64*)get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+ if (prop64)
+ tce_alloc_end = *prop64;
+
#ifdef CONFIG_PPC_RTAS
/* To help early debugging via the front panel, we retreive a minimal
* set of RTAS infos now if available
@@ -1067,6 +1081,7 @@ void __init early_init_devtree(void *params)
lmb_init();
scan_flat_dt(early_init_dt_scan_root, NULL);
scan_flat_dt(early_init_dt_scan_memory, NULL);
+ lmb_enforce_memory_limit();
lmb_analyze();
systemcfg->physicalMemorySize = lmb_phys_mem_size();
lmb_reserve(0, __pa(klimit));
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index d3ebe99915182f..8dffa9ae2623df 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -177,6 +177,10 @@ static int __initdata of_platform;
static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
+static unsigned long __initdata prom_memory_limit;
+static unsigned long __initdata prom_tce_alloc_start;
+static unsigned long __initdata prom_tce_alloc_end;
+
static unsigned long __initdata alloc_top;
static unsigned long __initdata alloc_top_high;
static unsigned long __initdata alloc_bottom;
@@ -384,10 +388,70 @@ static int __init prom_setprop(phandle node, const char *pname,
(u32)(unsigned long) value, (u32) valuelen);
}
+/* We can't use the standard versions because of RELOC headaches. */
+#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
+
+#define isdigit(c) ('0' <= (c) && (c) <= '9')
+#define islower(c) ('a' <= (c) && (c) <= 'z')
+#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c))
+
+unsigned long prom_strtoul(const char *cp, const char **endp)
+{
+ unsigned long result = 0, base = 10, value;
+
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if (toupper(*cp) == 'X') {
+ cp++;
+ base = 16;
+ }
+ }
+
+ while (isxdigit(*cp) &&
+ (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
+ result = result * base + value;
+ cp++;
+ }
+
+ if (endp)
+ *endp = cp;
+
+ return result;
+}
+
+unsigned long prom_memparse(const char *ptr, const char **retptr)
+{
+ unsigned long ret = prom_strtoul(ptr, retptr);
+ int shift = 0;
+
+ /*
+ * We can't use a switch here because GCC *may* generate a
+ * jump table which won't work, because we're not running at
+ * the address we're linked at.
+ */
+ if ('G' == **retptr || 'g' == **retptr)
+ shift = 30;
+
+ if ('M' == **retptr || 'm' == **retptr)
+ shift = 20;
+
+ if ('K' == **retptr || 'k' == **retptr)
+ shift = 10;
+
+ if (shift) {
+ ret <<= shift;
+ (*retptr)++;
+ }
+
+ return ret;
+}
/*
* Early parsing of the command line passed to the kernel, used for
- * the options that affect the iommu
+ * "mem=x" and the options that affect the iommu
*/
static void __init early_cmdline_parse(void)
{
@@ -418,6 +482,14 @@ static void __init early_cmdline_parse(void)
else if (!strncmp(opt, RELOC("force"), 5))
RELOC(iommu_force_on) = 1;
}
+
+ opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
+ if (opt) {
+ opt += 4;
+ RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
+ /* Align to 16 MB == size of large page */
+ RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
+ }
}
/*
@@ -664,15 +736,7 @@ static void __init prom_init_mem(void)
}
}
- /* Setup our top/bottom alloc points, that is top of RMO or top of
- * segment 0 when running non-LPAR
- */
- if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR )
- RELOC(alloc_top) = RELOC(rmo_top);
- else
- RELOC(alloc_top) = RELOC(rmo_top) = min(0x40000000ul, RELOC(ram_top));
RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(klimit) - offset + 0x4000);
- RELOC(alloc_top_high) = RELOC(ram_top);
/* Check if we have an initrd after the kernel, if we do move our bottom
* point to after it
@@ -682,7 +746,40 @@ static void __init prom_init_mem(void)
RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
}
+ /*
+ * If prom_memory_limit is set we reduce the upper limits *except* for
+ * alloc_top_high. This must be the real top of RAM so we can put
+ * TCE's up there.
+ */
+
+ RELOC(alloc_top_high) = RELOC(ram_top);
+
+ if (RELOC(prom_memory_limit)) {
+ if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
+ prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
+ prom_printf("Ignoring mem=%x >= ram_top.\n",
+ RELOC(prom_memory_limit));
+ RELOC(prom_memory_limit) = 0;
+ } else {
+ RELOC(ram_top) = RELOC(prom_memory_limit);
+ RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
+ }
+ }
+
+ /*
+ * Setup our top alloc point, that is top of RMO or top of
+ * segment 0 when running non-LPAR.
+ */
+ if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR )
+ RELOC(alloc_top) = RELOC(rmo_top);
+ else
+ RELOC(alloc_top) = RELOC(rmo_top) = min(0x40000000ul, RELOC(ram_top));
+
prom_printf("memory layout at init:\n");
+ prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom));
prom_printf(" alloc_top : %x\n", RELOC(alloc_top));
prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
@@ -871,6 +968,16 @@ static void __init prom_initialize_tce_table(void)
reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
+ if (RELOC(prom_memory_limit)) {
+ /*
+ * We align the start to a 16MB boundary so we can map the TCE area
+ * using large pages if possible. The end should be the top of RAM
+ * so no need to align it.
+ */
+ RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, 0x1000000);
+ RELOC(prom_tce_alloc_end) = local_alloc_top;
+ }
+
/* Flag the first invalid entry */
prom_debug("ending prom_initialize_tce_table\n");
}
@@ -1684,9 +1791,21 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
*/
if (RELOC(ppc64_iommu_off))
prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
+
if (RELOC(iommu_force_on))
prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
+ if (RELOC(prom_memory_limit))
+ prom_setprop(_prom->chosen, "linux,memory-limit",
+ PTRRELOC(&prom_memory_limit), sizeof(RELOC(prom_memory_limit)));
+
+ if (RELOC(prom_tce_alloc_start)) {
+ prom_setprop(_prom->chosen, "linux,tce-alloc-start",
+ PTRRELOC(&prom_tce_alloc_start), sizeof(RELOC(prom_tce_alloc_start)));
+ prom_setprop(_prom->chosen, "linux,tce-alloc-end",
+ PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
+ }
+
/*
* Now finally create the flattened device-tree
*/
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index ac89fbdb65b441..354a287c67eb84 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -27,6 +27,7 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/audit.h>
+#include <linux/seccomp.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -315,6 +316,8 @@ void do_syscall_trace_enter(struct pt_regs *regs)
void do_syscall_trace_leave(struct pt_regs *regs)
{
+ secure_computing(regs->gpr[0]);
+
if (unlikely(current->audit_context))
audit_syscall_exit(current, regs->result);
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index e0c547a9cfd31d..21c57f539c2930 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -636,12 +636,11 @@ void __init setup_system(void)
early_console_initialized = 1;
register_console(&udbg_console);
-#endif /* !CONFIG_PPC_ISERIES */
-
/* Save unparsed command line copy for /proc/cmdline */
strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
parse_early_param();
+#endif /* !CONFIG_PPC_ISERIES */
#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
/*
@@ -800,20 +799,31 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
-#if 0 /* XXX not currently used */
+/*
+ * These three variables are used to save values passed to us by prom_init()
+ * via the device tree. The TCE variables are needed because with a memory_limit
+ * in force we may need to explicitly map the TCE are at the top of RAM.
+ */
unsigned long memory_limit;
+unsigned long tce_alloc_start;
+unsigned long tce_alloc_end;
+#ifdef CONFIG_PPC_ISERIES
+/*
+ * On iSeries we just parse the mem=X option from the command line.
+ * On pSeries it's a bit more complicated, see prom_init_mem()
+ */
static int __init early_parsemem(char *p)
{
if (!p)
return 0;
- memory_limit = memparse(p, &p);
+ memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
return 0;
}
early_param("mem", early_parsemem);
-#endif
+#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_MULTIPLATFORM
static int __init set_preferred_console(void)
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
index 5fc27d0c5ed192..e48be12f518c48 100644
--- a/arch/ppc64/mm/hash_utils.c
+++ b/arch/ppc64/mm/hash_utils.c
@@ -149,6 +149,8 @@ void __init htab_initialize(void)
unsigned long pteg_count;
unsigned long mode_rw;
int i, use_largepages = 0;
+ unsigned long base = 0, size = 0;
+ extern unsigned long tce_alloc_start, tce_alloc_end;
DBG(" -> htab_initialize()\n");
@@ -204,8 +206,6 @@ void __init htab_initialize(void)
/* create bolted the linear mapping in the hash table */
for (i=0; i < lmb.memory.cnt; i++) {
- unsigned long base, size;
-
base = lmb.memory.region[i].physbase + KERNELBASE;
size = lmb.memory.region[i].size;
@@ -234,6 +234,25 @@ void __init htab_initialize(void)
#endif /* CONFIG_U3_DART */
create_pte_mapping(base, base + size, mode_rw, use_largepages);
}
+
+ /*
+ * If we have a memory_limit and we've allocated TCEs then we need to
+ * explicitly map the TCE area at the top of RAM. We also cope with the
+ * case that the TCEs start below memory_limit.
+ * tce_alloc_start/end are 16MB aligned so the mapping should work
+ * for either 4K or 16MB pages.
+ */
+ if (tce_alloc_start) {
+ tce_alloc_start += KERNELBASE;
+ tce_alloc_end += KERNELBASE;
+
+ if (base + size >= tce_alloc_start)
+ tce_alloc_start = base + size + 1;
+
+ create_pte_mapping(tce_alloc_start, tce_alloc_end,
+ mode_rw, use_largepages);
+ }
+
DBG(" <- htab_initialize()\n");
}
#undef KB
diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
index 5c603ba9823108..ea862ec643d3a9 100644
--- a/arch/ppc64/mm/numa.c
+++ b/arch/ppc64/mm/numa.c
@@ -285,6 +285,35 @@ static int cpu_numa_callback(struct notifier_block *nfb,
return ret;
}
+/*
+ * Check and possibly modify a memory region to enforce the memory limit.
+ *
+ * Returns the size the region should have to enforce the memory limit.
+ * This will either be the original value of size, a truncated value,
+ * or zero. If the returned value of size is 0 the region should be
+ * discarded as it lies wholy above the memory limit.
+ */
+static unsigned long __init numa_enforce_memory_limit(unsigned long start, unsigned long size)
+{
+ /*
+ * We use lmb_end_of_DRAM() in here instead of memory_limit because
+ * we've already adjusted it for the limit and it takes care of
+ * having memory holes below the limit.
+ */
+ extern unsigned long memory_limit;
+
+ if (! memory_limit)
+ return size;
+
+ if (start + size <= lmb_end_of_DRAM())
+ return size;
+
+ if (start >= lmb_end_of_DRAM())
+ return 0;
+
+ return lmb_end_of_DRAM() - start;
+}
+
static int __init parse_numa_properties(void)
{
struct device_node *cpu = NULL;
@@ -373,6 +402,13 @@ new_range:
if (max_domain < numa_domain)
max_domain = numa_domain;
+ if (! (size = numa_enforce_memory_limit(start, size))) {
+ if (--ranges)
+ goto new_range;
+ else
+ continue;
+ }
+
/*
* Initialize new node struct, or add to an existing one.
*/
@@ -405,8 +441,7 @@ new_range:
numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
numa_domain;
- ranges--;
- if (ranges)
+ if (--ranges)
goto new_range;
}
@@ -614,8 +649,11 @@ new_range:
if (numa_domain != nid)
continue;
- dbg("free_bootmem %lx %lx\n", mem_start, mem_size);
- free_bootmem_node(NODE_DATA(nid), mem_start, mem_size);
+ mem_size = numa_enforce_memory_limit(mem_start, mem_size);
+ if (mem_size) {
+ dbg("free_bootmem %lx %lx\n", mem_start, mem_size);
+ free_bootmem_node(NODE_DATA(nid), mem_start, mem_size);
+ }
if (--ranges) /* process all ranges in cell */
goto new_range;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index b1de24775c31ef..80306bc8c799b7 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -62,8 +62,8 @@ void bust_spinlocks(int yes)
oops_in_progress = 1;
} else {
int loglevel_save = console_loglevel;
- oops_in_progress = 0;
console_unblank();
+ oops_in_progress = 0;
/*
* OK, the message is on the console. Now we call printk()
* without oops_in_progress set so that printk will give klogd
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 7d97138f5d2e65..7066d7ba667a5e 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -68,8 +68,14 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
regs->tstate |= TSTATE_PIL;
- regs->tpc = (unsigned long) &p->ainsn.insn[0];
- regs->tnpc = (unsigned long) &p->ainsn.insn[1];
+ /*single step inline, if it a breakpoint instruction*/
+ if (p->opcode == BREAKPOINT_INSTRUCTION) {
+ regs->tpc = (unsigned long) p->addr;
+ regs->tnpc = current_kprobe_orig_tnpc;
+ } else {
+ regs->tpc = (unsigned long) &p->ainsn.insn[0];
+ regs->tnpc = (unsigned long) &p->ainsn.insn[1];
+ }
}
static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
@@ -97,6 +103,12 @@ static int kprobe_handler(struct pt_regs *regs)
*/
p = get_kprobe(addr);
if (p) {
+ if (kprobe_status == KPROBE_HIT_SS) {
+ regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
+ current_kprobe_orig_tstate_pil);
+ unlock_kprobes();
+ goto no_kprobe;
+ }
disarm_kprobe(p, regs);
ret = 1;
} else {
@@ -128,7 +140,7 @@ static int kprobe_handler(struct pt_regs *regs)
kprobe_status = KPROBE_HIT_ACTIVE;
current_kprobe = p;
- if (p->pre_handler(p, regs))
+ if (p->pre_handler && p->pre_handler(p, regs))
return 1;
ss_probe:
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index c27cab081ad28a..b89989de364d1d 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -16,7 +16,7 @@ config PT_PROXY
config GPROF
bool "Enable gprof support"
- depends on DEBUG_INFO && MODE_SKAS
+ depends on DEBUG_INFO && MODE_SKAS && !MODE_TT
help
This allows profiling of a User-Mode Linux kernel with the gprof
utility.
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index b760b5a2a34350..1f77deb3fd237a 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -248,11 +248,8 @@ int write_chan(struct list_head *chans, const char *buf, int len,
n = chan->ops->write(chan->fd, buf, len, chan->data);
if (chan->primary) {
ret = n;
- if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
+ if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
reactivate_fd(chan->fd, write_irq);
- if (ret == -EAGAIN)
- ret = 0;
- }
}
}
return(ret);
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index d4286de17f0700..6924f273ced9fd 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -128,7 +128,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
ret = buffer_data(line, buf, len);
err = flush_buffer(line);
local_irq_restore(flags);
- if(err <= 0)
+ if(err <= 0 && (err != -EAGAIN || !ret))
ret = err;
}
else {
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index b514ea28d16c4b..661d495e204488 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -9,15 +9,11 @@
#include "uml-config.h"
#include "user_constants.h"
-#ifdef UML_CONFIG_MODE_TT
-#include "sysdep/sc.h"
-#endif
-
-#ifdef UML_CONFIG_MODE_SKAS
-
#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
#define MAX_REG_OFFSET (UM_FRAME_SIZE)
+extern void update_debugregs(int seq);
+
/* syscall emulation path in ptrace */
#ifndef PTRACE_SYSEMU
@@ -28,9 +24,13 @@ void set_using_sysemu(int value);
int get_using_sysemu(void);
extern int sysemu_supported;
-#include "skas_ptregs.h"
+#ifdef UML_CONFIG_MODE_TT
+#include "sysdep/sc.h"
+#endif
-extern void update_debugregs(int seq);
+#ifdef UML_CONFIG_MODE_SKAS
+
+#include "skas_ptregs.h"
#define REGS_IP(r) ((r)[HOST_IP])
#define REGS_SP(r) ((r)[HOST_SP])
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 36d9beec431b8b..5db81ec9087d2f 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -23,6 +23,9 @@ extern long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
+/* On i386 they choose a meaningless naming.*/
+#define __NR_kexec_load __NR_sys_kexec_load
+
#define ARCH_SYSCALLS \
[ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
[ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
@@ -74,7 +77,7 @@ extern long sys_mmap2(unsigned long addr, unsigned long len,
[ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
[ __NR_select ] = (syscall_handler_t *) old_select, \
[ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
+ [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
[ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \
[ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \
[ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \
@@ -97,19 +100,16 @@ extern long sys_mmap2(unsigned long addr, unsigned long len,
[ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
[ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
[ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
- [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
[ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
[ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
- [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
- [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
-
+ [ 285 ] = (syscall_handler_t *) sys_ni_syscall,
+
/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
-#define LAST_ARCH_SYSCALL __NR_vserver
+#define LAST_ARCH_SYSCALL 285
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 5eac9bed21ad39..915c82daffbd6b 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -10,6 +10,9 @@
#include "uml-config.h"
#include "user_constants.h"
+#define MAX_REG_OFFSET (UM_FRAME_SIZE)
+#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
+
#ifdef UML_CONFIG_MODE_TT
#include "sysdep/sc.h"
#endif
@@ -17,9 +20,6 @@
#ifdef UML_CONFIG_MODE_SKAS
#include "skas_ptregs.h"
-#define MAX_REG_OFFSET (UM_FRAME_SIZE)
-#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
-
#define REGS_IP(r) ((r)[HOST_IP])
#define REGS_SP(r) ((r)[HOST_SP])
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
index 65fd494420f990..b187a4157ff367 100644
--- a/arch/um/include/sysdep-x86_64/syscalls.h
+++ b/arch/um/include/sysdep-x86_64/syscalls.h
@@ -71,12 +71,7 @@ extern syscall_handler_t sys_arch_prctl;
[ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
[ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
- [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
- [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
- [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, \
[ 251 ] = (syscall_handler_t *) sys_ni_syscall,
#define LAST_ARCH_SYSCALL 251
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 82d19b451d5eae..668df13d8c9d67 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -108,12 +108,14 @@ static void tty_output(int master, int slave)
panic("check_sigio : write failed, errno = %d\n", errno);
while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
- if(got_sigio){
+ if (got_sigio) {
printk("Yes\n");
pty_output_sigio = 1;
+ } else if (n == -EAGAIN) {
+ printk("No, enabling workaround\n");
+ } else {
+ panic("check_sigio : read failed, err = %d\n", n);
}
- else if(n == -EAGAIN) printk("No, enabling workaround\n");
- else panic("check_sigio : read failed, err = %d\n", n);
}
static void tty_close(int master, int slave)
@@ -235,6 +237,8 @@ static int need_poll(int n)
return(0);
}
+/* Must be called with sigio_lock held, because it's needed by the marked
+ * critical section. */
static void update_thread(void)
{
unsigned long flags;
@@ -257,7 +261,7 @@ static void update_thread(void)
set_signals(flags);
return;
fail:
- sigio_lock();
+ /* Critical section start */
if(write_sigio_pid != -1)
os_kill_process(write_sigio_pid, 1);
write_sigio_pid = -1;
@@ -265,7 +269,7 @@ static void update_thread(void)
os_close_file(sigio_private[1]);
os_close_file(write_sigio_fds[0]);
os_close_file(write_sigio_fds[1]);
- sigio_unlock();
+ /* Critical section end */
set_signals(flags);
}
@@ -418,19 +422,10 @@ int read_sigio_fd(int fd)
static void sigio_cleanup(void)
{
- if(write_sigio_pid != -1)
+ if (write_sigio_pid != -1) {
os_kill_process(write_sigio_pid, 1);
+ write_sigio_pid = -1;
+ }
}
__uml_exitcall(sigio_cleanup);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index c8e5fe49583aee..7575ec489b6302 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -61,7 +61,8 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
void *arg;
int *res;
- va_copy(args, *(va_list *)arg_ptr);
+ /* Some old gccs recognize __va_copy, but not va_copy */
+ __va_copy(args, *(va_list *)arg_ptr);
addr = va_arg(args, unsigned long);
len = va_arg(args, int);
is_write = va_arg(args, int);
diff --git a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
index 202662a4e52515..7fc06c85b29d93 100644
--- a/arch/um/kernel/sys_call_table.c
+++ b/arch/um/kernel/sys_call_table.c
@@ -47,7 +47,6 @@ extern syscall_handler_t sys_vfork;
extern syscall_handler_t old_select;
extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t sys_rt_sigsuspend;
-extern syscall_handler_t sys_vserver;
extern syscall_handler_t sys_mbind;
extern syscall_handler_t sys_get_mempolicy;
extern syscall_handler_t sys_set_mempolicy;
@@ -241,7 +240,8 @@ syscall_handler_t *sys_call_table[] = {
[ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
[ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
[ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
- [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
+ [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages,
+ [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
[ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
[ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
[ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
@@ -251,12 +251,10 @@ syscall_handler_t *sys_call_table[] = {
[ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
[ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
[ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
- [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64,
- [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64,
[ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
[ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
- [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64,
- [ __NR_vserver ] = (syscall_handler_t *) sys_vserver,
+ [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
+ [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
[ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
[ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
[ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
@@ -266,14 +264,13 @@ syscall_handler_t *sys_call_table[] = {
[ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
[ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
[ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
- [ __NR_sys_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
[ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
- [ 285 ] = (syscall_handler_t *) sys_ni_syscall,
[ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
[ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
[ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
ARCH_SYSCALLS
[ LAST_SYSCALL + 1 ... NR_syscalls ] =
- (syscall_handler_t *) sys_ni_syscall
+ (syscall_handler_t *) sys_ni_syscall
};
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index c75d1db0efc312..5c49d88eed3d07 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -47,7 +47,7 @@ char command_line[COMMAND_LINE_SIZE] = { 0 };
void add_arg(char *arg)
{
if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
- printf("add_arg: Too much command line!\n");
+ printf("add_arg: Too many command line arguments!\n");
exit(1);
}
if(strlen(command_line) > 0)
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index f0c459a4bfd581..68a9ab06ee7c21 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -65,7 +65,6 @@
#include <asm/types.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
-#include <asm/ipc.h>
#include <asm/atomic.h>
#include <asm/ldt.h>
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 131d24ef9a63db..4f2a852299b63d 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -25,6 +25,8 @@
* interface to access function arguments.
* 2004-Oct Jim Keniston <kenistoj@us.ibm.com> and Prasanna S Panchamukhi
* <prasanna@in.ibm.com> adapted for x86_64
+ * 2005-Mar Roland McGrath <roland@redhat.com>
+ * Fixed to handle %rip-relative addressing mode correctly.
*/
#include <linux/config.h>
@@ -34,7 +36,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/preempt.h>
-#include <linux/vmalloc.h>
+#include <linux/moduleloader.h>
#include <asm/pgtable.h>
#include <asm/kdebug.h>
@@ -86,9 +88,132 @@ int arch_prepare_kprobe(struct kprobe *p)
return 0;
}
+/*
+ * Determine if the instruction uses the %rip-relative addressing mode.
+ * If it does, return the address of the 32-bit displacement word.
+ * If not, return null.
+ */
+static inline s32 *is_riprel(u8 *insn)
+{
+#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \
+ (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
+ (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) | \
+ (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) | \
+ (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf)) \
+ << (row % 64))
+ static const u64 onebyte_has_modrm[256 / 64] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ W(0x00, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 00 */
+ W(0x10, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 10 */
+ W(0x20, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0)| /* 20 */
+ W(0x30, 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0), /* 30 */
+ W(0x40, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 40 */
+ W(0x50, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 50 */
+ W(0x60, 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0)| /* 60 */
+ W(0x70, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 70 */
+ W(0x80, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 80 */
+ W(0x90, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 90 */
+ W(0xa0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* a0 */
+ W(0xb0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* b0 */
+ W(0xc0, 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0)| /* c0 */
+ W(0xd0, 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1)| /* d0 */
+ W(0xe0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* e0 */
+ W(0xf0, 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1) /* f0 */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ };
+ static const u64 twobyte_has_modrm[256 / 64] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ W(0x00, 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1)| /* 0f */
+ W(0x10, 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0)| /* 1f */
+ W(0x20, 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1)| /* 2f */
+ W(0x30, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), /* 3f */
+ W(0x40, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 4f */
+ W(0x50, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 5f */
+ W(0x60, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 6f */
+ W(0x70, 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1), /* 7f */
+ W(0x80, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)| /* 8f */
+ W(0x90, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* 9f */
+ W(0xa0, 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1)| /* af */
+ W(0xb0, 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1), /* bf */
+ W(0xc0, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0)| /* cf */
+ W(0xd0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* df */
+ W(0xe0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)| /* ef */
+ W(0xf0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0) /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ };
+#undef W
+ int need_modrm;
+
+ /* Skip legacy instruction prefixes. */
+ while (1) {
+ switch (*insn) {
+ case 0x66:
+ case 0x67:
+ case 0x2e:
+ case 0x3e:
+ case 0x26:
+ case 0x64:
+ case 0x65:
+ case 0x36:
+ case 0xf0:
+ case 0xf3:
+ case 0xf2:
+ ++insn;
+ continue;
+ }
+ break;
+ }
+
+ /* Skip REX instruction prefix. */
+ if ((*insn & 0xf0) == 0x40)
+ ++insn;
+
+ if (*insn == 0x0f) { /* Two-byte opcode. */
+ ++insn;
+ need_modrm = test_bit(*insn, twobyte_has_modrm);
+ } else { /* One-byte opcode. */
+ need_modrm = test_bit(*insn, onebyte_has_modrm);
+ }
+
+ if (need_modrm) {
+ u8 modrm = *++insn;
+ if ((modrm & 0xc7) == 0x05) { /* %rip+disp32 addressing mode */
+ /* Displacement follows ModRM byte. */
+ return (s32 *) ++insn;
+ }
+ }
+
+ /* No %rip-relative addressing mode here. */
+ return NULL;
+}
+
void arch_copy_kprobe(struct kprobe *p)
{
+ s32 *ripdisp;
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
+ ripdisp = is_riprel(p->ainsn.insn);
+ if (ripdisp) {
+ /*
+ * The copied instruction uses the %rip-relative
+ * addressing mode. Adjust the displacement for the
+ * difference between the original location of this
+ * instruction and the location of the copy that will
+ * actually be run. The tricky bit here is making sure
+ * that the sign extension happens correctly in this
+ * calculation, since we need a signed 32-bit result to
+ * be sign-extended to 64 bits when it's added to the
+ * %rip value and yield the same 64-bit result that the
+ * sign-extension of the original signed 32-bit
+ * displacement would have given.
+ */
+ s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn;
+ BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
+ *ripdisp = disp;
+ }
}
void arch_remove_kprobe(struct kprobe *p)
@@ -108,8 +233,11 @@ static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
regs->eflags |= TF_MASK;
regs->eflags &= ~IF_MASK;
-
- regs->rip = (unsigned long)p->ainsn.insn;
+ /*single step inline if the instruction is an int3*/
+ if (p->opcode == BREAKPOINT_INSTRUCTION)
+ regs->rip = (unsigned long)p->addr;
+ else
+ regs->rip = (unsigned long)p->ainsn.insn;
}
/*
@@ -131,6 +259,12 @@ int kprobe_handler(struct pt_regs *regs)
Disarm the probe we just hit, and ignore it. */
p = get_kprobe(addr);
if (p) {
+ if (kprobe_status == KPROBE_HIT_SS) {
+ regs->eflags &= ~TF_MASK;
+ regs->eflags |= kprobe_saved_rflags;
+ unlock_kprobes();
+ goto no_kprobe;
+ }
disarm_kprobe(p, regs);
ret = 1;
} else {
@@ -168,17 +302,16 @@ int kprobe_handler(struct pt_regs *regs)
if (is_IF_modifier(p->ainsn.insn))
kprobe_saved_rflags &= ~IF_MASK;
- if (p->pre_handler(p, regs)) {
+ if (p->pre_handler && p->pre_handler(p, regs))
/* handler has already set things up, so skip ss setup */
return 1;
- }
- ss_probe:
+ss_probe:
prepare_singlestep(p, regs);
kprobe_status = KPROBE_HIT_SS;
return 1;
- no_kprobe:
+no_kprobe:
preempt_enable_no_resched();
return ret;
}
@@ -439,8 +572,15 @@ static kprobe_opcode_t *get_insn_slot(void)
if (!kip) {
return NULL;
}
- kip->insns = (kprobe_opcode_t*) __vmalloc(PAGE_SIZE,
- GFP_KERNEL|__GFP_HIGHMEM, __pgprot(__PAGE_KERNEL_EXEC));
+
+ /*
+ * For the %rip-relative displacement fixups to be doable, we
+ * need our instruction copy to be within +/- 2GB of any data it
+ * might access via %rip. That is, within 2GB of where the
+ * kernel image and loaded module images reside. So we allocate
+ * a page in the module loading area.
+ */
+ kip->insns = module_alloc(PAGE_SIZE);
if (!kip->insns) {
kfree(kip);
return NULL;
@@ -481,7 +621,7 @@ static void free_insn_slot(kprobe_opcode_t *slot)
hlist_add_head(&kip->hlist,
&kprobe_insn_pages);
} else {
- vfree(kip->insns);
+ module_free(NULL, kip->insns);
kfree(kip);
}
}
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 33feab9c75691e..171931ea7eaae8 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -62,7 +62,7 @@ EXPORT_SYMBOL(boot_option_idle_override);
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
-static cpumask_t cpu_idle_map;
+static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
void disable_hlt(void)
{
@@ -125,20 +125,31 @@ static void poll_idle (void)
}
}
-
void cpu_idle_wait(void)
{
- int cpu;
- cpumask_t map;
+ unsigned int cpu, this_cpu = get_cpu();
+ cpumask_t map;
+
+ set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
+ put_cpu();
+
+ cpus_clear(map);
+ for_each_online_cpu(cpu) {
+ per_cpu(cpu_idle_state, cpu) = 1;
+ cpu_set(cpu, map);
+ }
- for_each_online_cpu(cpu)
- cpu_set(cpu, cpu_idle_map);
+ __get_cpu_var(cpu_idle_state) = 0;
- wmb();
- do {
- ssleep(1);
- cpus_and(map, cpu_idle_map, cpu_online_map);
- } while (!cpus_empty(map));
+ wmb();
+ do {
+ ssleep(1);
+ for_each_online_cpu(cpu) {
+ if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
+ cpu_clear(cpu, map);
+ }
+ cpus_and(map, map, cpu_online_map);
+ } while (!cpus_empty(map));
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
@@ -150,21 +161,21 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
*/
void cpu_idle (void)
{
- int cpu = smp_processor_id();
-
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched()) {
void (*idle)(void);
- if (cpu_isset(cpu, cpu_idle_map))
- cpu_clear(cpu, cpu_idle_map);
+ if (__get_cpu_var(cpu_idle_state))
+ __get_cpu_var(cpu_idle_state) = 0;
+
rmb();
idle = pm_idle;
if (!idle)
idle = default_idle;
idle();
}
+
schedule();
}
}
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index d0725cd1b9d68b..e3cdbf9a88bd7a 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -373,7 +373,10 @@ void smp_send_stop(void)
__smp_call_function(smp_really_stop_cpu, NULL, 0, 0);
if (!nolock)
spin_unlock(&call_lock);
- smp_stop_cpu();
+
+ local_irq_disable();
+ disable_local_APIC();
+ local_irq_enable();
}
/*
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 624bcf8e54731e..477d8be57d64f0 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -18,7 +18,6 @@
#include <linux/personality.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/ia32.h>
/*
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 08b2d48494694e..02242e8ba99687 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -238,7 +238,7 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
q->make_request_fn = mfn;
q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
q->backing_dev_info.state = 0;
- q->backing_dev_info.memory_backed = 0;
+ q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
blk_queue_max_sectors(q, MAX_SECTORS);
blk_queue_hardsect_size(q, 512);
blk_queue_dma_alignment(q, 511);
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 6a126ee370d602..145c1fbffe0135 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -325,7 +325,7 @@ static int rd_ioctl(struct inode *inode, struct file *file,
*/
static struct backing_dev_info rd_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 1, /* Does not contribute to dirty memory */
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | BDI_CAP_MAP_COPY,
.unplug_io_fn = default_unplug_io_fn,
};
@@ -336,7 +336,7 @@ static struct backing_dev_info rd_backing_dev_info = {
*/
static struct backing_dev_info rd_file_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 0, /* Does contribute to dirty memory */
+ .capabilities = BDI_CAP_MAP_COPY, /* Does contribute to dirty memory */
.unplug_io_fn = default_unplug_io_fn,
};
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 3dfcaffd37ccd9..096a1202ea077d 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -271,7 +271,7 @@ config SPECIALIX_RTSCTS
config SX
tristate "Specialix SX (and SI) card support"
- depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+ depends on SERIAL_NONSTANDARD
help
This is a driver for the SX and SI multiport serial cards.
Please read the file <file:Documentation/sx.txt> for details.
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 4d159c610f7f37..947cb3cef81671 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -23,6 +23,7 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/ptrace.h>
#include <linux/device.h>
+#include <linux/backing-dev.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -282,30 +283,30 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
- ssize_t read, virtr, sz;
+ ssize_t low_count, read, sz;
char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
read = 0;
- virtr = 0;
if (p < (unsigned long) high_memory) {
- read = count;
+ low_count = count;
if (count > (unsigned long) high_memory - p)
- read = (unsigned long) high_memory - p;
+ low_count = (unsigned long) high_memory - p;
#ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
/* we don't have page 0 mapped on sparc and m68k.. */
- if (p < PAGE_SIZE && read > 0) {
+ if (p < PAGE_SIZE && low_count > 0) {
size_t tmp = PAGE_SIZE - p;
- if (tmp > read) tmp = read;
+ if (tmp > low_count) tmp = low_count;
if (clear_user(buf, tmp))
return -EFAULT;
buf += tmp;
p += tmp;
- read -= tmp;
+ read += tmp;
+ low_count -= tmp;
count -= tmp;
}
#endif
- while (read > 0) {
+ while (low_count > 0) {
/*
* Handle first page in case it's not aligned
*/
@@ -314,7 +315,7 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
else
sz = PAGE_SIZE;
- sz = min_t(unsigned long, sz, count);
+ sz = min_t(unsigned long, sz, low_count);
/*
* On ia64 if a page has been mapped somewhere as
@@ -327,7 +328,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
return -EFAULT;
buf += sz;
p += sz;
- read -= sz;
+ read += sz;
+ low_count -= sz;
count -= sz;
}
}
@@ -350,13 +352,13 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
}
count -= len;
buf += len;
- virtr += len;
+ read += len;
p += len;
}
free_page((unsigned long)kbuf);
}
*ppos = p;
- return virtr + read;
+ return read;
}
@@ -758,6 +760,10 @@ static struct file_operations zero_fops = {
.mmap = mmap_zero,
};
+static struct backing_dev_info zero_bdi = {
+ .capabilities = BDI_CAP_MAP_COPY,
+};
+
static struct file_operations full_fops = {
.llseek = full_lseek,
.read = read_full,
@@ -804,6 +810,7 @@ static int memory_open(struct inode * inode, struct file * filp)
break;
#endif
case 5:
+ filp->f_mapping->backing_dev_info = &zero_bdi;
filp->f_op = &zero_fops;
break;
case 7:
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 8f70185f192afe..533085ec6f1bb3 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -84,9 +84,7 @@ static struct IdentifyRta IdRta;
static struct KillNeighbour KillUnit;
int
-RIOFoadRta(HostP, MapP)
-struct Host * HostP;
-struct Map * MapP;
+RIOFoadRta(struct Host *HostP, struct Map *MapP)
{
struct CmdBlk *CmdBlkP;
@@ -117,9 +115,7 @@ struct Map * MapP;
}
int
-RIOZombieRta(HostP, MapP)
-struct Host * HostP;
-struct Map * MapP;
+RIOZombieRta(struct Host *HostP, struct Map *MapP)
{
struct CmdBlk *CmdBlkP;
@@ -150,10 +146,8 @@ struct Map * MapP;
}
int
-RIOCommandRta(p, RtaUnique, func)
-struct rio_info * p;
-uint RtaUnique;
-int (* func)( struct Host *HostP, struct Map *MapP );
+RIOCommandRta(struct rio_info *p, uint RtaUnique,
+ int (* func)(struct Host *HostP, struct Map *MapP))
{
uint Host;
@@ -195,9 +189,7 @@ int (* func)( struct Host *HostP, struct Map *MapP );
int
-RIOIdentifyRta(p, arg)
-struct rio_info * p;
-caddr_t arg;
+RIOIdentifyRta(struct rio_info *p, caddr_t arg)
{
uint Host;
@@ -263,9 +255,7 @@ caddr_t arg;
int
-RIOKillNeighbour(p, arg)
-struct rio_info * p;
-caddr_t arg;
+RIOKillNeighbour(struct rio_info *p, caddr_t arg)
{
uint Host;
uint ID;
@@ -329,10 +319,7 @@ caddr_t arg;
}
int
-RIOSuspendBootRta(HostP, ID, Link)
-struct Host *HostP;
-int ID;
-int Link;
+RIOSuspendBootRta(struct Host *HostP, int ID, int Link)
{
struct CmdBlk *CmdBlkP;
@@ -363,8 +350,7 @@ int Link;
}
int
-RIOFoadWakeup(p)
-struct rio_info * p;
+RIOFoadWakeup(struct rio_info *p)
{
int port;
register struct Port *PortP;
@@ -398,11 +384,7 @@ struct rio_info * p;
** Incoming command on the COMMAND_RUP to be processed.
*/
static int
-RIOCommandRup(p, Rup, HostP, PacketP)
-struct rio_info * p;
-uint Rup;
-struct Host *HostP;
-PKT *PacketP;
+RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP)
{
struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data;
struct Port *PortP;
@@ -619,7 +601,7 @@ PKT *PacketP;
** Allocate an empty command block.
*/
struct CmdBlk *
-RIOGetCmdBlk()
+RIOGetCmdBlk(void)
{
struct CmdBlk *CmdBlkP;
@@ -634,8 +616,7 @@ RIOGetCmdBlk()
** Return a block to the head of the free list.
*/
void
-RIOFreeCmdBlk(CmdBlkP)
-struct CmdBlk *CmdBlkP;
+RIOFreeCmdBlk(struct CmdBlk *CmdBlkP)
{
sysfree((void *)CmdBlkP, sizeof(struct CmdBlk));
}
@@ -645,10 +626,7 @@ struct CmdBlk *CmdBlkP;
** a given rup.
*/
int
-RIOQueueCmdBlk(HostP, Rup, CmdBlkP)
-struct Host *HostP;
-uint Rup;
-struct CmdBlk *CmdBlkP;
+RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP)
{
struct CmdBlk **Base;
struct UnixRup *UnixRupP;
@@ -679,7 +657,6 @@ struct CmdBlk *CmdBlkP;
:TRUE)) {
rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
CmdBlkP->Packet.data[0]);
-
/*
** Whammy! blat that pack!
@@ -737,9 +714,7 @@ struct CmdBlk *CmdBlkP;
** must be called at splrio() or higher.
*/
void
-RIOPollHostCommands(p, HostP)
-struct rio_info * p;
-struct Host * HostP;
+RIOPollHostCommands(struct rio_info *p, struct Host *HostP)
{
register struct CmdBlk *CmdBlkP;
register struct UnixRup *UnixRupP;
@@ -918,9 +893,7 @@ struct Host * HostP;
}
int
-RIOWFlushMark(iPortP, CmdBlkP)
-int iPortP;
-struct CmdBlk *CmdBlkP;
+RIOWFlushMark(int iPortP, struct CmdBlk *CmdBlkP)
{
struct Port * PortP = (struct Port *)iPortP;
unsigned long flags;
@@ -936,9 +909,7 @@ struct CmdBlk *CmdBlkP;
}
int
-RIORFlushEnable(iPortP, CmdBlkP)
-int iPortP;
-struct CmdBlk *CmdBlkP;
+RIORFlushEnable(int iPortP, struct CmdBlk *CmdBlkP)
{
struct Port * PortP = (struct Port *)iPortP;
PKT *PacketP;
@@ -965,9 +936,7 @@ struct CmdBlk *CmdBlkP;
}
int
-RIOUnUse(iPortP, CmdBlkP)
-int iPortP;
-struct CmdBlk *CmdBlkP;
+RIOUnUse(int iPortP, struct CmdBlk *CmdBlkP)
{
struct Port * PortP = (struct Port *)iPortP;
unsigned long flags;
@@ -1009,9 +978,7 @@ struct CmdBlk *CmdBlkP;
}
void
-ShowPacket(Flags, PacketP)
-uint Flags;
-struct PKT *PacketP;
+ShowPacket(uint Flags, struct PKT *PacketP)
{
}
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 5a250be53fa78f..3ad758a9a1dc10 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -4,7 +4,7 @@
* This driver will also support the older SI, and XIO cards.
*
*
- * (C) 1998 - 2000 R.E.Wolff@BitWizard.nl
+ * (C) 1998 - 2004 R.E.Wolff@BitWizard.nl
*
* Simon Allen (simonallen@cix.compulink.co.uk) wrote a previous
* version of this driver. Some fragments may have been copied. (none
@@ -354,13 +354,13 @@ static int si1_probe_addrs[]= { 0xd0000};
Some architectures may need more. */
static int sx_irqmask = -1;
-MODULE_PARM(sx_probe_addrs, "i");
-MODULE_PARM(si_probe_addrs, "i");
-MODULE_PARM(sx_poll, "i");
-MODULE_PARM(sx_slowpoll, "i");
-MODULE_PARM(sx_maxints, "i");
-MODULE_PARM(sx_debug, "i");
-MODULE_PARM(sx_irqmask, "i");
+module_param_array(sx_probe_addrs, int, NULL, 0);
+module_param_array(si_probe_addrs, int, NULL, 0);
+module_param(sx_poll, int, 0);
+module_param(sx_slowpoll, int, 0);
+module_param(sx_maxints, int, 0);
+module_param(sx_debug, int, 0);
+module_param(sx_irqmask, int, 0);
MODULE_LICENSE("GPL");
@@ -396,7 +396,7 @@ static struct real_driver sx_real_driver = {
-#define func_enter() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s\b",__FUNCTION__)
+#define func_enter() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__)
#define func_exit() sx_dprintk (SX_DEBUG_FLOW, "sx: exit %s\n", __FUNCTION__)
#define func_enter2() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \
@@ -1158,7 +1158,6 @@ static inline void sx_check_modem_signals (struct sx_port *port)
if (hi_state & ST_BREAK) {
hi_state &= ~ST_BREAK;
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n");
-
sx_write_channel_byte (port, hi_state, hi_state);
gs_got_break (&port->gs);
}
@@ -1206,7 +1205,7 @@ static irqreturn_t sx_interrupt (int irq, void *ptr, struct pt_regs *regs)
struct sx_port *port;
int i;
- /* func_enter (); */
+ func_enter ();
sx_dprintk (SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, board->irq);
/* AAargh! The order in which to do these things is essential and
@@ -1297,7 +1296,7 @@ static irqreturn_t sx_interrupt (int irq, void *ptr, struct pt_regs *regs)
clear_bit (SX_BOARD_INTR_LOCK, &board->locks);
sx_dprintk (SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, board->irq);
- /* func_exit (); */
+ func_exit ();
return IRQ_HANDLED;
}
@@ -1428,6 +1427,7 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
{
struct sx_port *port;
int retval, line;
+ unsigned long flags;
func_enter();
@@ -1449,9 +1449,12 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
sx_dprintk (SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd);
+ spin_lock_irqsave(&port->gs.driver_lock, flags);
+
tty->driver_data = port;
port->gs.tty = tty;
port->gs.count++;
+ spin_unlock_irqrestore(&port->gs.driver_lock, flags);
sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
@@ -1466,7 +1469,8 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
}
port->gs.flags |= GS_ACTIVE;
- sx_setsignals (port, 1,1);
+ if (port->gs.count <= 1)
+ sx_setsignals (port, 1,1);
#if 0
if (sx_debug & SX_DEBUG_OPEN)
@@ -1476,10 +1480,14 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
my_hd_io (port->board->base + port->ch_base, sizeof (*port));
#endif
- if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
- printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
- port->gs.count--;
- return -EIO;
+ if (port->gs.count <= 1) {
+ if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
+ printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
+ spin_lock_irqsave(&port->gs.driver_lock, flags);
+ port->gs.count--;
+ spin_unlock_irqrestore(&port->gs.driver_lock, flags);
+ return -EIO;
+ }
}
retval = gs_block_til_ready(port, filp);
@@ -1497,6 +1505,7 @@ static int sx_open (struct tty_struct * tty, struct file * filp)
port->c_dcd = sx_get_CD (port);
sx_dprintk (SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd);
+
func_exit();
return 0;
@@ -1531,7 +1540,8 @@ static void sx_close (void *ptr)
if(port->gs.count) {
sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
- port->gs.count = 0;
+ //printk ("%s SETTING port count to zero: %p count: %d\n", __FUNCTION__, port, port->gs.count);
+ //port->gs.count = 0;
}
func_exit ();
@@ -1747,12 +1757,16 @@ static void sx_break (struct tty_struct * tty, int flag)
struct sx_port *port = tty->driver_data;
int rv;
+ func_enter ();
+
if (flag)
rv = sx_send_command (port, HS_START, -1, HS_IDLE_BREAK);
else
rv = sx_send_command (port, HS_STOP, -1, HS_IDLE_OPEN);
if (rv != 1) printk (KERN_ERR "sx: couldn't send break (%x).\n",
read_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat)));
+
+ func_exit ();
}
@@ -2101,7 +2115,7 @@ static int probe_sx (struct sx_board *board)
}
if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == SX_ISA_UNIQUEID1) {
- if (board->hw_base & 0x8000) {
+ if (((unsigned long)board->hw_base) & 0x8000) {
printk (KERN_WARNING "sx: Warning: There may be hardware problems with the card at %lx.\n", board->hw_base);
printk (KERN_WARNING "sx: Read sx.txt for more info.\n");
}
@@ -2150,6 +2164,7 @@ static int probe_si (struct sx_board *board)
}
for (i=0;i<8;i++) {
if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) {
+ func_exit ();
return 0;
}
}
@@ -2164,11 +2179,13 @@ static int probe_si (struct sx_board *board)
/* This should be an SI1 board, which has this
location writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10)
+ func_exit ();
return 0;
} else {
/* This should be an SI2 board, which has the bottom
3 bits non-writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10)
+ func_exit ();
return 0;
}
@@ -2181,11 +2198,13 @@ static int probe_si (struct sx_board *board)
/* This should be an SI1 board, which has this
location writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10)
+ func_exit();
return 0;
} else {
/* This should be an SI2 board, which has the bottom
3 bits non-writable... */
if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10)
+ func_exit ();
return 0;
}
@@ -2302,6 +2321,7 @@ static int sx_init_portstructs (int nboards, int nports)
#ifdef NEW_WRITE_LOCKING
port->gs.port_write_sem = MUTEX;
#endif
+ port->gs.driver_lock = SPIN_LOCK_UNLOCKED;
/*
* Initializing wait queue
*/
@@ -2473,7 +2493,7 @@ static int __init sx_init(void)
found++;
fix_sx_pci (pdev, board);
} else
- iounmap(board->base);
+ iounmap(board->base2);
}
#endif
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 8c385a3f7e64ad..f59f7cbd525bcd 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -31,9 +31,10 @@
#include <linux/suspend.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h> /* for fsync_bdev() */
-
+#include <linux/swap.h>
#include <linux/spinlock.h>
#include <linux/vt_kern.h>
+#include <linux/workqueue.h>
#include <asm/ptrace.h>
@@ -209,6 +210,24 @@ static struct sysrq_key_op sysrq_term_op = {
.enable_mask = SYSRQ_ENABLE_SIGNAL,
};
+static void moom_callback(void *ignored)
+{
+ out_of_memory(GFP_KERNEL);
+}
+
+static DECLARE_WORK(moom_work, moom_callback, NULL);
+
+static void sysrq_handle_moom(int key, struct pt_regs *pt_regs,
+ struct tty_struct *tty)
+{
+ schedule_work(&moom_work);
+}
+static struct sysrq_key_op sysrq_moom_op = {
+ .handler = sysrq_handle_moom,
+ .help_msg = "Full",
+ .action_msg = "Manual OOM execution",
+};
+
static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
{
@@ -257,7 +276,7 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = {
/* c */ NULL,
/* d */ NULL,
/* e */ &sysrq_term_op,
-/* f */ NULL,
+/* f */ &sysrq_moom_op,
/* g */ NULL,
/* h */ NULL,
/* i */ &sysrq_kill_op,
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 6229dd04ac314d..e5ef1dfc54826a 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2212,9 +2212,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
}
set_cursor(vc);
- if (!oops_in_progress)
- poke_blanked_console();
-
quit:
clear_bit(0, &printing);
}
@@ -2815,6 +2812,13 @@ void do_unblank_screen(int leaving_gfx)
{
struct vc_data *vc;
+ /* This should now always be called from a "sane" (read: can schedule)
+ * context for the sake of the low level drivers, except in the special
+ * case of oops_in_progress
+ */
+ if (!oops_in_progress)
+ might_sleep();
+
WARN_CONSOLE_UNLOCKED();
ignore_poke = 0;
@@ -2871,6 +2875,14 @@ void poke_blanked_console(void)
{
WARN_CONSOLE_UNLOCKED();
+ /* Add this so we quickly catch whoever might call us in a non
+ * safe context. Nowadays, unblank_screen() isn't to be called in
+ * atomic contexts and is allowed to schedule (with the special case
+ * of oops_in_progress, but that isn't of any concern for this
+ * function. --BenH.
+ */
+ might_sleep();
+
/* This isn't perfectly race free, but a race here would be mostly harmless,
* at worse, we'll do a spurrious blank and it's unlikely
*/
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 6147e580a15364..ae16112a06535b 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -385,6 +385,30 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
};
}
+static int cx24110_diseqc_send_burst(struct dvb_frontend* fe,
+ fe_sec_mini_cmd_t burst)
+{
+ int rv, bit, i;
+ struct cx24110_state *state = fe->demodulator_priv;
+
+ if (burst == SEC_MINI_A)
+ bit = 0x00;
+ else if (burst == SEC_MINI_B)
+ bit = 0x08;
+ else
+ return -EINVAL;
+
+ rv = cx24110_readreg(state, 0x77);
+ cx24110_writereg(state, 0x77, rv|0x04);
+
+ rv = cx24110_readreg(state, 0x76);
+ cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
+ for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
+ ; /* wait for LNB ready */
+
+ return 0;
+}
+
static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd *cmd)
{
@@ -394,6 +418,9 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
for (i = 0; i < cmd->msg_len; i++)
cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
+ rv = cx24110_readreg(state, 0x77);
+ cx24110_writereg(state, 0x77, rv|0x04);
+
rv = cx24110_readreg(state, 0x76);
cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
@@ -616,6 +643,7 @@ static struct dvb_frontend_ops cx24110_ops = {
.diseqc_send_master_cmd = cx24110_send_diseqc_msg,
.set_tone = cx24110_set_tone,
.set_voltage = cx24110_set_voltage,
+ .diseqc_send_burst = cx24110_diseqc_send_burst,
};
module_param(debug, int, 0644);
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index 1e1bec697a5607..13b1e7b6fd6eb6 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -419,7 +419,7 @@ zr36050_set_dri (struct zr36050 *ptr)
dri_data[2] = 0x00;
dri_data[3] = 0x04;
dri_data[4] = ptr->dri >> 8;
- dri_data[5] = ptr->dri * 0xff;
+ dri_data[5] = ptr->dri & 0xff;
return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data);
}
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 2951b9084bfd2b..c5774e7855d036 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2976,10 +2976,12 @@ static void __devexit parport_pc_pci_remove(struct pci_dev *dev)
pci_set_drvdata(dev, NULL);
- for (i = data->num - 1; i >= 0; i--)
- parport_pc_unregister_port(data->ports[i]);
+ if (data) {
+ for (i = data->num - 1; i >= 0; i--)
+ parport_pc_unregister_port(data->ports[i]);
- kfree(data);
+ kfree(data);
+ }
}
static struct pci_driver parport_pc_pci_driver = {
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index fbfe5d35de3300..cdf110fd635181 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -615,7 +615,7 @@ config SERIAL_68360
config SERIAL_PMACZILOG
tristate "PowerMac z85c30 ESCC support"
- depends on PPC_OF
+ depends on PPC_OF && PPC_PMAC
select SERIAL_CORE
help
This driver supports the Zilog z85C30 serial ports found on
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 47945745291d2f..2a5cf174ca30d9 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -18,7 +18,7 @@
* Some of the code has been inspired/copied from the 2.4 code written
* by Dale Farnsworth <dfarnsworth@mvista.com>.
*
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003 MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public License
@@ -26,33 +26,26 @@
* kind, whether express or implied.
*/
-/* OCP Usage :
+/* Platform device Usage :
*
- * This drivers uses the OCP model. To load the serial driver for one of the
- * PSCs, just add this to the core_ocp table :
+ * Since PSCs can have multiple function, the correct driver for each one
+ * is selected by calling mpc52xx_match_psc_function(...). The function
+ * handled by this driver is "uart".
*
- * {
- * .vendor = OCP_VENDOR_FREESCALE,
- * .function = OCP_FUNC_PSC_UART,
- * .index = 0,
- * .paddr = MPC52xx_PSC1,
- * .irq = MPC52xx_PSC1_IRQ,
- * .pm = OCP_CPM_NA,
- * },
- *
- * This is for PSC1, replace the paddr and irq according to the PSC you want to
- * use. The driver all necessary registers to place the PSC in uart mode without
+ * The driver init all necessary registers to place the PSC in uart mode without
* DCD. However, the pin multiplexing aren't changed and should be set either
* by the bootloader or in the platform init code.
- * The index field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
+ *
+ * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
* and so on). So the PSC1 is mapped to /dev/ttyS0, PSC2 to /dev/ttyS1 and so
* on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly for
* the console code : without this 1:1 mapping, at early boot time, when we are
* parsing the kernel args console=ttyS?, we wouldn't know wich PSC it will be
- * mapped to because OCP stuff is not yet initialized.
+ * mapped to.
*/
#include <linux/config.h>
+#include <linux/device.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/serial.h>
@@ -61,7 +54,6 @@
#include <asm/delay.h>
#include <asm/io.h>
-#include <asm/ocp.h>
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
@@ -191,6 +183,13 @@ static int
mpc52xx_uart_startup(struct uart_port *port)
{
struct mpc52xx_psc __iomem *psc = PSC(port);
+ int ret;
+
+ /* Request IRQ */
+ ret = request_irq(port->irq, mpc52xx_uart_int,
+ SA_INTERRUPT | SA_SAMPLE_RANDOM, "mpc52xx_psc_uart", port);
+ if (ret)
+ return ret;
/* Reset/activate the port, clear and enable interrupts */
out_8(&psc->command,MPC52xx_PSC_RST_RX);
@@ -225,6 +224,9 @@ mpc52xx_uart_shutdown(struct uart_port *port)
port->read_status_mask = 0;
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
+
+ /* Release interrupt */
+ free_irq(port->irq, port);
}
static void
@@ -326,15 +328,21 @@ mpc52xx_uart_release_port(struct uart_port *port)
iounmap(port->membase);
port->membase = NULL;
}
+
+ release_mem_region(port->mapbase, MPC52xx_PSC_SIZE);
}
static int
mpc52xx_uart_request_port(struct uart_port *port)
{
if (port->flags & UPF_IOREMAP) /* Need to remap ? */
- port->membase = ioremap(port->mapbase, sizeof(struct mpc52xx_psc));
-
- return port->membase != NULL ? 0 : -EBUSY;
+ port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
+
+ if (!port->membase)
+ return -EINVAL;
+
+ return request_mem_region(port->mapbase, MPC52xx_PSC_SIZE,
+ "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
}
static void
@@ -354,7 +362,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
if ( (ser->irq != port->irq) ||
(ser->io_type != SERIAL_IO_MEM) ||
(ser->baud_base != port->uartclk) ||
- // FIXME Should check addresses/irq as well ?
+ (ser->iomem_base != (void*)port->mapbase) ||
(ser->hub6 != 0 ) )
return -EINVAL;
@@ -630,7 +638,7 @@ mpc52xx_console_setup(struct console *co, char *options)
{
struct uart_port *port = &mpc52xx_uart_ports[co->index];
- int baud = 9600;
+ int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
int bits = 8;
int parity = 'n';
int flow = 'n';
@@ -643,14 +651,12 @@ mpc52xx_console_setup(struct console *co, char *options)
spin_lock_init(&port->lock);
port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
port->ops = &mpc52xx_uart_ops;
- port->mapbase = MPC52xx_PSCx(co->index);
+ port->mapbase = MPC52xx_PA(MPC52xx_PSCx_OFFSET(co->index+1));
- /* We ioremap ourself */
- port->membase = ioremap(port->mapbase, sizeof(struct mpc52xx_psc));
- if (port->membase == NULL) {
- release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
- return -EBUSY;
- }
+ /* We ioremap ourself */
+ port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE);
+ if (port->membase == NULL)
+ return -EINVAL;
/* Setup the port parameters accoding to options */
if (options)
@@ -707,26 +713,32 @@ static struct uart_driver mpc52xx_uart_driver = {
/* ======================================================================== */
-/* OCP Driver */
+/* Platform Driver */
/* ======================================================================== */
static int __devinit
-mpc52xx_uart_probe(struct ocp_device *ocp)
+mpc52xx_uart_probe(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res = pdev->resource;
+
struct uart_port *port = NULL;
- int idx, ret;
+ int i, idx, ret;
- /* Get the corresponding port struct */
- idx = ocp->def->index;
+ /* Check validity & presence */
+ idx = pdev->id;
if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
return -EINVAL;
-
- port = &mpc52xx_uart_ports[idx];
+
+ if (!mpc52xx_match_psc_function(idx,"uart"))
+ return -ENODEV;
/* Init the port structure */
+ port = &mpc52xx_uart_ports[idx];
+
+ memset(port, 0x00, sizeof(struct uart_port));
+
spin_lock_init(&port->lock);
- port->mapbase = ocp->def->paddr;
- port->irq = ocp->def->irq;
port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
port->fifosize = 255; /* Should be 512 ! But it can't be */
/* stored in a unsigned char */
@@ -735,95 +747,65 @@ mpc52xx_uart_probe(struct ocp_device *ocp)
( uart_console(port) ? 0 : UPF_IOREMAP );
port->line = idx;
port->ops = &mpc52xx_uart_ops;
- port->read_status_mask = 0;
-
- /* Requests the mem & irqs */
- /* Unlike other serial drivers, we reserve the resources here, so we
- * can detect early if multiple drivers uses the same PSC. Special
- * care must be taken with the console PSC
- */
- ret = request_irq(
- port->irq, mpc52xx_uart_int,
- SA_INTERRUPT | SA_SAMPLE_RANDOM, "mpc52xx_psc_uart", port);
- if (ret)
- goto error;
- ret = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc),
- "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
- if (ret)
- goto free_irq;
+ /* Search for IRQ and mapbase */
+ for (i=0 ; i<pdev->num_resources ; i++, res++) {
+ if (res->flags & IORESOURCE_MEM)
+ port->mapbase = res->start;
+ else if (res->flags & IORESOURCE_IRQ)
+ port->irq = res->start;
+ }
+ if (!port->irq || !port->mapbase)
+ return -EINVAL;
/* Add the port to the uart sub-system */
ret = uart_add_one_port(&mpc52xx_uart_driver, port);
- if (ret)
- goto release_mem;
-
- ocp_set_drvdata(ocp, (void*)port);
-
- return 0;
-
-
-free_irq:
- free_irq(port->irq, mpc52xx_uart_int);
-
-release_mem:
- release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
-
-error:
- if (uart_console(port))
- printk( "mpc52xx_uart.c: Error during resource alloction for "
- "the console port !!! Check that the console PSC is "
- "not used by another OCP driver !!!\n" );
+ if (!ret)
+ dev_set_drvdata(dev, (void*)port);
return ret;
}
-static void
-mpc52xx_uart_remove(struct ocp_device *ocp)
+static int
+mpc52xx_uart_remove(struct device *dev)
{
- struct uart_port *port = (struct uart_port *) ocp_get_drvdata(ocp);
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
- ocp_set_drvdata(ocp, NULL);
+ dev_set_drvdata(dev, NULL);
- if (port) {
+ if (port)
uart_remove_one_port(&mpc52xx_uart_driver, port);
- release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
- free_irq(port->irq, mpc52xx_uart_int);
- }
+
+ return 0;
}
#ifdef CONFIG_PM
static int
-mpc52xx_uart_suspend(struct ocp_device *ocp, u32 state)
+mpc52xx_uart_suspend(struct device *dev, u32 state, u32 level)
{
- struct uart_port *port = (struct uart_port *) ocp_get_drvdata(ocp);
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
- uart_suspend_port(&mpc52xx_uart_driver, port);
+ if (sport && level == SUSPEND_DISABLE)
+ uart_suspend_port(&mpc52xx_uart_driver, port);
return 0;
}
static int
-mpc52xx_uart_resume(struct ocp_device *ocp)
+mpc52xx_uart_resume(struct device *dev, u32 level)
{
- struct uart_port *port = (struct uart_port *) ocp_get_drvdata(ocp);
+ struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
- uart_resume_port(&mpc52xx_uart_driver, port);
+ if (port && level == RESUME_ENABLE)
+ uart_resume_port(&mpc52xx_uart_driver, port);
return 0;
}
#endif
-static struct ocp_device_id mpc52xx_uart_ids[] __devinitdata = {
- { .vendor = OCP_VENDOR_FREESCALE, .function = OCP_FUNC_PSC_UART },
- { .vendor = OCP_VENDOR_INVALID /* Terminating entry */ }
-};
-
-MODULE_DEVICE_TABLE(ocp, mpc52xx_uart_ids);
-
-static struct ocp_driver mpc52xx_uart_ocp_driver = {
- .name = "mpc52xx_psc_uart",
- .id_table = mpc52xx_uart_ids,
+static struct device_driver mpc52xx_uart_platform_driver = {
+ .name = "mpc52xx-psc",
+ .bus = &platform_bus_type,
.probe = mpc52xx_uart_probe,
.remove = mpc52xx_uart_remove,
#ifdef CONFIG_PM
@@ -845,10 +827,11 @@ mpc52xx_uart_init(void)
printk(KERN_INFO "Serial: MPC52xx PSC driver\n");
ret = uart_register_driver(&mpc52xx_uart_driver);
- if (ret)
- return ret;
-
- ret = ocp_register_driver(&mpc52xx_uart_ocp_driver);
+ if (ret == 0) {
+ ret = driver_register(&mpc52xx_uart_platform_driver);
+ if (ret)
+ uart_unregister_driver(&mpc52xx_uart_driver);
+ }
return ret;
}
@@ -856,7 +839,7 @@ mpc52xx_uart_init(void)
static void __exit
mpc52xx_uart_exit(void)
{
- ocp_unregister_driver(&mpc52xx_uart_ocp_driver);
+ driver_unregister(&mpc52xx_uart_platform_driver);
uart_unregister_driver(&mpc52xx_uart_driver);
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f6821e39e2bda5..2a1c5965de2229 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -74,6 +74,11 @@ config FB_SOFT_CURSOR
This is used by drivers that don't provide their own (accelerated)
version.
+config FB_MACMODES
+ tristate
+ depends on FB
+ default n
+
config FB_MODE_HELPERS
bool "Enable Video Mode Handling Helpers"
depends on FB
@@ -323,6 +328,7 @@ config FB_OF
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES
help
Say Y if you want support with Open Firmware for your graphics
board.
@@ -334,6 +340,7 @@ config FB_CONTROL
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES
help
This driver supports a frame buffer for the graphics adapter in the
Power Macintosh 7300 and others.
@@ -345,6 +352,7 @@ config FB_PLATINUM
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES
help
This driver supports a frame buffer for the "platinum" graphics
adapter in some Power Macintoshes.
@@ -356,6 +364,7 @@ config FB_VALKYRIE
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES
help
This driver supports a frame buffer for the "valkyrie" graphics
adapter in some Power Macintoshes.
@@ -384,6 +393,7 @@ config FB_IMSTT
depends on (FB = y) && PCI
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES if PPC
help
The IMS Twin Turbo is a PCI-based frame buffer card bundled with
many Macintosh and compatible computers.
@@ -436,6 +446,7 @@ config FB_MAC
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES
# bool ' Apple DAFB display support' CONFIG_FB_DAFB
config FB_HP300
@@ -619,12 +630,11 @@ config FB_NVIDIA
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
- the the rivafb.
+ the rivafb.
Say Y if you have such a graphics board.
To compile this driver as a module, choose M here: the
module will be called nvidiafb.
- none yet
config FB_NVIDIA_I2C
bool "Enable DDC Support"
@@ -754,6 +764,7 @@ config FB_MATROX
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
select FB_TILEBLITTING
+ select FB_MACMODES if PPC_PMAC
---help---
Say Y here if you have a Matrox Millennium, Matrox Millennium II,
Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
@@ -893,6 +904,7 @@ config FB_RADEON_OLD
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES if PPC
help
Choose this option if you want to use an ATI Radeon graphics card as
a framebuffer device. There are both PCI and AGP versions. You
@@ -910,6 +922,7 @@ config FB_RADEON
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES if PPC_OF
help
Choose this option if you want to use an ATI Radeon graphics card as
a framebuffer device. There are both PCI and AGP versions. You
@@ -948,6 +961,7 @@ config FB_ATY128
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES if PPC_PMAC
help
This driver supports graphics boards with the ATI Rage128 chips.
Say Y if you have such a graphics board and read
@@ -963,6 +977,7 @@ config FB_ATY
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB_SOFT_CURSOR
+ select FB_MACMODES if PPC
help
This driver supports graphics boards with the ATI Mach64 chips.
Say Y if you have such a graphics board.
@@ -1433,6 +1448,18 @@ config FB_PXA_PARAMETERS
<file:Documentation/fb/pxafb.txt> describes the available parameters.
+config FB_S1D13XXX
+ tristate "Epson S1D13XXX framebuffer support"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_SOFT_CURSOR
+ help
+ Support for S1D13XXX framebuffer device family (currently only
+ working with S1D13806). Product specs at
+ <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+
config FB_VIRTUAL
tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index bf04cfb000bda5..92265b741dc3a4 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
obj-$(CONFIG_FB_SOFT_CURSOR) += softcursor.o
+obj-$(CONFIG_FB_MACMODES) += macmodes.o
# Hardware specific drivers go first
obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
@@ -29,8 +30,8 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_MATROX) += matrox/
obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o
obj-$(CONFIG_FB_NVIDIA) += nvidia/
-obj-$(CONFIG_FB_ATY) += aty/
-obj-$(CONFIG_FB_ATY128) += aty/
+obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
+obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
obj-$(CONFIG_FB_RADEON) += aty/
obj-$(CONFIG_FB_SIS) += sis/
obj-$(CONFIG_FB_KYRO) += kyro/
@@ -41,9 +42,9 @@ obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o
obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o
-obj-$(CONFIG_FB_CONTROL) += controlfb.o macmodes.o
-obj-$(CONFIG_FB_PLATINUM) += platinumfb.o macmodes.o
-obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o macmodes.o
+obj-$(CONFIG_FB_CONTROL) += controlfb.o
+obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
+obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
obj-$(CONFIG_FB_CT65550) += chipsfb.o
obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
@@ -61,7 +62,7 @@ obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
obj-$(CONFIG_FB_SGIVW) += sgivwfb.o
obj-$(CONFIG_FB_ACORN) += acornfb.o
obj-$(CONFIG_FB_ATARI) += atafb.o
-obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o
+obj-$(CONFIG_FB_MAC) += macfb.o
obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_IGA) += igafb.o
obj-$(CONFIG_FB_APOLLO) += dnfb.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
obj-$(CONFIG_FB_MAXINE) += maxinefb.o
obj-$(CONFIG_FB_TX3912) += tx3912fb.o
+obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index ed87832d789c4f..f4729f4df8cec0 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -604,7 +604,7 @@ static int __init asiliantfb_init(void)
if (fb_get_options("asiliantfb", NULL))
return -ENODEV;
- return pci_module_init(&asiliantfb_driver);
+ return pci_register_driver(&asiliantfb_driver);
}
module_init(asiliantfb_init);
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 7b090b23bfffd1..8a4ba3bb987284 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -2461,7 +2461,7 @@ static int __init aty128fb_init(void)
aty128fb_setup(option);
#endif
- return pci_module_init(&aty128fb_driver);
+ return pci_register_driver(&aty128fb_driver);
}
static void __exit aty128fb_exit(void)
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 4d37dffe3bf640..8c42538dc8c12d 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -100,8 +100,8 @@
/*
* Debug flags.
*/
-/*#undef DEBUG*/
-#define DEBUG
+#undef DEBUG
+/*#define DEBUG*/
/* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
/* - must be large enough to catch all GUI-Regs */
@@ -307,6 +307,7 @@ static int vram;
static int pll;
static int mclk;
static int xclk;
+static int comp_sync __initdata = -1;
static char *mode;
#ifdef CONFIG_PPC
@@ -2527,6 +2528,13 @@ static int __init aty_init(struct fb_info *info, const char *name)
else
var.accel_flags |= FB_ACCELF_TEXT;
+ if (comp_sync != -1) {
+ if (!comp_sync)
+ var.sync &= ~FB_SYNC_COMP_HIGH_ACT;
+ else
+ var.sync |= FB_SYNC_COMP_HIGH_ACT;
+ }
+
if (var.yres == var.yres_virtual) {
u32 videoram = (info->fix.smem_len - (PAGE_SIZE << 2));
var.yres_virtual = ((videoram * 8) / var.bits_per_pixel) / var.xres_virtual;
@@ -3427,8 +3435,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
err_release_io:
#ifdef __sparc__
- if (par->mmap_map)
- kfree(par->mmap_map);
+ kfree(par->mmap_map);
#else
if (par->ati_regbase)
iounmap(par->ati_regbase);
@@ -3436,7 +3443,7 @@ err_release_io:
iounmap(info->screen_base);
#endif
err_release_mem:
- if(par->aux_start)
+ if (par->aux_start)
release_mem_region(par->aux_start, par->aux_size);
release_mem_region(par->res_start, par->res_size);
@@ -3543,8 +3550,7 @@ static void __devexit atyfb_remove(struct fb_info *info)
#endif
#endif
#ifdef __sparc__
- if (par->mmap_map)
- kfree(par->mmap_map);
+ kfree(par->mmap_map);
#endif
if (par->aux_start)
release_mem_region(par->aux_start, par->aux_size);
@@ -3612,6 +3618,8 @@ static int __init atyfb_setup(char *options)
mclk = simple_strtoul(this_opt + 5, NULL, 0);
else if (!strncmp(this_opt, "xclk:", 5))
xclk = simple_strtoul(this_opt+5, NULL, 0);
+ else if (!strncmp(this_opt, "comp_sync:", 10))
+ comp_sync = simple_strtoul(this_opt+10, NULL, 0);
#ifdef CONFIG_PPC
else if (!strncmp(this_opt, "vmode:", 6)) {
unsigned int vmode =
@@ -3671,7 +3679,7 @@ static int __init atyfb_init(void)
#endif
#ifdef CONFIG_PCI
- pci_module_init(&atyfb_driver);
+ pci_register_driver(&atyfb_driver);
#endif
#ifdef CONFIG_ATARI
atyfb_atari_probe();
@@ -3701,6 +3709,9 @@ module_param(mclk, int, 0);
MODULE_PARM_DESC(mclk, "int: override memory clock");
module_param(xclk, int, 0);
MODULE_PARM_DESC(xclk, "int: override accelerated engine clock");
+module_param(comp_sync, int, 0);
+MODULE_PARM_DESC(comp_sync,
+ "Set composite sync signal to low (0) or high (1)");
module_param(mode, charp, 0);
MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
#ifdef CONFIG_MTRR
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index dc8598dacbcb2d..3ca27cb13caa0d 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -189,32 +189,6 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
radeon_engine_flush (rinfo);
- /* Some ASICs have bugs with dynamic-on feature, which are
- * ASIC-version dependent, so we force all blocks on for now
- * -- from XFree86
- * We don't do that on macs, things just work here with dynamic
- * clocking... --BenH
- */
-#ifdef CONFIG_ALL_PPC
- if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
-#else
- if (rinfo->has_CRTC2)
-#endif
- {
- u32 tmp;
-
- tmp = INPLL(SCLK_CNTL);
- OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
- CP_MAX_DYN_STOP_LAT |
- SCLK_FORCEON_MASK));
-
- if (rinfo->family == CHIP_FAMILY_RV200)
- {
- tmp = INPLL(SCLK_MORE_CNTL);
- OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
- }
- }
-
clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
mclk_cntl = INPLL(MCLK_CNTL);
@@ -274,8 +248,6 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
OUTPLL(MCLK_CNTL, mclk_cntl);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
}
void radeonfb_engine_init (struct radeonfb_info *rinfo)
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 7d1688a8900ec2..e8eb124754b136 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -1,4 +1,3 @@
-
/*
* drivers/video/aty/radeon_base.c
*
@@ -530,11 +529,8 @@ static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo)
break;
}
- radeon_pll_workaround_before(rinfo);
ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
- radeon_pll_workaround_after(rinfo);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_index(rinfo);
n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
m = (INPLL(PPLL_REF_DIV) & 0x3ff);
@@ -1173,11 +1169,8 @@ static void radeon_save_state (struct radeonfb_info *rinfo,
save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
/* PLL regs */
- radeon_pll_workaround_before(rinfo);
save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f;
- radeon_pll_workaround_after(rinfo);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_index(rinfo);
save->ppll_div_3 = INPLL(PPLL_DIV_3);
save->ppll_ref_div = INPLL(PPLL_REF_DIV);
}
@@ -1204,13 +1197,11 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
/* We still have to force a switch to selected PPLL div thanks to
* an XFree86 driver bug which will switch it away in some cases
* even when using UseFDev */
- radeon_pll_workaround_before(rinfo);
OUTREGP(CLOCK_CNTL_INDEX,
mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
~PPLL_DIV_SEL_MASK);
- radeon_pll_workaround_after(rinfo);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_index(rinfo);
+ radeon_pll_errata_after_data(rinfo);
return;
}
}
@@ -1224,13 +1215,11 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
/* Switch to selected PPLL divider */
- radeon_pll_workaround_before(rinfo);
OUTREGP(CLOCK_CNTL_INDEX,
mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
~PPLL_DIV_SEL_MASK);
- radeon_pll_workaround_after(rinfo);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_index(rinfo);
+ radeon_pll_errata_after_data(rinfo);
/* Set PPLL ref. div */
if (rinfo->family == CHIP_FAMILY_R300 ||
@@ -1754,8 +1743,7 @@ static int radeonfb_set_par(struct fb_info *info)
} else {
/* DFP */
newmode->fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
- newmode->tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
- ~(TMDS_PLLRST);
+ newmode->tmds_transmitter_cntl &= ~(TMDS_PLLRST);
/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
if (IS_R300_VARIANT(rinfo) ||
(rinfo->family == CHIP_FAMILY_R200) || !rinfo->has_CRTC2)
@@ -2248,7 +2236,7 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0;
rinfo->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0;
rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0;
-
+
/* Set base addrs */
rinfo->fb_base_phys = pci_resource_start (pdev, 0);
rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
@@ -2271,6 +2259,24 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+ /*
+ * Check for errata
+ */
+ rinfo->errata = 0;
+ if (rinfo->family == CHIP_FAMILY_R300 &&
+ (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
+ == CFG_ATI_REV_A11)
+ rinfo->errata |= CHIP_ERRATA_R300_CG;
+
+ if (rinfo->family == CHIP_FAMILY_RV200 ||
+ rinfo->family == CHIP_FAMILY_RS200)
+ rinfo->errata |= CHIP_ERRATA_PLL_DUMMYREADS;
+
+ if (rinfo->family == CHIP_FAMILY_RV100 ||
+ rinfo->family == CHIP_FAMILY_RS100 ||
+ rinfo->family == CHIP_FAMILY_RS200)
+ rinfo->errata |= CHIP_ERRATA_PLL_DELAY;
+
#ifdef CONFIG_PPC_OF
/* On PPC, we obtain the OF device-node pointer to the firmware
* data for this chip
@@ -2310,13 +2316,6 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
rinfo->mapped_vram/1024);
/*
- * Check for required workaround for PLL accesses
- */
- rinfo->R300_cg_workaround = (rinfo->family == CHIP_FAMILY_R300 &&
- (INREG(CONFIG_CNTL) & CFG_ATI_REV_ID_MASK)
- == CFG_ATI_REV_A11);
-
- /*
* Map the BIOS ROM if any and retreive PLL parameters from
* the BIOS. We skip that on mobility chips as the real panel
* values we need aren't in the ROM but in the BIOS image in
@@ -2420,10 +2419,8 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
err_unmap_fb:
iounmap(rinfo->fb_base);
err_unmap_rom:
- if (rinfo->mon1_EDID)
- kfree(rinfo->mon1_EDID);
- if (rinfo->mon2_EDID)
- kfree(rinfo->mon2_EDID);
+ kfree(rinfo->mon1_EDID);
+ kfree(rinfo->mon2_EDID);
if (rinfo->mon1_modedb)
fb_destroy_modedb(rinfo->mon1_modedb);
fb_dealloc_cmap(&info->cmap);
@@ -2479,10 +2476,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
pci_release_regions(pdev);
- if (rinfo->mon1_EDID)
- kfree(rinfo->mon1_EDID);
- if (rinfo->mon2_EDID)
- kfree(rinfo->mon2_EDID);
+ kfree(rinfo->mon1_EDID);
+ kfree(rinfo->mon2_EDID);
if (rinfo->mon1_modedb)
fb_destroy_modedb(rinfo->mon1_modedb);
#ifdef CONFIG_FB_RADEON_I2C
@@ -2551,7 +2546,7 @@ static int __init radeonfb_init (void)
return -ENODEV;
radeonfb_setup(option);
#endif
- return pci_module_init (&radeonfb_driver);
+ return pci_register_driver (&radeonfb_driver);
}
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index e87ef153d87bb4..762244164c81a9 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -236,6 +236,12 @@ int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_e
if (edid)
break;
}
+ /* Release the DDC lines when done or the Apple Cinema HD display
+ * will switch off
+ */
+ OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN));
+ (void)INREG(reg);
+
if (out_edid)
*out_edid = edid;
if (!edid) {
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 2918d5ec36c891..ea7c8630691845 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -618,11 +618,9 @@ void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
}
}
if (ignore_edid) {
- if (rinfo->mon1_EDID)
- kfree(rinfo->mon1_EDID);
+ kfree(rinfo->mon1_EDID);
rinfo->mon1_EDID = NULL;
- if (rinfo->mon2_EDID)
- kfree(rinfo->mon2_EDID);
+ kfree(rinfo->mon2_EDID);
rinfo->mon2_EDID = NULL;
}
@@ -657,11 +655,8 @@ static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
&& rinfo->is_mobility) {
int ppll_div_sel;
u32 ppll_divn;
- radeon_pll_workaround_before(rinfo);
ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
- radeon_pll_workaround_after(rinfo);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_index(rinfo);
ppll_divn = INPLL(PPLL_DIV_0 + ppll_div_sel);
rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
rinfo->panel_info.fbk_divider = ppll_divn & 0x7ff;
@@ -906,7 +901,7 @@ void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_
*/
/*
- * This is used when looking for modes. We assign a "goodness" value
+ * This is used when looking for modes. We assign a "distance" value
* to a mode in the modedb depending how "close" it is from what we
* are looking for.
* Currently, we don't compare that much, we could do better but
@@ -915,13 +910,11 @@ void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_
static int radeon_compare_modes(const struct fb_var_screeninfo *var,
const struct fb_videomode *mode)
{
- int goodness = 0;
+ int distance = 0;
- if (var->yres == mode->yres)
- goodness += 10;
- if (var->xres == mode->xres)
- goodness += 9;
- return goodness;
+ distance = mode->yres - var->yres;
+ distance += (mode->xres - var->xres)/2;
+ return distance;
}
/*
@@ -943,7 +936,7 @@ int radeon_match_mode(struct radeonfb_info *rinfo,
const struct fb_videomode *db = vesa_modes;
int i, dbsize = 34;
int has_rmx, native_db = 0;
- int goodness = 0;
+ int distance = INT_MAX;
const struct fb_videomode *candidate = NULL;
/* Start with a copy of the requested mode */
@@ -979,19 +972,19 @@ int radeon_match_mode(struct radeonfb_info *rinfo,
/* Now look for a mode in the database */
while (db) {
for (i = 0; i < dbsize; i++) {
- int g;
+ int d;
if (db[i].yres < src->yres)
continue;
if (db[i].xres < src->xres)
continue;
- g = radeon_compare_modes(src, &db[i]);
+ d = radeon_compare_modes(src, &db[i]);
/* If the new mode is at least as good as the previous one,
* then it's our new candidate
*/
- if (g >= goodness) {
+ if (d < distance) {
candidate = &db[i];
- goodness = g;
+ distance = d;
}
}
db = NULL;
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 365c049877b23c..23c677e5093fdd 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -1372,12 +1372,10 @@ static void radeon_pm_start_mclk_sclk(struct radeonfb_info *rinfo)
/* Reconfigure SPLL charge pump, VCO gain, duty cycle */
tmp = INPLL(pllSPLL_CNTL);
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);
- radeon_pll_workaround_after(rinfo);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_data(rinfo);
/* Set SPLL feedback divider */
tmp = INPLL(pllM_SPLL_REF_FB_DIV);
@@ -1409,12 +1407,10 @@ static void radeon_pm_start_mclk_sclk(struct radeonfb_info *rinfo)
/* Reconfigure MPLL charge pump, VCO gain, duty cycle */
tmp = INPLL(pllMPLL_CNTL);
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX, pllMPLL_CNTL + PLL_WR_EN);
- radeon_pll_workaround_after(rinfo);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_data(rinfo);
/* Set MPLL feedback divider */
tmp = INPLL(pllM_SPLL_REF_FB_DIV);
@@ -1532,12 +1528,10 @@ static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo)
{
u32 tmp;
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX, pllHTOTAL_CNTL + PLL_WR_EN);
- radeon_pll_workaround_after(rinfo);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA, 0);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_data(rinfo);
tmp = INPLL(pllVCLK_ECP_CNTL);
OUTPLL(pllVCLK_ECP_CNTL, tmp | 0x80);
@@ -1552,12 +1546,10 @@ static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo)
* probably useless since we already did it ...
*/
tmp = INPLL(pllPPLL_CNTL);
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);
- radeon_pll_workaround_after(rinfo);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_data(rinfo);
/* Restore our "reference" PPLL divider set by firmware
* according to proper spread spectrum calculations
@@ -1581,11 +1573,9 @@ static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo)
mdelay(5);
/* Switch pixel clock to firmware default div 0 */
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX+1, 0);
- radeon_pll_workaround_after(rinfo);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_index(rinfo);
+ radeon_pll_errata_after_data(rinfo);
}
static void radeon_pm_m10_reconfigure_mc(struct radeonfb_info *rinfo)
@@ -2173,7 +2163,9 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
tmp = INPLL(MPLL_CNTL);
OUTREG8(CLOCK_CNTL_INDEX, MPLL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+ radeon_pll_errata_after_data(rinfo);
tmp = INPLL(M_SPLL_REF_FB_DIV);
OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0x5900);
@@ -2194,7 +2186,9 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
tmp = INPLL(SPLL_CNTL);
OUTREG8(CLOCK_CNTL_INDEX, SPLL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+ radeon_pll_errata_after_data(rinfo);
tmp = INPLL(M_SPLL_REF_FB_DIV);
OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0x780000);
@@ -2322,7 +2316,9 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
OUTREG(CRTC_H_SYNC_STRT_WID, 0x008e0580);
OUTREG(CRTC_H_TOTAL_DISP, 0x009f00d2);
OUTREG8(CLOCK_CNTL_INDEX, HTOTAL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA, 0);
+ radeon_pll_errata_after_data(rinfo);
OUTREG(CRTC_V_SYNC_STRT_WID, 0x00830403);
OUTREG(CRTC_V_TOTAL_DISP, 0x03ff0429);
OUTREG(FP_CRTC_H_TOTAL_DISP, 0x009f0033);
@@ -2344,10 +2340,15 @@ static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
INPLL(PPLL_REF_DIV);
OUTREG8(CLOCK_CNTL_INDEX, PPLL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
OUTREG8(CLOCK_CNTL_DATA + 1, 0xbc);
+ radeon_pll_errata_after_data(rinfo);
tmp = INREG(CLOCK_CNTL_INDEX);
+ radeon_pll_errata_after_index(rinfo);
OUTREG(CLOCK_CNTL_INDEX, tmp & 0xff);
+ radeon_pll_errata_after_index(rinfo);
+ radeon_pll_errata_after_data(rinfo);
OUTPLL(PPLL_DIV_0, 0x48090);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index a1e9d39f0e8545..659bc9f62244aa 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -77,6 +77,15 @@ enum radeon_chip_flags {
CHIP_HAS_CRTC2 = 0x00040000UL,
};
+/*
+ * Errata workarounds
+ */
+enum radeon_errata {
+ CHIP_ERRATA_R300_CG = 0x00000001,
+ CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002,
+ CHIP_ERRATA_PLL_DELAY = 0x00000004,
+};
+
/*
* Monitor types
@@ -295,6 +304,7 @@ struct radeonfb_info {
int chipset;
u8 family;
u8 rev;
+ unsigned int errata;
unsigned long video_ram;
unsigned long mapped_vram;
int vram_width;
@@ -305,7 +315,6 @@ struct radeonfb_info {
int has_CRTC2;
int is_mobility;
int is_IGP;
- int R300_cg_workaround;
int reversed_DAC;
int reversed_TMDS;
struct panel_info panel_info;
@@ -369,6 +378,21 @@ struct radeonfb_info {
* IO macros
*/
+/* Note about this function: we have some rare cases where we must not schedule,
+ * this typically happen with our special "wake up early" hook which allows us to
+ * wake up the graphic chip (and thus get the console back) before everything else
+ * on some machines that support that mecanism. At this point, interrupts are off
+ * and scheduling is not permitted
+ */
+static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
+{
+ if (rinfo->no_schedule || oops_in_progress)
+ mdelay(ms);
+ else
+ msleep(ms);
+}
+
+
#define INREG8(addr) readb((rinfo->mmio_base)+addr)
#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
#define INREG(addr) readl((rinfo->mmio_base)+addr)
@@ -390,107 +414,85 @@ static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask)
-/* This function is required to workaround a hardware bug in some (all?)
- * revisions of the R300. This workaround should be called after every
- * CLOCK_CNTL_INDEX register access. If not, register reads afterward
- * may not be correct.
- */
-static inline void R300_cg_workardound(struct radeonfb_info *rinfo)
-{
- u32 save, tmp;
- save = INREG(CLOCK_CNTL_INDEX);
- tmp = save & ~(0x3f | PLL_WR_EN);
- OUTREG(CLOCK_CNTL_INDEX, tmp);
- tmp = INREG(CLOCK_CNTL_DATA);
- OUTREG(CLOCK_CNTL_INDEX, save);
-}
-
/*
- * PLL accesses suffer from various HW issues on the different chip
- * families. Some R300's need the above workaround, rv200 & friends
- * need a couple of dummy reads after any write of CLOCK_CNTL_INDEX,
- * and some RS100/200 need a dummy read before writing to
- * CLOCK_CNTL_INDEX as well. Instead of testing every chip revision,
- * we just unconditionally do the workarounds at once since PLL
- * accesses are far from beeing performance critical. Except for R300
- * one which stays separate for now
+ * Note about PLL register accesses:
+ *
+ * I have removed the spinlock on them on purpose. The driver now
+ * expects that it will only manipulate the PLL registers in normal
+ * task environment, where radeon_msleep() will be called, protected
+ * by a semaphore (currently the console semaphore) so that no conflict
+ * will happen on the PLL register index.
+ *
+ * With the latest changes to the VT layer, this is guaranteed for all
+ * calls except the actual drawing/blits which aren't supposed to use
+ * the PLL registers anyway
+ *
+ * This is very important for the workarounds to work properly. The only
+ * possible exception to this rule is the call to unblank(), which may
+ * be done at irq time if an oops is in progress.
*/
-
-static inline void radeon_pll_workaround_before(struct radeonfb_info *rinfo)
+static inline void radeon_pll_errata_after_index(struct radeonfb_info *rinfo)
{
+ if (!(rinfo->errata & CHIP_ERRATA_PLL_DUMMYREADS))
+ return;
+
+ (void)INREG(CLOCK_CNTL_DATA);
(void)INREG(CRTC_GEN_CNTL);
}
-static inline void radeon_pll_workaround_after(struct radeonfb_info *rinfo)
+static inline void radeon_pll_errata_after_data(struct radeonfb_info *rinfo)
{
- (void)INREG(CLOCK_CNTL_DATA);
- (void)INREG(CRTC_GEN_CNTL);
+ if (rinfo->errata & CHIP_ERRATA_PLL_DELAY) {
+ /* we can't deal with posted writes here ... */
+ _radeon_msleep(rinfo, 5);
+ }
+ if (rinfo->errata & CHIP_ERRATA_R300_CG) {
+ u32 save, tmp;
+ save = INREG(CLOCK_CNTL_INDEX);
+ tmp = save & ~(0x3f | PLL_WR_EN);
+ OUTREG(CLOCK_CNTL_INDEX, tmp);
+ tmp = INREG(CLOCK_CNTL_DATA);
+ OUTREG(CLOCK_CNTL_INDEX, save);
+ }
}
static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
{
u32 data;
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
- radeon_pll_workaround_after(rinfo);
+ radeon_pll_errata_after_index(rinfo);
data = INREG(CLOCK_CNTL_DATA);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_data(rinfo);
return data;
}
-static inline u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
-{
- unsigned long flags;
- u32 data;
-
- spin_lock_irqsave(&rinfo->reg_lock, flags);
- data = __INPLL(rinfo, addr);
- spin_unlock_irqrestore(&rinfo->reg_lock, flags);
- return data;
-}
-
-#define INPLL(addr) _INPLL(rinfo, addr)
-
-
static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index,
u32 val)
{
- radeon_pll_workaround_before(rinfo);
OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
- radeon_pll_workaround_after(rinfo);
+ radeon_pll_errata_after_index(rinfo);
OUTREG(CLOCK_CNTL_DATA, val);
- if (rinfo->R300_cg_workaround)
- R300_cg_workardound(rinfo);
+ radeon_pll_errata_after_data(rinfo);
}
-static inline void _OUTPLL(struct radeonfb_info *rinfo, unsigned int index, u32 val)
-{
- unsigned long flags;
- spin_lock_irqsave(&rinfo->reg_lock, flags);
- __OUTPLL(rinfo, index, val);
- spin_unlock_irqrestore(&rinfo->reg_lock, flags);
-}
-static inline void _OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
- u32 val, u32 mask)
+static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
+ u32 val, u32 mask)
{
- unsigned long flags;
unsigned int tmp;
- spin_lock_irqsave(&rinfo->reg_lock, flags);
tmp = __INPLL(rinfo, index);
tmp &= (mask);
tmp |= (val);
__OUTPLL(rinfo, index, tmp);
- spin_unlock_irqrestore(&rinfo->reg_lock, flags);
}
-#define OUTPLL(index, val) _OUTPLL(rinfo, index, val)
-#define OUTPLLP(index, val, mask) _OUTPLLP(rinfo, index, val, mask)
+#define INPLL(addr) __INPLL(rinfo, addr)
+#define OUTPLL(index, val) __OUTPLL(rinfo, index, val)
+#define OUTPLLP(index, val, mask) __OUTPLLP(rinfo, index, val, mask)
#define BIOS_IN8(v) (readb(rinfo->bios_seg + (v)))
@@ -582,20 +584,6 @@ static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
printk(KERN_ERR "radeonfb: Idle Timeout !\n");
}
-/* Note about this function: we have some rare cases where we must not schedule,
- * this typically happen with our special "wake up early" hook which allows us to
- * wake up the graphic chip (and thus get the console back) before everything else
- * on some machines that support that mecanism. At this point, interrupts are off
- * and scheduling is not permitted
- */
-static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
-{
- if (rinfo->no_schedule)
- mdelay(ms);
- else
- msleep(ms);
-}
-
#define radeon_engine_idle() _radeon_engine_idle(rinfo)
#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index a51f4d2b69d8b7..ab98f225fe3ee5 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -465,7 +465,7 @@ int __init chips_init(void)
if (fb_get_options("chipsfb", NULL))
return -ENODEV;
- return pci_module_init(&chipsfb_driver);
+ return pci_register_driver(&chipsfb_driver);
}
module_init(chips_init);
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 0255c61df6207b..a3040429c27b7e 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -2623,7 +2623,7 @@ static int __init cirrusfb_init(void)
error |= zorro_module_init(&cirrusfb_zorro_driver);
#endif
#ifdef CONFIG_PCI
- error |= pci_module_init(&cirrusfb_pci_driver);
+ error |= pci_register_driver(&cirrusfb_pci_driver);
#endif
return error;
}
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index b1d435940eb120..b28a4b0e395e6e 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -199,7 +199,10 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
count -= cnt;
}
- if (buf)
+ /* buf is always NULL except when in monochrome mode, so in this case
+ it's a gain to check buf against NULL even though kfree() handles
+ NULL pointers just fine */
+ if (unlikely(buf))
kfree(buf);
}
@@ -273,8 +276,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
if (!dst)
return;
- if (ops->cursor_data)
- kfree(ops->cursor_data);
+ kfree(ops->cursor_data);
ops->cursor_data = dst;
update_attr(dst, src, attribute, vc);
src = dst;
@@ -321,8 +323,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
if (!mask)
return;
- if (ops->cursor_state.mask)
- kfree(ops->cursor_state.mask);
+ kfree(ops->cursor_state.mask);
ops->cursor_state.mask = mask;
p->cursor_shape = vc->vc_cursor_type;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index de92afb5eecf4d..59e3b4b4e7e3e2 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,15 +107,15 @@ enum {
};
struct display fb_display[MAX_NR_CONSOLES];
-signed char con2fb_map[MAX_NR_CONSOLES];
-signed char con2fb_map_boot[MAX_NR_CONSOLES];
+static signed char con2fb_map[MAX_NR_CONSOLES];
+static signed char con2fb_map_boot[MAX_NR_CONSOLES];
static int logo_height;
static int logo_lines;
/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
enums. */
static int logo_shown = FBCON_LOGO_CANSHOW;
/* Software scrollback */
-int fbcon_softback_size = 32768;
+static int fbcon_softback_size = 32768;
static unsigned long softback_buf, softback_curr;
static unsigned long softback_in;
static unsigned long softback_top, softback_end;
@@ -130,6 +130,8 @@ static char fontname[40];
/* current fb_info */
static int info_idx = -1;
+static const struct consw fb_con;
+
#define CM_SOFTBACK (8)
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
@@ -204,8 +206,10 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
{
+ struct fbcon_ops *ops = info->fbcon_par;
+
return (info->state != FBINFO_STATE_RUNNING ||
- vc->vc_mode != KD_TEXT);
+ vc->vc_mode != KD_TEXT || ops->graphics);
}
static inline int get_color(struct vc_data *vc, struct fb_info *info,
@@ -307,7 +311,8 @@ static void cursor_timer_handler(unsigned long dev_addr)
mod_timer(&ops->cursor_timer, jiffies + HZ/5);
}
-int __init fb_console_setup(char *this_opt)
+#ifndef MODULE
+static int __init fb_console_setup(char *this_opt)
{
char *options;
int i, j;
@@ -361,6 +366,7 @@ int __init fb_console_setup(char *this_opt)
}
__setup("fbcon=", fb_console_setup);
+#endif
static int search_fb_in_map(int idx)
{
@@ -593,9 +599,12 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
ops->currcon = fg_console;
- if (info->fbops->fb_set_par)
+ if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT))
info->fbops->fb_set_par(info);
+ ops->flags |= FBCON_FLAGS_INIT;
+ ops->graphics = 0;
+
if (vc)
fbcon_set_disp(info, &info->var, vc);
else
@@ -695,6 +704,7 @@ static int var_to_display(struct display *disp,
disp->green = var->green;
disp->blue = var->blue;
disp->transp = var->transp;
+ disp->rotate = var->rotate;
disp->mode = fb_match_mode(var, &info->modelist);
if (disp->mode == NULL)
/* This should not happen */
@@ -718,6 +728,7 @@ static void display_to_var(struct fb_var_screeninfo *var,
var->green = disp->green;
var->blue = disp->blue;
var->transp = disp->transp;
+ var->rotate = disp->rotate;
}
static const char *fbcon_startup(void)
@@ -763,6 +774,7 @@ static const char *fbcon_startup(void)
memset(ops, 0, sizeof(struct fbcon_ops));
ops->currcon = -1;
+ ops->graphics = 1;
info->fbcon_par = ops;
set_blitting_type(vc, info, NULL);
@@ -889,6 +901,7 @@ static const char *fbcon_startup(void)
static void fbcon_init(struct vc_data *vc, int init)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops;
struct vc_data **default_mode = vc->vc_display_fg;
struct vc_data *svc = *default_mode;
struct display *t, *p = &fb_display[vc->vc_num];
@@ -939,6 +952,8 @@ static void fbcon_init(struct vc_data *vc, int init)
new_cols = info->var.xres / vc->vc_font.width;
new_rows = info->var.yres / vc->vc_font.height;
vc_resize(vc, new_cols, new_rows);
+
+ ops = info->fbcon_par;
/*
* We must always set the mode. The mode of the previous console
* driver could be in the same resolution but we are using different
@@ -946,9 +961,14 @@ static void fbcon_init(struct vc_data *vc, int init)
*
* We need to do it in fbcon_init() to prevent screen corruption.
*/
- if (CON_IS_VISIBLE(vc) && info->fbops->fb_set_par)
- info->fbops->fb_set_par(info);
+ if (CON_IS_VISIBLE(vc)) {
+ if (info->fbops->fb_set_par &&
+ !(ops->flags & FBCON_FLAGS_INIT))
+ info->fbops->fb_set_par(info);
+ ops->flags |= FBCON_FLAGS_INIT;
+ }
+ ops->graphics = 0;
if ((cap & FBINFO_HWACCEL_COPYAREA) &&
!(cap & FBINFO_HWACCEL_DISABLED))
@@ -1111,7 +1131,7 @@ static int scrollback_phys_max = 0;
static int scrollback_max = 0;
static int scrollback_current = 0;
-int update_var(int con, struct fb_info *info)
+static int update_var(int con, struct fb_info *info)
{
if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
return fb_pan_display(info, &info->var);
@@ -1871,7 +1891,6 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
var.activate = FB_ACTIVATE_NOW |
FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
- info->flags &= ~FBINFO_MISC_MODESWITCH;
}
var_to_display(p, &info->var, info);
}
@@ -1884,7 +1903,7 @@ static int fbcon_switch(struct vc_data *vc)
struct fb_info *info;
struct display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var;
- int i, prev_console, do_set_par = 0;
+ int i, prev_console;
info = registered_fb[con2fb_map[vc->vc_num]];
@@ -1943,14 +1962,9 @@ static int fbcon_switch(struct vc_data *vc)
fb_set_var(info, &var);
if (prev_console != -1 &&
- registered_fb[con2fb_map[prev_console]] != info)
- do_set_par = 1;
-
- if (do_set_par || info->flags & FBINFO_MISC_MODESWITCH) {
- if (info->fbops->fb_set_par)
- info->fbops->fb_set_par(info);
- info->flags &= ~FBINFO_MISC_MODESWITCH;
- }
+ registered_fb[con2fb_map[prev_console]] != info &&
+ info->fbops->fb_set_par)
+ info->fbops->fb_set_par(info);
set_blitting_type(vc, info, p);
((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
@@ -2013,29 +2027,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par;
- int active = !fbcon_is_inactive(vc, info);
if (mode_switch) {
struct fb_var_screeninfo var = info->var;
-/*
- * HACK ALERT: Some hardware will require reinitializion at this stage,
- * others will require it to be done as late as possible.
- * For now, we differentiate this with the
- * FBINFO_MISC_MODESWITCHLATE bitflag. Worst case will be
- * hardware that requires it here and another one later.
- * A definitive solution may require fixing X or the VT
- * system.
- */
- if (info->flags & FBINFO_MISC_MODESWITCHLATE)
- info->flags |= FBINFO_MISC_MODESWITCH;
- if (!blank && !(info->flags & FBINFO_MISC_MODESWITCHLATE)) {
+ ops->graphics = 1;
+
+ if (!blank) {
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
+ ops->graphics = 0;
}
}
- if (active) {
+ if (!fbcon_is_inactive(vc, info)) {
if (ops->blank_state != blank) {
ops->blank_state = blank;
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
@@ -2326,6 +2331,9 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
if (fbcon_is_inactive(vc, info))
return -EINVAL;
+ if (!CON_IS_VISIBLE(vc))
+ return 0;
+
depth = fb_get_color_depth(&info->var);
if (depth > 3) {
for (i = j = 0; i < 16; i++) {
@@ -2733,7 +2741,7 @@ static int fbcon_event_notify(struct notifier_block *self,
* The console `switch' structure for the frame buffer based console
*/
-const struct consw fb_con = {
+static const struct consw fb_con = {
.owner = THIS_MODULE,
.con_startup = fbcon_startup,
.con_init = fbcon_init,
@@ -2763,7 +2771,7 @@ static struct notifier_block fbcon_event_notifier = {
.notifier_call = fbcon_event_notify,
};
-int __init fb_console_init(void)
+static int __init fb_console_init(void)
{
int i;
@@ -2791,7 +2799,7 @@ module_init(fb_console_init);
#ifdef MODULE
-void __exit fb_console_exit(void)
+static void __exit fb_console_exit(void)
{
acquire_console_sem();
fb_unregister_client(&fbcon_event_notifier);
@@ -2803,10 +2811,4 @@ module_exit(fb_console_exit);
#endif
-/*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fb_con);
-
MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 30e641160bf674..5d377860bce283 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -18,6 +18,8 @@
#include <asm/io.h>
+#define FBCON_FLAGS_INIT 1
+
/*
* This is the interface between the low-level console driver and the
* low-level frame buffer device
@@ -41,6 +43,7 @@ struct display {
u32 grayscale;
u32 nonstd;
u32 accel_flags;
+ u32 rotate;
struct fb_bitfield red;
struct fb_bitfield green;
struct fb_bitfield blue;
@@ -67,6 +70,8 @@ struct fbcon_ops {
int cursor_flash;
int cursor_reset;
int blank_state;
+ int graphics;
+ int flags;
char *cursor_data;
};
/*
@@ -156,13 +161,10 @@ struct fbcon_ops {
#define SCROLL_REDRAW 0x004
#define SCROLL_PAN_REDRAW 0x005
-extern int fb_console_init(void);
#ifdef CONFIG_FB_TILEBLITTING
extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
struct display *p, struct fbcon_ops *ops);
#endif
extern void fbcon_set_bitops(struct fbcon_ops *ops);
-extern const struct consw fb_con;
-
#endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 4a26c828b798f3..989e4d49e5bbea 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -564,7 +564,7 @@ static int mdacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
* The console `switch' structure for the MDA based console
*/
-const struct consw mda_con = {
+static const struct consw mda_con = {
.owner = THIS_MODULE,
.con_startup = mdacon_startup,
.con_init = mdacon_init,
@@ -591,7 +591,7 @@ int __init mda_console_init(void)
return take_over_console(&mda_con, mda_first_vc-1, mda_last_vc-1, 0);
}
-void __exit mda_console_exit(void)
+static void __exit mda_console_exit(void)
{
give_up_console(&mda_con);
}
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 1c5961ce00517b..d940f605acb684 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -798,11 +798,8 @@ sti_read_rom(int wordmode, struct sti_struct *sti, unsigned long address)
return 1;
out_err:
- if(raw)
- kfree(raw);
- if(cooked)
- kfree(cooked);
-
+ kfree(raw);
+ kfree(cooked);
return 0;
}
@@ -1058,7 +1055,7 @@ static void __init sti_init_roms(void)
/* Register drivers for native & PCI cards */
register_parisc_driver(&pa_sti_driver);
- pci_module_init(&pci_sti_driver);
+ pci_register_driver(&pci_sti_driver);
/* if we didn't find the given default sti, take the first one */
if (!default_sti)
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index de51017107179c..8b1b7c687a991a 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1740,7 +1740,7 @@ static int __init cyber2000fb_init(void)
}
#endif
#ifdef CONFIG_PCI
- err = pci_module_init(&cyberpro_driver);
+ err = pci_register_driver(&cyberpro_driver);
if (!err)
ret = 0;
#endif
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 4a45e287ba4591..25f460ca0daf10 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -446,8 +446,7 @@ int fb_show_logo(struct fb_info *info)
logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height,
GFP_KERNEL);
if (logo_new == NULL) {
- if (palette)
- kfree(palette);
+ kfree(palette);
if (saved_pseudo_palette)
info->pseudo_palette = saved_pseudo_palette;
return 0;
@@ -466,12 +465,10 @@ int fb_show_logo(struct fb_info *info)
info->fbops->fb_imageblit(info, &image);
}
- if (palette != NULL)
- kfree(palette);
+ kfree(palette);
if (saved_pseudo_palette != NULL)
info->pseudo_palette = saved_pseudo_palette;
- if (logo_new != NULL)
- kfree(logo_new);
+ kfree(logo_new);
return fb_logo.logo->height;
}
#else
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 905f2e132f43da..978def01358798 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -74,10 +74,9 @@ static struct broken_edid brokendb[] = {
},
};
-const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
+static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00
};
-const unsigned char edid_v1_descriptor_flag[] = { 0x00, 0x00 };
static void copy_string(unsigned char *c, unsigned char *s)
{
@@ -589,8 +588,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
*/
void fb_destroy_modedb(struct fb_videomode *modedb)
{
- if (modedb)
- kfree(modedb);
+ kfree(modedb);
}
static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
@@ -872,18 +870,6 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
DPRINTK("========================================\n");
}
-char *get_EDID_from_firmware(struct device *dev)
-{
- unsigned char *pedid = NULL;
-
-#if defined(CONFIG_EDID_FIRMWARE) && defined(CONFIG_X86)
- pedid = edid_info.dummy;
- if (!pedid)
- return NULL;
-#endif
- return pedid;
-}
-
/*
* VESA Generalized Timing Formula (GTF)
*/
@@ -1193,10 +1179,6 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
{
specs = NULL;
}
-char *get_EDID_from_firmware(struct device *dev)
-{
- return NULL;
-}
void fb_destroy_modedb(struct fb_videomode *modedb)
{
}
@@ -1270,7 +1252,6 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
EXPORT_SYMBOL(fb_parse_edid);
EXPORT_SYMBOL(fb_edid_to_monspecs);
-EXPORT_SYMBOL(get_EDID_from_firmware);
EXPORT_SYMBOL(fb_get_mode);
EXPORT_SYMBOL(fb_validate_mode);
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 2da19ea040d0f4..e326f44f652d74 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -536,8 +536,7 @@ int __init igafb_init(void)
if (!iga_init(info, par)) {
iounmap((void *)par->io_base);
iounmap(info->screen_base);
- if (par->mmap_map)
- kfree(par->mmap_map);
+ kfree(par->mmap_map);
kfree(info);
}
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index c1c9e073a12fdb..5a72ca3c01385b 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1611,7 +1611,7 @@ static int __init imsttfb_init(void)
imsttfb_setup(option);
#endif
- return pci_module_init(&imsttfb_pci_driver);
+ return pci_register_driver(&imsttfb_pci_driver);
}
static void __exit imsttfb_exit(void)
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 75a874ce37b185..6a05b70008301f 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -360,7 +360,7 @@ intelfb_init(void)
intelfb_setup(option);
#endif
- return pci_module_init(&intelfb_driver);
+ return pci_register_driver(&intelfb_driver);
}
static void __exit
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index 67f4deaa6a4547..d8bac9e978421b 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -802,7 +802,7 @@ static int __init kyrofb_init(void)
return -ENODEV;
kyrofb_setup(option);
#endif
- return pci_module_init(&kyrofb_pci_driver);
+ return pci_register_driver(&kyrofb_pci_driver);
}
static void __exit kyrofb_exit(void)
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index 3cd1145a6c6625..de5a0f38360083 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/string.h>
+#include <linux/module.h>
#include "macmodes.h"
@@ -281,7 +282,7 @@ int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var)
var->vmode = mode->vmode;
return 0;
}
-
+EXPORT_SYMBOL(mac_vmode_to_var);
/**
* mac_var_to_vmode - convert var structure to MacOS vmode/cmode pair
@@ -326,7 +327,7 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
}
return -EINVAL;
}
-
+EXPORT_SYMBOL(mac_var_to_vmode);
/**
* mac_map_monitor_sense - Convert monitor sense to vmode
@@ -348,7 +349,7 @@ int mac_map_monitor_sense(int sense)
break;
return map->vmode;
}
-
+EXPORT_SYMBOL(mac_map_monitor_sense);
/**
* mac_find_mode - find a video mode
@@ -384,3 +385,5 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
return fb_find_mode(var, info, mode_option, db, dbsize,
&mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp);
}
+EXPORT_SYMBOL(mac_find_mode);
+
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c
index 8f14c9b300c286..c7f3e1321224d3 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/matrox/matroxfb_accel.c
@@ -438,13 +438,21 @@ static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx,
} else if (step == 1) {
/* Special case for 1..8bit widths */
while (height--) {
- mga_writel(mmio, 0, *chardata);
+#if defined(__BIG_ENDIAN)
+ fb_writel((*chardata) << 24, mmio.vaddr);
+#else
+ fb_writel(*chardata, mmio.vaddr);
+#endif
chardata++;
}
} else if (step == 2) {
/* Special case for 9..15bit widths */
while (height--) {
- mga_writel(mmio, 0, *(u_int16_t*)chardata);
+#if defined(__BIG_ENDIAN)
+ fb_writel((*(u_int16_t*)chardata) << 16, mmio.vaddr);
+#else
+ fb_writel(*(u_int16_t*)chardata, mmio.vaddr);
+#endif
chardata += 2;
}
} else {
@@ -454,7 +462,7 @@ static void matroxfb_1bpp_imageblit(WPMINFO u_int32_t fgx, u_int32_t bgx,
for (i = 0; i < step; i += 4) {
/* Hope that there are at least three readable bytes beyond the end of bitmap */
- mga_writel(mmio, 0, get_unaligned((u_int32_t*)(chardata + i)));
+ fb_writel(get_unaligned((u_int32_t*)(chardata + i)),mmio.vaddr);
}
chardata += step;
}
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index 942ec768abd970..85a0b255845279 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -170,14 +170,14 @@ static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) {
if ((unsigned long)src & 3) {
while (len >= 4) {
- writel(get_unaligned((u32 *)src), addr);
+ fb_writel(get_unaligned((u32 *)src), addr);
addr++;
len -= 4;
src += 4;
}
} else {
while (len >= 4) {
- writel(*(u32 *)src, addr);
+ fb_writel(*(u32 *)src, addr);
addr++;
len -= 4;
src += 4;
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 805f6831af0bc5..fbf659b6dab01e 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -404,8 +404,8 @@ static int my_atoi(const char *name)
*
*/
-int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
- const struct fb_videomode *mode, unsigned int bpp)
+static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
+ const struct fb_videomode *mode, unsigned int bpp)
{
int err = 0;
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 085b4704a46ef8..5d424a30270acd 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1691,7 +1691,27 @@ static int __devinit neo_map_mmio(struct fb_info *info,
DBG("neo_map_mmio");
- info->fix.mmio_start = pci_resource_start(dev, 1);
+ switch (info->fix.accel) {
+ case FB_ACCEL_NEOMAGIC_NM2070:
+ info->fix.mmio_start = pci_resource_start(dev, 0)+
+ 0x100000;
+ break;
+ case FB_ACCEL_NEOMAGIC_NM2090:
+ case FB_ACCEL_NEOMAGIC_NM2093:
+ info->fix.mmio_start = pci_resource_start(dev, 0)+
+ 0x200000;
+ break;
+ case FB_ACCEL_NEOMAGIC_NM2160:
+ case FB_ACCEL_NEOMAGIC_NM2097:
+ case FB_ACCEL_NEOMAGIC_NM2200:
+ case FB_ACCEL_NEOMAGIC_NM2230:
+ case FB_ACCEL_NEOMAGIC_NM2360:
+ case FB_ACCEL_NEOMAGIC_NM2380:
+ info->fix.mmio_start = pci_resource_start(dev, 1);
+ break;
+ default:
+ info->fix.mmio_start = pci_resource_start(dev, 0);
+ }
info->fix.mmio_len = MMIO_SIZE;
if (!request_mem_region
@@ -2010,6 +2030,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
par->internal_display = internal;
par->external_display = external;
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
switch (info->fix.accel) {
case FB_ACCEL_NEOMAGIC_NM2070:
@@ -2029,15 +2050,27 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
break;
case FB_ACCEL_NEOMAGIC_NM2200:
sprintf(info->fix.id, "MagicGraph 256AV");
+ info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
break;
case FB_ACCEL_NEOMAGIC_NM2230:
sprintf(info->fix.id, "MagicGraph 256AV+");
+ info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
break;
case FB_ACCEL_NEOMAGIC_NM2360:
sprintf(info->fix.id, "MagicGraph 256ZX");
+ info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
break;
case FB_ACCEL_NEOMAGIC_NM2380:
sprintf(info->fix.id, "MagicGraph 256XL+");
+ info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
break;
}
@@ -2049,9 +2082,6 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
info->fix.accel = id->driver_data;
info->fbops = &neofb_ops;
- info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
- FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA |
- FBINFO_HWACCEL_COPYAREA;
info->pseudo_palette = (void *) (par + 1);
return info;
}
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index 8050ff979f9d73..f377a29ec97a6c 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -1,12 +1,50 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
+|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
+|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+ \***************************************************************************/
+
/*
- * linux/drivers/video/nvidia/nv_accel.c - nVidia Hardware Acceleration
- *
- * Copyright 2004 Antonino Daplas <adaplas@pol.net>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
+ * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
+ * XFree86 'nv' driver, this source code is provided under MIT-style licensing
+ * where the source code is provided "as is" without warranty of any kind.
+ * The only usage restriction is for the copyright notices to be retained
+ * whenever code is used.
*
+ * Antonino Daplas <adaplas@pol.net> 2005-03-11
*/
#include <linux/fb.h>
@@ -321,10 +359,10 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
struct nvidia_par *par = info->par;
u32 fg, bg, mask = ~(~0 >> (32 - info->var.bits_per_pixel));
u32 dsize, width, *data = (u32 *) image->data, tmp;
- int i, j, k = 0;
+ int j, k = 0;
width = (image->width + 31) & ~31;
- dsize = width >> 5;
+ dsize = (width * image->height) >> 5;
if (info->var.bits_per_pixel == 8) {
fg = image->fg_color | mask;
@@ -344,8 +382,22 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
NVDmaNext(par, (image->height << 16) | width);
NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
- for (i = image->height; i--;) {
+ while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) {
+ NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0),
+ RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS);
+
+ for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) {
+ tmp = data[k++];
+ reverse_order(&tmp);
+ NVDmaNext(par, tmp);
+ }
+
+ dsize -= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS;
+ }
+
+ if (dsize) {
NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize);
+
for (j = dsize; j--;) {
tmp = data[k++];
reverse_order(&tmp);
diff --git a/drivers/video/nvidia/nv_dma.h b/drivers/video/nvidia/nv_dma.h
index 5cc42537d006f0..a7ed1c0acbbbd5 100644
--- a/drivers/video/nvidia/nv_dma.h
+++ b/drivers/video/nvidia/nv_dma.h
@@ -38,6 +38,16 @@
|* *|
\***************************************************************************/
+/*
+ * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
+ * XFree86 'nv' driver, this source code is provided under MIT-style licensing
+ * where the source code is provided "as is" without warranty of any kind.
+ * The only usage restriction is for the copyright notices to be retained
+ * whenever code is used.
+ *
+ * Antonino Daplas <adaplas@pol.net> 2005-03-11
+ */
+
#define SURFACE_FORMAT 0x00000300
#define SURFACE_FORMAT_DEPTH8 0x00000001
#define SURFACE_FORMAT_DEPTH15 0x00000002
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index ffecb23bca210a..b989358437b372 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -36,6 +36,17 @@
|* those rights set forth herein. *|
|* *|
\***************************************************************************/
+
+/*
+ * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
+ * XFree86 'nv' driver, this source code is provided under MIT-style licensing
+ * where the source code is provided "as is" without warranty of any kind.
+ * The only usage restriction is for the copyright notices to be retained
+ * whenever code is used.
+ *
+ * Antonino Daplas <adaplas@pol.net> 2005-03-11
+ */
+
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_hw.c,v 1.4 2003/11/03 05:11:25 tsi Exp $ */
#include <linux/pci.h>
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 9e49e9ee44190e..3757c1407c1901 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -146,7 +146,6 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
nvidia_setup_i2c_bus(&par->chan[2], "BUS3");
}
-#if 0
void nvidia_delete_i2c_busses(struct nvidia_par *par)
{
if (par->chan[0].par)
@@ -162,7 +161,6 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par)
par->chan[2].par = NULL;
}
-#endif /* 0 */
static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
{
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index 89a0ae89ea4473..9da320986f4c92 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -37,6 +37,16 @@
|* *|
\***************************************************************************/
+/*
+ * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
+ * XFree86 'nv' driver, this source code is provided under MIT-style licensing
+ * where the source code is provided "as is" without warranty of any kind.
+ * The only usage restriction is for the copyright notices to be retained
+ * whenever code is used.
+ *
+ * Antonino Daplas <adaplas@pol.net> 2005-03-11
+ */
+
#ifndef __NV_LOCAL_H__
#define __NV_LOCAL_H__
@@ -77,9 +87,8 @@
#endif
#define WRITE_PUT(par, data) { \
- volatile u8 scratch; \
_NV_FENCE() \
- scratch = NV_RD08((par)->FbStart, 0); \
+ NV_RD08((par)->FbStart, 0); \
NV_WR32(&(par)->FIFO[0x0010], 0, (data) << 2); \
mb(); \
}
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 660ac29d723e1a..7d12eb85310de0 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -28,6 +28,7 @@
#include "nv_proto.h"
void nvidia_create_i2c_busses(struct nvidia_par *par) {}
+void nvidia_delete_i2c_busses(struct nvidia_par *par) {}
int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn, u8 **out_edid)
{
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 0c5dd425eb5d86..42847ce1b8dd76 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -33,10 +33,12 @@ void NVLockUnlock(struct nvidia_par *par, int);
/* in nvidia-i2c.c */
#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
void nvidia_create_i2c_busses(struct nvidia_par *par);
+void nvidia_delete_i2c_busses(struct nvidia_par *par);
int nvidia_probe_i2c_connector(struct nvidia_par *par, int conn,
u8 ** out_edid);
#else
#define nvidia_create_i2c_busses(...)
+#define nvidia_delete_i2c_busses(...)
#define nvidia_probe_i2c_connector(p, c, edid) \
do { \
*(edid) = NULL; \
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index ed2566cbe8c726..0bbdca2e0f9118 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -37,6 +37,16 @@
|* *|
\***************************************************************************/
+/*
+ * GPL Licensing Note - According to Mark Vojkovich, author of the Xorg/
+ * XFree86 'nv' driver, this source code is provided under MIT-style licensing
+ * where the source code is provided "as is" without warranty of any kind.
+ * The only usage restriction is for the copyright notices to be retained
+ * whenever code is used.
+ *
+ * Antonino Daplas <adaplas@pol.net> 2005-03-11
+ */
+
#include <video/vga.h>
#include <linux/delay.h>
#include <linux/pci.h>
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 2dfecddc308e30..3a6555a8aaa252 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -402,25 +402,25 @@ static struct pci_device_id nvidiafb_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
/* command line data, set in nvidiafb_setup() */
-static int flatpanel __initdata = -1; /* Autodetect later */
-static int forceCRTC __initdata = -1;
-static int hwcur __initdata = 0;
-static int noaccel __initdata = 0;
-static int noscale __initdata = 0;
-static int paneltweak __initdata = 0;
+static int flatpanel __devinitdata = -1; /* Autodetect later */
+static int forceCRTC __devinitdata = -1;
+static int hwcur __devinitdata = 0;
+static int noaccel __devinitdata = 0;
+static int noscale __devinitdata = 0;
+static int paneltweak __devinitdata = 0;
#ifdef CONFIG_MTRR
-static int nomtrr __initdata = 0;
+static int nomtrr __devinitdata = 0;
#endif
-static char *mode_option __initdata = NULL;
+static char *mode_option __devinitdata = NULL;
-static struct fb_fix_screeninfo __initdata nvidiafb_fix = {
+static struct fb_fix_screeninfo __devinitdata nvidiafb_fix = {
.type = FB_TYPE_PACKED_PIXELS,
.xpanstep = 8,
.ypanstep = 1,
};
-static struct fb_var_screeninfo __initdata nvidiafb_default_var = {
+static struct fb_var_screeninfo __devinitdata nvidiafb_default_var = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
@@ -1191,6 +1191,7 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,
var->yres_virtual = var->yres;
var->xres_virtual = vramlen / var->yres_virtual;
var->xres_virtual /= var->bits_per_pixel / 8;
+ var->xres_virtual &= ~63;
pitch = (var->xres_virtual *
var->bits_per_pixel + 7) / 8;
memlen = pitch * var->yres;
@@ -1301,7 +1302,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
| FBINFO_HWACCEL_IMAGEBLIT
| FBINFO_HWACCEL_FILLRECT
| FBINFO_HWACCEL_COPYAREA
- | FBINFO_HWACCEL_YPAN | FBINFO_MISC_MODESWITCHLATE;
+ | FBINFO_HWACCEL_YPAN;
fb_videomode_to_modelist(info->monspecs.modedb,
info->monspecs.modedb_len, &info->modelist);
@@ -1352,8 +1353,6 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
if (!hwcur)
info->fbops->fb_cursor = soft_cursor;
info->var.accel_flags = (!noaccel);
- par->FpScale = (!noscale);
- par->paneltweak = paneltweak;
switch (par->Architecture) {
case NV_ARCH_04:
@@ -1485,6 +1484,8 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
printk(KERN_INFO PFX "flatpanel support enabled\n");
par->CRTCnumber = forceCRTC;
+ par->FpScale = (!noscale);
+ par->paneltweak = paneltweak;
/* enable IO and mem if not already done */
pci_read_config_word(pd, PCI_COMMAND, &cmd);
@@ -1565,8 +1566,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
err_out_iounmap_fb:
iounmap(info->screen_base);
- err_out_free_base1:
fb_destroy_modedb(info->monspecs.modedb);
+ nvidia_delete_i2c_busses(par);
+ err_out_free_base1:
iounmap(par->REGS);
err_out_free_base0:
pci_release_regions(pd);
@@ -1596,9 +1598,10 @@ static void __exit nvidiafb_remove(struct pci_dev *pd)
info->fix.smem_len);
#endif /* CONFIG_MTRR */
+ iounmap(info->screen_base);
fb_destroy_modedb(info->monspecs.modedb);
+ nvidia_delete_i2c_busses(par);
iounmap(par->REGS);
- iounmap(info->screen_base);
pci_release_regions(pd);
pci_disable_device(pd);
kfree(info->pixmap.addr);
@@ -1614,7 +1617,7 @@ static void __exit nvidiafb_remove(struct pci_dev *pd)
* ------------------------------------------------------------------------- */
#ifndef MODULE
-static int __init nvidiafb_setup(char *options)
+static int __devinit nvidiafb_setup(char *options)
{
char *this_opt;
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 496624c277c1b2..5dceddedf50752 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -747,7 +747,7 @@ static int pm2fb_set_par(struct fb_info *info)
}
if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
video |= PM2F_LINE_DOUBLE;
- if (info->var.activate==FB_ACTIVATE_NOW)
+ if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW)
video |= PM2F_VIDEO_ENABLE;
par->video = video;
@@ -1282,7 +1282,7 @@ static int __init pm2fb_init(void)
pm2fb_setup(option);
#endif
- return pci_module_init(&pm2fb_driver);
+ return pci_register_driver(&pm2fb_driver);
}
module_init(pm2fb_init);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 6741b522c0d365..31c547fd383bf7 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -967,7 +967,7 @@ static struct pci_driver pvr2fb_pci_driver = {
static int __init pvr2fb_pci_init(void)
{
- return pci_module_init(&pvr2fb_pci_driver);
+ return pci_register_driver(&pvr2fb_pci_driver);
}
static void pvr2fb_pci_exit(void)
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 552a38e5f143fb..483ad9bab53904 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1343,8 +1343,7 @@ int __init pxafb_probe(struct device *dev)
failed:
dev_set_drvdata(dev, NULL);
- if (fbi)
- kfree(fbi);
+ kfree(fbi);
return ret;
}
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index 3fad3f70b9d3d5..d9a084e77a6323 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -3150,7 +3150,7 @@ static int __init radeonfb_old_init (void)
return -ENODEV;
radeonfb_old_setup(option);
#endif
- return pci_module_init (&radeonfb_driver);
+ return pci_register_driver (&radeonfb_driver);
}
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 7a6e82567ff897..b0c886de04043c 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1708,8 +1708,7 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
| FBINFO_HWACCEL_YPAN
| FBINFO_HWACCEL_COPYAREA
| FBINFO_HWACCEL_FILLRECT
- | FBINFO_HWACCEL_IMAGEBLIT
- | FBINFO_MISC_MODESWITCHLATE;
+ | FBINFO_HWACCEL_IMAGEBLIT;
/* Accel seems to not work properly on NV30 yet...*/
if ((par->riva.Architecture == NV_ARCH_30) || noaccel) {
@@ -2109,8 +2108,7 @@ static void __exit rivafb_remove(struct pci_dev *pd)
#ifdef CONFIG_FB_RIVA_I2C
riva_delete_i2c_busses(par);
- if (par->EDID)
- kfree(par->EDID);
+ kfree(par->EDID);
#endif
unregister_framebuffer(info);
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
new file mode 100644
index 00000000000000..b637c389e4f480
--- /dev/null
+++ b/drivers/video/s1d13xxxfb.c
@@ -0,0 +1,772 @@
+/* drivers/video/s1d13xxxfb.c
+ *
+ * (c) 2004 Simtec Electronics
+ * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * Driver for Epson S1D13xxx series framebuffer chips
+ *
+ * Adapted from
+ * linux/drivers/video/skeletonfb.c
+ * linux/drivers/video/epson1355fb.c
+ * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson)
+ *
+ * Note, currently only tested on S1D13806 with 16bit CRT.
+ * As such, this driver might still contain some hardcoded bits relating to
+ * S1D13806.
+ * Making it work on other S1D13XXX chips should merely be a matter of adding
+ * a few switch()s, some missing glue here and there maybe, and split header
+ * files.
+ *
+ * TODO: - handle dual screen display (CRT and LCD at the same time).
+ * - check_var(), mode change, etc.
+ * - PM untested.
+ * - Accelerated interfaces.
+ * - Probably not SMP safe :)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/fb.h>
+
+#include <asm/io.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define PFX "s1d13xxxfb: "
+
+#if 0
+#define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0)
+#else
+#define dbg(fmt, args...) do { } while (0)
+#endif
+
+/*
+ * Here we define the default struct fb_fix_screeninfo
+ */
+static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = {
+ .id = S1D_FBID,
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 0,
+ .ypanstep = 1,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+};
+
+static inline u8
+s1d13xxxfb_readreg(struct s1d13xxxfb_par *par, u16 regno)
+{
+ return readb(par->regs + regno);
+}
+
+static inline void
+s1d13xxxfb_writereg(struct s1d13xxxfb_par *par, u16 regno, u8 value)
+{
+ writeb(value, par->regs + regno);
+}
+
+static inline void
+s1d13xxxfb_runinit(struct s1d13xxxfb_par *par,
+ const struct s1d13xxxfb_regval *initregs,
+ const unsigned int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if ((initregs[i].addr == S1DREG_DELAYOFF) ||
+ (initregs[i].addr == S1DREG_DELAYON))
+ mdelay((int)initregs[i].value);
+ else {
+ s1d13xxxfb_writereg(par, initregs[i].addr, initregs[i].value);
+ }
+ }
+
+ /* make sure the hardware can cope with us */
+ mdelay(1);
+}
+
+static inline void
+lcd_enable(struct s1d13xxxfb_par *par, int enable)
+{
+ u8 mode = s1d13xxxfb_readreg(par, S1DREG_COM_DISP_MODE);
+
+ if (enable)
+ mode |= 0x01;
+ else
+ mode &= ~0x01;
+
+ s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode);
+}
+
+static inline void
+crt_enable(struct s1d13xxxfb_par *par, int enable)
+{
+ u8 mode = s1d13xxxfb_readreg(par, S1DREG_COM_DISP_MODE);
+
+ if (enable)
+ mode |= 0x02;
+ else
+ mode &= ~0x02;
+
+ s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode);
+}
+
+/* framebuffer control routines */
+
+static inline void
+s1d13xxxfb_setup_pseudocolour(struct fb_info *info)
+{
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ info->var.red.length = 4;
+ info->var.green.length = 4;
+ info->var.blue.length = 4;
+}
+
+static inline void
+s1d13xxxfb_setup_truecolour(struct fb_info *info)
+{
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->var.bits_per_pixel = 16;
+
+ info->var.red.length = 5;
+ info->var.red.offset = 11;
+
+ info->var.green.length = 6;
+ info->var.green.offset = 5;
+
+ info->var.blue.length = 5;
+ info->var.blue.offset = 0;
+}
+
+/**
+ * s1d13xxxfb_set_par - Alters the hardware state.
+ * @info: frame buffer structure
+ *
+ * Using the fb_var_screeninfo in fb_info we set the depth of the
+ * framebuffer. This function alters the par AND the
+ * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in
+ * fb_info since we are using that data. This means we depend on the
+ * data in var inside fb_info to be supported by the hardware.
+ * xxxfb_check_var is always called before xxxfb_set_par to ensure this.
+ *
+ * XXX TODO: write proper s1d13xxxfb_check_var(), without which that
+ * function is quite useless.
+ */
+static int
+s1d13xxxfb_set_par(struct fb_info *info)
+{
+ struct s1d13xxxfb_par *s1dfb = info->par;
+ unsigned int val;
+
+ dbg("s1d13xxxfb_set_par: bpp=%d\n", info->var.bits_per_pixel);
+
+ if ((s1dfb->display & 0x01)) /* LCD */
+ val = s1d13xxxfb_readreg(s1dfb, S1DREG_LCD_DISP_MODE); /* read colour control */
+ else /* CRT */
+ val = s1d13xxxfb_readreg(s1dfb, S1DREG_CRT_DISP_MODE); /* read colour control */
+
+ val &= ~0x07;
+
+ switch (info->var.bits_per_pixel) {
+ case 4:
+ dbg("pseudo colour 4\n");
+ s1d13xxxfb_setup_pseudocolour(info);
+ val |= 2;
+ break;
+ case 8:
+ dbg("pseudo colour 8\n");
+ s1d13xxxfb_setup_pseudocolour(info);
+ val |= 3;
+ break;
+ case 16:
+ dbg("true colour\n");
+ s1d13xxxfb_setup_truecolour(info);
+ val |= 5;
+ break;
+
+ default:
+ dbg("bpp not supported!\n");
+ return -EINVAL;
+ }
+
+ dbg("writing %02x to display mode register\n", val);
+
+ if ((s1dfb->display & 0x01)) /* LCD */
+ s1d13xxxfb_writereg(s1dfb, S1DREG_LCD_DISP_MODE, val);
+ else /* CRT */
+ s1d13xxxfb_writereg(s1dfb, S1DREG_CRT_DISP_MODE, val);
+
+ info->fix.line_length = info->var.xres * info->var.bits_per_pixel;
+ info->fix.line_length /= 8;
+
+ dbg("setting line_length to %d\n", info->fix.line_length);
+
+ dbg("done setup\n");
+
+ return 0;
+}
+
+/**
+ * s1d13xxxfb_setcolreg - sets a color register.
+ * @regno: Which register in the CLUT we are programming
+ * @red: The red value which can be up to 16 bits wide
+ * @green: The green value which can be up to 16 bits wide
+ * @blue: The blue value which can be up to 16 bits wide.
+ * @transp: If supported the alpha value which can be up to 16 bits wide.
+ * @info: frame buffer info structure
+ *
+ * Returns negative errno on error, or zero on success.
+ */
+static int
+s1d13xxxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct s1d13xxxfb_par *s1dfb = info->par;
+ unsigned int pseudo_val;
+
+ if (regno >= S1D_PALETTE_SIZE)
+ return -EINVAL;
+
+ dbg("s1d13xxxfb_setcolreg: %d: rgb=%d,%d,%d, tr=%d\n",
+ regno, red, green, blue, transp);
+
+ if (info->var.grayscale)
+ red = green = blue = (19595*red + 38470*green + 7471*blue) >> 16;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ if (regno >= 16)
+ return -EINVAL;
+
+ /* deal with creating pseudo-palette entries */
+
+ pseudo_val = (red >> 11) << info->var.red.offset;
+ pseudo_val |= (green >> 10) << info->var.green.offset;
+ pseudo_val |= (blue >> 11) << info->var.blue.offset;
+
+ dbg("s1d13xxxfb_setcolreg: pseudo %d, val %08x\n",
+ regno, pseudo_val);
+
+ ((u32 *)info->pseudo_palette)[regno] = pseudo_val;
+
+ break;
+ case FB_VISUAL_PSEUDOCOLOR:
+ s1d13xxxfb_writereg(s1dfb, S1DREG_LKUP_ADDR, regno);
+ s1d13xxxfb_writereg(s1dfb, S1DREG_LKUP_DATA, red);
+ s1d13xxxfb_writereg(s1dfb, S1DREG_LKUP_DATA, green);
+ s1d13xxxfb_writereg(s1dfb, S1DREG_LKUP_DATA, blue);
+
+ break;
+ default:
+ return -ENOSYS;
+ }
+
+ dbg("s1d13xxxfb_setcolreg: done\n");
+
+ return 0;
+}
+
+/**
+ * s1d13xxxfb_blank - blanks the display.
+ * @blank_mode: the blank mode we want.
+ * @info: frame buffer structure that represents a single frame buffer
+ *
+ * Blank the screen if blank_mode != 0, else unblank. Return 0 if
+ * blanking succeeded, != 0 if un-/blanking failed due to e.g. a
+ * video mode which doesn't support it. Implements VESA suspend
+ * and powerdown modes on hardware that supports disabling hsync/vsync:
+ * blank_mode == 2: suspend vsync
+ * blank_mode == 3: suspend hsync
+ * blank_mode == 4: powerdown
+ *
+ * Returns negative errno on error, or zero on success.
+ */
+static int
+s1d13xxxfb_blank(int blank_mode, struct fb_info *info)
+{
+ struct s1d13xxxfb_par *par = info->par;
+
+ dbg("s1d13xxxfb_blank: blank=%d, info=%p\n", blank_mode, info);
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ case FB_BLANK_NORMAL:
+ if ((par->display & 0x01) != 0)
+ lcd_enable(par, 1);
+ if ((par->display & 0x02) != 0)
+ crt_enable(par, 1);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ break;
+ case FB_BLANK_POWERDOWN:
+ lcd_enable(par, 0);
+ crt_enable(par, 0);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* let fbcon do a soft blank for us */
+ return ((blank_mode == FB_BLANK_NORMAL) ? 1 : 0);
+}
+
+/**
+ * s1d13xxxfb_pan_display - Pans the display.
+ * @var: frame buffer variable screen structure
+ * @info: frame buffer structure that represents a single frame buffer
+ *
+ * Pan (or wrap, depending on the `vmode' field) the display using the
+ * `yoffset' field of the `var' structure (`xoffset' not yet supported).
+ * If the values don't fit, return -EINVAL.
+ *
+ * Returns negative errno on error, or zero on success.
+ */
+static int
+s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct s1d13xxxfb_par *par = info->par;
+ u32 start;
+
+ if (var->xoffset != 0) /* not yet ... */
+ return -EINVAL;
+
+ if (var->yoffset + info->var.yres > info->var.yres_virtual)
+ return -EINVAL;
+
+ start = (info->fix.line_length >> 1) * var->yoffset;
+
+ if ((par->display & 0x01)) {
+ /* LCD */
+ s1d13xxxfb_writereg(par, S1DREG_LCD_DISP_START0, (start & 0xff));
+ s1d13xxxfb_writereg(par, S1DREG_LCD_DISP_START1, ((start >> 8) & 0xff));
+ s1d13xxxfb_writereg(par, S1DREG_LCD_DISP_START2, ((start >> 16) & 0x0f));
+ } else {
+ /* CRT */
+ s1d13xxxfb_writereg(par, S1DREG_CRT_DISP_START0, (start & 0xff));
+ s1d13xxxfb_writereg(par, S1DREG_CRT_DISP_START1, ((start >> 8) & 0xff));
+ s1d13xxxfb_writereg(par, S1DREG_CRT_DISP_START2, ((start >> 16) & 0x0f));
+ }
+
+ return 0;
+}
+
+
+/* framebuffer information structures */
+
+static struct fb_ops s1d13xxxfb_fbops = {
+ .owner = THIS_MODULE,
+ .fb_set_par = s1d13xxxfb_set_par,
+ .fb_setcolreg = s1d13xxxfb_setcolreg,
+ .fb_blank = s1d13xxxfb_blank,
+
+ .fb_pan_display = s1d13xxxfb_pan_display,
+
+ /* to be replaced by any acceleration we can */
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor
+};
+
+static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
+ {4, 8, 16, -1},
+ {9, 12, 18, -1},
+};
+
+/**
+ * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to
+ * hardware setup.
+ * @info: frame buffer structure
+ *
+ * We setup the framebuffer structures according to the current
+ * hardware setup. On some machines, the BIOS will have filled
+ * the chip registers with such info, on others, these values will
+ * have been written in some init procedure. In any case, the
+ * software values needs to match the hardware ones. This is what
+ * this function ensures.
+ *
+ * Note: some of the hardcoded values here might need some love to
+ * work on various chips, and might need to no longer be hardcoded.
+ */
+static void __devinit
+s1d13xxxfb_fetch_hw_state(struct fb_info *info)
+{
+ struct fb_var_screeninfo *var = &info->var;
+ struct fb_fix_screeninfo *fix = &info->fix;
+ struct s1d13xxxfb_par *par = info->par;
+ u8 panel, display;
+ u16 offset;
+ u32 xres, yres;
+ u32 xres_virtual, yres_virtual;
+ int bpp, lcd_bpp;
+ int is_color, is_dual, is_tft;
+ int lcd_enabled, crt_enabled;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+
+ /* general info */
+ par->display = s1d13xxxfb_readreg(par, S1DREG_COM_DISP_MODE);
+ crt_enabled = (par->display & 0x02) != 0;
+ lcd_enabled = (par->display & 0x01) != 0;
+
+ if (lcd_enabled && crt_enabled)
+ printk(KERN_WARNING PFX "Warning: LCD and CRT detected, using LCD\n");
+
+ if (lcd_enabled)
+ display = s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_MODE);
+ else /* CRT */
+ display = s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_MODE);
+
+ bpp = display & 0x07;
+
+ switch (bpp) {
+ case 2: /* 4 bpp */
+ case 3: /* 8 bpp */
+ var->bits_per_pixel = 8;
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
+ case 5: /* 16 bpp */
+ s1d13xxxfb_setup_truecolour(info);
+ break;
+ default:
+ dbg("bpp: %i\n", bpp);
+ }
+ fb_alloc_cmap(&info->cmap, 256, 0);
+
+ /* LCD info */
+ panel = s1d13xxxfb_readreg(par, S1DREG_PANEL_TYPE);
+ is_color = (panel & 0x04) != 0;
+ is_dual = (panel & 0x02) != 0;
+ is_tft = (panel & 0x01) != 0;
+ lcd_bpp = s1d13xxxfb_width_tab[is_tft][(panel >> 4) & 3];
+
+ if (lcd_enabled) {
+ xres = (s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_HWIDTH) + 1) * 8;
+ yres = (s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_VHEIGHT0) +
+ ((s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_VHEIGHT1) & 0x03) << 8) + 1);
+
+ offset = (s1d13xxxfb_readreg(par, S1DREG_LCD_MEM_OFF0) +
+ ((s1d13xxxfb_readreg(par, S1DREG_LCD_MEM_OFF1) & 0x7) << 8));
+ } else { /* crt */
+ xres = (s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_HWIDTH) + 1) * 8;
+ yres = (s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_VHEIGHT0) +
+ ((s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_VHEIGHT1) & 0x03) << 8) + 1);
+
+ offset = (s1d13xxxfb_readreg(par, S1DREG_CRT_MEM_OFF0) +
+ ((s1d13xxxfb_readreg(par, S1DREG_CRT_MEM_OFF1) & 0x7) << 8));
+ }
+ xres_virtual = offset * 16 / var->bits_per_pixel;
+ yres_virtual = fix->smem_len / (offset * 2);
+
+ var->xres = xres;
+ var->yres = yres;
+ var->xres_virtual = xres_virtual;
+ var->yres_virtual = yres_virtual;
+ var->xoffset = var->yoffset = 0;
+
+ fix->line_length = offset * 2;
+
+ var->grayscale = !is_color;
+
+ var->activate = FB_ACTIVATE_NOW;
+
+ dbg(PFX "bpp=%d, lcd_bpp=%d, "
+ "crt_enabled=%d, lcd_enabled=%d\n",
+ var->bits_per_pixel, lcd_bpp, crt_enabled, lcd_enabled);
+ dbg(PFX "xres=%d, yres=%d, vxres=%d, vyres=%d "
+ "is_color=%d, is_dual=%d, is_tft=%d\n",
+ xres, yres, xres_virtual, yres_virtual, is_color, is_dual, is_tft);
+}
+
+
+static int __devexit
+s1d13xxxfb_remove(struct device *dev)
+{
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct s1d13xxxfb_par *par = NULL;
+
+ if (info) {
+ par = info->par;
+ if (par && par->regs) {
+ /* disable output & enable powersave */
+ s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, 0x00);
+ s1d13xxxfb_writereg(par, S1DREG_PS_CNF, 0x11);
+ iounmap(par->regs);
+ }
+
+ fb_dealloc_cmap(&info->cmap);
+
+ if (info->screen_base)
+ iounmap(info->screen_base);
+
+ framebuffer_release(info);
+ }
+
+ release_mem_region(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start +1);
+ release_mem_region(pdev->resource[1].start,
+ pdev->resource[1].end - pdev->resource[1].start +1);
+ return 0;
+}
+
+static int __devinit
+s1d13xxxfb_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct s1d13xxxfb_par *default_par;
+ struct fb_info *info;
+ struct s1d13xxxfb_pdata *pdata = NULL;
+ int ret = 0;
+ u8 revision;
+
+ dbg("probe called: device is %p\n", dev);
+
+ printk(KERN_INFO "Epson S1D13XXX FB Driver\n");
+
+ /* enable platform-dependent hardware glue, if any */
+ if (dev->platform_data)
+ pdata = dev->platform_data;
+
+ if (pdata && pdata->platform_init_video)
+ pdata->platform_init_video();
+
+
+ if (pdev->num_resources != 2) {
+ dev_err(&pdev->dev, "invalid num_resources: %i\n",
+ pdev->num_resources);
+ ret = -ENODEV;
+ goto bail;
+ }
+
+ /* resource[0] is VRAM, resource[1] is registers */
+ if (pdev->resource[0].flags != IORESOURCE_MEM
+ || pdev->resource[1].flags != IORESOURCE_MEM) {
+ dev_err(&pdev->dev, "invalid resource type\n");
+ ret = -ENODEV;
+ goto bail;
+ }
+
+ if (!request_mem_region(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start +1, "s1d13xxxfb mem")) {
+ dev_dbg(dev, "request_mem_region failed\n");
+ ret = -EBUSY;
+ goto bail;
+ }
+
+ if (!request_mem_region(pdev->resource[1].start,
+ pdev->resource[1].end - pdev->resource[1].start +1, "s1d13xxxfb regs")) {
+ dev_dbg(dev, "request_mem_region failed\n");
+ ret = -EBUSY;
+ goto bail;
+ }
+
+ info = framebuffer_alloc(sizeof(struct s1d13xxxfb_par) + sizeof(u32) * 256, &pdev->dev);
+ if (!info) {
+ ret = -ENOMEM;
+ goto bail;
+ }
+
+ default_par = info->par;
+ default_par->regs = ioremap_nocache(pdev->resource[1].start,
+ pdev->resource[1].end - pdev->resource[1].start +1);
+ if (!default_par->regs) {
+ printk(KERN_ERR PFX "unable to map registers\n");
+ ret = -ENOMEM;
+ goto bail;
+ }
+ info->pseudo_palette = default_par->pseudo_palette;
+
+ info->screen_base = ioremap_nocache(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start +1);
+
+ if (!info->screen_base) {
+ printk(KERN_ERR PFX "unable to map framebuffer\n");
+ ret = -ENOMEM;
+ goto bail;
+ }
+
+ revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE);
+ if ((revision >> 2) != S1D_CHIP_REV) {
+ printk(KERN_INFO PFX "chip not found: %i\n", (revision >> 2));
+ ret = -ENODEV;
+ goto bail;
+ }
+
+ info->fix = s1d13xxxfb_fix;
+ info->fix.mmio_start = pdev->resource[1].start;
+ info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start +1;
+ info->fix.smem_start = pdev->resource[0].start;
+ info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start +1;
+
+ printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n",
+ default_par->regs, info->fix.smem_len / 1024, info->screen_base);
+
+ info->par = default_par;
+ info->fbops = &s1d13xxxfb_fbops;
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+ /* perform "manual" chip initialization, if needed */
+ if (pdata && pdata->initregs)
+ s1d13xxxfb_runinit(info->par, pdata->initregs, pdata->initregssize);
+
+ s1d13xxxfb_fetch_hw_state(info);
+
+ if (register_framebuffer(info) < 0) {
+ ret = -EINVAL;
+ goto bail;
+ }
+
+ dev_set_drvdata(&pdev->dev, info);
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ info->node, info->fix.id);
+
+ return 0;
+
+bail:
+ s1d13xxxfb_remove(dev);
+ return ret;
+
+}
+
+#ifdef CONFIG_PM
+static int s1d13xxxfb_suspend(struct device *dev, u32 state, u32 level)
+{
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct s1d13xxxfb_par *s1dfb = info->par;
+ struct s1d13xxxfb_pdata *pdata = NULL;
+
+ /* disable display */
+ lcd_enable(s1dfb, 0);
+ crt_enable(s1dfb, 0);
+
+ if (dev->platform_data)
+ pdata = dev->platform_data;
+
+#if 0
+ if (!s1dfb->disp_save)
+ s1dfb->disp_save = kmalloc(info->fix.smem_len, GFP_KERNEL);
+
+ if (!s1dfb->disp_save) {
+ printk(KERN_ERR PFX "no memory to save screen");
+ return -ENOMEM;
+ }
+
+ memcpy_fromio(s1dfb->disp_save, info->screen_base, info->fix.smem_len);
+#else
+ s1dfb->disp_save = NULL;
+#endif
+
+ if (!s1dfb->regs_save)
+ s1dfb->regs_save = kmalloc(info->fix.mmio_len, GFP_KERNEL);
+
+ if (!s1dfb->regs_save) {
+ printk(KERN_ERR PFX "no memory to save registers");
+ return -ENOMEM;
+ }
+
+ /* backup all registers */
+ memcpy_fromio(s1dfb->regs_save, s1dfb->regs, info->fix.mmio_len);
+
+ /* now activate power save mode */
+ s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x11);
+
+ if (pdata && pdata->platform_suspend_video)
+ return pdata->platform_suspend_video();
+ else
+ return 0;
+}
+
+static int s1d13xxxfb_resume(struct device *dev, u32 level)
+{
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct s1d13xxxfb_par *s1dfb = info->par;
+ struct s1d13xxxfb_pdata *pdata = NULL;
+
+ if (level != RESUME_ENABLE)
+ return 0;
+
+ /* awaken the chip */
+ s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x10);
+
+ /* do not let go until SDRAM "wakes up" */
+ while ((s1d13xxxfb_readreg(s1dfb, S1DREG_PS_STATUS) & 0x01))
+ udelay(10);
+
+ if (dev->platform_data)
+ pdata = dev->platform_data;
+
+ if (s1dfb->regs_save) {
+ /* will write RO regs, *should* get away with it :) */
+ memcpy_toio(s1dfb->regs, s1dfb->regs_save, info->fix.mmio_len);
+ kfree(s1dfb->regs_save);
+ }
+
+ if (s1dfb->disp_save) {
+ memcpy_toio(info->screen_base, s1dfb->disp_save,
+ info->fix.smem_len);
+ kfree(s1dfb->disp_save); /* XXX kmalloc()'d when? */
+ }
+
+ if ((s1dfb->display & 0x01) != 0)
+ lcd_enable(s1dfb, 1);
+ if ((s1dfb->display & 0x02) != 0)
+ crt_enable(s1dfb, 1);
+
+ if (pdata && pdata->platform_resume_video)
+ return pdata->platform_resume_video();
+ else
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static struct device_driver s1d13xxxfb_driver = {
+ .name = S1D_DEVICENAME,
+ .bus = &platform_bus_type,
+ .probe = s1d13xxxfb_probe,
+ .remove = s1d13xxxfb_remove,
+#ifdef CONFIG_PM
+ .suspend = s1d13xxxfb_suspend,
+ .resume = s1d13xxxfb_resume
+#endif
+};
+
+
+static int __init
+s1d13xxxfb_init(void)
+{
+ if (fb_get_options("s1d13xxxfb", NULL))
+ return -ENODEV;
+
+ return driver_register(&s1d13xxxfb_driver);
+}
+
+
+static void __exit
+s1d13xxxfb_exit(void)
+{
+ driver_unregister(&s1d13xxxfb_driver);
+}
+
+module_init(s1d13xxxfb_init);
+module_exit(s1d13xxxfb_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Framebuffer driver for S1D13xxx devices");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, Thibaut VARENE <varenet@parisc-linux.org>");
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 33bedf94247ec3..4f8043a71f21d1 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1507,8 +1507,7 @@ static int __init sa1100fb_probe(struct device *dev)
failed:
dev_set_drvdata(dev, NULL);
- if (fbi)
- kfree(fbi);
+ kfree(fbi);
release_mem_region(0xb0100000, 0x10000);
return ret;
}
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 301cef041a4e02..e1c9c946be2dc2 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1883,8 +1883,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
info->fbops = &savagefb_ops;
info->flags = FBINFO_DEFAULT |
FBINFO_HWACCEL_YPAN |
- FBINFO_HWACCEL_XPAN |
- FBINFO_MISC_MODESWITCHLATE;
+ FBINFO_HWACCEL_XPAN;
info->pseudo_palette = par->pseudo_palette;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 96a0d60e12ab8a..b773c98f6513d1 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -5640,7 +5640,7 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
/* Unmap */
iounmap(ivideo->video_vbase);
iounmap(ivideo->mmio_vbase);
- if(ivideo->bios_abase) vfree(ivideo->bios_abase);
+ vfree(ivideo->bios_abase);
/* Release mem regions */
release_mem_region(ivideo->video_base, ivideo->video_size);
@@ -5695,7 +5695,7 @@ SISINITSTATIC int __init sisfb_init(void)
sisfb_setup(options);
#endif
#endif
- return(pci_module_init(&sisfb_driver));
+ return(pci_register_driver(&sisfb_driver));
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index aa455152235874..663d53657fa4cf 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1575,7 +1575,7 @@ static int __devinit sstfb_init(void)
return -ENODEV;
sstfb_setup(option);
#endif
- return pci_module_init(&sstfb_driver);
+ return pci_register_driver(&sstfb_driver);
}
#ifdef MODULE
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index ded8cc87dfc431..c34ba39b6f7e7c 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1350,7 +1350,7 @@ static int __init tdfxfb_init(void)
tdfxfb_setup(option);
#endif
- return pci_module_init(&tdfxfb_driver);
+ return pci_register_driver(&tdfxfb_driver);
}
static void __exit tdfxfb_exit(void)
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 075c66de9af0e5..3099630d0c3d0b 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -1540,7 +1540,7 @@ tgafb_init(void)
return -ENODEV;
tgafb_setup(option);
#endif
- return pci_module_init(&tgafb_driver);
+ return pci_register_driver(&tgafb_driver);
}
/*
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 2ad715a6cb2cab..da8004e5d03de6 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1163,7 +1163,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
fb_info.var = default_var;
fb_info.device = &dev->dev;
if (register_framebuffer(&fb_info) < 0) {
- output("Could not register Trident framebuffer\n");
+ printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
return -EINVAL;
}
output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
@@ -1264,7 +1264,7 @@ static int __init tridentfb_init(void)
tridentfb_setup(option);
#endif
output("Trident framebuffer %s initializing\n", VERSION);
- return pci_module_init(&tridentfb_pci_driver);
+ return pci_register_driver(&tridentfb_pci_driver);
}
static void __exit tridentfb_exit(void)
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 4e508df8212ebf..b46454c55c91b0 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -874,7 +874,7 @@ static int vga16fb_blank(int blank, struct fb_info *info)
return 0;
}
-void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+static void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
u32 dx = rect->dx, width = rect->width;
char oldindex = getindex();
@@ -928,7 +928,7 @@ void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
setindex(oldindex);
}
-void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+static void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
int x, x2, y2, vxres, vyres, width, height, line_ofs;
char __iomem *dst;
@@ -1003,7 +1003,7 @@ void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
}
}
-void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
char oldindex = getindex();
char oldmode = setmode(0x41);
@@ -1058,7 +1058,7 @@ void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area)
setindex(oldindex);
}
-void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
int x, x2, y2, old_dx, old_dy, vxres, vyres;
@@ -1166,7 +1166,7 @@ static unsigned int transl_l[] =
#endif
#endif
-void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
+static void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
{
char oldindex = getindex();
char oldmode = setmode(0x40);
@@ -1197,7 +1197,7 @@ void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
setindex(oldindex);
}
-void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image)
+static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image)
{
char __iomem *where = info->screen_base + (image->dx/8) +
image->dy * info->fix.line_length;
@@ -1261,7 +1261,7 @@ void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image)
}
}
-void vga_imageblit_color(struct fb_info *info, const struct fb_image *image)
+static void vga_imageblit_color(struct fb_info *info, const struct fb_image *image)
{
/*
* Draw logo
@@ -1306,7 +1306,7 @@ void vga_imageblit_color(struct fb_info *info, const struct fb_image *image)
}
}
-void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image)
{
if (image->depth == 1)
vga_imageblit_expand(info, image);
@@ -1329,7 +1329,8 @@ static struct fb_ops vga16fb_ops = {
.fb_cursor = soft_cursor,
};
-int vga16fb_setup(char *options)
+#ifndef MODULE
+static int vga16fb_setup(char *options)
{
char *this_opt;
@@ -1341,8 +1342,9 @@ int vga16fb_setup(char *options)
}
return 0;
}
+#endif
-int __init vga16fb_init(void)
+static int __init vga16fb_init(void)
{
int i;
int ret;
@@ -1427,9 +1429,7 @@ static void __exit vga16fb_exit(void)
/* XXX unshare VGA regions */
}
-#ifdef MODULE
MODULE_LICENSE("GPL");
-#endif
module_init(vga16fb_init);
module_exit(vga16fb_exit);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 8c4de816297208..057e154c8858d2 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -537,10 +537,8 @@ static void w100fb_clear_buffer(void)
{
int i;
for (i = 0; i < W100_BUF_NUM; i++) {
- if (gSaveImagePtr[i] != NULL) {
- kfree(gSaveImagePtr[i]);
- gSaveImagePtr[i] = NULL;
- }
+ kfree(gSaveImagePtr[i]);
+ gSaveImagePtr[i] = NULL;
}
}
diff --git a/fs/buffer.c b/fs/buffer.c
index f847c686dcaa47..f961605a904b1c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -878,7 +878,7 @@ int __set_page_dirty_buffers(struct page *page)
if (!TestSetPageDirty(page)) {
write_lock_irq(&mapping->tree_lock);
if (page->mapping) { /* Race with truncate? */
- if (!mapping->backing_dev_info->memory_backed)
+ if (mapping_cap_account_dirty(mapping))
inc_page_state(nr_dirty);
radix_tree_tag_set(&mapping->page_tree,
page_index(page),
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 6d0e70efd39905..d6efb36cab2a7d 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -315,7 +315,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
struct backing_dev_info *bdi = mapping->backing_dev_info;
long pages_skipped;
- if (bdi->memory_backed) {
+ if (!bdi_cap_writeback_dirty(bdi)) {
list_move(&inode->i_list, &sb->s_dirty);
if (sb == blockdev_superblock) {
/*
@@ -566,7 +566,7 @@ int write_inode_now(struct inode *inode, int sync)
.sync_mode = WB_SYNC_ALL,
};
- if (inode->i_mapping->backing_dev_info->memory_backed)
+ if (!mapping_cap_writeback_dirty(inode->i_mapping))
return 0;
might_sleep();
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index cfb9801f6ccffb..a88ad292485110 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -806,15 +806,21 @@ int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
char *name;
int r = 0, w = 0, x = 0, err;
- if(desired & MAY_READ) r = 1;
- if(desired & MAY_WRITE) w = 1;
- if(desired & MAY_EXEC) x = 1;
+ if (desired & MAY_READ) r = 1;
+ if (desired & MAY_WRITE) w = 1;
+ if (desired & MAY_EXEC) x = 1;
name = inode_name(ino, 0);
- if(name == NULL) return(-ENOMEM);
- err = access_file(name, r, w, x);
+ if (name == NULL) return(-ENOMEM);
+
+ if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
+ S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
+ err = 0;
+ else
+ err = access_file(name, r, w, x);
kfree(name);
- if(!err) err = generic_permission(ino, desired, NULL);
- return(err);
+ if(!err)
+ err = generic_permission(ino, desired, NULL);
+ return err;
}
int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 7a006cc6e1c242..2af3338f891bb1 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -40,7 +40,7 @@ static struct inode_operations hugetlbfs_inode_operations;
static struct backing_dev_info hugetlbfs_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 1, /* Does not contribute to dirty memory */
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
};
int sysctl_hugetlb_shm_group;
diff --git a/fs/inode.c b/fs/inode.c
index ff654a26833128..90025a39a789f5 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1098,15 +1098,16 @@ static inline void iput_final(struct inode *inode)
* @inode: inode to put
*
* Puts an inode, dropping its usage count. If the inode use count hits
- * zero the inode is also then freed and may be destroyed.
+ * zero, the inode is then freed and may also be destroyed.
+ *
+ * Consequently, iput() can sleep.
*/
void iput(struct inode *inode)
{
if (inode) {
struct super_operations *op = inode->i_sb->s_op;
- if (inode->i_state == I_CLEAR)
- BUG();
+ BUG_ON(inode->i_state == I_CLEAR);
if (op && op->put_inode)
op->put_inode(inode);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index cb094d03287cf1..73f96acd5d378b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1472,8 +1472,8 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
if (cache->cred)
put_rpccred(cache->cred);
cache->cred = get_rpccred(set->cred);
- NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS;
}
+ NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS;
cache->jiffies = set->jiffies;
cache->mask = set->mask;
}
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 172393942ac0c9..11ebf6c4aa54c5 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -49,12 +49,16 @@
/* mode bit translations: */
-#define NFS4_READ_MODE (NFS4_ACE_READ_DATA | NFS4_ACE_READ_NAMED_ATTRS)
-#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_WRITE_NAMED_ATTRS | NFS4_ACE_APPEND_DATA)
+#define NFS4_READ_MODE (NFS4_ACE_READ_DATA)
+#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE)
#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
+/* We don't support these bits; insist they be neither allowed nor denied */
+#define NFS4_MASK_UNSUPP (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
+ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
+
/* flags used to simulate posix default ACLs */
#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
| NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
@@ -83,12 +87,15 @@ mask_from_posix(unsigned short perm, unsigned int flags)
static u32
deny_mask(u32 allow_mask, unsigned int flags)
{
- u32 ret = ~allow_mask & ~NFS4_ACE_DELETE;
+ u32 ret = ~allow_mask & ~NFS4_MASK_UNSUPP;
if (!(flags & NFS4_ACL_DIR))
ret &= ~NFS4_ACE_DELETE_CHILD;
return ret;
}
+/* XXX: modify functions to return NFS errors; they're only ever
+ * used by nfs code, after all.... */
+
static int
mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
{
@@ -940,35 +947,8 @@ match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
}
}
-/* 0 = granted, -EACCES = denied; mask is an nfsv4 mask, not mode bits */
-int
-nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group,
- uid_t who, u32 mask)
-{
- struct nfs4_ace *ace;
- u32 allowed = 0;
-
- list_for_each_entry(ace, &acl->ace_head, l_ace) {
- if (!match_who(ace, group, owner, who))
- continue;
- switch (ace->type) {
- case NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE:
- allowed |= ace->access_mask;
- if ((allowed & mask) == mask)
- return 0;
- break;
- case NFS4_ACE_ACCESS_DENIED_ACE_TYPE:
- if (ace->access_mask & mask)
- return -EACCES;
- break;
- }
- }
- return -EACCES;
-}
-
EXPORT_SYMBOL(nfs4_acl_new);
EXPORT_SYMBOL(nfs4_acl_free);
EXPORT_SYMBOL(nfs4_acl_add_ace);
EXPORT_SYMBOL(nfs4_acl_get_whotype);
EXPORT_SYMBOL(nfs4_acl_write_who);
-EXPORT_SYMBOL(nfs4_acl_permission);
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 271c231e7ba440..c70de9c2af7465 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -541,7 +541,7 @@ out:
atomic_set(&clp->cl_callback.cb_set, 0);
/* Success or failure, now we're either waiting for lease expiration
* or deleg_return. */
- nfs4_put_delegation(dp);
dprintk("NFSD: nfs4_cb_recall: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count));
+ nfs4_put_delegation(dp);
return;
}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 6146c284da0f15..e8158741e8b5c0 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -197,30 +197,40 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
}
if (status)
goto out;
- if (open->op_claim_type == NFS4_OPEN_CLAIM_NULL) {
- /*
- * This block of code will (1) set CURRENT_FH to the file being opened,
- * creating it if necessary, (2) set open->op_cinfo,
- * (3) set open->op_truncate if the file is to be truncated
- * after opening, (4) do permission checking.
- */
- status = do_open_lookup(rqstp, current_fh, open);
- if (status)
+ switch (open->op_claim_type) {
+ case NFS4_OPEN_CLAIM_NULL:
+ /*
+ * (1) set CURRENT_FH to the file being opened,
+ * creating it if necessary, (2) set open->op_cinfo,
+ * (3) set open->op_truncate if the file is to be
+ * truncated after opening, (4) do permission checking.
+ */
+ status = do_open_lookup(rqstp, current_fh, open);
+ if (status)
+ goto out;
+ break;
+ case NFS4_OPEN_CLAIM_PREVIOUS:
+ /*
+ * The CURRENT_FH is already set to the file being
+ * opened. (1) set open->op_cinfo, (2) set
+ * open->op_truncate if the file is to be truncated
+ * after opening, (3) do permission checking.
+ */
+ status = do_open_fhandle(rqstp, current_fh, open);
+ if (status)
+ goto out;
+ break;
+ case NFS4_OPEN_CLAIM_DELEGATE_CUR:
+ case NFS4_OPEN_CLAIM_DELEGATE_PREV:
+ printk("NFSD: unsupported OPEN claim type %d\n",
+ open->op_claim_type);
+ status = nfserr_notsupp;
goto out;
- } else if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
- /*
- * The CURRENT_FH is already set to the file being opened. This
- * block of code will (1) set open->op_cinfo, (2) set
- * open->op_truncate if the file is to be truncated after opening,
- * (3) do permission checking.
- */
- status = do_open_fhandle(rqstp, current_fh, open);
- if (status)
+ default:
+ printk("NFSD: Invalid OPEN claim type %d\n",
+ open->op_claim_type);
+ status = nfserr_inval;
goto out;
- } else {
- printk("NFSD: unsupported OPEN claim type\n");
- status = nfserr_inval;
- goto out;
}
/*
* nfsd4_process_open2() does the actual opening of the file. If
@@ -573,8 +583,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
status = nfs_ok;
if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
nfs4_lock_state();
- if ((status = nfs4_preprocess_stateid_op(current_fh,
- &setattr->sa_stateid,
+ if ((status = nfs4_preprocess_stateid_op(current_fh,
+ &setattr->sa_stateid,
CHECK_FH | WR_STATE, NULL))) {
dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
goto out_unlock;
@@ -609,7 +619,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
return nfserr_inval;
nfs4_lock_state();
- if ((status = nfs4_preprocess_stateid_op(current_fh, stateid,
+ if ((status = nfs4_preprocess_stateid_op(current_fh, stateid,
CHECK_FH | WR_STATE, &filp))) {
dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
goto out;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 945328d7c3a2a8..579f7fea796811 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -176,15 +176,11 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
}
}
-/* release_delegation:
- *
- * Remove the associated file_lock first, then remove the delegation.
+/* Remove the associated file_lock first, then remove the delegation.
* lease_modify() is called to remove the FS_LEASE file_lock from
* the i_flock list, eventually calling nfsd's lock_manager
* fl_release_callback.
- *
*/
-
static void
nfs4_close_delegation(struct nfs4_delegation *dp)
{
@@ -201,7 +197,7 @@ nfs4_close_delegation(struct nfs4_delegation *dp)
/* Called under the state lock. */
static void
-release_delegation(struct nfs4_delegation *dp)
+unhash_delegation(struct nfs4_delegation *dp)
{
list_del_init(&dp->dl_del_perfile);
list_del_init(&dp->dl_del_perclnt);
@@ -345,7 +341,7 @@ expire_client(struct nfs4_client *clp)
while (!list_empty(&reaplist)) {
dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
list_del_init(&dp->dl_recall_lru);
- release_delegation(dp);
+ unhash_delegation(dp);
}
list_del(&clp->cl_idhash);
list_del(&clp->cl_strhash);
@@ -1123,7 +1119,8 @@ release_stateowner(struct nfs4_stateowner *sop)
}
static inline void
-init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) {
+init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *open) {
+ struct nfs4_stateowner *sop = open->op_stateowner;
unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
INIT_LIST_HEAD(&stp->st_hash);
@@ -1529,20 +1526,19 @@ out:
}
static int
-nfs4_check_open(struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open, struct nfs4_stateid **stpp)
+nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp)
{
struct nfs4_stateid *local;
int status = nfserr_share_denied;
+ struct nfs4_stateowner *sop = open->op_stateowner;
list_for_each_entry(local, &fp->fi_perfile, st_perfile) {
- /* have we seen this open owner */
- if (local->st_stateowner == sop) {
- *stpp = local;
- continue;
- }
/* ignore lock owners */
if (local->st_stateowner->so_is_open_owner == 0)
continue;
+ /* remember if we have seen this open owner */
+ if (local->st_stateowner == sop)
+ *stpp = local;
/* check for conflicting share reservations */
if (!test_share(local, open))
goto out;
@@ -1575,6 +1571,21 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
return 0;
}
+static inline int
+nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
+ struct nfsd4_open *open)
+{
+ struct iattr iattr = {
+ .ia_valid = ATTR_SIZE,
+ .ia_size = 0,
+ };
+ if (!open->op_truncate)
+ return 0;
+ if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
+ return -EINVAL;
+ return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
+}
+
static int
nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
{
@@ -1587,29 +1598,22 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta
share_access = ~share_access;
share_access &= open->op_share_access;
- /* update the struct file */
- if (share_access & NFS4_SHARE_ACCESS_WRITE) {
- status = get_write_access(inode);
- if (status)
- return nfserrno(status);
- if (open->op_truncate) {
- struct iattr iattr = {
- .ia_valid = ATTR_SIZE,
- .ia_size = 0,
- };
- status = nfsd_setattr(rqstp, cur_fh, &iattr, 0,
- (time_t)0);
- if (status) {
- put_write_access(inode);
- return status;
- }
- }
+ if (!(share_access & NFS4_SHARE_ACCESS_WRITE))
+ return nfsd4_truncate(rqstp, cur_fh, open);
- /* remember the open */
- filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
- set_bit(open->op_share_access, &stp->st_access_bmap);
- set_bit(open->op_share_deny, &stp->st_deny_bmap);
+ status = get_write_access(inode);
+ if (status)
+ return nfserrno(status);
+ status = nfsd4_truncate(rqstp, cur_fh, open);
+ if (status) {
+ put_write_access(inode);
+ return status;
}
+ /* remember the open */
+ filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ;
+ set_bit(open->op_share_access, &stp->st_access_bmap);
+ set_bit(open->op_share_deny, &stp->st_deny_bmap);
+
return nfs_ok;
}
@@ -1694,7 +1698,6 @@ out:
int
nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
{
- struct nfs4_stateowner *sop = open->op_stateowner;
struct nfs4_file *fp = NULL;
struct inode *ino = current_fh->fh_dentry->d_inode;
struct nfs4_stateid *stp = NULL;
@@ -1710,7 +1713,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
*/
fp = find_file(ino);
if (fp) {
- if ((status = nfs4_check_open(fp, sop, open, &stp)))
+ if ((status = nfs4_check_open(fp, open, &stp)))
goto out;
} else {
status = nfserr_resource;
@@ -1737,18 +1740,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
flags = MAY_READ;
if ((status = nfs4_new_open(rqstp, &stp, current_fh, flags)))
goto out;
- init_stateid(stp, fp, sop, open);
- if (open->op_truncate) {
- struct iattr iattr = {
- .ia_valid = ATTR_SIZE,
- .ia_size = 0,
- };
- status = nfsd_setattr(rqstp, current_fh, &iattr, 0,
- (time_t)0);
- if (status) {
- release_stateid(stp, OPEN_STATE);
- goto out;
- }
+ init_stateid(stp, fp, open);
+ status = nfsd4_truncate(rqstp, current_fh, open);
+ if (status) {
+ release_stateid(stp, OPEN_STATE);
+ goto out;
}
}
memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
@@ -1859,7 +1855,7 @@ nfs4_laundromat(void)
list_for_each_safe(pos, next, &reaplist) {
dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
list_del_init(&dp->dl_recall_lru);
- release_delegation(dp);
+ unhash_delegation(dp);
}
test_val = NFSD_LEASE_TIME;
list_for_each_safe(pos, next, &close_lru) {
@@ -1929,7 +1925,8 @@ static inline int
access_permit_read(unsigned long access_bmap)
{
return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) ||
- test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap);
+ test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) ||
+ test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap);
}
static inline int
@@ -2063,7 +2060,7 @@ nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int fl
goto out;
renew_client(dp->dl_client);
if (flags & DELEG_RET)
- release_delegation(dp);
+ unhash_delegation(dp);
if (filpp)
*filpp = dp->dl_vfs_file;
}
@@ -3238,7 +3235,7 @@ __nfs4_state_shutdown(void)
list_for_each_safe(pos, next, &reaplist) {
dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
list_del_init(&dp->dl_recall_lru);
- release_delegation(dp);
+ unhash_delegation(dp);
}
release_all_files();
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index f5e1833094dbce..36a058a112d57e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1331,7 +1331,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
if (bmval0 & FATTR4_WORD0_ACL) {
if (status == -EOPNOTSUPP)
bmval0 &= ~FATTR4_WORD0_ACL;
- else if (status != 0)
+ else if (status == -EINVAL) {
+ status = nfserr_attrnotsupp;
+ goto out;
+ } else if (status != 0)
goto out_nfserr;
}
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0fc725c3bd45c0..e3e9d217236e46 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -393,7 +393,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
}
out:
kfree(buf);
- return (error);
+ return error;
}
int
@@ -417,7 +417,10 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
flags = NFS4_ACL_DIR;
error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
- if (error < 0)
+ if (error == -EINVAL) {
+ error = nfserr_attrnotsupp;
+ goto out;
+ } else if (error < 0)
goto out_nfserr;
if (pacl) {
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 97a7a8f30eb4e8..0a88917605aee6 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -45,7 +45,9 @@ static struct inode_operations ramfs_dir_inode_operations;
static struct backing_dev_info ramfs_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 1, /* Does not contribute to dirty memory */
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK |
+ BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
+ BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
};
struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 97dc6db0870ca8..aff7b2dfa8eed3 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -23,7 +23,7 @@ static struct address_space_operations sysfs_aops = {
static struct backing_dev_info sysfs_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 1, /* Does not contribute to dirty memory */
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
};
struct inode * sysfs_new_inode(mode_t mode)
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index dc96af6e9caab8..2885972b0855ca 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -151,6 +151,7 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
#define atomic_inc_return(v) (atomic_add_return(1, v))
#define atomic_dec_return(v) (atomic_sub_return(1, v))
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
diff --git a/include/asm-arm/ipc.h b/include/asm-arm/ipc.h
index 2bbbf6335d9c3a..a46e3d9c2a3fc1 100644
--- a/include/asm-arm/ipc.h
+++ b/include/asm-arm/ipc.h
@@ -1,29 +1 @@
-#ifndef __ASMARM_IPC_H
-#define __ASMARM_IPC_H
-
-/*
- * These are used to wrap system calls on ARM.
- *
- * See arch/arm/kernel/sys-arm.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-arm26/ipc.h b/include/asm-arm26/ipc.h
index c330504ba3f4c1..a46e3d9c2a3fc1 100644
--- a/include/asm-arm26/ipc.h
+++ b/include/asm-arm26/ipc.h
@@ -1,28 +1 @@
-#ifndef __ASMARM_IPC_H
-#define __ASMARM_IPC_H
-
-/*
- * These are used to wrap system calls on ARM.
- *
- * See arch/arm/kernel/sys-arm.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-cris/ipc.h b/include/asm-cris/ipc.h
index f086af6fa03ff2..a46e3d9c2a3fc1 100644
--- a/include/asm-cris/ipc.h
+++ b/include/asm-cris/ipc.h
@@ -1,35 +1 @@
-#ifndef __CRIS_IPC_H__
-#define __CRIS_IPC_H__
-
-/*
- * These are used to wrap system calls on CRIS.
- *
- * See arch/cris/kernel/sys_cris.c for ugly details..
- *
- * Same as x86 version.
- *
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-frv/ipc.h b/include/asm-frv/ipc.h
index 2f72065c633773..a46e3d9c2a3fc1 100644
--- a/include/asm-frv/ipc.h
+++ b/include/asm-frv/ipc.h
@@ -1,33 +1 @@
-#ifndef __ASM_IPC_H__
-#define __ASM_IPC_H__
-
-/*
- * These are used to wrap system calls on FR-V
- *
- * See arch/frv/kernel/sys_frv.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
-
+#include <asm-generic/ipc.h>
diff --git a/include/asm-generic/ipc.h b/include/asm-generic/ipc.h
new file mode 100644
index 00000000000000..a40407a165cec6
--- /dev/null
+++ b/include/asm-generic/ipc.h
@@ -0,0 +1,31 @@
+#ifndef _ASM_GENERIC_IPC_H
+#define _ASM_GENERIC_IPC_H
+/*
+ * These are used to wrap system calls.
+ *
+ * See architecture code for ugly details..
+ */
+struct ipc_kludge {
+ struct msgbuf __user *msgp;
+ long msgtyp;
+};
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define SEMTIMEDOP 4
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC 25
+
+#define IPCCALL(version,op) ((version)<<16 | (op))
+
+#endif /* _ASM_GENERIC_IPC_H */
diff --git a/include/asm-h8300/ipc.h b/include/asm-h8300/ipc.h
index 6219d8a90e552f..a46e3d9c2a3fc1 100644
--- a/include/asm-h8300/ipc.h
+++ b/include/asm-h8300/ipc.h
@@ -1,31 +1 @@
-#ifndef __H8300_IPC_H__
-#define __H8300_IPC_H__
-
-/*
- * These are used to wrap system calls on H8/300.
- *
- * See arch/h8300/kernel/sys_h8300.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h
index fb8cdcf41d4b5b..11e67811a9901b 100644
--- a/include/asm-i386/desc.h
+++ b/include/asm-i386/desc.h
@@ -4,6 +4,8 @@
#include <asm/ldt.h>
#include <asm/segment.h>
+#define CPU_16BIT_STACK_SIZE 1024
+
#ifndef __ASSEMBLY__
#include <linux/preempt.h>
@@ -15,6 +17,8 @@
extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
+DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
+
struct Xgt_desc_struct {
unsigned short size;
unsigned long address __attribute__((packed));
diff --git a/include/asm-i386/ipc.h b/include/asm-i386/ipc.h
index 810a449f8a7e9c..a46e3d9c2a3fc1 100644
--- a/include/asm-i386/ipc.h
+++ b/include/asm-i386/ipc.h
@@ -1,32 +1 @@
-#ifndef __i386_IPC_H__
-#define __i386_IPC_H__
-
-/*
- * These are used to wrap system calls on x86.
- *
- * See arch/i386/kernel/sys_i386.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 8b28beda0e707c..be258b0e5a5fb6 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -146,6 +146,18 @@ static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
: "0" (op), "c"(0));
}
+/* Some CPUID calls want 'count' to be placed in ecx */
+static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
+ int *edx)
+{
+ __asm__("cpuid"
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (op), "c" (count));
+}
+
/*
* CPUID functions returning a single datum
*/
diff --git a/include/asm-i386/seccomp.h b/include/asm-i386/seccomp.h
new file mode 100644
index 00000000000000..18da19e89bff29
--- /dev/null
+++ b/include/asm-i386/seccomp.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h>
+
+#ifdef TIF_32BIT
+#error "unexpected TIF_32BIT on i386"
+#endif
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h
index abe3440a93cebc..bb5ff5b2c02ec2 100644
--- a/include/asm-i386/segment.h
+++ b/include/asm-i386/segment.h
@@ -38,7 +38,7 @@
* 24 - APM BIOS support
* 25 - APM BIOS support
*
- * 26 - unused
+ * 26 - ESPFIX small SS
* 27 - unused
* 28 - unused
* 29 - unused
@@ -71,6 +71,9 @@
#define GDT_ENTRY_PNPBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 6)
#define GDT_ENTRY_APMBIOS_BASE (GDT_ENTRY_KERNEL_BASE + 11)
+#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
+#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
+
#define GDT_ENTRY_DOUBLEFAULT_TSS 31
/*
diff --git a/include/asm-m32r/ipc.h b/include/asm-m32r/ipc.h
index 03aac6644b5873..a46e3d9c2a3fc1 100644
--- a/include/asm-m32r/ipc.h
+++ b/include/asm-m32r/ipc.h
@@ -1,35 +1 @@
-#ifndef __M32R_IPC_H__
-#define __M32R_IPC_H__
-
-/* orig : i386/ipc.h 2.6.0-test3 */
-
-/*
- * These are used to wrap system calls on x86.
- *
- * See arch/i386/kernel/sys_i386.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* __M32R_IPC_H__ */
-
+#include <asm-generic/ipc.h>
diff --git a/include/asm-m32r/spinlock.h b/include/asm-m32r/spinlock.h
index ecf80b74d2c112..6608d8371c5084 100644
--- a/include/asm-m32r/spinlock.h
+++ b/include/asm-m32r/spinlock.h
@@ -102,10 +102,8 @@ static inline void _raw_spin_lock(spinlock_t *lock)
unsigned long tmp0, tmp1;
#ifdef CONFIG_DEBUG_SPINLOCK
- __label__ here;
-here:
- if (lock->magic != SPINLOCK_MAGIC) {
- printk("pc: %p\n", &&here);
+ if (unlikely(lock->magic != SPINLOCK_MAGIC)) {
+ printk("pc: %p\n", __builtin_return_address(0));
BUG();
}
#endif
diff --git a/include/asm-m68k/ipc.h b/include/asm-m68k/ipc.h
index 19e9cbe3f26613..a46e3d9c2a3fc1 100644
--- a/include/asm-m68k/ipc.h
+++ b/include/asm-m68k/ipc.h
@@ -1,31 +1 @@
-#ifndef __m68k_IPC_H__
-#define __m68k_IPC_H__
-
-/*
- * These are used to wrap system calls on m68k.
- *
- * See arch/m68k/kernel/sys_m68k.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-m68knommu/ipc.h b/include/asm-m68knommu/ipc.h
index d66c4b21940067..a46e3d9c2a3fc1 100644
--- a/include/asm-m68knommu/ipc.h
+++ b/include/asm-m68knommu/ipc.h
@@ -1 +1 @@
-#include <asm-m68k/ipc.h>
+#include <asm-generic/ipc.h>
diff --git a/include/asm-mips/ipc.h b/include/asm-mips/ipc.h
index 377bbd5ef62fc4..a46e3d9c2a3fc1 100644
--- a/include/asm-mips/ipc.h
+++ b/include/asm-mips/ipc.h
@@ -1,33 +1 @@
-#ifndef _ASM_IPC_H
-#define _ASM_IPC_H
-
-/*
- * These are used to wrap system calls on MIPS.
- *
- * See arch/mips/kernel/sysmips.c for ugly details..
- * FIXME: split up into ordinary syscalls ...
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* _ASM_IPC_H */
+#include <asm-generic/ipc.h>
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index 7dbda12a876d74..42fd1068cf2a41 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -86,7 +86,7 @@
*/
#define CPM_DATAONLY_BASE ((uint)128)
#define CPM_DP_NOSPACE ((uint)0x7fffffff)
-#ifdef CONFIG_8272
+#if defined(CONFIG_8272) || defined(CONFIG_MPC8555)
#define CPM_DATAONLY_SIZE ((uint)(8 * 1024) - CPM_DATAONLY_BASE)
#define CPM_FCC_SPECIAL_BASE ((uint)0x00009000)
#else
diff --git a/include/asm-ppc/ipc.h b/include/asm-ppc/ipc.h
index 512dfe962d8bb8..a46e3d9c2a3fc1 100644
--- a/include/asm-ppc/ipc.h
+++ b/include/asm-ppc/ipc.h
@@ -1,29 +1 @@
-#ifndef __PPC_IPC_H__
-#define __PPC_IPC_H__
-
-/*
- * These are used to wrap system calls on PowerPC.
- *
- * See arch/ppc/kernel/syscalls.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* __PPC_IPC_H__ */
+#include <asm-generic/ipc.h>
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
index 8e77baad0c4a4d..06b86be61ed13e 100644
--- a/include/asm-ppc/irq.h
+++ b/include/asm-ppc/irq.h
@@ -171,7 +171,7 @@ static __inline__ int irq_canonicalize(int irq)
#define NR_IRQS (NR_IPIC_INTS)
-#elif defined(CONFIG_CPM2) && defined(CONFIG_85xx)
+#elif defined(CONFIG_85xx)
/* Now include the board configuration specific associations.
*/
#include <asm/mpc85xx.h>
@@ -186,7 +186,7 @@ static __inline__ int irq_canonicalize(int irq)
#define NR_CPM_INTS 64
#define NR_EPIC_INTS 44
#ifndef NR_8259_INTS
-#define NR_8259_INTS 0
+#define NR_8259_INTS 0
#endif
#define NUM_8259_INTERRUPTS NR_8259_INTS
@@ -196,13 +196,59 @@ static __inline__ int irq_canonicalize(int irq)
#define NR_IRQS (NR_EPIC_INTS + NR_CPM_INTS + NR_8259_INTS)
-/* These values must be zero-based and map 1:1 with the EPIC configuration.
- * They are used throughout the 8560 I/O subsystem to generate
- * interrupt masks, flags, and other control patterns. This is why the
- * current kernel assumption of the 8259 as the base controller is such
- * a pain in the butt.
- */
+/* Internal IRQs on MPC85xx OpenPIC */
+
+#ifndef MPC85xx_OPENPIC_IRQ_OFFSET
+#ifdef CONFIG_CPM2
+#define MPC85xx_OPENPIC_IRQ_OFFSET (CPM_IRQ_OFFSET + NR_CPM_INTS)
+#else
+#define MPC85xx_OPENPIC_IRQ_OFFSET 0
+#endif
+#endif
+/* Not all of these exist on all MPC85xx implementations */
+#define MPC85xx_IRQ_L2CACHE ( 0 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_ECM ( 1 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DDR ( 2 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_LBIU ( 3 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA0 ( 4 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA1 ( 5 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA2 ( 6 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DMA3 ( 7 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_PCI1 ( 8 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_PCI2 ( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_ERROR ( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_BELL (10 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_TX (11 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_RIO_RX (12 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC1_TX (13 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC1_RX (14 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC1_ERROR (18 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC2_TX (19 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC2_RX (20 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC2_ERROR (24 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_FEC (25 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_DUART (26 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_IIC1 (27 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_PERFMON (28 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_SEC2 (29 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_CPM (30 + MPC85xx_OPENPIC_IRQ_OFFSET)
+
+/* The 12 external interrupt lines */
+#define MPC85xx_IRQ_EXT0 (32 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT1 (33 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT2 (34 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT3 (35 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT4 (36 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT5 (37 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT6 (38 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT7 (39 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT8 (40 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT9 (41 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT10 (42 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT11 (43 + MPC85xx_OPENPIC_IRQ_OFFSET)
+
+/* CPM related interrupts */
#define SIU_INT_ERROR ((uint)0x00+CPM_IRQ_OFFSET)
#define SIU_INT_I2C ((uint)0x01+CPM_IRQ_OFFSET)
#define SIU_INT_SPI ((uint)0x02+CPM_IRQ_OFFSET)
@@ -267,57 +313,62 @@ static __inline__ int irq_canonicalize(int irq)
* (Document errata updates have fixed this...make sure you have up to
* date processor documentation -- Dan).
*/
-#define NR_SIU_INTS 64
-
-#define SIU_INT_ERROR ((uint)0x00)
-#define SIU_INT_I2C ((uint)0x01)
-#define SIU_INT_SPI ((uint)0x02)
-#define SIU_INT_RISC ((uint)0x03)
-#define SIU_INT_SMC1 ((uint)0x04)
-#define SIU_INT_SMC2 ((uint)0x05)
-#define SIU_INT_IDMA1 ((uint)0x06)
-#define SIU_INT_IDMA2 ((uint)0x07)
-#define SIU_INT_IDMA3 ((uint)0x08)
-#define SIU_INT_IDMA4 ((uint)0x09)
-#define SIU_INT_SDMA ((uint)0x0a)
-#define SIU_INT_TIMER1 ((uint)0x0c)
-#define SIU_INT_TIMER2 ((uint)0x0d)
-#define SIU_INT_TIMER3 ((uint)0x0e)
-#define SIU_INT_TIMER4 ((uint)0x0f)
-#define SIU_INT_TMCNT ((uint)0x10)
-#define SIU_INT_PIT ((uint)0x11)
-#define SIU_INT_IRQ1 ((uint)0x13)
-#define SIU_INT_IRQ2 ((uint)0x14)
-#define SIU_INT_IRQ3 ((uint)0x15)
-#define SIU_INT_IRQ4 ((uint)0x16)
-#define SIU_INT_IRQ5 ((uint)0x17)
-#define SIU_INT_IRQ6 ((uint)0x18)
-#define SIU_INT_IRQ7 ((uint)0x19)
-#define SIU_INT_FCC1 ((uint)0x20)
-#define SIU_INT_FCC2 ((uint)0x21)
-#define SIU_INT_FCC3 ((uint)0x22)
-#define SIU_INT_MCC1 ((uint)0x24)
-#define SIU_INT_MCC2 ((uint)0x25)
-#define SIU_INT_SCC1 ((uint)0x28)
-#define SIU_INT_SCC2 ((uint)0x29)
-#define SIU_INT_SCC3 ((uint)0x2a)
-#define SIU_INT_SCC4 ((uint)0x2b)
-#define SIU_INT_PC15 ((uint)0x30)
-#define SIU_INT_PC14 ((uint)0x31)
-#define SIU_INT_PC13 ((uint)0x32)
-#define SIU_INT_PC12 ((uint)0x33)
-#define SIU_INT_PC11 ((uint)0x34)
-#define SIU_INT_PC10 ((uint)0x35)
-#define SIU_INT_PC9 ((uint)0x36)
-#define SIU_INT_PC8 ((uint)0x37)
-#define SIU_INT_PC7 ((uint)0x38)
-#define SIU_INT_PC6 ((uint)0x39)
-#define SIU_INT_PC5 ((uint)0x3a)
-#define SIU_INT_PC4 ((uint)0x3b)
-#define SIU_INT_PC3 ((uint)0x3c)
-#define SIU_INT_PC2 ((uint)0x3d)
-#define SIU_INT_PC1 ((uint)0x3e)
-#define SIU_INT_PC0 ((uint)0x3f)
+
+#ifndef CPM_IRQ_OFFSET
+#define CPM_IRQ_OFFSET 0
+#endif
+
+#define NR_CPM_INTS 64
+
+#define SIU_INT_ERROR ((uint)0x00 + CPM_IRQ_OFFSET)
+#define SIU_INT_I2C ((uint)0x01 + CPM_IRQ_OFFSET)
+#define SIU_INT_SPI ((uint)0x02 + CPM_IRQ_OFFSET)
+#define SIU_INT_RISC ((uint)0x03 + CPM_IRQ_OFFSET)
+#define SIU_INT_SMC1 ((uint)0x04 + CPM_IRQ_OFFSET)
+#define SIU_INT_SMC2 ((uint)0x05 + CPM_IRQ_OFFSET)
+#define SIU_INT_IDMA1 ((uint)0x06 + CPM_IRQ_OFFSET)
+#define SIU_INT_IDMA2 ((uint)0x07 + CPM_IRQ_OFFSET)
+#define SIU_INT_IDMA3 ((uint)0x08 + CPM_IRQ_OFFSET)
+#define SIU_INT_IDMA4 ((uint)0x09 + CPM_IRQ_OFFSET)
+#define SIU_INT_SDMA ((uint)0x0a + CPM_IRQ_OFFSET)
+#define SIU_INT_TIMER1 ((uint)0x0c + CPM_IRQ_OFFSET)
+#define SIU_INT_TIMER2 ((uint)0x0d + CPM_IRQ_OFFSET)
+#define SIU_INT_TIMER3 ((uint)0x0e + CPM_IRQ_OFFSET)
+#define SIU_INT_TIMER4 ((uint)0x0f + CPM_IRQ_OFFSET)
+#define SIU_INT_TMCNT ((uint)0x10 + CPM_IRQ_OFFSET)
+#define SIU_INT_PIT ((uint)0x11 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ2 ((uint)0x14 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ3 ((uint)0x15 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ4 ((uint)0x16 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ5 ((uint)0x17 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ6 ((uint)0x18 + CPM_IRQ_OFFSET)
+#define SIU_INT_IRQ7 ((uint)0x19 + CPM_IRQ_OFFSET)
+#define SIU_INT_FCC1 ((uint)0x20 + CPM_IRQ_OFFSET)
+#define SIU_INT_FCC2 ((uint)0x21 + CPM_IRQ_OFFSET)
+#define SIU_INT_FCC3 ((uint)0x22 + CPM_IRQ_OFFSET)
+#define SIU_INT_MCC1 ((uint)0x24 + CPM_IRQ_OFFSET)
+#define SIU_INT_MCC2 ((uint)0x25 + CPM_IRQ_OFFSET)
+#define SIU_INT_SCC1 ((uint)0x28 + CPM_IRQ_OFFSET)
+#define SIU_INT_SCC2 ((uint)0x29 + CPM_IRQ_OFFSET)
+#define SIU_INT_SCC3 ((uint)0x2a + CPM_IRQ_OFFSET)
+#define SIU_INT_SCC4 ((uint)0x2b + CPM_IRQ_OFFSET)
+#define SIU_INT_PC15 ((uint)0x30 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC14 ((uint)0x31 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC13 ((uint)0x32 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC12 ((uint)0x33 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC11 ((uint)0x34 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC10 ((uint)0x35 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC9 ((uint)0x36 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC8 ((uint)0x37 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC7 ((uint)0x38 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC6 ((uint)0x39 + CPM_IRQ_OFFSET)
+#define SIU_INT_PC5 ((uint)0x3a + CPM_IRQ_OFFSET)
+#define SIU_INT_PC4 ((uint)0x3b + CPM_IRQ_OFFSET)
+#define SIU_INT_PC3 ((uint)0x3c + CPM_IRQ_OFFSET)
+#define SIU_INT_PC2 ((uint)0x3d + CPM_IRQ_OFFSET)
+#define SIU_INT_PC1 ((uint)0x3e + CPM_IRQ_OFFSET)
+#define SIU_INT_PC0 ((uint)0x3f + CPM_IRQ_OFFSET)
#endif /* CONFIG_8260 */
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index edda15befa2de5..e5f80c22fbfcfc 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -10,7 +10,7 @@
* Originally written by Dale Farnsworth <dfarnsworth@mvista.com>
* for the 2.4 kernel.
*
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
* Copyright (C) 2003 MontaVista, Software, Inc.
*
* This file is licensed under the terms of the GNU General Public License
@@ -26,53 +26,73 @@
#include <asm/types.h>
struct pt_regs;
-struct ocp_def;
#endif /* __ASSEMBLY__ */
/* ======================================================================== */
+/* PPC Sys devices definition */
+/* ======================================================================== */
+
+enum ppc_sys_devices {
+ MPC52xx_MSCAN1,
+ MPC52xx_MSCAN2,
+ MPC52xx_SPI,
+ MPC52xx_USB,
+ MPC52xx_BDLC,
+ MPC52xx_PSC1,
+ MPC52xx_PSC2,
+ MPC52xx_PSC3,
+ MPC52xx_PSC4,
+ MPC52xx_PSC5,
+ MPC52xx_PSC6,
+ MPC52xx_FEC,
+ MPC52xx_ATA,
+ MPC52xx_I2C1,
+ MPC52xx_I2C2,
+};
+
+
+/* ======================================================================== */
/* Main registers/struct addresses */
/* ======================================================================== */
-/* Theses are PHYSICAL addresses ! */
-/* TODO : There should be no static mapping, but it's not yet the case, so */
-/* we require a 1:1 mapping */
+/* MBAR position */
#define MPC52xx_MBAR 0xf0000000 /* Phys address */
-#define MPC52xx_MBAR_SIZE 0x00010000
#define MPC52xx_MBAR_VIRT 0xf0000000 /* Virt address */
+#define MPC52xx_MBAR_SIZE 0x00010000
-#define MPC52xx_MMAP_CTL (MPC52xx_MBAR + 0x0000)
-#define MPC52xx_SDRAM (MPC52xx_MBAR + 0x0100)
-#define MPC52xx_CDM (MPC52xx_MBAR + 0x0200)
-#define MPC52xx_SFTRST (MPC52xx_MBAR + 0x0220)
-#define MPC52xx_SFTRST_BIT 0x01000000
-#define MPC52xx_INTR (MPC52xx_MBAR + 0x0500)
-#define MPC52xx_GPTx(x) (MPC52xx_MBAR + 0x0600 + ((x)<<4))
-#define MPC52xx_RTC (MPC52xx_MBAR + 0x0800)
-#define MPC52xx_MSCAN1 (MPC52xx_MBAR + 0x0900)
-#define MPC52xx_MSCAN2 (MPC52xx_MBAR + 0x0980)
-#define MPC52xx_GPIO (MPC52xx_MBAR + 0x0b00)
-#define MPC52xx_GPIO_WKUP (MPC52xx_MBAR + 0x0c00)
-#define MPC52xx_PCI (MPC52xx_MBAR + 0x0d00)
-#define MPC52xx_USB_OHCI (MPC52xx_MBAR + 0x1000)
-#define MPC52xx_SDMA (MPC52xx_MBAR + 0x1200)
-#define MPC52xx_XLB (MPC52xx_MBAR + 0x1f00)
-#define MPC52xx_PSCx(x) (MPC52xx_MBAR + 0x2000 + ((x)<<9))
-#define MPC52xx_PSC1 (MPC52xx_MBAR + 0x2000)
-#define MPC52xx_PSC2 (MPC52xx_MBAR + 0x2200)
-#define MPC52xx_PSC3 (MPC52xx_MBAR + 0x2400)
-#define MPC52xx_PSC4 (MPC52xx_MBAR + 0x2600)
-#define MPC52xx_PSC5 (MPC52xx_MBAR + 0x2800)
-#define MPC52xx_PSC6 (MPC52xx_MBAR + 0x2C00)
-#define MPC52xx_FEC (MPC52xx_MBAR + 0x3000)
-#define MPC52xx_ATA (MPC52xx_MBAR + 0x3a00)
-#define MPC52xx_I2C1 (MPC52xx_MBAR + 0x3d00)
-#define MPC52xx_I2C_MICR (MPC52xx_MBAR + 0x3d20)
-#define MPC52xx_I2C2 (MPC52xx_MBAR + 0x3d40)
+#define MPC52xx_PA(x) ((phys_addr_t)(MPC52xx_MBAR + (x)))
+#define MPC52xx_VA(x) ((void __iomem *)(MPC52xx_MBAR_VIRT + (x)))
+
+/* Registers zone offset/size */
+#define MPC52xx_MMAP_CTL_OFFSET 0x0000
+#define MPC52xx_MMAP_CTL_SIZE 0x068
+#define MPC52xx_SDRAM_OFFSET 0x0100
+#define MPC52xx_SDRAM_SIZE 0x010
+#define MPC52xx_CDM_OFFSET 0x0200
+#define MPC52xx_CDM_SIZE 0x038
+#define MPC52xx_INTR_OFFSET 0x0500
+#define MPC52xx_INTR_SIZE 0x04c
+#define MPC52xx_GPTx_OFFSET(x) (0x0600 + ((x)<<4))
+#define MPC52xx_GPT_SIZE 0x010
+#define MPC52xx_RTC_OFFSET 0x0800
+#define MPC52xx_RTC_SIZE 0x024
+#define MPC52xx_GPIO_OFFSET 0x0b00
+#define MPC52xx_GPIO_SIZE 0x040
+#define MPC52xx_GPIO_WKUP_OFFSET 0x0c00
+#define MPC52xx_GPIO_WKUP_SIZE 0x028
+#define MPC52xx_PCI_OFFSET 0x0d00
+#define MPC52xx_PCI_SIZE 0x100
+#define MPC52xx_SDMA_OFFSET 0x1200
+#define MPC52xx_SDMA_SIZE 0x100
+#define MPC52xx_XLB_OFFSET 0x1f00
+#define MPC52xx_XLB_SIZE 0x100
+#define MPC52xx_PSCx_OFFSET(x) (((x)!=6)?(0x1e00+((x)<<9)):0x2c00)
+#define MPC52xx_PSC_SIZE 0x0a0
/* SRAM used for SDMA */
-#define MPC52xx_SRAM (MPC52xx_MBAR + 0x8000)
-#define MPC52xx_SRAM_SIZE (16*1024)
+#define MPC52xx_SRAM_OFFSET 0x8000
+#define MPC52xx_SRAM_SIZE 0x4000
/* ======================================================================== */
@@ -119,11 +139,12 @@ struct ocp_def;
#define MPC52xx_SPI_SPIF_IRQ (MPC52xx_PERP_IRQ_BASE + 14)
#define MPC52xx_I2C1_IRQ (MPC52xx_PERP_IRQ_BASE + 15)
#define MPC52xx_I2C2_IRQ (MPC52xx_PERP_IRQ_BASE + 16)
-#define MPC52xx_CAN1_IRQ (MPC52xx_PERP_IRQ_BASE + 17)
-#define MPC52xx_CAN2_IRQ (MPC52xx_PERP_IRQ_BASE + 18)
+#define MPC52xx_MSCAN1_IRQ (MPC52xx_PERP_IRQ_BASE + 17)
+#define MPC52xx_MSCAN2_IRQ (MPC52xx_PERP_IRQ_BASE + 18)
#define MPC52xx_IR_RX_IRQ (MPC52xx_PERP_IRQ_BASE + 19)
#define MPC52xx_IR_TX_IRQ (MPC52xx_PERP_IRQ_BASE + 20)
#define MPC52xx_XLB_ARB_IRQ (MPC52xx_PERP_IRQ_BASE + 21)
+#define MPC52xx_BDLC_IRQ (MPC52xx_PERP_IRQ_BASE + 22)
@@ -163,7 +184,7 @@ struct mpc52xx_mmap_ctl {
u32 cs6_start; /* MMAP_CTRL + 0x58 */
u32 cs6_stop; /* MMAP_CTRL + 0x5c */
u32 cs7_start; /* MMAP_CTRL + 0x60 */
- u32 cs7_stop; /* MMAP_CTRL + 0x60 */
+ u32 cs7_stop; /* MMAP_CTRL + 0x64 */
};
/* SDRAM control */
@@ -209,7 +230,7 @@ struct mpc52xx_sdma {
u16 tcr[16]; /* SDMA + 0x1c .. 0x3a */
- u8 ipr[32]; /* SDMA + 0x3c .. 5b */
+ u8 ipr[32]; /* SDMA + 0x3c .. 0x5b */
u32 cReqSelect; /* SDMA + 0x5c */
u32 task_size0; /* SDMA + 0x60 */
@@ -391,10 +412,20 @@ extern void mpc52xx_halt(void);
extern void mpc52xx_power_off(void);
extern void mpc52xx_progress(char *s, unsigned short hex);
extern void mpc52xx_calibrate_decr(void);
-extern void mpc52xx_add_board_devices(struct ocp_def board_ocp[]);
extern void mpc52xx_find_bridges(void);
+
+ /* Matching of PSC function */
+struct mpc52xx_psc_func {
+ int id;
+ char *func;
+};
+
+extern int mpc52xx_match_psc_function(int psc_idx, const char *func);
+extern struct mpc52xx_psc_func mpc52xx_psc_functions[];
+ /* This array is to be defined in platform file */
+
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 3f9e4237bf6f06..22713e331585a7 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -52,55 +52,6 @@
*/
extern unsigned char __res[];
-/* Internal IRQs on MPC85xx OpenPIC */
-/* Not all of these exist on all MPC85xx implementations */
-
-#ifndef MPC85xx_OPENPIC_IRQ_OFFSET
-#define MPC85xx_OPENPIC_IRQ_OFFSET 64
-#endif
-
-/* The 32 internal sources */
-#define MPC85xx_IRQ_L2CACHE ( 0 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_ECM ( 1 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_DDR ( 2 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_LBIU ( 3 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_DMA0 ( 4 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_DMA1 ( 5 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_DMA2 ( 6 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_DMA3 ( 7 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_PCI1 ( 8 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_PCI2 ( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_RIO_ERROR ( 9 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_RIO_BELL (10 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_RIO_TX (11 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_RIO_RX (12 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_TSEC1_TX (13 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_TSEC1_RX (14 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_TSEC1_ERROR (18 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_TSEC2_TX (19 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_TSEC2_RX (20 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_TSEC2_ERROR (24 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_FEC (25 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_DUART (26 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_IIC1 (27 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_PERFMON (28 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_SEC2 (29 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_CPM (30 + MPC85xx_OPENPIC_IRQ_OFFSET)
-
-/* The 12 external interrupt lines */
-#define MPC85xx_IRQ_EXT0 (32 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT1 (33 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT2 (34 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT3 (35 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT4 (36 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT5 (37 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT6 (38 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT7 (39 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT8 (40 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT9 (41 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT10 (42 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT11 (43 + MPC85xx_OPENPIC_IRQ_OFFSET)
-
/* Offset from CCSRBAR */
#define MPC85xx_CPM_OFFSET (0x80000)
#define MPC85xx_CPM_SIZE (0x40000)
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 293e47f1d99a54..24b991c427694d 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -25,6 +25,8 @@
#include <asm/mpc83xx.h>
#elif defined(CONFIG_85xx)
#include <asm/mpc85xx.h>
+#elif defined(CONFIG_PPC_MPC52xx)
+#include <asm/mpc52xx.h>
#else
#error "need definition of ppc_sys_devices"
#endif
diff --git a/include/asm-ppc64/ipc.h b/include/asm-ppc64/ipc.h
index f91bf5b0d092ef..a46e3d9c2a3fc1 100644
--- a/include/asm-ppc64/ipc.h
+++ b/include/asm-ppc64/ipc.h
@@ -1,34 +1 @@
-#ifndef __PPC64_IPC_H__
-#define __PPC64_IPC_H__
-
-/*
- * These are used to wrap system calls on PowerPC.
- *
- * See arch/ppc64/kernel/syscalls.c for ugly details..
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* __PPC64_IPC_H__ */
+#include <asm-generic/ipc.h>
diff --git a/include/asm-ppc64/lmb.h b/include/asm-ppc64/lmb.h
index 3da661161cc52d..a6cbca21ac1d70 100644
--- a/include/asm-ppc64/lmb.h
+++ b/include/asm-ppc64/lmb.h
@@ -51,6 +51,7 @@ extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
extern unsigned long __init lmb_phys_mem_size(void);
extern unsigned long __init lmb_end_of_DRAM(void);
extern unsigned long __init lmb_abs_to_phys(unsigned long);
+extern void __init lmb_enforce_memory_limit(void);
extern void lmb_dump_all(void);
diff --git a/include/asm-ppc64/seccomp.h b/include/asm-ppc64/seccomp.h
new file mode 100644
index 00000000000000..c130c334bda1c1
--- /dev/null
+++ b/include/asm-ppc64/seccomp.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h> /* already defines TIF_32BIT */
+
+#ifndef TIF_32BIT
+#error "unexpected TIF_32BIT on ppc64"
+#endif
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#define __NR_seccomp_read_32 __NR_read
+#define __NR_seccomp_write_32 __NR_write
+#define __NR_seccomp_exit_32 __NR_exit
+#define __NR_seccomp_sigreturn_32 __NR_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
index d4b978c26d7106..037b5e06083c0c 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -101,6 +101,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */
#define TIF_SINGLESTEP 9 /* singlestepping active */
#define TIF_MEMDIE 10
+#define TIF_SECCOMP 11 /* secure computing */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -113,7 +114,8 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
-#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
+#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
_TIF_NEED_RESCHED)
diff --git a/include/asm-s390/ipc.h b/include/asm-s390/ipc.h
index d6c041e9ca9aa8..a46e3d9c2a3fc1 100644
--- a/include/asm-s390/ipc.h
+++ b/include/asm-s390/ipc.h
@@ -1,40 +1 @@
-/*
- * include/asm-s390/ipc.h
- *
- * S390 version
- *
- * Derived from "include/asm-i386/ipc.h"
- */
-
-#ifndef __s390_IPC_H__
-#define __s390_IPC_H__
-
-/*
- * These are used to wrap system calls on S390.
- *
- * See arch/s390/kernel/sys_s390.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-sh/ipc.h b/include/asm-sh/ipc.h
index 6ced9bec6abcd3..a46e3d9c2a3fc1 100644
--- a/include/asm-sh/ipc.h
+++ b/include/asm-sh/ipc.h
@@ -1,32 +1 @@
-#ifndef __ASM_SH_IPC_H
-#define __ASM_SH_IPC_H
-
-/*
- * These are used to wrap system calls on x86.
- *
- * See arch/i386/kernel/sys_i386.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* __ASM_SH_IPC_H */
+#include <asm-generic/ipc.h>
diff --git a/include/asm-sh64/ipc.h b/include/asm-sh64/ipc.h
index d8d9389bd3ce7a..a46e3d9c2a3fc1 100644
--- a/include/asm-sh64/ipc.h
+++ b/include/asm-sh64/ipc.h
@@ -1,6 +1 @@
-#ifndef __ASM_SH64_IPC_H
-#define __ASM_SH64_IPC_H
-
-#include <asm-sh/ipc.h>
-
-#endif /* __ASM_SH64_IPC_H */
+#include <asm-generic/ipc.h>
diff --git a/include/asm-sparc/ipc.h b/include/asm-sparc/ipc.h
index 3064aaf8fa27c3..a46e3d9c2a3fc1 100644
--- a/include/asm-sparc/ipc.h
+++ b/include/asm-sparc/ipc.h
@@ -1,32 +1 @@
-#ifndef __SPARC_IPC_H__
-#define __SPARC_IPC_H__
-
-/*
- * These are used to wrap system calls on the sparc.
- *
- * See arch/sparc/kernel/sys_sparc.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-sparc64/ipc.h b/include/asm-sparc64/ipc.h
index 39261d5523ef9f..a46e3d9c2a3fc1 100644
--- a/include/asm-sparc64/ipc.h
+++ b/include/asm-sparc64/ipc.h
@@ -1,33 +1 @@
-#ifndef __SPARC64_IPC_H__
-#define __SPARC64_IPC_H__
-
-/*
- * These are used to wrap system calls on the sparc.
- *
- * See arch/sparc64/kernel/sys_sparc32.c for ugly details..
- */
-struct ipc_kludge {
- u32 msgp;
- s32 msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-/* We don't need to maintain backward compatibility on 64bit, we've started fresh */
-#define IPCCALL(version,op) (op)
-
-#endif
+#include <asm-generic/ipc.h>
diff --git a/include/asm-v850/ipc.h b/include/asm-v850/ipc.h
index 5656799cd4e85d..a46e3d9c2a3fc1 100644
--- a/include/asm-v850/ipc.h
+++ b/include/asm-v850/ipc.h
@@ -1,31 +1 @@
-#ifndef __V850_IPC_H__
-#define __V850_IPC_H__
-
-/*
- * These are used to wrap system calls on v850.
- *
- * See arch/v850/kernel/syscalls.c for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* __V850_IPC_H__ */
+#include <asm-generic/ipc.h>
diff --git a/include/asm-x86_64/ipc.h b/include/asm-x86_64/ipc.h
deleted file mode 100644
index 8736ba68c11835..00000000000000
--- a/include/asm-x86_64/ipc.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __x8664_IPC_H__
-#define __x8664_IPC_H__
-
-/* dummy */
-
-#endif
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index 2aac15a1290fc1..66f0be191ab4f5 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -80,6 +80,18 @@ extern inline void cpuid(int op, unsigned int *eax, unsigned int *ebx,
: "0" (op));
}
+/* Some CPUID calls want 'count' to be placed in ecx */
+static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
+ int *edx)
+{
+ __asm__("cpuid"
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (op), "c" (count));
+}
+
/*
* CPUID functions returning a single datum
*/
diff --git a/include/asm-x86_64/seccomp.h b/include/asm-x86_64/seccomp.h
new file mode 100644
index 00000000000000..553af65a2287aa
--- /dev/null
+++ b/include/asm-x86_64/seccomp.h
@@ -0,0 +1,24 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h>
+
+#ifdef TIF_32BIT
+#error "unexpected TIF_32BIT on x86_64"
+#else
+#define TIF_32BIT TIF_IA32
+#endif
+
+#include <linux/unistd.h>
+#include <asm/ia32_unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#define __NR_seccomp_read_32 __NR_ia32_read
+#define __NR_seccomp_write_32 __NR_ia32_write
+#define __NR_seccomp_exit_32 __NR_ia32_exit
+#define __NR_seccomp_sigreturn_32 __NR_ia32_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index f2a09f442d7dcc..a8ea0164f3ab01 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -774,7 +774,7 @@ asmlinkage long sys_pipe(int *fildes);
asmlinkage long sys_ptrace(long request, long pid,
unsigned long addr, long data);
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs regs);
+asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
struct sigaction;
asmlinkage long sys_rt_sigaction(int sig,
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 3c369c6553e3ed..f7a1390d67f5b3 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -25,13 +25,39 @@ typedef int (congested_fn)(void *, int);
struct backing_dev_info {
unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
unsigned long state; /* Always use atomic bitops on this */
- int memory_backed; /* Cannot clean pages with writepage */
+ unsigned int capabilities; /* Device capabilities */
congested_fn *congested_fn; /* Function pointer if device is md/dm */
void *congested_data; /* Pointer to aux data for congested func */
void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
void *unplug_io_data;
};
+
+/*
+ * Flags in backing_dev_info::capability
+ * - The first two flags control whether dirty pages will contribute to the
+ * VM's accounting and whether writepages() should be called for dirty pages
+ * (something that would not, for example, be appropriate for ramfs)
+ * - These flags let !MMU mmap() govern direct device mapping vs immediate
+ * copying more easily for MAP_PRIVATE, especially for ROM filesystems
+ */
+#define BDI_CAP_NO_ACCT_DIRTY 0x00000001 /* Dirty pages shouldn't contribute to accounting */
+#define BDI_CAP_NO_WRITEBACK 0x00000002 /* Don't write pages back */
+#define BDI_CAP_MAP_COPY 0x00000004 /* Copy can be mapped (MAP_PRIVATE) */
+#define BDI_CAP_MAP_DIRECT 0x00000008 /* Can be mapped directly (MAP_SHARED) */
+#define BDI_CAP_READ_MAP 0x00000010 /* Can be mapped for reading */
+#define BDI_CAP_WRITE_MAP 0x00000020 /* Can be mapped for writing */
+#define BDI_CAP_EXEC_MAP 0x00000040 /* Can be mapped for execution */
+#define BDI_CAP_VMFLAGS \
+ (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP)
+
+#if defined(VM_MAYREAD) && \
+ (BDI_CAP_READ_MAP != VM_MAYREAD || \
+ BDI_CAP_WRITE_MAP != VM_MAYWRITE || \
+ BDI_CAP_EXEC_MAP != VM_MAYEXEC)
+#error please change backing_dev_info::capabilities flags
+#endif
+
extern struct backing_dev_info default_backing_dev_info;
void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
@@ -62,4 +88,17 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi)
(1 << BDI_write_congested));
}
+#define bdi_cap_writeback_dirty(bdi) \
+ (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))
+
+#define bdi_cap_account_dirty(bdi) \
+ (!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY))
+
+#define mapping_cap_writeback_dirty(mapping) \
+ bdi_cap_writeback_dirty((mapping)->backing_dev_info)
+
+#define mapping_cap_account_dirty(mapping) \
+ bdi_cap_account_dirty((mapping)->backing_dev_info)
+
+
#endif /* _LINUX_BACKING_DEV_H */
diff --git a/include/linux/console.h b/include/linux/console.h
index b9b183e986e5e4..721371382ae5ff 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -59,7 +59,6 @@ struct consw {
extern const struct consw *conswitchp;
extern const struct consw dummy_con; /* dummy console buffer */
-extern const struct consw fb_con; /* frame buffer based console */
extern const struct consw vga_con; /* VGA text console */
extern const struct consw newport_con; /* SGI Newport console */
extern const struct consw prom_con; /* SPARC PROM console */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 9d1507c87cecc5..b45d3e2d711a38 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -702,9 +702,7 @@ struct fb_tile_ops {
#define FBINFO_MISC_USEREVENT 0x10000 /* event request
from userspace */
-#define FBINFO_MISC_MODESWITCH 0x20000 /* mode switch */
-#define FBINFO_MISC_MODESWITCHLATE 0x40000 /* init hardware later */
-#define FBINFO_MISC_TILEBLITTING 0x80000 /* use tile blitting */
+#define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */
struct fb_info {
int node;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index ee989b6ee22aa1..3a2702bbb1d67d 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -8,6 +8,7 @@
#define NR_SECCOMP_MODES 1
#include <linux/thread_info.h>
+#include <asm/seccomp.h>
typedef struct { int mode; } seccomp_t;
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index 29a1b14bb218bd..c119ce7cbd22ae 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -26,21 +26,23 @@ struct svc_cred {
struct svc_rqst; /* forward decl */
/* Authentication is done in the context of a domain.
- * For a server, a domain represents a group of clients using
+ *
+ * Currently, the nfs server uses the auth_domain to stand
+ * for the "client" listed in /etc/exports.
+ *
+ * More generally, a domain might represent a group of clients using
* a common mechanism for authentication and having a common mapping
* between local identity (uid) and network identity. All clients
* in a domain have similar general access rights. Each domain can
* contain multiple principals which will have different specific right
* based on normal Discretionary Access Control.
*
- * For a client, a domain represents a number of servers which all
- * use a common authentication mechanism and network identity name space.
- *
* A domain is created by an authentication flavour module based on name
* only. Userspace then fills in detail on demand.
*
- * The creation of a domain typically implies creation of one or
- * more caches for storing domain specific information.
+ * In the case of auth_unix and auth_null, the auth_domain is also
+ * associated with entries in another cache representing the mapping
+ * of ip addresses to the given client.
*/
struct auth_domain {
struct cache_head h;
diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h
new file mode 100644
index 00000000000000..f06cc88607f51d
--- /dev/null
+++ b/include/video/s1d13xxxfb.h
@@ -0,0 +1,166 @@
+/* drivers/video/s1d3xxxfb.h
+ *
+ * (c) 2004 Simtec Electronics
+ * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * Header file for Epson S1D13XXX driver code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#ifndef S1D13XXXFB_H
+#define S1D13XXXFB_H
+
+#define S1D_PALETTE_SIZE 256
+#define S1D_CHIP_REV 7 /* expected chip revision number for s1d13806 */
+#define S1D_FBID "S1D13806"
+#define S1D_DEVICENAME "s1d13806fb"
+
+/* register definitions (tested on s1d13896) */
+#define S1DREG_REV_CODE 0x0000 /* Revision Code Register */
+#define S1DREG_MISC 0x0001 /* Miscellaneous Register */
+#define S1DREG_GPIO_CNF0 0x0004 /* General IO Pins Configuration Register 0 */
+#define S1DREG_GPIO_CNF1 0x0005 /* General IO Pins Configuration Register 1 */
+#define S1DREG_GPIO_CTL0 0x0008 /* General IO Pins Control Register 0 */
+#define S1DREG_GPIO_CTL1 0x0009 /* General IO Pins Control Register 1 */
+#define S1DREG_CNF_STATUS 0x000C /* Configuration Status Readback Register */
+#define S1DREG_CLK_CNF 0x0010 /* Memory Clock Configuration Register */
+#define S1DREG_LCD_CLK_CNF 0x0014 /* LCD Pixel Clock Configuration Register */
+#define S1DREG_CRT_CLK_CNF 0x0018 /* CRT/TV Pixel Clock Configuration Register */
+#define S1DREG_MPLUG_CLK_CNF 0x001C /* MediaPlug Clock Configuration Register */
+#define S1DREG_CPU2MEM_WST_SEL 0x001E /* CPU To Memory Wait State Select Register */
+#define S1DREG_MEM_CNF 0x0020 /* Memory Configuration Register */
+#define S1DREG_SDRAM_REF_RATE 0x0021 /* SDRAM Refresh Rate Register */
+#define S1DREG_SDRAM_TC0 0x002A /* SDRAM Timing Control Register 0 */
+#define S1DREG_SDRAM_TC1 0x002B /* SDRAM Timing Control Register 1 */
+#define S1DREG_PANEL_TYPE 0x0030 /* Panel Type Register */
+#define S1DREG_MOD_RATE 0x0031 /* MOD Rate Register */
+#define S1DREG_LCD_DISP_HWIDTH 0x0032 /* LCD Horizontal Display Width Register: ((val)+1)*8)=pix/line */
+#define S1DREG_LCD_NDISP_HPER 0x0034 /* LCD Horizontal Non-Display Period Register: ((val)+1)*8)=NDpix/line */
+#define S1DREG_TFT_FPLINE_START 0x0035 /* TFT FPLINE Start Position Register */
+#define S1DREG_TFT_FPLINE_PWIDTH 0x0036 /* TFT FPLINE Pulse Width Register. */
+#define S1DREG_LCD_DISP_VHEIGHT0 0x0038 /* LCD Vertical Display Height Register 0 */
+#define S1DREG_LCD_DISP_VHEIGHT1 0x0039 /* LCD Vertical Display Height Register 1 */
+#define S1DREG_LCD_NDISP_VPER 0x003A /* LCD Vertical Non-Display Period Register: (val)+1=NDlines */
+#define S1DREG_TFT_FPFRAME_START 0x003B /* TFT FPFRAME Start Position Register */
+#define S1DREG_TFT_FPFRAME_PWIDTH 0x003C /* TFT FPFRAME Pulse Width Register */
+#define S1DREG_LCD_DISP_MODE 0x0040 /* LCD Display Mode Register */
+#define S1DREG_LCD_MISC 0x0041 /* LCD Miscellaneous Register */
+#define S1DREG_LCD_DISP_START0 0x0042 /* LCD Display Start Address Register 0 */
+#define S1DREG_LCD_DISP_START1 0x0043 /* LCD Display Start Address Register 1 */
+#define S1DREG_LCD_DISP_START2 0x0044 /* LCD Display Start Address Register 2 */
+#define S1DREG_LCD_MEM_OFF0 0x0046 /* LCD Memory Address Offset Register 0 */
+#define S1DREG_LCD_MEM_OFF1 0x0047 /* LCD Memory Address Offset Register 1 */
+#define S1DREG_LCD_PIX_PAN 0x0048 /* LCD Pixel Panning Register */
+#define S1DREG_LCD_DISP_FIFO_HTC 0x004A /* LCD Display FIFO High Threshold Control Register */
+#define S1DREG_LCD_DISP_FIFO_LTC 0x004B /* LCD Display FIFO Low Threshold Control Register */
+#define S1DREG_CRT_DISP_HWIDTH 0x0050 /* CRT/TV Horizontal Display Width Register: ((val)+1)*8)=pix/line */
+#define S1DREG_CRT_NDISP_HPER 0x0052 /* CRT/TV Horizontal Non-Display Period Register */
+#define S1DREG_CRT_HRTC_START 0x0053 /* CRT/TV HRTC Start Position Register */
+#define S1DREG_CRT_HRTC_PWIDTH 0x0054 /* CRT/TV HRTC Pulse Width Register */
+#define S1DREG_CRT_DISP_VHEIGHT0 0x0056 /* CRT/TV Vertical Display Height Register 0 */
+#define S1DREG_CRT_DISP_VHEIGHT1 0x0057 /* CRT/TV Vertical Display Height Register 1 */
+#define S1DREG_CRT_NDISP_VPER 0x0058 /* CRT/TV Vertical Non-Display Period Register */
+#define S1DREG_CRT_VRTC_START 0x0059 /* CRT/TV VRTC Start Position Register */
+#define S1DREG_CRT_VRTC_PWIDTH 0x005A /* CRT/TV VRTC Pulse Width Register */
+#define S1DREG_TV_OUT_CTL 0x005B /* TV Output Control Register */
+#define S1DREG_CRT_DISP_MODE 0x0060 /* CRT/TV Display Mode Register */
+#define S1DREG_CRT_DISP_START0 0x0062 /* CRT/TV Display Start Address Register 0 */
+#define S1DREG_CRT_DISP_START1 0x0063 /* CRT/TV Display Start Address Register 1 */
+#define S1DREG_CRT_DISP_START2 0x0064 /* CRT/TV Display Start Address Register 2 */
+#define S1DREG_CRT_MEM_OFF0 0x0066 /* CRT/TV Memory Address Offset Register 0 */
+#define S1DREG_CRT_MEM_OFF1 0x0067 /* CRT/TV Memory Address Offset Register 1 */
+#define S1DREG_CRT_PIX_PAN 0x0068 /* CRT/TV Pixel Panning Register */
+#define S1DREG_CRT_DISP_FIFO_HTC 0x006A /* CRT/TV Display FIFO High Threshold Control Register */
+#define S1DREG_CRT_DISP_FIFO_LTC 0x006B /* CRT/TV Display FIFO Low Threshold Control Register */
+#define S1DREG_LCD_CUR_CTL 0x0070 /* LCD Ink/Cursor Control Register */
+#define S1DREG_LCD_CUR_START 0x0071 /* LCD Ink/Cursor Start Address Register */
+#define S1DREG_LCD_CUR_XPOS0 0x0072 /* LCD Cursor X Position Register 0 */
+#define S1DREG_LCD_CUR_XPOS1 0x0073 /* LCD Cursor X Position Register 1 */
+#define S1DREG_LCD_CUR_YPOS0 0x0074 /* LCD Cursor Y Position Register 0 */
+#define S1DREG_LCD_CUR_YPOS1 0x0075 /* LCD Cursor Y Position Register 1 */
+#define S1DREG_LCD_CUR_BCTL0 0x0076 /* LCD Ink/Cursor Blue Color 0 Register */
+#define S1DREG_LCD_CUR_GCTL0 0x0077 /* LCD Ink/Cursor Green Color 0 Register */
+#define S1DREG_LCD_CUR_RCTL0 0x0078 /* LCD Ink/Cursor Red Color 0 Register */
+#define S1DREG_LCD_CUR_BCTL1 0x007A /* LCD Ink/Cursor Blue Color 1 Register */
+#define S1DREG_LCD_CUR_GCTL1 0x007B /* LCD Ink/Cursor Green Color 1 Register */
+#define S1DREG_LCD_CUR_RCTL1 0x007C /* LCD Ink/Cursor Red Color 1 Register */
+#define S1DREG_LCD_CUR_FIFO_HTC 0x007E /* LCD Ink/Cursor FIFO High Threshold Register */
+#define S1DREG_CRT_CUR_CTL 0x0080 /* CRT/TV Ink/Cursor Control Register */
+#define S1DREG_CRT_CUR_START 0x0081 /* CRT/TV Ink/Cursor Start Address Register */
+#define S1DREG_CRT_CUR_XPOS0 0x0082 /* CRT/TV Cursor X Position Register 0 */
+#define S1DREG_CRT_CUR_XPOS1 0x0083 /* CRT/TV Cursor X Position Register 1 */
+#define S1DREG_CRT_CUR_YPOS0 0x0084 /* CRT/TV Cursor Y Position Register 0 */
+#define S1DREG_CRT_CUR_YPOS1 0x0085 /* CRT/TV Cursor Y Position Register 1 */
+#define S1DREG_CRT_CUR_BCTL0 0x0086 /* CRT/TV Ink/Cursor Blue Color 0 Register */
+#define S1DREG_CRT_CUR_GCTL0 0x0087 /* CRT/TV Ink/Cursor Green Color 0 Register */
+#define S1DREG_CRT_CUR_RCTL0 0x0088 /* CRT/TV Ink/Cursor Red Color 0 Register */
+#define S1DREG_CRT_CUR_BCTL1 0x008A /* CRT/TV Ink/Cursor Blue Color 1 Register */
+#define S1DREG_CRT_CUR_GCTL1 0x008B /* CRT/TV Ink/Cursor Green Color 1 Register */
+#define S1DREG_CRT_CUR_RCTL1 0x008C /* CRT/TV Ink/Cursor Red Color 1 Register */
+#define S1DREG_CRT_CUR_FIFO_HTC 0x008E /* CRT/TV Ink/Cursor FIFO High Threshold Register */
+#define S1DREG_BBLT_CTL0 0x0100 /* BitBLT Control Register 0 */
+#define S1DREG_BBLT_CTL1 0x0101 /* BitBLT Control Register 1 */
+#define S1DREG_BBLT_CC_EXP 0x0102 /* BitBLT Code/Color Expansion Register */
+#define S1DREG_BBLT_OP 0x0103 /* BitBLT Operation Register */
+#define S1DREG_BBLT_SRC_START0 0x0104 /* BitBLT Source Start Address Register 0 */
+#define S1DREG_BBLT_SRC_START1 0x0105 /* BitBLT Source Start Address Register 1 */
+#define S1DREG_BBLT_SRC_START2 0x0106 /* BitBLT Source Start Address Register 2 */
+#define S1DREG_BBLT_DST_START0 0x0108 /* BitBLT Destination Start Address Register 0 */
+#define S1DREG_BBLT_DST_START1 0x0109 /* BitBLT Destination Start Address Register 1 */
+#define S1DREG_BBLT_DST_START2 0x010A /* BitBLT Destination Start Address Register 2 */
+#define S1DREG_BBLT_MEM_OFF0 0x010C /* BitBLT Memory Address Offset Register 0 */
+#define S1DREG_BBLT_MEM_OFF1 0x010D /* BitBLT Memory Address Offset Register 1 */
+#define S1DREG_BBLT_WIDTH0 0x0110 /* BitBLT Width Register 0 */
+#define S1DREG_BBLT_WIDTH1 0x0111 /* BitBLT Width Register 1 */
+#define S1DREG_BBLT_HEIGHT0 0x0112 /* BitBLT Height Register 0 */
+#define S1DREG_BBLT_HEIGHT1 0x0113 /* BitBLT Height Register 1 */
+#define S1DREG_BBLT_BGC0 0x0114 /* BitBLT Background Color Register 0 */
+#define S1DREG_BBLT_BGC1 0x0115 /* BitBLT Background Color Register 1 */
+#define S1DREG_BBLT_FGC0 0x0118 /* BitBLT Foreground Color Register 0 */
+#define S1DREG_BBLT_FGC1 0x0119 /* BitBLT Foreground Color Register 1 */
+#define S1DREG_LKUP_MODE 0x01E0 /* Look-Up Table Mode Register */
+#define S1DREG_LKUP_ADDR 0x01E2 /* Look-Up Table Address Register */
+#define S1DREG_LKUP_DATA 0x01E4 /* Look-Up Table Data Register */
+#define S1DREG_PS_CNF 0x01F0 /* Power Save Configuration Register */
+#define S1DREG_PS_STATUS 0x01F1 /* Power Save Status Register */
+#define S1DREG_CPU2MEM_WDOGT 0x01F4 /* CPU-to-Memory Access Watchdog Timer Register */
+#define S1DREG_COM_DISP_MODE 0x01FC /* Common Display Mode Register */
+
+#define S1DREG_DELAYOFF 0xFFFE
+#define S1DREG_DELAYON 0xFFFF
+
+/* Note: all above defines should go in separate header files
+ when implementing other S1D13xxx chip support. */
+
+struct s1d13xxxfb_regval {
+ u16 addr;
+ u8 value;
+};
+
+
+struct s1d13xxxfb_par {
+ void __iomem *regs;
+ unsigned char display;
+
+ unsigned int pseudo_palette[16];
+#ifdef CONFIG_PM
+ void *regs_save; /* pm saves all registers here */
+ void *disp_save; /* pm saves entire screen here */
+#endif
+};
+
+struct s1d13xxxfb_pdata {
+ const struct s1d13xxxfb_regval *initregs;
+ const unsigned int initregssize;
+ void (*platform_init_video)(void);
+#ifdef CONFIG_PM
+ int (*platform_suspend_video)(void);
+ int (*platform_resume_video)(void);
+#endif
+};
+
+#endif
+
diff --git a/include/video/trident.h b/include/video/trident.h
index abe7d67756de7b..200be255168191 100644
--- a/include/video/trident.h
+++ b/include/video/trident.h
@@ -9,7 +9,7 @@
#define debug(f,a...)
#endif
-#define output(f, a...) printk("tridentfb: " f, ## a)
+#define output(f, a...) pr_info("tridentfb: " f, ## a)
#define Kb (1024)
#define Mb (Kb*Kb)
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index cd942ce30b7384..a6584d9099d32a 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -193,7 +193,7 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry);
static struct backing_dev_info cpuset_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 1, /* Does not contribute to dirty memory */
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
};
static struct inode *cpuset_new_inode(mode_t mode)
@@ -1456,7 +1456,7 @@ void cpuset_init_current_mems_allowed(void)
* Do not call this routine if in_interrupt().
*/
-void cpuset_update_current_mems_allowed()
+void cpuset_update_current_mems_allowed(void)
{
struct cpuset *cs = current->cpuset;
diff --git a/kernel/printk.c b/kernel/printk.c
index 5d5754964bf40a..1498689548d1e6 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -54,7 +54,12 @@ int console_printk[4] = {
EXPORT_SYMBOL(console_printk);
+/*
+ * Low lever drivers may need that to know if they can schedule in
+ * their unblank() callback or not. So let's export it.
+ */
int oops_in_progress;
+EXPORT_SYMBOL(oops_in_progress);
/*
* console_sem protects the console_drivers list, and also
@@ -751,12 +756,15 @@ void console_unblank(void)
struct console *c;
/*
- * Try to get the console semaphore. If someone else owns it
- * we have to return without unblanking because console_unblank
- * may be called in interrupt context.
+ * console_unblank can no longer be called in interrupt context unless
+ * oops_in_progress is set to 1..
*/
- if (down_trylock(&console_sem) != 0)
- return;
+ if (oops_in_progress) {
+ if (down_trylock(&console_sem) != 0)
+ return;
+ } else
+ acquire_console_sem();
+
console_locked = 1;
console_may_schedule = 0;
for (c = console_drivers; c != NULL; c = c->next)
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index f0ae3c3c013eb6..d00eded75d71f8 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -465,6 +465,6 @@ void synchronize_kernel(void)
}
module_param(maxbatch, int, 0);
-EXPORT_SYMBOL(call_rcu);
-EXPORT_SYMBOL(call_rcu_bh);
-EXPORT_SYMBOL(synchronize_kernel);
+EXPORT_SYMBOL_GPL(call_rcu);
+EXPORT_SYMBOL_GPL(call_rcu_bh);
+EXPORT_SYMBOL_GPL(synchronize_kernel);
diff --git a/kernel/sched.c b/kernel/sched.c
index dff94ba6df3860..f69c4a5361e3b8 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -314,7 +314,6 @@ static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags)
static int show_schedstat(struct seq_file *seq, void *v)
{
int cpu;
- enum idle_type itype;
seq_printf(seq, "version %d\n", SCHEDSTAT_VERSION);
seq_printf(seq, "timestamp %lu\n", jiffies);
@@ -340,6 +339,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
#ifdef CONFIG_SMP
/* domain-specific stats */
for_each_domain(cpu, sd) {
+ enum idle_type itype;
char mask_str[NR_CPUS];
cpumask_scnprintf(mask_str, NR_CPUS, sd->span);
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index b6c5b35c737c04..c3391b6020e855 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -8,10 +8,6 @@
#include <linux/seccomp.h>
#include <linux/sched.h>
-#include <asm/unistd.h>
-#ifdef TIF_IA32
-#include <asm/ia32_unistd.h>
-#endif
/* #define SECCOMP_DEBUG 1 */
@@ -21,27 +17,13 @@
* to limit the stack allocations too.
*/
static int mode1_syscalls[] = {
- __NR_read, __NR_write, __NR_exit,
- /*
- * Allow either sigreturn or rt_sigreturn, newer archs
- * like x86-64 only defines __NR_rt_sigreturn.
- */
-#ifdef __NR_sigreturn
- __NR_sigreturn,
-#else
- __NR_rt_sigreturn,
-#endif
+ __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
0, /* null terminated */
};
-#ifdef TIF_IA32
-static int mode1_syscalls_32bit[] = {
- __NR_ia32_read, __NR_ia32_write, __NR_ia32_exit,
- /*
- * Allow either sigreturn or rt_sigreturn, newer archs
- * like x86-64 only defines __NR_rt_sigreturn.
- */
- __NR_ia32_sigreturn,
+#ifdef TIF_32BIT
+static int mode1_syscalls_32[] = {
+ __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
0, /* null terminated */
};
#endif
@@ -54,9 +36,9 @@ void __secure_computing(int this_syscall)
switch (mode) {
case 1:
syscall = mode1_syscalls;
-#ifdef TIF_IA32
- if (test_thread_flag(TIF_IA32))
- syscall = mode1_syscalls_32bit;
+#ifdef TIF_32BIT
+ if (test_thread_flag(TIF_32BIT))
+ syscall = mode1_syscalls_32;
#endif
do {
if (*syscall == this_syscall)
diff --git a/mm/filemap.c b/mm/filemap.c
index 553681db603d48..439b2bea8e3421 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -172,7 +172,7 @@ static int __filemap_fdatawrite_range(struct address_space *mapping,
.end = end,
};
- if (mapping->backing_dev_info->memory_backed)
+ if (!mapping_cap_writeback_dirty(mapping))
return 0;
ret = do_writepages(mapping, &wbc);
@@ -269,7 +269,7 @@ int sync_page_range(struct inode *inode, struct address_space *mapping,
pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
int ret;
- if (mapping->backing_dev_info->memory_backed || !count)
+ if (!mapping_cap_writeback_dirty(mapping) || !count)
return 0;
ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
if (ret == 0) {
@@ -295,7 +295,7 @@ int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
int ret;
- if (mapping->backing_dev_info->memory_backed || !count)
+ if (!mapping_cap_writeback_dirty(mapping) || !count)
return 0;
ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
if (ret == 0)
diff --git a/mm/nommu.c b/mm/nommu.c
index a9cf49a0e03507..f613db39e84743 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -396,6 +396,7 @@ unsigned long do_mmap_pgoff(struct file *file,
unsigned int vm_flags;
void *result;
int ret, membacked;
+ unsigned long reqprot = prot;
/* do the simple checks first */
if (flags & MAP_FIXED || addr) {
@@ -506,7 +507,7 @@ unsigned long do_mmap_pgoff(struct file *file,
}
/* allow the security API to have its say */
- ret = security_file_mmap(file, prot, flags);
+ ret = security_file_mmap(file, reqprot, prot, flags);
if (ret)
return ret;
@@ -1063,3 +1064,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin)
return -ENOMEM;
}
+int in_gate_area_no_task(unsigned long addr)
+{
+ return 0;
+}
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index ab35f448db18e0..6ddd6a29c73b20 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -627,7 +627,7 @@ int __set_page_dirty_nobuffers(struct page *page)
mapping2 = page_mapping(page);
if (mapping2) { /* Race with truncate? */
BUG_ON(mapping2 != mapping);
- if (!mapping->backing_dev_info->memory_backed)
+ if (mapping_cap_account_dirty(mapping))
inc_page_state(nr_dirty);
radix_tree_tag_set(&mapping->page_tree,
page_index(page), PAGECACHE_TAG_DIRTY);
@@ -713,7 +713,7 @@ int test_clear_page_dirty(struct page *page)
page_index(page),
PAGECACHE_TAG_DIRTY);
write_unlock_irqrestore(&mapping->tree_lock, flags);
- if (!mapping->backing_dev_info->memory_backed)
+ if (mapping_cap_account_dirty(mapping))
dec_page_state(nr_dirty);
return 1;
}
@@ -744,7 +744,7 @@ int clear_page_dirty_for_io(struct page *page)
if (mapping) {
if (TestClearPageDirty(page)) {
- if (!mapping->backing_dev_info->memory_backed)
+ if (mapping_cap_account_dirty(mapping))
dec_page_state(nr_dirty);
return 1;
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e87a9e1809f271..c73dbbc1cd8f5f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -780,6 +780,9 @@ __alloc_pages(unsigned int __nocast gfp_mask, unsigned int order,
/*
* Go through the zonelist again. Let __GFP_HIGH and allocations
* coming from realtime tasks to go deeper into reserves
+ *
+ * This is the last chance, in general, before the goto nopage.
+ * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc.
*/
for (i = 0; (z = zones[i]) != NULL; i++) {
if (!zone_watermark_ok(z, order, z->pages_min,
@@ -787,7 +790,7 @@ __alloc_pages(unsigned int __nocast gfp_mask, unsigned int order,
gfp_mask & __GFP_HIGH))
continue;
- if (!cpuset_zone_allowed(z))
+ if (wait && !cpuset_zone_allowed(z))
continue;
page = buffered_rmqueue(z, order, gfp_mask);
diff --git a/mm/readahead.c b/mm/readahead.c
index 8c4ac1267120f4..b840e7c6ea7404 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -23,6 +23,7 @@ EXPORT_SYMBOL(default_unplug_io_fn);
struct backing_dev_info default_backing_dev_info = {
.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE,
.state = 0,
+ .capabilities = BDI_CAP_MAP_COPY,
.unplug_io_fn = default_unplug_io_fn,
};
EXPORT_SYMBOL_GPL(default_backing_dev_info);
diff --git a/mm/shmem.c b/mm/shmem.c
index c1d60dd5579ef4..61574b81d979f3 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -184,8 +184,8 @@ static struct vm_operations_struct shmem_vm_ops;
static struct backing_dev_info shmem_backing_dev_info = {
.ra_pages = 0, /* No readahead */
- .memory_backed = 1, /* Does not contribute to dirty memory */
- .unplug_io_fn = default_unplug_io_fn,
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+ .unplug_io_fn = default_unplug_io_fn,
};
static LIST_HEAD(shmem_swaplist);
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 994c262ae084d7..a063a902ed0347 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -29,7 +29,7 @@ static struct address_space_operations swap_aops = {
};
static struct backing_dev_info swap_backing_dev_info = {
- .memory_backed = 1, /* Does not contribute to dirty memory */
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
.unplug_io_fn = swap_unplug_io_fn,
};