diff --git a/[refs] b/[refs]
index 444fc807a6c4..e368c8b33b3c 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 51f39eae14b4874618e73281c236e3a1c1572d4d
+refs/heads/master: 103926c689650396901002c3a8c38970fff70391
diff --git a/trunk/.gitignore b/trunk/.gitignore
index 8363e48cdcdc..fdcce40226d7 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -53,3 +53,5 @@ cscope.*
*.orig
*.rej
+*~
+\#*#
diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl
index f31601e8bd89..dc0f30c3e571 100644
--- a/trunk/Documentation/DocBook/kernel-api.tmpl
+++ b/trunk/Documentation/DocBook/kernel-api.tmpl
@@ -361,12 +361,14 @@ X!Edrivers/pnp/system.c
Block Devices
!Eblock/blk-core.c
+!Iblock/blk-core.c
!Eblock/blk-map.c
!Iblock/blk-sysfs.c
!Eblock/blk-settings.c
!Eblock/blk-exec.c
!Eblock/blk-barrier.c
!Eblock/blk-tag.c
+!Iblock/blk-tag.c
diff --git a/trunk/Documentation/controllers/memory.txt b/trunk/Documentation/controllers/memory.txt
index 6015347b41e2..866b9cd9a959 100644
--- a/trunk/Documentation/controllers/memory.txt
+++ b/trunk/Documentation/controllers/memory.txt
@@ -1,4 +1,8 @@
-Memory Controller
+Memory Resource Controller
+
+NOTE: The Memory Resource Controller has been generically been referred
+to as the memory controller in this document. Do not confuse memory controller
+used here with the memory controller that is used in hardware.
Salient features
@@ -152,7 +156,7 @@ The memory controller uses the following hierarchy
a. Enable CONFIG_CGROUPS
b. Enable CONFIG_RESOURCE_COUNTERS
-c. Enable CONFIG_CGROUP_MEM_CONT
+c. Enable CONFIG_CGROUP_MEM_RES_CTLR
1. Prepare the cgroups
# mkdir -p /cgroups
@@ -164,7 +168,7 @@ c. Enable CONFIG_CGROUP_MEM_CONT
Since now we're in the 0 cgroup,
We can alter the memory limit:
-# echo -n 4M > /cgroups/0/memory.limit_in_bytes
+# echo 4M > /cgroups/0/memory.limit_in_bytes
NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo,
mega or gigabytes.
@@ -185,7 +189,7 @@ number of factors, such as rounding up to page boundaries or the total
availability of memory on the system. The user is required to re-read
this file after a write to guarantee the value committed by the kernel.
-# echo -n 1 > memory.limit_in_bytes
+# echo 1 > memory.limit_in_bytes
# cat memory.limit_in_bytes
4096
@@ -197,7 +201,7 @@ caches, RSS and Active pages/Inactive pages are shown.
The memory.force_empty gives an interface to drop *all* charges by force.
-# echo -n 1 > memory.force_empty
+# echo 1 > memory.force_empty
will drop all charges in cgroup. Currently, this is maintained for test.
diff --git a/trunk/Documentation/debugging-via-ohci1394.txt b/trunk/Documentation/debugging-via-ohci1394.txt
index de4804e8b396..c360d4e91b48 100644
--- a/trunk/Documentation/debugging-via-ohci1394.txt
+++ b/trunk/Documentation/debugging-via-ohci1394.txt
@@ -36,14 +36,15 @@ available (notebooks) or too slow for extensive debug information (like ACPI).
Drivers
-------
-The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize
-the OHCI-1394 controllers to a working state and can be used to enable
-physical DMA. By default you only have to load the driver, and physical
-DMA access will be granted to all remote nodes, but it can be turned off
-when using the ohci1394 driver.
-
-Because these drivers depend on the PCI enumeration to be completed, an
-initialization routine which can runs pretty early (long before console_init(),
+The ohci1394 driver in drivers/ieee1394 initializes the OHCI-1394 controllers
+to a working state and enables physical DMA by default for all remote nodes.
+This can be turned off by ohci1394's module parameter phys_dma=0.
+
+The alternative firewire-ohci driver in drivers/firewire uses filtered physical
+DMA, hence is not yet suitable for remote debugging.
+
+Because ohci1394 depends on the PCI enumeration to be completed, an
+initialization routine which runs pretty early (long before console_init()
which makes the printk buffer appear on the console can be called) was written.
To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu:
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 4d3aa519eadf..c1d1fd0c299b 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -172,6 +172,16 @@ Who: Len Brown
---------------------------
+What: ide-tape driver
+When: July 2008
+Files: drivers/ide/ide-tape.c
+Why: This driver might not have any users anymore and maintaining it for no
+ reason is an effort no one wants to make.
+Who: Bartlomiej Zolnierkiewicz , Borislav Petkov
+
+
+---------------------------
+
What: libata spindown skipping and warning
When: Dec 2008
Why: Some halt(8) implementations synchronize caches for and spin
@@ -306,3 +316,15 @@ Why: Largely unmaintained and almost entirely unused. File system
is largely pointless as without a lot of work only the most
trivial of Solaris binaries can work with the emulation code.
Who: David S. Miller
+
+---------------------------
+
+What: init_mm export
+When: 2.6.26
+Why: Not used in-tree. The current out-of-tree users used it to
+ work around problems in the CPA code which should be resolved
+ by now. One usecase was described to provide verification code
+ of the CPA operation. That's a good idea in general, but such
+ code / infrastructure should be in the kernel and not in some
+ out-of-tree driver.
+Who: Thomas Gleixner
diff --git a/trunk/Documentation/gpio.txt b/trunk/Documentation/gpio.txt
index 8da724e2a0ff..54630095aa3c 100644
--- a/trunk/Documentation/gpio.txt
+++ b/trunk/Documentation/gpio.txt
@@ -2,6 +2,9 @@ GPIO Interfaces
This provides an overview of GPIO access conventions on Linux.
+These calls use the gpio_* naming prefix. No other calls should use that
+prefix, or the related __gpio_* prefix.
+
What is a GPIO?
===============
@@ -69,11 +72,13 @@ in this document, but drivers acting as clients to the GPIO interface must
not care how it's implemented.)
That said, if the convention is supported on their platform, drivers should
-use it when possible. Platforms should declare GENERIC_GPIO support in
-Kconfig (boolean true), which multi-platform drivers can depend on when
-using the include file:
+use it when possible. Platforms must declare GENERIC_GPIO support in their
+Kconfig (boolean true), and provide an file. Drivers that can't
+work without standard GPIO calls should have Kconfig entries which depend
+on GENERIC_GPIO. The GPIO calls are available, either as "real code" or as
+optimized-away stubs, when drivers use the include file:
- #include
+ #include
If you stick to this convention then it'll be easier for other developers to
see what your code is doing, and help maintain it.
@@ -316,6 +321,9 @@ pulldowns integrated on some platforms. Not all platforms support them,
or support them in the same way; and any given board might use external
pullups (or pulldowns) so that the on-chip ones should not be used.
(When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.)
+Likewise drive strength (2 mA vs 20 mA) and voltage (1.8V vs 3.3V) is a
+platform-specific issue, as are models like (not) having a one-to-one
+correspondence between configurable pins and GPIOs.
There are other system-specific mechanisms that are not specified here,
like the aforementioned options for input de-glitching and wire-OR output.
diff --git a/trunk/Documentation/i2c/busses/i2c-i801 b/trunk/Documentation/i2c/busses/i2c-i801
index 3bd958360159..c31e0291e167 100644
--- a/trunk/Documentation/i2c/busses/i2c-i801
+++ b/trunk/Documentation/i2c/busses/i2c-i801
@@ -12,8 +12,9 @@ Supported adapters:
* Intel 82801G (ICH7)
* Intel 631xESB/632xESB (ESB2)
* Intel 82801H (ICH8)
- * Intel ICH9
+ * Intel 82801I (ICH9)
* Intel Tolapai
+ * Intel ICH10
Datasheets: Publicly available at the Intel website
Authors:
diff --git a/trunk/Documentation/ide.txt b/trunk/Documentation/ide.txt
index 94e2e3b9e77f..bcd7cd1278ef 100644
--- a/trunk/Documentation/ide.txt
+++ b/trunk/Documentation/ide.txt
@@ -258,8 +258,6 @@ Summary of ide driver parameters for kernel command line
As for VLB, it is safest to not specify it.
Bigger values are safer than smaller ones.
- "idex=noprobe" : do not attempt to access/use this interface
-
"idex=base" : probe for an interface at the addr specified,
where "base" is usually 0x1f0 or 0x170
and "ctl" is assumed to be "base"+0x206
@@ -307,53 +305,6 @@ Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb"
kernel paremeter to enable probing for VLB version of the chipset (PCI ones
are detected automatically).
-================================================================================
-
-IDE ATAPI streaming tape driver
--------------------------------
-
-This driver is a part of the Linux ide driver and works in co-operation
-with linux/drivers/block/ide.c.
-
-The driver, in co-operation with ide.c, basically traverses the
-request-list for the block device interface. The character device
-interface, on the other hand, creates new requests, adds them
-to the request-list of the block device, and waits for their completion.
-
-Pipelined operation mode is now supported on both reads and writes.
-
-The block device major and minor numbers are determined from the
-tape's relative position in the ide interfaces, as explained in ide.c.
-
-The character device interface consists of the following devices:
-
- ht0 major 37, minor 0 first IDE tape, rewind on close.
- ht1 major 37, minor 1 second IDE tape, rewind on close.
- ...
- nht0 major 37, minor 128 first IDE tape, no rewind on close.
- nht1 major 37, minor 129 second IDE tape, no rewind on close.
- ...
-
-Run /dev/MAKEDEV to create the above entries.
-
-The general magnetic tape commands compatible interface, as defined by
-include/linux/mtio.h, is accessible through the character device.
-
-General ide driver configuration options, such as the interrupt-unmask
-flag, can be configured by issuing an ioctl to the block device interface,
-as any other ide device.
-
-Our own ide-tape ioctl's can be issued to either the block device or
-the character device interface.
-
-Maximal throughput with minimal bus load will usually be achieved in the
-following scenario:
-
- 1. ide-tape is operating in the pipelined operation mode.
- 2. No buffering is performed by the user backup program.
-
-
-
================================================================================
Some Terminology
diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt
index 83f515c2905a..be89f393274f 100644
--- a/trunk/Documentation/kprobes.txt
+++ b/trunk/Documentation/kprobes.txt
@@ -192,7 +192,8 @@ code mapping.
The Kprobes API includes a "register" function and an "unregister"
function for each type of probe. Here are terse, mini-man-page
specifications for these functions and the associated probe handlers
-that you'll write. See the latter half of this document for examples.
+that you'll write. See the files in the samples/kprobes/ sub-directory
+for examples.
4.1 register_kprobe
@@ -420,249 +421,15 @@ e. Watchpoint probes (which fire on data references).
8. Kprobes Example
-Here's a sample kernel module showing the use of kprobes to dump a
-stack trace and selected i386 registers when do_fork() is called.
------ cut here -----
-/*kprobe_example.c*/
-#include
-#include
-#include
-#include
-
-/*For each probe you need to allocate a kprobe structure*/
-static struct kprobe kp;
-
-/*kprobe pre_handler: called just before the probed instruction is executed*/
-int handler_pre(struct kprobe *p, struct pt_regs *regs)
-{
- printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n",
- p->addr, regs->eip, regs->eflags);
- dump_stack();
- return 0;
-}
-
-/*kprobe post_handler: called after the probed instruction is executed*/
-void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
-{
- printk("post_handler: p->addr=0x%p, eflags=0x%lx\n",
- p->addr, regs->eflags);
-}
-
-/* fault_handler: this is called if an exception is generated for any
- * instruction within the pre- or post-handler, or when Kprobes
- * single-steps the probed instruction.
- */
-int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
-{
- printk("fault_handler: p->addr=0x%p, trap #%dn",
- p->addr, trapnr);
- /* Return 0 because we don't handle the fault. */
- return 0;
-}
-
-static int __init kprobe_init(void)
-{
- int ret;
- kp.pre_handler = handler_pre;
- kp.post_handler = handler_post;
- kp.fault_handler = handler_fault;
- kp.symbol_name = "do_fork";
-
- ret = register_kprobe(&kp);
- if (ret < 0) {
- printk("register_kprobe failed, returned %d\n", ret);
- return ret;
- }
- printk("kprobe registered\n");
- return 0;
-}
-
-static void __exit kprobe_exit(void)
-{
- unregister_kprobe(&kp);
- printk("kprobe unregistered\n");
-}
-
-module_init(kprobe_init)
-module_exit(kprobe_exit)
-MODULE_LICENSE("GPL");
------ cut here -----
-
-You can build the kernel module, kprobe-example.ko, using the following
-Makefile:
------ cut here -----
-obj-m := kprobe-example.o
-KDIR := /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-default:
- $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
-clean:
- rm -f *.mod.c *.ko *.o
------ cut here -----
-
-$ make
-$ su -
-...
-# insmod kprobe-example.ko
-
-You will see the trace data in /var/log/messages and on the console
-whenever do_fork() is invoked to create a new process.
+See samples/kprobes/kprobe_example.c
9. Jprobes Example
-Here's a sample kernel module showing the use of jprobes to dump
-the arguments of do_fork().
------ cut here -----
-/*jprobe-example.c */
-#include
-#include
-#include
-#include
-#include
-
-/*
- * Jumper probe for do_fork.
- * Mirror principle enables access to arguments of the probed routine
- * from the probe handler.
- */
-
-/* Proxy routine having the same arguments as actual do_fork() routine */
-long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
- struct pt_regs *regs, unsigned long stack_size,
- int __user * parent_tidptr, int __user * child_tidptr)
-{
- printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n",
- clone_flags, stack_size, regs);
- /* Always end with a call to jprobe_return(). */
- jprobe_return();
- /*NOTREACHED*/
- return 0;
-}
-
-static struct jprobe my_jprobe = {
- .entry = jdo_fork
-};
-
-static int __init jprobe_init(void)
-{
- int ret;
- my_jprobe.kp.symbol_name = "do_fork";
-
- if ((ret = register_jprobe(&my_jprobe)) <0) {
- printk("register_jprobe failed, returned %d\n", ret);
- return -1;
- }
- printk("Planted jprobe at %p, handler addr %p\n",
- my_jprobe.kp.addr, my_jprobe.entry);
- return 0;
-}
-
-static void __exit jprobe_exit(void)
-{
- unregister_jprobe(&my_jprobe);
- printk("jprobe unregistered\n");
-}
-
-module_init(jprobe_init)
-module_exit(jprobe_exit)
-MODULE_LICENSE("GPL");
------ cut here -----
-
-Build and insert the kernel module as shown in the above kprobe
-example. You will see the trace data in /var/log/messages and on
-the console whenever do_fork() is invoked to create a new process.
-(Some messages may be suppressed if syslogd is configured to
-eliminate duplicate messages.)
+See samples/kprobes/jprobe_example.c
10. Kretprobes Example
-Here's a sample kernel module showing the use of return probes to
-report failed calls to sys_open().
------ cut here -----
-/*kretprobe-example.c*/
-#include
-#include
-#include
-#include
-
-/* per-instance private data */
-struct my_data {
- ktime_t entry_stamp;
-};
-
-static const char *probed_func = "sys_open";
-
-/* Timestamp function entry. */
-static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- struct my_data *data;
-
- if(!current->mm)
- return 1; /* skip kernel threads */
-
- data = (struct my_data *)ri->data;
- data->entry_stamp = ktime_get();
- return 0;
-}
-
-/* If the probed function failed, log the return value and duration.
- * Duration may turn out to be zero consistently, depending upon the
- * granularity of time accounting on the platform. */
-static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
- int retval = regs_return_value(regs);
- struct my_data *data = (struct my_data *)ri->data;
- s64 delta;
- ktime_t now;
-
- if (retval < 0) {
- now = ktime_get();
- delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
- printk("%s: return val = %d (duration = %lld ns)\n",
- probed_func, retval, delta);
- }
- return 0;
-}
-
-static struct kretprobe my_kretprobe = {
- .handler = return_handler,
- .entry_handler = entry_handler,
- .data_size = sizeof(struct my_data),
- .maxactive = 20, /* probe up to 20 instances concurrently */
-};
-
-static int __init kretprobe_init(void)
-{
- int ret;
- my_kretprobe.kp.symbol_name = (char *)probed_func;
-
- if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
- printk("register_kretprobe failed, returned %d\n", ret);
- return -1;
- }
- printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name);
- return 0;
-}
-
-static void __exit kretprobe_exit(void)
-{
- unregister_kretprobe(&my_kretprobe);
- printk("kretprobe unregistered\n");
- /* nmissed > 0 suggests that maxactive was set too low. */
- printk("Missed probing %d instances of %s\n",
- my_kretprobe.nmissed, probed_func);
-}
-
-module_init(kretprobe_init)
-module_exit(kretprobe_exit)
-MODULE_LICENSE("GPL");
------ cut here -----
-
-Build and insert the kernel module as shown in the above kprobe
-example. You will see the trace data in /var/log/messages and on the
-console whenever sys_open() returns a negative value. (Some messages
-may be suppressed if syslogd is configured to eliminate duplicate
-messages.)
+See samples/kprobes/kretprobe_example.c
For additional information on Kprobes, refer to the following URLs:
http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
diff --git a/trunk/Documentation/pci.txt b/trunk/Documentation/pci.txt
index 72b20c639596..bb7bd27d4682 100644
--- a/trunk/Documentation/pci.txt
+++ b/trunk/Documentation/pci.txt
@@ -123,7 +123,8 @@ initialization with a pointer to a structure describing the driver
The ID table is an array of struct pci_device_id entries ending with an
-all-zero entry. Each entry consists of:
+all-zero entry; use of the macro DECLARE_PCI_DEVICE_TABLE is the preferred
+method of declaring the table. Each entry consists of:
vendor,device Vendor and device ID to match (or PCI_ANY_ID)
@@ -191,7 +192,8 @@ Tips on when/where to use the above attributes:
o Do not mark the struct pci_driver.
- o The ID table array should be marked __devinitdata.
+ o The ID table array should be marked __devinitconst; this is done
+ automatically if the table is declared with DECLARE_PCI_DEVICE_TABLE().
o The probe() and remove() functions should be marked __devinit
and __devexit respectively. All initialization functions
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 36c7bc641dba..558636e3a954 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -767,14 +767,14 @@ S: Maintained
BLACKFIN ARCHITECTURE
P: Bryan Wu
-M: bryan.wu@analog.com
+M: cooloney@kernel.org
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
BLACKFIN EMAC DRIVER
P: Bryan Wu
-M: bryan.wu@analog.com
+M: cooloney@kernel.org
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
@@ -982,6 +982,12 @@ M: mchan@broadcom.com
L: netdev@vger.kernel.org
S: Supported
+BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
+P: Eliezer Tamir
+M: eliezert@broadcom.com
+L: netdev@vger.kernel.org
+S: Supported
+
BROADCOM TG3 GIGABIT ETHERNET DRIVER
P: Michael Chan
M: mchan@broadcom.com
@@ -1132,6 +1138,12 @@ L: accessrunner-general@lists.sourceforge.net
W: http://accessrunner.sourceforge.net/
S: Maintained
+CONTROL GROUPS (CGROUPS)
+P: Paul Menage
+M: menage@google.com
+L: containers@lists.linux-foundation.org
+S: Maintained
+
CORETEMP HARDWARE MONITORING DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
@@ -1583,6 +1595,13 @@ L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
W: http://linux-fbdev.sourceforge.net/
S: Maintained
+FREESCALE DMA DRIVER
+P; Zhang Wei
+M: wei.zhang@freescale.com
+L: linuxppc-embedded@ozlabs.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
FREESCALE SOC FS_ENET DRIVER
P: Pantelis Antoniou
M: pantelis.antoniou@gmail.com
@@ -2620,6 +2639,17 @@ L: linux-kernel@vger.kernel.org
W: http://www.linux-mm.org
S: Maintained
+MEMORY RESOURCE CONTROLLER
+P: Balbir Singh
+M: balbir@linux.vnet.ibm.com
+P: Pavel Emelyanov
+M: xemul@openvz.org
+P: KAMEZAWA Hiroyuki
+M: kamezawa.hiroyu@jp.fujitsu.com
+L: linux-mm@kvack.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
MEI MN10300/AM33 PORT
P: David Howells
M: dhowells@redhat.com
@@ -2744,6 +2774,8 @@ S: Maintained
NETEFFECT IWARP RNIC DRIVER (IW_NES)
P: Faisal Latif
M: flatif@neteffect.com
+P: Nishi Gupta
+M: ngupta@neteffect.com
P: Glenn Streiff
M: gstreiff@neteffect.com
L: general@lists.openfabrics.org
@@ -3884,10 +3916,13 @@ M: trivial@kernel.org
L: linux-kernel@vger.kernel.org
S: Maintained
-TULIP NETWORK DRIVER
-L: tulip-users@lists.sourceforge.net
-W: http://sourceforge.net/projects/tulip/
-S: Orphan
+TULIP NETWORK DRIVERS
+P: Grant Grundler
+M: grundler@parisc-linux.org
+P: Kyle McMartin
+M: kyle@parisc-linux.org
+L: netdev@vger.kernel.org
+S: Maintained
TUN/TAP driver
P: Maxim Krasnyansky
diff --git a/trunk/Makefile b/trunk/Makefile
index 99300dc680e9..ae78a31a9de2 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 25
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc4
NAME = Funky Weasel is Jiggy wit it
# *DOCUMENTATION*
diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig
index 3d72dc3fc8f5..694c9af520bb 100644
--- a/trunk/arch/Kconfig
+++ b/trunk/arch/Kconfig
@@ -27,5 +27,12 @@ config KPROBES
for kernel debugging, non-intrusive instrumentation and testing.
If in doubt, say "N".
+config KRETPROBES
+ def_bool y
+ depends on KPROBES && HAVE_KRETPROBES
+
config HAVE_KPROBES
def_bool n
+
+config HAVE_KRETPROBES
+ def_bool n
diff --git a/trunk/arch/alpha/kernel/pci_iommu.c b/trunk/arch/alpha/kernel/pci_iommu.c
index 26d3789dfdd0..be6fa105cd34 100644
--- a/trunk/arch/alpha/kernel/pci_iommu.c
+++ b/trunk/arch/alpha/kernel/pci_iommu.c
@@ -31,7 +31,6 @@
#endif
#define DEBUG_NODIRECT 0
-#define DEBUG_FORCEDAC 0
#define ISA_DMA_MASK 0x00ffffff
@@ -126,39 +125,67 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
return iommu_arena_new_node(0, hose, base, window_size, align);
}
+static inline int is_span_boundary(unsigned int index, unsigned int nr,
+ unsigned long shift,
+ unsigned long boundary_size)
+{
+ shift = (shift + index) & (boundary_size - 1);
+ return shift + nr > boundary_size;
+}
+
/* Must be called with the arena lock held */
static long
-iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
+iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena,
+ long n, long mask)
{
unsigned long *ptes;
long i, p, nent;
+ int pass = 0;
+ unsigned long base;
+ unsigned long boundary_size;
+
+ BUG_ON(arena->dma_base & ~PAGE_MASK);
+ base = arena->dma_base >> PAGE_SHIFT;
+ if (dev)
+ boundary_size = ALIGN(dma_get_max_seg_size(dev) + 1, PAGE_SIZE)
+ >> PAGE_SHIFT;
+ else
+ boundary_size = ALIGN(1UL << 32, PAGE_SIZE) >> PAGE_SHIFT;
+
+ BUG_ON(!is_power_of_2(boundary_size));
/* Search forward for the first mask-aligned sequence of N free ptes */
ptes = arena->ptes;
nent = arena->size >> PAGE_SHIFT;
- p = (arena->next_entry + mask) & ~mask;
+ p = ALIGN(arena->next_entry, mask + 1);
i = 0;
+
+again:
while (i < n && p+i < nent) {
+ if (!i && is_span_boundary(p, n, base, boundary_size)) {
+ p = ALIGN(p + 1, mask + 1);
+ goto again;
+ }
+
if (ptes[p+i])
- p = (p + i + 1 + mask) & ~mask, i = 0;
+ p = ALIGN(p + i + 1, mask + 1), i = 0;
else
i = i + 1;
}
if (i < n) {
- /* Reached the end. Flush the TLB and restart the
- search from the beginning. */
- alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
-
- p = 0, i = 0;
- while (i < n && p+i < nent) {
- if (ptes[p+i])
- p = (p + i + 1 + mask) & ~mask, i = 0;
- else
- i = i + 1;
- }
-
- if (i < n)
+ if (pass < 1) {
+ /*
+ * Reached the end. Flush the TLB and restart
+ * the search from the beginning.
+ */
+ alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
+
+ pass++;
+ p = 0;
+ i = 0;
+ goto again;
+ } else
return -1;
}
@@ -168,7 +195,8 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask)
}
static long
-iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align)
+iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n,
+ unsigned int align)
{
unsigned long flags;
unsigned long *ptes;
@@ -179,7 +207,7 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align)
/* Search for N empty ptes */
ptes = arena->ptes;
mask = max(align, arena->align_entry) - 1;
- p = iommu_arena_find_pages(arena, n, mask);
+ p = iommu_arena_find_pages(dev, arena, n, mask);
if (p < 0) {
spin_unlock_irqrestore(&arena->lock, flags);
return -1;
@@ -229,6 +257,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
unsigned long paddr;
dma_addr_t ret;
unsigned int align = 0;
+ struct device *dev = pdev ? &pdev->dev : NULL;
paddr = __pa(cpu_addr);
@@ -276,7 +305,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
/* Force allocation to 64KB boundary for ISA bridges. */
if (pdev && pdev == isa_bridge)
align = 8;
- dma_ofs = iommu_arena_alloc(arena, npages, align);
+ dma_ofs = iommu_arena_alloc(dev, arena, npages, align);
if (dma_ofs < 0) {
printk(KERN_WARNING "pci_map_single failed: "
"could not allocate dma page tables\n");
@@ -563,7 +592,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
paddr &= ~PAGE_MASK;
npages = calc_npages(paddr + size);
- dma_ofs = iommu_arena_alloc(arena, npages, 0);
+ dma_ofs = iommu_arena_alloc(dev, arena, npages, 0);
if (dma_ofs < 0) {
/* If we attempted a direct map above but failed, die. */
if (leader->dma_address == 0)
@@ -830,7 +859,7 @@ iommu_reserve(struct pci_iommu_arena *arena, long pg_count, long align_mask)
/* Search for N empty ptes. */
ptes = arena->ptes;
- p = iommu_arena_find_pages(arena, pg_count, align_mask);
+ p = iommu_arena_find_pages(NULL, arena, pg_count, align_mask);
if (p < 0) {
spin_unlock_irqrestore(&arena->lock, flags);
return -1;
diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig
index 9619c43783ff..955fc53c1c01 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -12,6 +12,7 @@ config ARM
select SYS_SUPPORTS_APM_EMULATION
select HAVE_OPROFILE
select HAVE_KPROBES if (!XIP_KERNEL)
+ select HAVE_KRETPROBES if (HAVE_KPROBES)
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -939,7 +940,8 @@ config KEXEC
config ATAGS_PROC
bool "Export atags in procfs"
- default n
+ depends on KEXEC
+ default y
help
Should the atags used to boot the kernel be exported in an "atags"
file in procfs. Useful with kexec.
diff --git a/trunk/arch/arm/mach-omap1/board-sx1.c b/trunk/arch/arm/mach-omap1/board-sx1.c
index 1c7f09aedf07..e473fa6d4a5f 100644
--- a/trunk/arch/arm/mach-omap1/board-sx1.c
+++ b/trunk/arch/arm/mach-omap1/board-sx1.c
@@ -61,6 +61,7 @@ int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
data[0] = regoffset; /* register num */
data[1] = value; /* register data */
err = i2c_transfer(adap, msg, 1);
+ i2c_put_adapter(adap);
if (err >= 0)
return 0;
return err;
@@ -91,6 +92,7 @@ int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
msg->buf = data;
err = i2c_transfer(adap, msg, 1);
*value = data[0];
+ i2c_put_adapter(adap);
if (err >= 0)
return 0;
diff --git a/trunk/arch/arm/mach-pxa/cpu-pxa.c b/trunk/arch/arm/mach-pxa/cpu-pxa.c
index 939a3867f77c..4b21479332ae 100644
--- a/trunk/arch/arm/mach-pxa/cpu-pxa.c
+++ b/trunk/arch/arm/mach-pxa/cpu-pxa.c
@@ -43,7 +43,7 @@
#ifdef DEBUG
static unsigned int freq_debug;
-MODULE_PARM(freq_debug, "i");
+module_param(freq_debug, uint, 0);
MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
#else
#define freq_debug 0
diff --git a/trunk/arch/arm/mach-pxa/pxa3xx.c b/trunk/arch/arm/mach-pxa/pxa3xx.c
index 7cd9ef8deb02..35f25fdaeba3 100644
--- a/trunk/arch/arm/mach-pxa/pxa3xx.c
+++ b/trunk/arch/arm/mach-pxa/pxa3xx.c
@@ -129,28 +129,20 @@ static void clk_pxa3xx_cken_enable(struct clk *clk)
{
unsigned long mask = 1ul << (clk->cken & 0x1f);
- local_irq_disable();
-
if (clk->cken < 32)
CKENA |= mask;
else
CKENB |= mask;
-
- local_irq_enable();
}
static void clk_pxa3xx_cken_disable(struct clk *clk)
{
unsigned long mask = 1ul << (clk->cken & 0x1f);
- local_irq_disable();
-
if (clk->cken < 32)
CKENA &= ~mask;
else
CKENB &= ~mask;
-
- local_irq_enable();
}
static const struct clkops clk_pxa3xx_cken_ops = {
diff --git a/trunk/arch/arm/mach-pxa/zylonite.c b/trunk/arch/arm/mach-pxa/zylonite.c
index 7731d50dd86c..afd2cbfca0d9 100644
--- a/trunk/arch/arm/mach-pxa/zylonite.c
+++ b/trunk/arch/arm/mach-pxa/zylonite.c
@@ -58,7 +58,7 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
-#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static void zylonite_backlight_power(int on)
{
gpio_set_value(gpio_backlight, on);
diff --git a/trunk/arch/arm/mm/mmap.c b/trunk/arch/arm/mm/mmap.c
index 2728b0e7d2bb..3f6dc40b8353 100644
--- a/trunk/arch/arm/mm/mmap.c
+++ b/trunk/arch/arm/mm/mmap.c
@@ -120,6 +120,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
*/
int valid_phys_addr_range(unsigned long addr, size_t size)
{
+ if (addr < PHYS_OFFSET)
+ return 0;
if (addr + size > __pa(high_memory))
return 0;
diff --git a/trunk/arch/arm/mm/pgd.c b/trunk/arch/arm/mm/pgd.c
index 500c9610ab30..e0f19ab91163 100644
--- a/trunk/arch/arm/mm/pgd.c
+++ b/trunk/arch/arm/mm/pgd.c
@@ -75,7 +75,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
{
pmd_t *pmd;
- struct page *pte;
+ pgtable_t pte;
if (!pgd)
return;
@@ -90,10 +90,8 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
goto free;
}
- pte = pmd_page(*pmd);
+ pte = pmd_pgtable(*pmd);
pmd_clear(pmd);
- dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
- pte_lock_deinit(pte);
pte_free(mm, pte);
pmd_free(mm, pmd);
free:
diff --git a/trunk/arch/avr32/boards/atstk1000/atstk1004.c b/trunk/arch/avr32/boards/atstk1000/atstk1004.c
index 5a77030e07a0..e765a8652b3e 100644
--- a/trunk/arch/avr32/boards/atstk1000/atstk1004.c
+++ b/trunk/arch/avr32/boards/atstk1000/atstk1004.c
@@ -129,7 +129,7 @@ static int __init atstk1004_init(void)
#ifdef CONFIG_BOARD_ATSTK100X_SPI1
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif
-#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_mci(0);
#endif
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
diff --git a/trunk/arch/avr32/kernel/process.c b/trunk/arch/avr32/kernel/process.c
index eaaa69bbdc38..7f4af0b1e111 100644
--- a/trunk/arch/avr32/kernel/process.c
+++ b/trunk/arch/avr32/kernel/process.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
@@ -30,8 +31,10 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
+ tick_nohz_stop_sched_tick();
while (!need_resched())
cpu_idle_sleep();
+ tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
preempt_disable();
@@ -345,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.cpu_context.ksp = (unsigned long)childregs;
p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
+ clear_tsk_thread_flag(p, TIF_DEBUG);
if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
ocd_enable(p);
diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c
index 6560cb18b4e3..ce4e4296b954 100644
--- a/trunk/arch/avr32/mm/fault.c
+++ b/trunk/arch/avr32/mm/fault.c
@@ -189,6 +189,8 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
page = sysreg_read(PTBR);
printk(KERN_ALERT "ptbr = %08lx", page);
+ if (address >= TASK_SIZE)
+ page = (unsigned long)swapper_pg_dir;
if (page) {
page = ((unsigned long *)page)[address >> 22];
printk(" pgd = %08lx", page);
diff --git a/trunk/arch/blackfin/Makefile b/trunk/arch/blackfin/Makefile
index fe254f886a6e..75eba2ca7881 100644
--- a/trunk/arch/blackfin/Makefile
+++ b/trunk/arch/blackfin/Makefile
@@ -98,8 +98,11 @@ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/
# them changed. We use .mach to indicate when they were updated
# last, otherwise make uses the target directory mtime.
+ show_mach_symlink = :
+ quiet_show_mach_symlink = echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
+silent_show_mach_symlink = :
include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf
- @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
+ @$($(quiet)show_mach_symlink)
ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p include/asm-$(ARCH)
$(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach
diff --git a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig
index d59ee1530bd4..ae320dcfedef 100644
--- a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22.14
-# Thu Nov 29 17:32:47 2007
+# Linux kernel version: 2.6.22.16
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -116,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
# Processor and Board Settings
#
# CONFIG_BF522 is not set
+# CONFIG_BF523 is not set
+# CONFIG_BF524 is not set
# CONFIG_BF525 is not set
+# CONFIG_BF526 is not set
CONFIG_BF527=y
# CONFIG_BF531 is not set
# CONFIG_BF532 is not set
@@ -306,6 +308,7 @@ CONFIG_BFIN_DCACHE=y
# CONFIG_BFIN_WB is not set
CONFIG_BFIN_WT=y
CONFIG_L1_MAX_PIECE=16
+# CONFIG_MPU is not set
#
# Asynchonous Memory Configuration
@@ -354,6 +357,7 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# Networking
@@ -496,7 +500,6 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_INTELEXT is not set
# CONFIG_MTD_CFI_AMDSTD is not set
# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_MW320D=m
CONFIG_MTD_RAM=y
CONFIG_MTD_ROM=m
# CONFIG_MTD_ABSENT is not set
@@ -506,9 +509,6 @@ CONFIG_MTD_ROM=m
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_BF5xx=m
-CONFIG_BFIN_FLASH_SIZE=0x400000
-CONFIG_EBIU_FLASH_BASE=0x20000000
# CONFIG_MTD_UCLINUX is not set
# CONFIG_MTD_PLATRAM is not set
@@ -684,7 +684,6 @@ CONFIG_INPUT_MISC=y
# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_UINPUT is not set
-# CONFIG_BF53X_PFBUTTONS is not set
# CONFIG_TWI_KEYPAD is not set
#
@@ -702,12 +701,12 @@ CONFIG_INPUT_MISC=y
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
# CONFIG_BF5xx_PPI is not set
+CONFIG_BFIN_OTP=y
+# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
# CONFIG_BFIN_SPORT is not set
# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_TWI_LCD is not set
# CONFIG_AD5304 is not set
-# CONFIG_BF5xx_TEA5764 is not set
-# CONFIG_BF5xx_FBDMA is not set
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
@@ -772,7 +771,6 @@ CONFIG_I2C_CHARDEV=m
#
# I2C Hardware Bus support
#
-# CONFIG_I2C_BLACKFIN_GPIO is not set
CONFIG_I2C_BLACKFIN_TWI=m
CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
# CONFIG_I2C_GPIO is not set
diff --git a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig
index 811711f59a25..9621caa60b5f 100644
--- a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -322,10 +322,9 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+CONFIG_PM_BFIN_SLEEP_DEEPER=y
+# CONFIG_PM_BFIN_SLEEP is not set
# CONFIG_PM_WAKEUP_BY_GPIO is not set
-# CONFIG_PM_WAKEUP_GPIO_API is not set
-CONFIG_PM_WAKEUP_SIC_IWR=0x80
#
# CPU Frequency scaling
@@ -697,7 +696,6 @@ CONFIG_SERIAL_BFIN_DMA=y
# CONFIG_SERIAL_BFIN_PIO is not set
CONFIG_SERIAL_BFIN_UART0=y
# CONFIG_BFIN_UART0_CTSRTS is not set
-# CONFIG_SERIAL_BFIN_UART1 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
diff --git a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig
index 198f4123af4b..b51e76ce7f4f 100644
--- a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -323,10 +323,9 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+CONFIG_PM_BFIN_SLEEP_DEEPER=y
+# CONFIG_PM_BFIN_SLEEP is not set
# CONFIG_PM_WAKEUP_BY_GPIO is not set
-# CONFIG_PM_WAKEUP_GPIO_API is not set
-CONFIG_PM_WAKEUP_SIC_IWR=0x80
#
# CPU Frequency scaling
@@ -714,7 +713,6 @@ CONFIG_SERIAL_BFIN_DMA=y
# CONFIG_SERIAL_BFIN_PIO is not set
CONFIG_SERIAL_BFIN_UART0=y
# CONFIG_BFIN_UART0_CTSRTS is not set
-# CONFIG_SERIAL_BFIN_UART1 is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_BFIN_SPORT is not set
diff --git a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig
index b37ccc681e7a..d45fa535dad7 100644
--- a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -330,10 +330,9 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+CONFIG_PM_BFIN_SLEEP_DEEPER=y
+# CONFIG_PM_BFIN_SLEEP is not set
# CONFIG_PM_WAKEUP_BY_GPIO is not set
-# CONFIG_PM_WAKEUP_GPIO_API is not set
-CONFIG_PM_WAKEUP_SIC_IWR=0x8
#
# CPU Frequency scaling
@@ -1013,6 +1012,7 @@ CONFIG_SND_BFIN_AD73311_SE=4
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC=m
CONFIG_SND_BF5XX_SOC=m
+CONFIG_SND_MMAP_SUPPORT=y
CONFIG_SND_BF5XX_SOC_AC97=m
# CONFIG_SND_BF5XX_SOC_WM8750 is not set
# CONFIG_SND_BF5XX_SOC_WM8731 is not set
diff --git a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig
index fd702161ef59..c9707f7665ad 100644
--- a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -396,6 +396,7 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -1075,6 +1076,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC=y
CONFIG_SND_BF5XX_SOC=y
+CONFIG_SND_MMAP_SUPPORT=y
CONFIG_SND_BF5XX_SOC_AC97=y
CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y
# CONFIG_SND_BF5XX_SOC_WM8750 is not set
diff --git a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig
index 8546994939fb..4d8a63331309 100644
--- a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -367,6 +367,7 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# Networking
diff --git a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c
index 5453bc3664fc..8fd5d22cec34 100644
--- a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -105,13 +105,14 @@ int request_dma(unsigned int channel, char *device_id)
mutex_unlock(&(dma_ch[channel].dmalock));
#ifdef CONFIG_BF54x
- if (channel >= CH_UART2_RX && channel <= CH_UART3_TX &&
- strncmp(device_id, "BFIN_UART", 9) == 0)
- dma_ch[channel].regs->peripheral_map |=
- (channel - CH_UART2_RX + 0xC);
- else
- dma_ch[channel].regs->peripheral_map |=
- (channel - CH_UART2_RX + 0x6);
+ if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) {
+ if (strncmp(device_id, "BFIN_UART", 9) == 0)
+ dma_ch[channel].regs->peripheral_map |=
+ (channel - CH_UART2_RX + 0xC);
+ else
+ dma_ch[channel].regs->peripheral_map |=
+ (channel - CH_UART2_RX + 0x6);
+ }
#endif
dma_ch[channel].device_id = device_id;
diff --git a/trunk/arch/blackfin/kernel/gptimers.c b/trunk/arch/blackfin/kernel/gptimers.c
index 5cf4bdb1df3b..1904d8b53328 100644
--- a/trunk/arch/blackfin/kernel/gptimers.c
+++ b/trunk/arch/blackfin/kernel/gptimers.c
@@ -1,9 +1,9 @@
/*
- * bfin_gptimers.c - derived from bf53x_timers.c
- * Driver for General Purpose Timer functions on the Blackfin processor
+ * gptimers.c - Blackfin General Purpose Timer core API
*
- * Copyright (C) 2005 John DeHority
- * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
*
* Licensed under the GPLv2.
*/
diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c
index 8229b1090eb9..2255c289a714 100644
--- a/trunk/arch/blackfin/kernel/setup.c
+++ b/trunk/arch/blackfin/kernel/setup.c
@@ -32,6 +32,7 @@
static DEFINE_PER_CPU(struct cpu, cpu_devices);
u16 _bfin_swrst;
+EXPORT_SYMBOL(_bfin_swrst);
unsigned long memory_start, memory_end, physical_mem_end;
unsigned long reserved_mem_dcache_on;
@@ -514,6 +515,7 @@ static __init void memory_setup(void)
printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
printk(KERN_INFO "Memory map:\n"
+ KERN_INFO " fixedcode = 0x%p-0x%p\n"
KERN_INFO " text = 0x%p-0x%p\n"
KERN_INFO " rodata = 0x%p-0x%p\n"
KERN_INFO " bss = 0x%p-0x%p\n"
@@ -527,7 +529,8 @@ static __init void memory_setup(void)
#if DMA_UNCACHED_REGION > 0
KERN_INFO " DMA Zone = 0x%p-0x%p\n"
#endif
- , _stext, _etext,
+ , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END,
+ _stext, _etext,
__start_rodata, __end_rodata,
__bss_start, __bss_stop,
_sdata, _edata,
diff --git a/trunk/arch/blackfin/kernel/vmlinux.lds.S b/trunk/arch/blackfin/kernel/vmlinux.lds.S
index aed832540b3b..cb01a9de2680 100644
--- a/trunk/arch/blackfin/kernel/vmlinux.lds.S
+++ b/trunk/arch/blackfin/kernel/vmlinux.lds.S
@@ -147,44 +147,64 @@ SECTIONS
__l1_lma_start = .;
+#if L1_CODE_LENGTH
+# define LDS_L1_CODE *(.l1.text)
+#else
+# define LDS_L1_CODE
+#endif
.text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs))
{
. = ALIGN(4);
__stext_l1 = .;
- *(.l1.text)
-
+ LDS_L1_CODE
. = ALIGN(4);
__etext_l1 = .;
}
+#if L1_DATA_A_LENGTH
+# define LDS_L1_A_DATA *(.l1.data)
+# define LDS_L1_A_BSS *(.l1.bss)
+# define LDS_L1_A_CACHE *(.data_l1.cacheline_aligned)
+#else
+# define LDS_L1_A_DATA
+# define LDS_L1_A_BSS
+# define LDS_L1_A_CACHE
+#endif
.data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1))
{
. = ALIGN(4);
__sdata_l1 = .;
- *(.l1.data)
+ LDS_L1_A_DATA
__edata_l1 = .;
. = ALIGN(4);
__sbss_l1 = .;
- *(.l1.bss)
+ LDS_L1_A_BSS
. = ALIGN(32);
- *(.data_l1.cacheline_aligned)
+ LDS_L1_A_CACHE
. = ALIGN(4);
__ebss_l1 = .;
}
+#if L1_DATA_B_LENGTH
+# define LDS_L1_B_DATA *(.l1.data.B)
+# define LDS_L1_B_BSS *(.l1.bss.B)
+#else
+# define LDS_L1_B_DATA
+# define LDS_L1_B_BSS
+#endif
.data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
{
. = ALIGN(4);
__sdata_b_l1 = .;
- *(.l1.data.B)
+ LDS_L1_B_DATA
__edata_b_l1 = .;
. = ALIGN(4);
__sbss_b_l1 = .;
- *(.l1.bss.B)
+ LDS_L1_B_BSS
. = ALIGN(4);
__ebss_b_l1 = .;
diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c
index 337515fba612..cf4bc0d83355 100644
--- a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -180,8 +180,8 @@ static struct mtd_partition partition_info[] = {
},
{
.name = "File System",
- .offset = 4 * SIZE_1M,
- .size = (256 - 4) * SIZE_1M,
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
},
};
@@ -422,11 +422,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -484,13 +484,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
.enable_dma = 0,
@@ -611,17 +604,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
{
.modalias = "ad7877",
@@ -818,6 +800,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
&bf5xx_nand_device,
@@ -895,6 +890,8 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
#endif
+
+ &bfin_gpios_device,
};
static int __init stamp_init(void)
@@ -921,13 +918,18 @@ void native_machine_restart(char *cmd)
bfin_gpio_reset_spi0_ssel1();
}
-/*
- * Currently the MAC address is saved in Flash by U-Boot
- */
-#define FLASH_MAC 0x203f0000
void bfin_get_ether_addr(char *addr)
{
- *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC);
- *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4);
+ /* the MAC is stored in OTP memory page 0xDF */
+ u32 ret;
+ u64 otp_mac;
+ u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A;
+
+ ret = otp_read(0xDF, 0x00, &otp_mac);
+ if (!(ret & 0x1)) {
+ char *otp_mac_p = (char *)&otp_mac;
+ for (ret = 0; ret < 6; ++ret)
+ addr[ret] = otp_mac_p[5 - ret];
+ }
}
EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/trunk/arch/blackfin/mach-bf533/boards/ezkit.c b/trunk/arch/blackfin/mach-bf533/boards/ezkit.c
index 2b09aa39f565..241b5a20a36a 100644
--- a/trunk/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/trunk/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -99,11 +99,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -298,6 +298,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include
@@ -350,6 +363,8 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
+
+ &bfin_gpios_device,
};
static int __init ezkit_init(void)
diff --git a/trunk/arch/blackfin/mach-bf533/boards/stamp.c b/trunk/arch/blackfin/mach-bf533/boards/stamp.c
index a645f6fd091b..b2ac4816ae62 100644
--- a/trunk/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/trunk/arch/blackfin/mach-bf533/boards/stamp.c
@@ -112,7 +112,7 @@ static struct platform_device net2272_bfin_device = {
static struct mtd_partition stamp_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -160,17 +160,17 @@ static struct platform_device stamp_flash_device = {
static struct mtd_partition bfin_spi_flash_partitions[] = {
{
.name = "bootloader",
- .size = 0x00020000,
+ .size = 0x00040000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -212,13 +212,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
static struct bfin5xx_spi_chip spi_mmc_chip_info = {
.enable_dma = 1,
@@ -308,17 +301,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
{
.modalias = "spidev",
@@ -457,6 +439,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include
@@ -518,6 +513,8 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
&i2c_gpio_device,
#endif
+
+ &bfin_gpios_device,
&stamp_flash_device,
};
diff --git a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c b/trunk/arch/blackfin/mach-bf537/boards/generic_board.c
index 8a3397db1d21..c95395ba7bfa 100644
--- a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/trunk/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -371,13 +371,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
.enable_dma = 0,
@@ -483,17 +476,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
{
.modalias = "ad7877",
diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c
index 9e2277e0d25c..ea83148993da 100644
--- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c
@@ -128,6 +128,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
static struct resource bfin_pcmcia_cf_resources[] = {
{
@@ -343,7 +356,7 @@ static struct platform_device net2272_bfin_device = {
static struct mtd_partition stamp_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -351,7 +364,7 @@ static struct mtd_partition stamp_partitions[] = {
.offset = MTDPART_OFS_APPEND,
}, {
.name = "RootFS",
- .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000,
+ .size = 0x400000 - 0x40000 - 0xE0000 - 0x10000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "MAC Address",
@@ -391,17 +404,17 @@ static struct platform_device stamp_flash_device = {
static struct mtd_partition bfin_spi_flash_partitions[] = {
{
.name = "bootloader",
- .size = 0x00020000,
+ .size = 0x00040000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = 0x20000
+ .offset = MTDPART_OFS_APPEND,
}, {
.name = "file system",
- .size = 0x700000,
- .offset = 0x00100000,
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -459,13 +472,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
};
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
-static struct bfin5xx_spi_chip ad5304_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-#endif
-
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
.enable_dma = 0,
@@ -578,17 +584,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.mode = SPI_MODE_3,
},
#endif
-#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
- {
- .modalias = "ad5304_spi",
- .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
- .bus_num = 0,
- .chip_select = 2,
- .platform_data = NULL,
- .controller_data = &ad5304_chip_info,
- .mode = SPI_MODE_2,
- },
-#endif
#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
{
.modalias = "ad7877",
@@ -821,6 +816,8 @@ static struct platform_device *stamp_devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
#endif
+
+ &bfin_gpios_device,
&stamp_flash_device,
};
diff --git a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c
index 916e963e83ba..a0950c1fd800 100644
--- a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -285,8 +285,8 @@ static struct mtd_partition partition_info[] = {
},
{
.name = "File System",
- .offset = 4 * SIZE_1M,
- .size = (256 - 4) * SIZE_1M,
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
},
};
@@ -333,7 +333,7 @@ static struct platform_device bf54x_sdh_device = {
static struct mtd_partition ezkit_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -381,8 +381,8 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
.mask_flags = MTD_CAP_ROM
}, {
.name = "linux kernel",
- .size = 0x1c0000,
- .offset = 0x40000
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
}
};
@@ -594,6 +594,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
&rtc_device,
@@ -646,6 +659,8 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
&bfin_device_gpiokeys,
#endif
+
+ &bfin_gpios_device,
&ezkit_flash_device,
};
diff --git a/trunk/arch/blackfin/mach-bf548/dma.c b/trunk/arch/blackfin/mach-bf548/dma.c
index 374803a8d2e8..f5479298bb79 100644
--- a/trunk/arch/blackfin/mach-bf548/dma.c
+++ b/trunk/arch/blackfin/mach-bf548/dma.c
@@ -27,6 +27,8 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include
+
#include
#include
diff --git a/trunk/arch/blackfin/mach-bf548/head.S b/trunk/arch/blackfin/mach-bf548/head.S
index 74fe258421a5..46222a75321a 100644
--- a/trunk/arch/blackfin/mach-bf548/head.S
+++ b/trunk/arch/blackfin/mach-bf548/head.S
@@ -28,6 +28,7 @@
*/
#include
+#include
#include
#include
#if CONFIG_BFIN_KERNEL_CLOCK
@@ -44,10 +45,9 @@
#define INITIAL_STACK 0xFFB01000
-.text
+__INIT
ENTRY(__start)
-ENTRY(__stext)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
/* Enable Cycle Counter and Nesting Of Interrupts */
@@ -213,6 +213,7 @@ ENTRY(__stext)
.LWAIT_HERE:
jump .LWAIT_HERE;
+ENDPROC(__start)
ENTRY(_real_start)
[ -- sp ] = reti;
@@ -285,6 +286,9 @@ ENTRY(_real_start)
call _start_kernel;
.L_exit:
jump.s .L_exit;
+ENDPROC(_real_start)
+
+__FINIT
.section .l1.text
#if CONFIG_BFIN_KERNEL_CLOCK
@@ -450,6 +454,7 @@ ENTRY(_start_dma_code)
SSYNC;
RTS;
+ENDPROC(_start_dma_code)
#endif /* CONFIG_BFIN_KERNEL_CLOCK */
.data
diff --git a/trunk/arch/blackfin/mach-bf561/boards/ezkit.c b/trunk/arch/blackfin/mach-bf561/boards/ezkit.c
index 43c1b0982819..d357f648d963 100644
--- a/trunk/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/trunk/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -223,7 +223,7 @@ static struct platform_device bfin_uart_device = {
static struct mtd_partition ezkit_partitions[] = {
{
.name = "Bootloader",
- .size = 0x20000,
+ .size = 0x40000,
.offset = 0,
}, {
.name = "Kernel",
@@ -389,6 +389,19 @@ static struct platform_device bfin_device_gpiokeys = {
};
#endif
+static struct resource bfin_gpios_resources = {
+ .start = 0,
+ .end = MAX_BLACKFIN_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+ .name = "simple-gpio",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &bfin_gpios_resources,
+};
+
#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
#include
@@ -446,6 +459,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
&isp1362_hcd_device,
#endif
+ &bfin_gpios_device,
&ezkit_flash_device,
};
diff --git a/trunk/arch/blackfin/mach-common/dpmc.S b/trunk/arch/blackfin/mach-common/dpmc.S
index b80ddd8b232d..9d45aa3265b1 100644
--- a/trunk/arch/blackfin/mach-common/dpmc.S
+++ b/trunk/arch/blackfin/mach-common/dpmc.S
@@ -31,140 +31,6 @@
#include
#include
-.text
-
-ENTRY(_unmask_wdog_wakeup_evt)
- [--SP] = ( R7:0, P5:0 );
-#if defined(CONFIG_BF561)
- P0.H = hi(SICA_IWR1);
- P0.L = lo(SICA_IWR1);
-#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
- P0.h = HI(SIC_IWR0);
- P0.l = LO(SIC_IWR0);
-#else
- P0.h = HI(SIC_IWR);
- P0.l = LO(SIC_IWR);
-#endif
- R7 = [P0];
-#if defined(CONFIG_BF561)
- BITSET(R7, 27);
-#else
- BITSET(R7,(IRQ_WATCH - IVG7));
-#endif
- [P0] = R7;
- SSYNC;
-
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-.LWRITE_TO_STAT:
- /* When watch dog timer is enabled, a write to STAT will load the
- * contents of CNT to STAT
- */
- R7 = 0x0000(z);
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_STAT);
- P0.l = LO(WDOGA_STAT);
-#else
- P0.h = HI(WDOG_STAT);
- P0.l = LO(WDOG_STAT);
-#endif
- [P0] = R7;
- SSYNC;
- JUMP .LSKIP_WRITE_TO_STAT;
-
-ENTRY(_program_wdog_timer)
- [--SP] = ( R7:0, P5:0 );
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CNT);
- P0.l = LO(WDOGA_CNT);
-#else
- P0.h = HI(WDOG_CNT);
- P0.l = LO(WDOG_CNT);
-#endif
- [P0] = R0;
- SSYNC;
-
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = W[P0](Z);
- CC = BITTST(R7,1);
- if !CC JUMP .LWRITE_TO_STAT;
- CC = BITTST(R7,2);
- if !CC JUMP .LWRITE_TO_STAT;
-
-.LSKIP_WRITE_TO_STAT:
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = W[P0](Z);
- BITCLR(R7,1); /* Enable GP event */
- BITSET(R7,2);
- W[P0] = R7.L;
- SSYNC;
- NOP;
-
- R7 = W[P0](Z);
- BITCLR(R7,4); /* Enable the wdog counter */
- W[P0] = R7.L;
- SSYNC;
-
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-ENTRY(_clear_wdog_wakeup_evt)
- [--SP] = ( R7:0, P5:0 );
-
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = 0x0AD6(Z);
- W[P0] = R7.L;
- SSYNC;
-
- R7 = W[P0](Z);
- BITSET(R7,15);
- W[P0] = R7.L;
- SSYNC;
-
- R7 = W[P0](Z);
- BITSET(R7,1);
- BITSET(R7,2);
- W[P0] = R7.L;
- SSYNC;
-
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-ENTRY(_disable_wdog_timer)
- [--SP] = ( R7:0, P5:0 );
-#if defined(CONFIG_BF561)
- P0.h = HI(WDOGA_CTL);
- P0.l = LO(WDOGA_CTL);
-#else
- P0.h = HI(WDOG_CTL);
- P0.l = LO(WDOG_CTL);
-#endif
- R7 = 0xAD6(Z);
- W[P0] = R7.L;
- SSYNC;
- ( R7:0, P5:0 ) = [SP++];
- RTS;
-
-#if !defined(CONFIG_BF561)
.section .l1.text
@@ -459,10 +325,12 @@ ENTRY(_set_sic_iwr)
RTS;
ENTRY(_set_rtc_istat)
+#ifndef CONFIG_BF561
P0.H = hi(RTC_ISTAT);
P0.L = lo(RTC_ISTAT);
w[P0] = R0.L;
SSYNC;
+#endif
RTS;
ENTRY(_test_pll_locked)
@@ -473,4 +341,3 @@ ENTRY(_test_pll_locked)
CC = BITTST(R0,5);
IF !CC JUMP 1b;
RTS;
-#endif
diff --git a/trunk/arch/blackfin/mach-common/ints-priority.c b/trunk/arch/blackfin/mach-common/ints-priority.c
index 880595afe98d..225ef14af75e 100644
--- a/trunk/arch/blackfin/mach-common/ints-priority.c
+++ b/trunk/arch/blackfin/mach-common/ints-priority.c
@@ -74,7 +74,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */
#endif
struct ivgx {
- /* irq number for request_irq, available in mach-bf533/irq.h */
+ /* irq number for request_irq, available in mach-bf5xx/irq.h */
unsigned int irqno;
/* corresponding bit in the SIC_ISR register */
unsigned int isrflag;
@@ -86,7 +86,6 @@ struct ivg_slice {
struct ivgx *istop;
} ivg7_13[IVG13 - IVG7 + 1];
-static void search_IAR(void);
/*
* Search SIC_IAR and fill tables with the irqvalues
@@ -120,10 +119,10 @@ static void __init search_IAR(void)
}
/*
- * This is for BF533 internal IRQs
+ * This is for core internal IRQs
*/
-static void ack_noop(unsigned int irq)
+static void bfin_ack_noop(unsigned int irq)
{
/* Dummy function. */
}
@@ -156,11 +155,11 @@ static void bfin_internal_mask_irq(unsigned int irq)
{
#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
- ~(1 << (irq - (IRQ_CORETMR + 1))));
+ ~(1 << SIC_SYSIRQ(irq)));
#else
unsigned mask_bank, mask_bit;
- mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
- mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+ mask_bank = SIC_SYSIRQ(irq) / 32;
+ mask_bit = SIC_SYSIRQ(irq) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
~(1 << mask_bit));
#endif
@@ -171,11 +170,11 @@ static void bfin_internal_unmask_irq(unsigned int irq)
{
#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
- (1 << (irq - (IRQ_CORETMR + 1))));
+ (1 << SIC_SYSIRQ(irq)));
#else
unsigned mask_bank, mask_bit;
- mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
- mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
+ mask_bank = SIC_SYSIRQ(irq) / 32;
+ mask_bit = SIC_SYSIRQ(irq) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
(1 << mask_bit));
#endif
@@ -187,8 +186,8 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
unsigned bank, bit;
unsigned long flags;
- bank = (irq - (IRQ_CORETMR + 1)) / 32;
- bit = (irq - (IRQ_CORETMR + 1)) % 32;
+ bank = SIC_SYSIRQ(irq) / 32;
+ bit = SIC_SYSIRQ(irq) % 32;
local_irq_save(flags);
@@ -204,15 +203,18 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
#endif
static struct irq_chip bfin_core_irqchip = {
- .ack = ack_noop,
+ .ack = bfin_ack_noop,
.mask = bfin_core_mask_irq,
.unmask = bfin_core_unmask_irq,
};
static struct irq_chip bfin_internal_irqchip = {
- .ack = ack_noop,
+ .ack = bfin_ack_noop,
.mask = bfin_internal_mask_irq,
.unmask = bfin_internal_unmask_irq,
+ .mask_ack = bfin_internal_mask_irq,
+ .disable = bfin_internal_mask_irq,
+ .enable = bfin_internal_unmask_irq,
#ifdef CONFIG_PM
.set_wake = bfin_internal_set_wake,
#endif
@@ -221,38 +223,23 @@ static struct irq_chip bfin_internal_irqchip = {
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
static int error_int_mask;
-static void bfin_generic_error_ack_irq(unsigned int irq)
-{
-
-}
-
static void bfin_generic_error_mask_irq(unsigned int irq)
{
error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
- if (!error_int_mask) {
- local_irq_disable();
- bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
- ~(1 << (IRQ_GENERIC_ERROR -
- (IRQ_CORETMR + 1))));
- SSYNC();
- local_irq_enable();
- }
+ if (!error_int_mask)
+ bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
}
static void bfin_generic_error_unmask_irq(unsigned int irq)
{
- local_irq_disable();
- bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 <<
- (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1)));
- SSYNC();
- local_irq_enable();
-
+ bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
}
static struct irq_chip bfin_generic_error_irqchip = {
- .ack = bfin_generic_error_ack_irq,
+ .ack = bfin_ack_noop,
+ .mask_ack = bfin_generic_error_mask_irq,
.mask = bfin_generic_error_mask_irq,
.unmask = bfin_generic_error_unmask_irq,
};
@@ -608,7 +595,7 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
(struct pin_int_t *)PINT3_MASK_SET,
};
-unsigned short get_irq_base(u8 bank, u8 bmap)
+inline unsigned short get_irq_base(u8 bank, u8 bmap)
{
u16 irq_base;
@@ -969,17 +956,12 @@ int __init init_arch_irq(void)
#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
- bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
- bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
# ifdef CONFIG_BF54x
bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
- bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
# endif
#else
bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
- bfin_write_SIC_IWR(IWR_ENABLE_ALL);
#endif
- SSYNC();
local_irq_disable();
@@ -1001,90 +983,53 @@ int __init init_arch_irq(void)
set_irq_chip(irq, &bfin_core_irqchip);
else
set_irq_chip(irq, &bfin_internal_irqchip);
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- if (irq != IRQ_GENERIC_ERROR) {
-#endif
- switch (irq) {
+ switch (irq) {
#if defined(CONFIG_BF53x)
- case IRQ_PROG_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PROG_INTA:
# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
- case IRQ_MAC_RX:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_MAC_RX:
# endif
#elif defined(CONFIG_BF54x)
- case IRQ_PINT0:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PINT1:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PINT2:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PINT3:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PINT0:
+ case IRQ_PINT1:
+ case IRQ_PINT2:
+ case IRQ_PINT3:
#elif defined(CONFIG_BF52x)
- case IRQ_PORTF_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PORTG_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PORTH_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PORTF_INTA:
+ case IRQ_PORTG_INTA:
+ case IRQ_PORTH_INTA:
#elif defined(CONFIG_BF561)
- case IRQ_PROG0_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PROG1_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
- case IRQ_PROG2_INTA:
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ case IRQ_PROG0_INTA:
+ case IRQ_PROG1_INTA:
+ case IRQ_PROG2_INTA:
#endif
- default:
- set_irq_handler(irq, handle_simple_irq);
- break;
- }
-
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- } else {
+ case IRQ_GENERIC_ERROR:
set_irq_handler(irq, bfin_demux_error_irq);
- }
+
+ break;
#endif
+ default:
+ set_irq_handler(irq, handle_simple_irq);
+ break;
+ }
}
+
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) {
- set_irq_chip(irq, &bfin_generic_error_irqchip);
- set_irq_handler(irq, handle_level_irq);
- }
+ for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
+ set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
+ handle_level_irq);
#endif
- for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) {
+ /* if configured as edge, then will be changed to do_edge_IRQ */
+ for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++)
+ set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
+ handle_level_irq);
- set_irq_chip(irq, &bfin_gpio_irqchip);
- /* if configured as edge, then will be changed to do_edge_IRQ */
- set_irq_handler(irq, handle_level_irq);
- }
bfin_write_IMASK(0);
CSYNC();
@@ -1106,6 +1051,16 @@ int __init init_arch_irq(void)
IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
+ bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
+ bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+# ifdef CONFIG_BF54x
+ bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+# endif
+#else
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif
+
return 0;
}
@@ -1122,7 +1077,6 @@ void do_irq(int vec, struct pt_regs *fp)
#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
unsigned long sic_status[3];
- SSYNC();
sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
#ifdef CONFIG_BF54x
@@ -1138,7 +1092,7 @@ void do_irq(int vec, struct pt_regs *fp)
}
#else
unsigned long sic_status;
- SSYNC();
+
sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
for (;; ivg++) {
diff --git a/trunk/arch/blackfin/mm/init.c b/trunk/arch/blackfin/mm/init.c
index 1f516c55bde6..ec3141fefd20 100644
--- a/trunk/arch/blackfin/mm/init.c
+++ b/trunk/arch/blackfin/mm/init.c
@@ -181,7 +181,7 @@ void __init mem_init(void)
}
}
-static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end)
+static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end)
{
unsigned long addr;
/* next to check that the page we free is not a partial page */
@@ -203,7 +203,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
}
#endif
-void __init free_initmem(void)
+void __init_refok free_initmem(void)
{
#if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
free_init_pages("unused kernel memory",
diff --git a/trunk/arch/cris/arch-v10/kernel/time.c b/trunk/arch/cris/arch-v10/kernel/time.c
index 9310a7b476e9..525483f0ddf8 100644
--- a/trunk/arch/cris/arch-v10/kernel/time.c
+++ b/trunk/arch/cris/arch-v10/kernel/time.c
@@ -13,7 +13,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/trunk/arch/cris/arch-v10/lib/string.c b/trunk/arch/cris/arch-v10/lib/string.c
index 7161a2bef4fe..c7bd6ebdc93c 100644
--- a/trunk/arch/cris/arch-v10/lib/string.c
+++ b/trunk/arch/cris/arch-v10/lib/string.c
@@ -1,55 +1,59 @@
-/*#************************************************************************#*/
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# FUNCTION NAME: memcpy() */
-/*# */
-/*# PARAMETERS: void* dst; Destination address. */
-/*# void* src; Source address. */
-/*# int len; Number of bytes to copy. */
-/*# */
-/*# RETURNS: dst. */
-/*# */
-/*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */
-/*# about copying of overlapping memory areas. This routine is */
-/*# very sensitive to compiler changes in register allocation. */
-/*# Should really be rewritten to avoid this problem. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# HISTORY */
-/*# */
-/*# DATE NAME CHANGES */
-/*# ---- ---- ------- */
-/*# 941007 Kenny R Creation */
-/*# 941011 Kenny R Lots of optimizations and inlining. */
-/*# 941129 Ulf A Adapted for use in libc. */
-/*# 950216 HP N==0 forgotten if non-aligned src/dst. */
-/*# Added some optimizations. */
-/*# 001025 HP Make src and dst char *. Align dst to */
-/*# dword, not just word-if-both-src-and-dst- */
-/*# are-misaligned. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-
-#include
-
-void *memcpy(void *pdst,
- const void *psrc,
- size_t pn)
+/* A memcpy for CRIS.
+ Copyright (C) 1994-2005 Axis Communications.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Neither the name of Axis Communications nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+ COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* FIXME: This file should really only be used for reference, as the
+ result is somewhat depending on gcc generating what we expect rather
+ than what we describe. An assembly file should be used instead. */
+
+#include
+
+/* Break even between movem and move16 is really at 38.7 * 2, but
+ modulo 44, so up to the next multiple of 44, we use ordinary code. */
+#define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2)
+
+/* No name ambiguities in this file. */
+__asm__ (".syntax no_register_prefix");
+
+void *
+memcpy(void *pdst, const void *psrc, size_t pn)
{
- /* Ok. Now we want the parameters put in special registers.
+ /* Now we want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
- As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+ As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
- If gcc was alright, it really would need no temporaries, and no
- stack space to save stuff on. */
+ If gcc was allright, it really would need no temporaries, and no
+ stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
- register char *dst __asm__ ("r13") = pdst;
- register const char *src __asm__ ("r11") = psrc;
+ register unsigned char *dst __asm__ ("r13") = pdst;
+ register unsigned const char *src __asm__ ("r11") = psrc;
register int n __asm__ ("r12") = pn;
-
-
+
/* When src is aligned but not dst, this makes a few extra needless
cycles. I believe it would take as many to check that the
re-alignment was unnecessary. */
@@ -59,167 +63,174 @@ void *memcpy(void *pdst,
&& n >= 3)
{
if ((unsigned long) dst & 1)
- {
- n--;
- *(char*)dst = *(char*)src;
- src++;
- dst++;
- }
+ {
+ n--;
+ *dst = *src;
+ src++;
+ dst++;
+ }
if ((unsigned long) dst & 2)
- {
- n -= 2;
- *(short*)dst = *(short*)src;
- src += 2;
- dst += 2;
- }
+ {
+ n -= 2;
+ *(short *) dst = *(short *) src;
+ src += 2;
+ dst += 2;
+ }
}
- /* Decide which copying method to use. */
- if (n >= 44*2) /* Break even between movem and
- move16 is at 38.7*2, but modulo 44. */
- {
- /* For large copies we use 'movem' */
-
- /* It is not optimal to tell the compiler about clobbering any
- registers; that will move the saving/restoring of those registers
- to the function prologue/epilogue, and make non-movem sizes
- suboptimal.
-
- This method is not foolproof; it assumes that the "asm reg"
- declarations at the beginning of the function really are used
- here (beware: they may be moved to temporary registers).
- This way, we do not have to save/move the registers around into
- temporaries; we can safely use them straight away.
-
- If you want to check that the allocation was right; then
- check the equalities in the first comment. It should say
- "r13=r13, r11=r11, r12=r12" */
- __asm__ volatile ("\n\
- ;; Check that the following is true (same register names on \n\
- ;; both sides of equal sign, as in r8=r8): \n\
- ;; %0=r13, %1=r11, %2=r12 \n\
- ;; \n\
- ;; Save the registers we'll use in the movem process \n\
- ;; on the stack. \n\
- subq 11*4,$sp \n\
- movem $r10,[$sp] \n\
+ /* Decide which copying method to use. */
+ if (n >= MEMCPY_BY_BLOCK_THRESHOLD)
+ {
+ /* It is not optimal to tell the compiler about clobbering any
+ registers; that will move the saving/restoring of those registers
+ to the function prologue/epilogue, and make non-movem sizes
+ suboptimal. */
+ __asm__ volatile
+ ("\
+ ;; GCC does promise correct register allocations, but let's \n\
+ ;; make sure it keeps its promises. \n\
+ .ifnc %0-%1-%2,$r13-$r11-$r12 \n\
+ .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\
+ .endif \n\
+ \n\
+ ;; Save the registers we'll use in the movem process \n\
+ ;; on the stack. \n\
+ subq 11*4,sp \n\
+ movem r10,[sp] \n\
\n\
- ;; Now we've got this: \n\
- ;; r11 - src \n\
- ;; r13 - dst \n\
- ;; r12 - n \n\
+ ;; Now we've got this: \n\
+ ;; r11 - src \n\
+ ;; r13 - dst \n\
+ ;; r12 - n \n\
\n\
- ;; Update n for the first loop \n\
- subq 44,$r12 \n\
+ ;; Update n for the first loop. \n\
+ subq 44,r12 \n\
0: \n\
- movem [$r11+],$r10 \n\
- subq 44,$r12 \n\
- bge 0b \n\
- movem $r10,[$r13+] \n\
+"
+#ifdef __arch_common_v10_v32
+ /* Cater to branch offset difference between v32 and v10. We
+ assume the branch below has an 8-bit offset. */
+" setf\n"
+#endif
+" movem [r11+],r10 \n\
+ subq 44,r12 \n\
+ bge 0b \n\
+ movem r10,[r13+] \n\
\n\
- addq 44,$r12 ;; compensate for last loop underflowing n \n\
+ ;; Compensate for last loop underflowing n. \n\
+ addq 44,r12 \n\
\n\
- ;; Restore registers from stack \n\
- movem [$sp+],$r10"
+ ;; Restore registers from stack. \n\
+ movem [sp+],r10"
- /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
- /* Inputs */ : "0" (dst), "1" (src), "2" (n));
-
- }
+ /* Outputs. */
+ : "=r" (dst), "=r" (src), "=r" (n)
- /* Either we directly starts copying, using dword copying
- in a loop, or we copy as much as possible with 'movem'
- and then the last block (<44 bytes) is copied here.
- This will work since 'movem' will have updated src,dst,n. */
+ /* Inputs. */
+ : "0" (dst), "1" (src), "2" (n));
+ }
- while ( n >= 16 )
- {
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- n -= 16;
- }
+ while (n >= 16)
+ {
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+
+ n -= 16;
+ }
- /* A switch() is definitely the fastest although it takes a LOT of code.
- * Particularly if you inline code this.
- */
switch (n)
- {
+ {
case 0:
break;
+
case 1:
- *(char*)dst = *(char*)src;
+ *dst = *src;
break;
+
case 2:
- *(short*)dst = *(short*)src;
+ *(short *) dst = *(short *) src;
break;
+
case 3:
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 4:
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src;
break;
+
case 5:
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 6:
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 7:
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 8:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 9:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 10:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 11:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 12:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 13:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 14:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 15:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
- }
+ }
- return return_dst; /* destination pointer. */
-} /* memcpy() */
+ return return_dst;
+}
diff --git a/trunk/arch/cris/arch-v10/lib/usercopy.c b/trunk/arch/cris/arch-v10/lib/usercopy.c
index b8e6c0430e5b..b0a608da7bd1 100644
--- a/trunk/arch/cris/arch-v10/lib/usercopy.c
+++ b/trunk/arch/cris/arch-v10/lib/usercopy.c
@@ -193,7 +193,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
inaccessible. */
unsigned long
-__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
+__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn)
{
/* We want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
diff --git a/trunk/arch/cris/arch-v32/lib/string.c b/trunk/arch/cris/arch-v32/lib/string.c
index 6740b2cebae5..c7bd6ebdc93c 100644
--- a/trunk/arch/cris/arch-v32/lib/string.c
+++ b/trunk/arch/cris/arch-v32/lib/string.c
@@ -1,55 +1,59 @@
-/*#************************************************************************#*/
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# FUNCTION NAME: memcpy() */
-/*# */
-/*# PARAMETERS: void* dst; Destination address. */
-/*# void* src; Source address. */
-/*# int len; Number of bytes to copy. */
-/*# */
-/*# RETURNS: dst. */
-/*# */
-/*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */
-/*# about copying of overlapping memory areas. This routine is */
-/*# very sensitive to compiler changes in register allocation. */
-/*# Should really be rewritten to avoid this problem. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-/*# */
-/*# HISTORY */
-/*# */
-/*# DATE NAME CHANGES */
-/*# ---- ---- ------- */
-/*# 941007 Kenny R Creation */
-/*# 941011 Kenny R Lots of optimizations and inlining. */
-/*# 941129 Ulf A Adapted for use in libc. */
-/*# 950216 HP N==0 forgotten if non-aligned src/dst. */
-/*# Added some optimizations. */
-/*# 001025 HP Make src and dst char *. Align dst to */
-/*# dword, not just word-if-both-src-and-dst- */
-/*# are-misaligned. */
-/*# */
-/*#-------------------------------------------------------------------------*/
-
-#include
-
-void *memcpy(void *pdst,
- const void *psrc,
- size_t pn)
+/* A memcpy for CRIS.
+ Copyright (C) 1994-2005 Axis Communications.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Neither the name of Axis Communications nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+ COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* FIXME: This file should really only be used for reference, as the
+ result is somewhat depending on gcc generating what we expect rather
+ than what we describe. An assembly file should be used instead. */
+
+#include
+
+/* Break even between movem and move16 is really at 38.7 * 2, but
+ modulo 44, so up to the next multiple of 44, we use ordinary code. */
+#define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2)
+
+/* No name ambiguities in this file. */
+__asm__ (".syntax no_register_prefix");
+
+void *
+memcpy(void *pdst, const void *psrc, size_t pn)
{
- /* Ok. Now we want the parameters put in special registers.
+ /* Now we want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
- As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+ As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
- If gcc was alright, it really would need no temporaries, and no
- stack space to save stuff on. */
+ If gcc was allright, it really would need no temporaries, and no
+ stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
- register char *dst __asm__ ("r13") = pdst;
- register const char *src __asm__ ("r11") = psrc;
+ register unsigned char *dst __asm__ ("r13") = pdst;
+ register unsigned const char *src __asm__ ("r11") = psrc;
register int n __asm__ ("r12") = pn;
-
/* When src is aligned but not dst, this makes a few extra needless
cycles. I believe it would take as many to check that the
re-alignment was unnecessary. */
@@ -59,161 +63,174 @@ void *memcpy(void *pdst,
&& n >= 3)
{
if ((unsigned long) dst & 1)
- {
- n--;
- *(char*)dst = *(char*)src;
- src++;
- dst++;
- }
+ {
+ n--;
+ *dst = *src;
+ src++;
+ dst++;
+ }
if ((unsigned long) dst & 2)
- {
- n -= 2;
- *(short*)dst = *(short*)src;
- src += 2;
- dst += 2;
- }
+ {
+ n -= 2;
+ *(short *) dst = *(short *) src;
+ src += 2;
+ dst += 2;
+ }
}
- /* Decide which copying method to use. Movem is dirt cheap, so the
- overheap is low enough to always use the minimum block size as the
- threshold. */
- if (n >= 44)
- {
- /* For large copies we use 'movem' */
-
- /* It is not optimal to tell the compiler about clobbering any
- registers; that will move the saving/restoring of those registers
- to the function prologue/epilogue, and make non-movem sizes
- suboptimal. */
- __asm__ volatile (" \n\
- ;; Check that the register asm declaration got right. \n\
- ;; The GCC manual explicitly says TRT will happen. \n\
- .ifnc %0-%1-%2,$r13-$r11-$r12 \n\
- .err \n\
- .endif \n\
- \n\
- ;; Save the registers we'll use in the movem process \n\
+ /* Decide which copying method to use. */
+ if (n >= MEMCPY_BY_BLOCK_THRESHOLD)
+ {
+ /* It is not optimal to tell the compiler about clobbering any
+ registers; that will move the saving/restoring of those registers
+ to the function prologue/epilogue, and make non-movem sizes
+ suboptimal. */
+ __asm__ volatile
+ ("\
+ ;; GCC does promise correct register allocations, but let's \n\
+ ;; make sure it keeps its promises. \n\
+ .ifnc %0-%1-%2,$r13-$r11-$r12 \n\
+ .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\
+ .endif \n\
\n\
- ;; on the stack. \n\
- subq 11*4,$sp \n\
- movem $r10,[$sp] \n\
+ ;; Save the registers we'll use in the movem process \n\
+ ;; on the stack. \n\
+ subq 11*4,sp \n\
+ movem r10,[sp] \n\
\n\
- ;; Now we've got this: \n\
- ;; r11 - src \n\
- ;; r13 - dst \n\
- ;; r12 - n \n\
+ ;; Now we've got this: \n\
+ ;; r11 - src \n\
+ ;; r13 - dst \n\
+ ;; r12 - n \n\
\n\
- ;; Update n for the first loop \n\
- subq 44,$r12 \n\
+ ;; Update n for the first loop. \n\
+ subq 44,r12 \n\
0: \n\
- movem [$r11+],$r10 \n\
- subq 44,$r12 \n\
- bge 0b \n\
- movem $r10,[$r13+] \n\
+"
+#ifdef __arch_common_v10_v32
+ /* Cater to branch offset difference between v32 and v10. We
+ assume the branch below has an 8-bit offset. */
+" setf\n"
+#endif
+" movem [r11+],r10 \n\
+ subq 44,r12 \n\
+ bge 0b \n\
+ movem r10,[r13+] \n\
\n\
- addq 44,$r12 ;; compensate for last loop underflowing n \n\
+ ;; Compensate for last loop underflowing n. \n\
+ addq 44,r12 \n\
\n\
- ;; Restore registers from stack \n\
- movem [$sp+],$r10"
+ ;; Restore registers from stack. \n\
+ movem [sp+],r10"
- /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
- /* Inputs */ : "0" (dst), "1" (src), "2" (n));
+ /* Outputs. */
+ : "=r" (dst), "=r" (src), "=r" (n)
- }
+ /* Inputs. */
+ : "0" (dst), "1" (src), "2" (n));
+ }
- /* Either we directly starts copying, using dword copying
- in a loop, or we copy as much as possible with 'movem'
- and then the last block (<44 bytes) is copied here.
- This will work since 'movem' will have updated src,dst,n. */
+ while (n >= 16)
+ {
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
- while ( n >= 16 )
- {
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- n -= 16;
- }
+ n -= 16;
+ }
- /* A switch() is definitely the fastest although it takes a LOT of code.
- * Particularly if you inline code this.
- */
switch (n)
- {
+ {
case 0:
break;
+
case 1:
- *(char*)dst = *(char*)src;
+ *dst = *src;
break;
+
case 2:
- *(short*)dst = *(short*)src;
+ *(short *) dst = *(short *) src;
break;
+
case 3:
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 4:
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src;
break;
+
case 5:
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 6:
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 7:
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 8:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 9:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 10:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 11:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
+
case 12:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src;
break;
+
case 13:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *dst = *src;
break;
+
case 14:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *(short*)dst = *(short*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src;
break;
+
case 15:
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((long*)dst)++ = *((long*)src)++;
- *((short*)dst)++ = *((short*)src)++;
- *(char*)dst = *(char*)src;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(long *) dst = *(long *) src; dst += 4; src += 4;
+ *(short *) dst = *(short *) src; dst += 2; src += 2;
+ *dst = *src;
break;
- }
+ }
- return return_dst; /* destination pointer. */
-} /* memcpy() */
+ return return_dst;
+}
diff --git a/trunk/arch/cris/arch-v32/lib/usercopy.c b/trunk/arch/cris/arch-v32/lib/usercopy.c
index 04d0cf35a276..0b5b70d5f58a 100644
--- a/trunk/arch/cris/arch-v32/lib/usercopy.c
+++ b/trunk/arch/cris/arch-v32/lib/usercopy.c
@@ -161,7 +161,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
inaccessible. */
unsigned long
-__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
+__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn)
{
/* We want the parameters put in special registers.
Make sure the compiler is able to make something useful of this.
diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig
index dff9edfc7465..8fa3faf5ef1b 100644
--- a/trunk/arch/ia64/Kconfig
+++ b/trunk/arch/ia64/Kconfig
@@ -18,6 +18,7 @@ config IA64
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
default y
help
The Itanium Processor Family is Intel's 64-bit successor to
@@ -155,6 +156,8 @@ config IA64_HP_ZX1_SWIOTLB
config IA64_SGI_SN2
bool "SGI-SN2"
+ select NUMA
+ select ACPI_NUMA
help
Selecting this option will optimize the kernel for use on sn2 based
systems, but the resulting kernel binary will not run on other
diff --git a/trunk/arch/ia64/Makefile b/trunk/arch/ia64/Makefile
index b916ccfdef84..f1645c4f7039 100644
--- a/trunk/arch/ia64/Makefile
+++ b/trunk/arch/ia64/Makefile
@@ -11,6 +11,8 @@
# Copyright (C) 1998-2004 by David Mosberger-Tang
#
+KBUILD_DEFCONFIG := generic_defconfig
+
NM := $(CROSS_COMPILE)nm -B
READELF := $(CROSS_COMPILE)readelf
diff --git a/trunk/arch/ia64/defconfig b/trunk/arch/ia64/configs/generic_defconfig
similarity index 100%
rename from trunk/arch/ia64/defconfig
rename to trunk/arch/ia64/configs/generic_defconfig
diff --git a/trunk/arch/ia64/ia32/ia32_signal.c b/trunk/arch/ia64/ia32/ia32_signal.c
index 85e82f32e480..256a7faeda07 100644
--- a/trunk/arch/ia64/ia32/ia32_signal.c
+++ b/trunk/arch/ia64/ia32/ia32_signal.c
@@ -766,8 +766,19 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!on_sig_stack(esp))
+ int onstack = sas_ss_flags(esp);
+
+ if (onstack == 0)
esp = current->sas_ss_sp + current->sas_ss_size;
+ else if (onstack == SS_ONSTACK) {
+ /*
+ * If we are on the alternate signal stack and would
+ * overflow it, don't. Return an always-bogus address
+ * instead so we will die with SIGSEGV.
+ */
+ if (!likely(on_sig_stack(esp - frame_size)))
+ return (void __user *) -1L;
+ }
}
/* Legacy stack switching not supported */
diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c
index 398e2fd1cd25..7b3292282dea 100644
--- a/trunk/arch/ia64/kernel/iosapic.c
+++ b/trunk/arch/ia64/kernel/iosapic.c
@@ -345,7 +345,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
if (cpus_empty(mask))
return;
- if (reassign_irq_vector(irq, first_cpu(mask)))
+ if (irq_prepare_move(irq, first_cpu(mask)))
return;
dest = cpu_physical_id(first_cpu(mask));
@@ -397,6 +397,7 @@ iosapic_end_level_irq (unsigned int irq)
struct iosapic_rte_info *rte;
int do_unmask_irq = 0;
+ irq_complete_move(irq);
if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
do_unmask_irq = 1;
mask_irq(irq);
@@ -450,6 +451,7 @@ iosapic_ack_edge_irq (unsigned int irq)
{
irq_desc_t *idesc = irq_desc + irq;
+ irq_complete_move(irq);
move_native_irq(irq);
/*
* Once we have recorded IRQ_PENDING already, we can mask the
diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c
index 0b52f19ed046..2b8cf6e85af4 100644
--- a/trunk/arch/ia64/kernel/irq_ia64.c
+++ b/trunk/arch/ia64/kernel/irq_ia64.c
@@ -260,6 +260,8 @@ void __setup_vector_irq(int cpu)
}
#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
+#define IA64_IRQ_MOVE_VECTOR IA64_DEF_FIRST_DEVICE_VECTOR
+
static enum vector_domain_type {
VECTOR_DOMAIN_NONE,
VECTOR_DOMAIN_PERCPU
@@ -272,6 +274,101 @@ static cpumask_t vector_allocation_domain(int cpu)
return CPU_MASK_ALL;
}
+static int __irq_prepare_move(int irq, int cpu)
+{
+ struct irq_cfg *cfg = &irq_cfg[irq];
+ int vector;
+ cpumask_t domain;
+
+ if (cfg->move_in_progress || cfg->move_cleanup_count)
+ return -EBUSY;
+ if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu))
+ return -EINVAL;
+ if (cpu_isset(cpu, cfg->domain))
+ return 0;
+ domain = vector_allocation_domain(cpu);
+ vector = find_unassigned_vector(domain);
+ if (vector < 0)
+ return -ENOSPC;
+ cfg->move_in_progress = 1;
+ cfg->old_domain = cfg->domain;
+ cfg->vector = IRQ_VECTOR_UNASSIGNED;
+ cfg->domain = CPU_MASK_NONE;
+ BUG_ON(__bind_irq_vector(irq, vector, domain));
+ return 0;
+}
+
+int irq_prepare_move(int irq, int cpu)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ ret = __irq_prepare_move(irq, cpu);
+ spin_unlock_irqrestore(&vector_lock, flags);
+ return ret;
+}
+
+void irq_complete_move(unsigned irq)
+{
+ struct irq_cfg *cfg = &irq_cfg[irq];
+ cpumask_t cleanup_mask;
+ int i;
+
+ if (likely(!cfg->move_in_progress))
+ return;
+
+ if (unlikely(cpu_isset(smp_processor_id(), cfg->old_domain)))
+ return;
+
+ cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map);
+ cfg->move_cleanup_count = cpus_weight(cleanup_mask);
+ for_each_cpu_mask(i, cleanup_mask)
+ platform_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0);
+ cfg->move_in_progress = 0;
+}
+
+static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id)
+{
+ int me = smp_processor_id();
+ ia64_vector vector;
+ unsigned long flags;
+
+ for (vector = IA64_FIRST_DEVICE_VECTOR;
+ vector < IA64_LAST_DEVICE_VECTOR; vector++) {
+ int irq;
+ struct irq_desc *desc;
+ struct irq_cfg *cfg;
+ irq = __get_cpu_var(vector_irq)[vector];
+ if (irq < 0)
+ continue;
+
+ desc = irq_desc + irq;
+ cfg = irq_cfg + irq;
+ spin_lock(&desc->lock);
+ if (!cfg->move_cleanup_count)
+ goto unlock;
+
+ if (!cpu_isset(me, cfg->old_domain))
+ goto unlock;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ __get_cpu_var(vector_irq)[vector] = -1;
+ cpu_clear(me, vector_table[vector]);
+ spin_unlock_irqrestore(&vector_lock, flags);
+ cfg->move_cleanup_count--;
+ unlock:
+ spin_unlock(&desc->lock);
+ }
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_move_irqaction = {
+ .handler = smp_irq_move_cleanup_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "irq_move"
+};
+
static int __init parse_vector_domain(char *arg)
{
if (!arg)
@@ -303,36 +400,6 @@ void destroy_and_reserve_irq(unsigned int irq)
spin_unlock_irqrestore(&vector_lock, flags);
}
-static int __reassign_irq_vector(int irq, int cpu)
-{
- struct irq_cfg *cfg = &irq_cfg[irq];
- int vector;
- cpumask_t domain;
-
- if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu))
- return -EINVAL;
- if (cpu_isset(cpu, cfg->domain))
- return 0;
- domain = vector_allocation_domain(cpu);
- vector = find_unassigned_vector(domain);
- if (vector < 0)
- return -ENOSPC;
- __clear_irq_vector(irq);
- BUG_ON(__bind_irq_vector(irq, vector, domain));
- return 0;
-}
-
-int reassign_irq_vector(int irq, int cpu)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&vector_lock, flags);
- ret = __reassign_irq_vector(irq, cpu);
- spin_unlock_irqrestore(&vector_lock, flags);
- return ret;
-}
-
/*
* Dynamic irq allocate and deallocation for MSI
*/
@@ -578,6 +645,13 @@ init_IRQ (void)
register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
+ if (vector_domain_type != VECTOR_DOMAIN_NONE) {
+ BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR);
+ IA64_FIRST_DEVICE_VECTOR++;
+ register_percpu_irq(IA64_IRQ_MOVE_VECTOR, &irq_move_irqaction);
+ }
+#endif
#endif
#ifdef CONFIG_PERFMON
pfm_init_percpu();
diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c
index b618487cdc85..615c3d2b6348 100644
--- a/trunk/arch/ia64/kernel/kprobes.c
+++ b/trunk/arch/ia64/kernel/kprobes.c
@@ -1001,6 +1001,11 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
return 1;
}
+/* ia64 does not need this */
+void __kprobes jprobe_return(void)
+{
+}
+
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
diff --git a/trunk/arch/ia64/kernel/msi_ia64.c b/trunk/arch/ia64/kernel/msi_ia64.c
index e86d02959794..60c6ef67ebb2 100644
--- a/trunk/arch/ia64/kernel/msi_ia64.c
+++ b/trunk/arch/ia64/kernel/msi_ia64.c
@@ -57,7 +57,7 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
if (!cpu_online(cpu))
return;
- if (reassign_irq_vector(irq, cpu))
+ if (irq_prepare_move(irq, cpu))
return;
read_msi_msg(irq, &msg);
@@ -119,6 +119,7 @@ void ia64_teardown_msi_irq(unsigned int irq)
static void ia64_ack_msi_irq(unsigned int irq)
{
+ irq_complete_move(irq);
move_native_irq(irq);
ia64_eoi();
}
diff --git a/trunk/arch/ia64/kernel/sal.c b/trunk/arch/ia64/kernel/sal.c
index f44fe8412162..a3022dc48ef8 100644
--- a/trunk/arch/ia64/kernel/sal.c
+++ b/trunk/arch/ia64/kernel/sal.c
@@ -109,6 +109,13 @@ check_versions (struct ia64_sal_systab *systab)
sal_revision = SAL_VERSION_CODE(2, 8);
sal_version = SAL_VERSION_CODE(0, 0);
}
+
+ if (ia64_platform_is("sn2") && (sal_revision == SAL_VERSION_CODE(2, 9)))
+ /*
+ * SGI Altix has hard-coded version 2.9 in their prom
+ * but they actually implement 3.2, so let's fix it here.
+ */
+ sal_revision = SAL_VERSION_CODE(3, 2);
}
static void __init
diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c
index 309da3567bc8..5740296c35af 100644
--- a/trunk/arch/ia64/kernel/signal.c
+++ b/trunk/arch/ia64/kernel/signal.c
@@ -342,15 +342,33 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
new_sp = scr->pt.r12;
tramp_addr = (unsigned long) __kernel_sigtramp;
- if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
- new_sp = current->sas_ss_sp + current->sas_ss_size;
- /*
- * We need to check for the register stack being on the signal stack
- * separately, because it's switched separately (memory stack is switched
- * in the kernel, register stack is switched in the signal trampoline).
- */
- if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
- new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ int onstack = sas_ss_flags(new_sp);
+
+ if (onstack == 0) {
+ new_sp = current->sas_ss_sp + current->sas_ss_size;
+ /*
+ * We need to check for the register stack being on the
+ * signal stack separately, because it's switched
+ * separately (memory stack is switched in the kernel,
+ * register stack is switched in the signal trampoline).
+ */
+ if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
+ new_rbs = ALIGN(current->sas_ss_sp,
+ sizeof(long));
+ } else if (onstack == SS_ONSTACK) {
+ unsigned long check_sp;
+
+ /*
+ * If we are on the alternate signal stack and would
+ * overflow it, don't. Return an always-bogus address
+ * instead so we will die with SIGSEGV.
+ */
+ check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
+ if (!likely(on_sig_stack(check_sp)))
+ return force_sigsegv_info(sig, (void __user *)
+ check_sp);
+ }
}
frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
diff --git a/trunk/arch/m68k/kernel/entry.S b/trunk/arch/m68k/kernel/entry.S
index 6dfa3b3c0e2a..18a9c5f4b00d 100644
--- a/trunk/arch/m68k/kernel/entry.S
+++ b/trunk/arch/m68k/kernel/entry.S
@@ -742,7 +742,9 @@ sys_call_table:
.long sys_epoll_pwait /* 315 */
.long sys_utimensat
.long sys_signalfd
- .long sys_ni_syscall
+ .long sys_timerfd_create
.long sys_eventfd
.long sys_fallocate /* 320 */
+ .long sys_timerfd_settime
+ .long sys_timerfd_gettime
diff --git a/trunk/arch/m68knommu/defconfig b/trunk/arch/m68knommu/defconfig
index 648113075f97..670b0a99cfa0 100644
--- a/trunk/arch/m68knommu/defconfig
+++ b/trunk/arch/m68knommu/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23
-# Thu Oct 18 13:17:38 2007
+# Linux kernel version: 2.6.25-rc3
+# Mon Feb 25 15:03:00 2008
#
CONFIG_M68K=y
# CONFIG_MMU is not set
@@ -15,8 +15,10 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
CONFIG_TIME_LOW_RES=y
CONFIG_NO_IOPORT=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -31,12 +33,14 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -48,15 +52,22 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
# CONFIG_EVENTFD is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+# CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_KPROBES is not set
+CONFIG_SLABINFO=y
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
@@ -83,6 +94,8 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PREEMPT_RCU is not set
#
# Processor type and features
@@ -121,6 +134,7 @@ CONFIG_M5272C3=y
# CONFIG_MOD5272 is not set
CONFIG_FREESCALE=y
CONFIG_4KSTACKS=y
+CONFIG_HZ=100
#
# RAM configuration
@@ -147,6 +161,7 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
@@ -158,10 +173,6 @@ CONFIG_VIRT_TO_BUS=y
# CONFIG_PCI is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-
#
# Executable file formats
#
@@ -205,6 +216,7 @@ CONFIG_IP_FIB_HASH=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
@@ -229,10 +241,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
#
@@ -240,6 +248,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
@@ -283,6 +292,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -339,10 +349,11 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -360,9 +371,15 @@ CONFIG_NETDEVICES=y
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
CONFIG_FEC=y
# CONFIG_FEC2 is not set
# CONFIG_NETDEV_1000 is not set
@@ -377,7 +394,7 @@ CONFIG_FEC=y
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
+CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
@@ -386,7 +403,6 @@ CONFIG_PPP=y
# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
CONFIG_SLHC=y
-# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
@@ -418,12 +434,16 @@ CONFIG_SLHC=y
#
# Non-8250 serial port support
#
-CONFIG_SERIAL_COLDFIRE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_COLDFIRE is not set
+CONFIG_SERIAL_MCF=y
+CONFIG_SERIAL_MCF_BAUDRATE=19200
+CONFIG_SERIAL_MCF_CONSOLE=y
# CONFIG_UNIX98_PTYS is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
@@ -439,6 +459,14 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -450,20 +478,20 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-# CONFIG_FB is not set
#
# Sound
@@ -471,22 +499,10 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y
# CONFIG_SOUND is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_RTC_CLASS is not set
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
#
# Userspace I/O
#
@@ -505,11 +521,9 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
-# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -535,7 +549,6 @@ CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
@@ -551,42 +564,27 @@ CONFIG_RAMFS=y
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
# CONFIG_DLM is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
# CONFIG_ENABLE_MUST_CHECK is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
@@ -594,6 +592,7 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SAMPLES is not set
# CONFIG_FULLDEBUG is not set
# CONFIG_HIGHPROFILE is not set
# CONFIG_BOOTPARAM is not set
@@ -605,6 +604,7 @@ CONFIG_MSDOS_PARTITION=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
#
diff --git a/trunk/arch/m68knommu/kernel/syscalltable.S b/trunk/arch/m68knommu/kernel/syscalltable.S
index 1b02b8820068..fca2e49917a3 100644
--- a/trunk/arch/m68knommu/kernel/syscalltable.S
+++ b/trunk/arch/m68knommu/kernel/syscalltable.S
@@ -336,9 +336,11 @@ ENTRY(sys_call_table)
.long sys_epoll_pwait /* 315 */
.long sys_utimensat
.long sys_signalfd
- .long sys_ni_syscall
+ .long sys_timerfd_create
.long sys_eventfd
.long sys_fallocate /* 320 */
+ .long sys_timerfd_settime
+ .long sys_timerfd_gettime
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
diff --git a/trunk/arch/m68knommu/platform/68328/timers.c b/trunk/arch/m68knommu/platform/68328/timers.c
index 9159fd05c9ac..6bafefa546e5 100644
--- a/trunk/arch/m68knommu/platform/68328/timers.c
+++ b/trunk/arch/m68knommu/platform/68328/timers.c
@@ -67,16 +67,6 @@ static irqreturn_t hw_tick(int irq, void *dummy)
/***************************************************************************/
-static irqreturn_t hw_tick(int irq, void *dummy)
-{
- /* Reset Timer1 */
- TSTAT &= 0;
-
- return arch_timer_interrupt(irq, dummy);
-}
-
-/***************************************************************************/
-
static struct irqaction m68328_timer_irq = {
.name = "timer",
.flags = IRQF_DISABLED | IRQF_TIMER,
diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig
index 5b8d8382b762..1189d8d6170d 100644
--- a/trunk/arch/powerpc/Kconfig
+++ b/trunk/arch/powerpc/Kconfig
@@ -90,6 +90,7 @@ config PPC
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
config EARLY_PRINTK
bool
diff --git a/trunk/arch/powerpc/boot/cuboot-bamboo.c b/trunk/arch/powerpc/boot/cuboot-bamboo.c
index 900c7ff2b7e9..b5c30f766c40 100644
--- a/trunk/arch/powerpc/boot/cuboot-bamboo.c
+++ b/trunk/arch/powerpc/boot/cuboot-bamboo.c
@@ -17,6 +17,7 @@
#include "44x.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/trunk/arch/powerpc/boot/cuboot-ebony.c b/trunk/arch/powerpc/boot/cuboot-ebony.c
index c5f37ce172ea..56564ba37f62 100644
--- a/trunk/arch/powerpc/boot/cuboot-ebony.c
+++ b/trunk/arch/powerpc/boot/cuboot-ebony.c
@@ -17,6 +17,7 @@
#include "44x.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/trunk/arch/powerpc/boot/cuboot-katmai.c b/trunk/arch/powerpc/boot/cuboot-katmai.c
index c021167f9381..5434d70b5660 100644
--- a/trunk/arch/powerpc/boot/cuboot-katmai.c
+++ b/trunk/arch/powerpc/boot/cuboot-katmai.c
@@ -22,6 +22,7 @@
#include "44x.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/trunk/arch/powerpc/boot/cuboot-taishan.c b/trunk/arch/powerpc/boot/cuboot-taishan.c
index f66455a45ab1..b55b80467eed 100644
--- a/trunk/arch/powerpc/boot/cuboot-taishan.c
+++ b/trunk/arch/powerpc/boot/cuboot-taishan.c
@@ -21,7 +21,9 @@
#include "dcr.h"
#include "4xx.h"
+#define TARGET_4xx
#define TARGET_44x
+#define TARGET_440GX
#include "ppcboot.h"
static bd_t bd;
diff --git a/trunk/arch/powerpc/boot/cuboot-warp.c b/trunk/arch/powerpc/boot/cuboot-warp.c
index bdedebe1bc14..3db93e85e9ea 100644
--- a/trunk/arch/powerpc/boot/cuboot-warp.c
+++ b/trunk/arch/powerpc/boot/cuboot-warp.c
@@ -11,6 +11,7 @@
#include "4xx.h"
#include "cuboot.h"
+#define TARGET_4xx
#define TARGET_44x
#include "ppcboot.h"
diff --git a/trunk/arch/powerpc/boot/dts/haleakala.dts b/trunk/arch/powerpc/boot/dts/haleakala.dts
index 5dd3d15f0feb..ae68fefc01b6 100644
--- a/trunk/arch/powerpc/boot/dts/haleakala.dts
+++ b/trunk/arch/powerpc/boot/dts/haleakala.dts
@@ -235,7 +235,7 @@
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
- compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex";
+ compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex";
primary;
port = <0>; /* port number */
reg = ; /* Filled in by zImage */
i-cache-line-size = <20>;
d-cache-line-size = <20>;
- i-cache-size = <20000>;
- d-cache-size = <20000>;
+ i-cache-size = <8000>;
+ d-cache-size = <8000>;
dcr-controller;
dcr-access-method = "native";
};
@@ -136,11 +136,11 @@
};
POB0: opb {
- compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
+ compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <00000000 4 e0000000 20000000>;
- clock-frequency = <0>; /* Filled in by zImage */
+ ranges = <00000000 4 e0000000 20000000>;
+ clock-frequency = <0>; /* Filled in by zImage */
EBC0: ebc {
compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc";
@@ -153,38 +153,38 @@
};
UART0: serial@10000200 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <10000200 8>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <10000200 8>;
virtual-reg = ;
- clock-frequency = <0>; /* Filled in by zImage */
- current-speed = <1c200>;
- interrupt-parent = <&UIC0>;
- interrupts = <0 4>;
- };
+ clock-frequency = <0>; /* Filled in by zImage */
+ current-speed = <1c200>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
UART1: serial@10000300 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <10000300 8>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <10000300 8>;
virtual-reg = ;
- clock-frequency = <0>;
- current-speed = <0>;
- interrupt-parent = <&UIC0>;
- interrupts = <1 4>;
- };
+ clock-frequency = <0>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
UART2: serial@10000600 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <10000600 8>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <10000600 8>;
virtual-reg = ;
- clock-frequency = <0>;
- current-speed = <0>;
- interrupt-parent = <&UIC1>;
- interrupts = <5 4>;
- };
+ clock-frequency = <0>;
+ current-speed = <0>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <5 4>;
+ };
IIC0: i2c@10000400 {
compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic";
diff --git a/trunk/arch/powerpc/oprofile/op_model_cell.c b/trunk/arch/powerpc/oprofile/op_model_cell.c
index 13929771bee7..9eed1f68fcab 100644
--- a/trunk/arch/powerpc/oprofile/op_model_cell.c
+++ b/trunk/arch/powerpc/oprofile/op_model_cell.c
@@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs,
for (i = 0; i < num_counters; ++i) {
if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
&& ctr[i].enabled) {
- oprofile_add_pc(pc, is_kernel, i);
+ oprofile_add_ext_sample(pc, regs, i, is_kernel);
cbe_write_ctr(cpu, i, reset_value[i]);
}
}
diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 9aa4425d80b2..4d5fd1dbd400 100644
--- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
return 0;
}
+EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
/**
* mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c
index edab631a8dcb..20ea0e118f24 100644
--- a/trunk/arch/powerpc/platforms/cell/iommu.c
+++ b/trunk/arch/powerpc/platforms/cell/iommu.c
@@ -113,7 +113,7 @@
/* IOMMU sizing */
#define IO_SEGMENT_SHIFT 28
-#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT)
+#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift))
/* The high bit needs to be set on every DMA address */
#define SPIDER_DMA_OFFSET 0x80000000ul
@@ -123,7 +123,6 @@ struct iommu_window {
struct cbe_iommu *iommu;
unsigned long offset;
unsigned long size;
- unsigned long pte_offset;
unsigned int ioid;
struct iommu_table table;
};
@@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
(window->ioid & IOPTE_IOID_Mask);
#endif
- io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
+ io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
@@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
| (window->ioid & IOPTE_IOID_Mask);
#endif
- io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
+ io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
for (i = 0; i < npages; i++)
io_pte[i] = pte;
@@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
return -ENODEV;
}
-static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
+static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
unsigned long dbase, unsigned long dsize,
unsigned long fbase, unsigned long fsize)
{
struct page *page;
- int i;
- unsigned long reg, segments, pages_per_segment, ptab_size, stab_size,
- n_pte_pages, base;
-
- base = dbase;
- if (fsize != 0)
- base = min(fbase, dbase);
+ unsigned long segments, stab_size;
segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
- pages_per_segment = 1ull << IO_PAGENO_BITS;
- pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n",
- __FUNCTION__, iommu->nid, segments, pages_per_segment);
+ pr_debug("%s: iommu[%d]: segments: %lu\n",
+ __FUNCTION__, iommu->nid, segments);
/* set up the segment table */
stab_size = segments * sizeof(unsigned long);
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size));
BUG_ON(!page);
iommu->stab = page_address(page);
- clear_page(iommu->stab);
+ memset(iommu->stab, 0, stab_size);
+}
+
+static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu,
+ unsigned long base, unsigned long size, unsigned long gap_base,
+ unsigned long gap_size, unsigned long page_shift)
+{
+ struct page *page;
+ int i;
+ unsigned long reg, segments, pages_per_segment, ptab_size,
+ n_pte_pages, start_seg, *ptab;
+
+ start_seg = base >> IO_SEGMENT_SHIFT;
+ segments = size >> IO_SEGMENT_SHIFT;
+ pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift);
+ /* PTEs for each segment must start on a 4K bounday */
+ pages_per_segment = max(pages_per_segment,
+ (1 << 12) / sizeof(unsigned long));
- /* ... and the page tables. Since these are contiguous, we can treat
- * the page tables as one array of ptes, like pSeries does.
- */
ptab_size = segments * pages_per_segment * sizeof(unsigned long);
pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
iommu->nid, ptab_size, get_order(ptab_size));
page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
BUG_ON(!page);
- iommu->ptab = page_address(page);
- memset(iommu->ptab, 0, ptab_size);
+ ptab = page_address(page);
+ memset(ptab, 0, ptab_size);
- /* allocate a bogus page for the end of each mapping */
- page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
- BUG_ON(!page);
- iommu->pad_page = page_address(page);
- clear_page(iommu->pad_page);
-
- /* number of pages needed for a page table */
- n_pte_pages = (pages_per_segment *
- sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
+ /* number of 4K pages needed for a page table */
+ n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;
pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
- __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab,
+ __FUNCTION__, iommu->nid, iommu->stab, ptab,
n_pte_pages);
/* initialise the STEs */
reg = IOSTE_V | ((n_pte_pages - 1) << 5);
- if (IOMMU_PAGE_SIZE == 0x1000)
- reg |= IOSTE_PS_4K;
- else if (IOMMU_PAGE_SIZE == 0x10000)
- reg |= IOSTE_PS_64K;
- else {
- extern void __unknown_page_size_error(void);
- __unknown_page_size_error();
+ switch (page_shift) {
+ case 12: reg |= IOSTE_PS_4K; break;
+ case 16: reg |= IOSTE_PS_64K; break;
+ case 20: reg |= IOSTE_PS_1M; break;
+ case 24: reg |= IOSTE_PS_16M; break;
+ default: BUG();
}
+ gap_base = gap_base >> IO_SEGMENT_SHIFT;
+ gap_size = gap_size >> IO_SEGMENT_SHIFT;
+
pr_debug("Setting up IOMMU stab:\n");
- for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) {
- iommu->stab[i] = reg |
- (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
+ for (i = start_seg; i < (start_seg + segments); i++) {
+ if (i >= gap_base && i < (gap_base + gap_size)) {
+ pr_debug("\toverlap at %d, skipping\n", i);
+ continue;
+ }
+ iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) *
+ (i - start_seg));
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
}
+
+ return ptab;
}
static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
@@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
static void cell_iommu_setup_hardware(struct cbe_iommu *iommu,
unsigned long base, unsigned long size)
{
- cell_iommu_setup_page_tables(iommu, base, size, 0, 0);
+ cell_iommu_setup_stab(iommu, base, size, 0, 0);
+ iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
+ IOMMU_PAGE_SHIFT);
cell_iommu_enable_hardware(iommu);
}
@@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
unsigned long pte_offset)
{
struct iommu_window *window;
+ struct page *page;
u32 ioid;
ioid = cell_iommu_get_ioid(np);
@@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
window->size = size;
window->ioid = ioid;
window->iommu = iommu;
- window->pte_offset = pte_offset;
window->table.it_blocksize = 16;
window->table.it_base = (unsigned long)iommu->ptab;
window->table.it_index = iommu->nid;
- window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
- window->pte_offset;
+ window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset;
window->table.it_size = size >> IOMMU_PAGE_SHIFT;
iommu_init_table(&window->table, iommu->nid);
@@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
* This code also assumes that we have a window that starts at 0,
* which is the case on all spider based blades.
*/
+ page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
+ BUG_ON(!page);
+ iommu->pad_page = page_address(page);
+ clear_page(iommu->pad_page);
+
__set_bit(0, window->table.it_map);
tce_build_cell(&window->table, window->table.it_offset, 1,
(unsigned long)iommu->pad_page, DMA_TO_DEVICE);
@@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
archdata->dma_data = &window->table;
}
-static void cell_dma_dev_setup_static(struct device *dev);
+static void cell_dma_dev_setup_fixed(struct device *dev);
static void cell_dma_dev_setup(struct device *dev)
{
@@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev)
/* Order is important here, these are not mutually exclusive */
if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
- cell_dma_dev_setup_static(dev);
+ cell_dma_dev_setup_fixed(dev);
else if (get_pci_dma_ops() == &dma_iommu_ops)
cell_dma_dev_setup_iommu(dev);
else if (get_pci_dma_ops() == &dma_direct_ops)
@@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
return 0;
}
-static void cell_dma_dev_setup_static(struct device *dev)
+static void cell_dma_dev_setup_fixed(struct device *dev)
{
struct dev_archdata *archdata = &dev->archdata;
u64 addr;
@@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev)
dev_dbg(dev, "iommu: fixed addr = %lx\n", addr);
}
+static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
+ unsigned long base_pte)
+{
+ unsigned long segment, offset;
+
+ segment = addr >> IO_SEGMENT_SHIFT;
+ offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24));
+ ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long));
+
+ pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
+ addr, ptab, segment, offset);
+
+ ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask);
+}
+
static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
struct device_node *np, unsigned long dbase, unsigned long dsize,
unsigned long fbase, unsigned long fsize)
{
- unsigned long base_pte, uaddr, *io_pte;
- int i;
+ unsigned long base_pte, uaddr, ioaddr, *ptab;
- dma_iommu_fixed_base = fbase;
+ ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24);
- /* convert from bytes into page table indices */
- dbase = dbase >> IOMMU_PAGE_SHIFT;
- dsize = dsize >> IOMMU_PAGE_SHIFT;
- fbase = fbase >> IOMMU_PAGE_SHIFT;
- fsize = fsize >> IOMMU_PAGE_SHIFT;
+ dma_iommu_fixed_base = fbase;
pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
- io_pte = iommu->ptab;
base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
| (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
- uaddr = 0;
- for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
+ for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
/* Don't touch the dynamic region */
- if (i >= dbase && i < (dbase + dsize)) {
- pr_debug("iommu: static/dynamic overlap, skipping\n");
+ ioaddr = uaddr + fbase;
+ if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
+ pr_debug("iommu: fixed/dynamic overlap, skipping\n");
continue;
}
- io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
+
+ insert_16M_pte(uaddr, ptab, base_pte);
}
mb();
@@ -995,7 +1018,9 @@ static int __init cell_iommu_fixed_mapping_init(void)
"fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
dbase + dsize, fbase, fbase + fsize);
- cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
+ cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize);
+ iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
+ IOMMU_PAGE_SHIFT);
cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize,
fbase, fsize);
cell_iommu_enable_hardware(iommu);
diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c
index a7f609b3b876..dda34650cb07 100644
--- a/trunk/arch/powerpc/platforms/cell/setup.c
+++ b/trunk/arch/powerpc/platforms/cell/setup.c
@@ -149,6 +149,11 @@ static void __init cell_init_irq(void)
mpic_init_IRQ();
}
+static void __init cell_set_dabrx(void)
+{
+ mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
+}
+
static void __init cell_setup_arch(void)
{
#ifdef CONFIG_SPU_BASE
@@ -158,6 +163,8 @@ static void __init cell_setup_arch(void)
cbe_regs_init();
+ cell_set_dabrx();
+
#ifdef CONFIG_CBE_RAS
cbe_ras_init();
#endif
diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c
index 87eb07f94c5f..712001f6b7da 100644
--- a/trunk/arch/powerpc/platforms/cell/spu_base.c
+++ b/trunk/arch/powerpc/platforms/cell/spu_base.c
@@ -81,9 +81,12 @@ struct spu_slb {
void spu_invalidate_slbs(struct spu *spu)
{
struct spu_priv2 __iomem *priv2 = spu->priv2;
+ unsigned long flags;
+ spin_lock_irqsave(&spu->register_lock, flags);
if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
out_be64(&priv2->slb_invalidate_all_W, 0UL);
+ spin_unlock_irqrestore(&spu->register_lock, flags);
}
EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
@@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
__func__, slbe, slb->vsid, slb->esid);
out_be64(&priv2->slb_index_W, slbe);
+ /* set invalid before writing vsid */
+ out_be64(&priv2->slb_esid_RW, 0);
+ /* now it's safe to write the vsid */
out_be64(&priv2->slb_vsid_RW, slb->vsid);
+ /* setting the new esid makes the entry valid again */
out_be64(&priv2->slb_esid_RW, slb->esid);
}
@@ -290,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
nr_slbs++;
}
+ spin_lock_irq(&spu->register_lock);
/* Add the set of SLBs */
for (i = 0; i < nr_slbs; i++)
spu_load_slb(spu, i, &slbs[i]);
+ spin_unlock_irq(&spu->register_lock);
}
EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
@@ -337,13 +346,14 @@ spu_irq_class_1(int irq, void *data)
if (stat & CLASS1_STORAGE_FAULT_INTR)
spu_mfc_dsisr_set(spu, 0ul);
spu_int_stat_clear(spu, 1, stat);
- spin_unlock(&spu->register_lock);
- pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
- dar, dsisr);
if (stat & CLASS1_SEGMENT_FAULT_INTR)
__spu_trap_data_seg(spu, dar);
+ spin_unlock(&spu->register_lock);
+ pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
+ dar, dsisr);
+
if (stat & CLASS1_STORAGE_FAULT_INTR)
__spu_trap_data_map(spu, dar, dsisr);
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c
index 133995ed5cc7..cf6c2c89211d 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/context.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c
@@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx)
/*
* This is basically an open-coded spu_acquire_saved, except that
- * we don't acquire the state mutex interruptible.
+ * we don't acquire the state mutex interruptible, and we don't
+ * want this context to be rescheduled on release.
*/
mutex_lock(&ctx->state_mutex);
- if (ctx->state != SPU_STATE_SAVED) {
- set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
+ if (ctx->state != SPU_STATE_SAVED)
spu_deactivate(ctx);
- }
mm = ctx->owner;
ctx->owner = NULL;
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c
index c66c3756970d..f7a7e8635fb6 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/file.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c
@@ -366,6 +366,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
if (offset >= ps_size)
return NOPFN_SIGBUS;
+ /*
+ * Because we release the mmap_sem, the context may be destroyed while
+ * we're in spu_wait. Grab an extra reference so it isn't destroyed
+ * in the meantime.
+ */
+ get_spu_context(ctx);
+
/*
* We have to wait for context to be loaded before we have
* pages to hand out to the user, but we don't want to wait
@@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
* hanged.
*/
if (spu_acquire(ctx))
- return NOPFN_REFAULT;
+ goto refault;
if (ctx->state == SPU_STATE_SAVED) {
up_read(¤t->mm->mmap_sem);
@@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
if (!ret)
spu_release(ctx);
+
+refault:
+ put_spu_context(ctx);
return NOPFN_REFAULT;
}
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c
index 3a5972117de7..5d5f680cd0b8 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c
@@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
spu_switch_notify(spu, ctx);
ctx->state = SPU_STATE_RUNNABLE;
- spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
+ spuctx_switch_state(ctx, SPU_UTIL_USER);
}
/*
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c b/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c
index 01974f7776e1..79aa773f3c99 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n)
ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
return snprintf(tbuf, n,
- "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
+ "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
(unsigned long) tv.tv_sec,
(unsigned long) tv.tv_nsec,
- t->owner_tid,
- t->name,
t->curr_tid,
+ t->name,
+ t->owner_tid,
t->number);
}
@@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = {
{ "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
{ "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
{ "destroy_spu_context__enter", "%p", spu_context_nospu_event },
+ { "spufs_stop_callback__enter", "%p %p", spu_context_event },
};
static int __init sputrace_init(void)
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c
index 6f5886c7b1f9..e9dc7a55d1b9 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c
@@ -34,6 +34,7 @@
#include
#include
+#include
#include
#include
#include
@@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
* Write INT_MASK_class1 with value of 0.
* Save INT_Mask_class2 in CSA.
* Write INT_MASK_class2 with value of 0.
+ * Synchronize all three interrupts to be sure
+ * we no longer execute a handler on another CPU.
*/
spin_lock_irq(&spu->register_lock);
if (csa) {
@@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
spu_int_mask_set(spu, 2, 0ul);
eieio();
spin_unlock_irq(&spu->register_lock);
+ synchronize_irq(spu->irqs[0]);
+ synchronize_irq(spu->irqs[1]);
+ synchronize_irq(spu->irqs[2]);
}
static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)
diff --git a/trunk/arch/powerpc/platforms/celleb/beat.h b/trunk/arch/powerpc/platforms/celleb/beat.h
index b2e292df13ca..ac82ac35b991 100644
--- a/trunk/arch/powerpc/platforms/celleb/beat.h
+++ b/trunk/arch/powerpc/platforms/celleb/beat.h
@@ -21,9 +21,6 @@
#ifndef _CELLEB_BEAT_H
#define _CELLEB_BEAT_H
-#define DABRX_KERNEL (1UL<<1)
-#define DABRX_USER (1UL<<0)
-
int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*);
int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t);
int64_t beat_repository_encode(int, const char *, uint64_t[4]);
diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig
index b21444b681b6..1831833c430e 100644
--- a/trunk/arch/s390/Kconfig
+++ b/trunk/arch/s390/Kconfig
@@ -61,6 +61,7 @@ config S390
def_bool y
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
source "init/Kconfig"
@@ -350,6 +351,10 @@ endchoice
source "fs/Kconfig.binfmt"
+config FORCE_MAX_ZONEORDER
+ int
+ default "9"
+
config PROCESS_DEBUG
bool "Show crashed user process info"
help
diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig
index 39921f3a9685..62f6b5a606dd 100644
--- a/trunk/arch/s390/defconfig
+++ b/trunk/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24
-# Sat Feb 9 12:13:01 2008
+# Linux kernel version: 2.6.25-rc4
+# Wed Mar 5 11:22:59 2008
#
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
@@ -43,12 +43,15 @@ CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
# CONFIG_CPUSETS is not set
+CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
@@ -85,7 +88,9 @@ CONFIG_SLAB=y
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
@@ -185,6 +190,7 @@ CONFIG_IPL=y
CONFIG_IPL_VM=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
+CONFIG_FORCE_MAX_ZONEORDER=9
# CONFIG_PROCESS_DEBUG is not set
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
@@ -435,6 +441,7 @@ CONFIG_DASD_EER=y
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_IDE is not set
#
# SCSI device support
@@ -593,6 +600,7 @@ CONFIG_S390_VMUR=m
#
# Sonics Silicon Backplane
#
+# CONFIG_MEMSTICK is not set
#
# File systems
@@ -750,7 +758,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_FRAME_POINTER is not set
-CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
@@ -759,6 +766,7 @@ CONFIG_FORCED_INLINING=y
# CONFIG_LATENCYTOP is not set
CONFIG_SAMPLES=y
# CONFIG_SAMPLE_KOBJECT is not set
+# CONFIG_SAMPLE_KPROBES is not set
# CONFIG_DEBUG_PAGEALLOC is not set
#
diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile
index b3b650a93c7c..4d3e38392cb1 100644
--- a/trunk/arch/s390/kernel/Makefile
+++ b/trunk/arch/s390/kernel/Makefile
@@ -4,6 +4,11 @@
EXTRA_AFLAGS := -traditional
+#
+# Passing null pointers is ok for smp code, since we access the lowcore here.
+#
+CFLAGS_smp.o := -Wno-nonnull
+
obj-y := bitmap.o traps.o time.o process.o base.o early.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o
diff --git a/trunk/arch/s390/kernel/early.c b/trunk/arch/s390/kernel/early.c
index 9f7b73b180f0..01832c440636 100644
--- a/trunk/arch/s390/kernel/early.c
+++ b/trunk/arch/s390/kernel/early.c
@@ -88,13 +88,17 @@ static noinline __init void create_kernel_nss(void)
__cpcmd(defsys_cmd, NULL, 0, &response);
- if (response != 0)
+ if (response != 0) {
+ kernel_nss_name[0] = '\0';
return;
+ }
__cpcmd(savesys_cmd, NULL, 0, &response);
- if (response != strlen(savesys_cmd))
+ if (response != strlen(savesys_cmd)) {
+ kernel_nss_name[0] = '\0';
return;
+ }
ipl_flags = IPL_NSS_VALID;
}
diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c
index 60acdc266db1..375232c46c7a 100644
--- a/trunk/arch/s390/kernel/ipl.c
+++ b/trunk/arch/s390/kernel/ipl.c
@@ -704,6 +704,7 @@ void reipl_run(struct shutdown_trigger *trigger)
default:
break;
}
+ disabled_wait((unsigned long) __builtin_return_address(0));
}
static void __init reipl_probe(void)
diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c
index 1c59ec161cf8..ce203154d8ce 100644
--- a/trunk/arch/s390/kernel/process.c
+++ b/trunk/arch/s390/kernel/process.c
@@ -152,6 +152,10 @@ static void default_idle(void)
local_mcck_disable();
if (test_thread_flag(TIF_MCCK_PENDING)) {
local_mcck_enable();
+ /* disable monitor call class 0 */
+ __ctl_clear_bit(8, 15);
+ atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
+ hcpu);
local_irq_enable();
s390_handle_mcck();
return;
diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c
index 818bd09c0260..8f894d380a62 100644
--- a/trunk/arch/s390/kernel/smp.c
+++ b/trunk/arch/s390/kernel/smp.c
@@ -629,14 +629,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
panic_stack = __get_free_page(GFP_KERNEL);
if (!panic_stack || !async_stack)
goto out;
- /*
- * Only need to copy the first 512 bytes from address 0. But since
- * the compiler emits a warning if src == NULL for memcpy use copy_page
- * instead. Copies more than needed but this code is not performance
- * critical.
- */
- copy_page(lowcore, &S390_lowcore);
- memset((void *)lowcore + 512, 0, sizeof(*lowcore) - 512);
+ memcpy(lowcore, &S390_lowcore, 512);
+ memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
lowcore->async_stack = async_stack + ASYNC_SIZE;
lowcore->panic_stack = panic_stack + PAGE_SIZE;
diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c
index 76a5dd1b4ce9..cb232c155360 100644
--- a/trunk/arch/s390/kernel/time.c
+++ b/trunk/arch/s390/kernel/time.c
@@ -209,8 +209,6 @@ static void stop_hz_timer(void)
*/
static void start_hz_timer(void)
{
- BUG_ON(!in_interrupt());
-
if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
return;
account_ticks(get_clock());
diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig
index b3400b5ad5c6..783cfbbf87ca 100644
--- a/trunk/arch/sh/Kconfig
+++ b/trunk/arch/sh/Kconfig
@@ -330,6 +330,7 @@ config CPU_SUBTYPE_SH5_101
config CPU_SUBTYPE_SH5_103
bool "Support SH5-103 processor"
+ select CPU_SH5
endchoice
diff --git a/trunk/arch/sh/drivers/dma/dma-sh.c b/trunk/arch/sh/drivers/dma/dma-sh.c
index 5c3359756a92..71ff3d6f26e2 100644
--- a/trunk/arch/sh/drivers/dma/dma-sh.c
+++ b/trunk/arch/sh/drivers/dma/dma-sh.c
@@ -90,7 +90,7 @@ static irqreturn_t dma_tei(int irq, void *dev_id)
static int sh_dmac_request_dma(struct dma_channel *chan)
{
- if (unlikely(!chan->flags & DMA_TEI_CAPABLE))
+ if (unlikely(!(chan->flags & DMA_TEI_CAPABLE)))
return 0;
return request_irq(get_dmte_irq(chan->chan), dma_tei,
diff --git a/trunk/arch/sh/drivers/heartbeat.c b/trunk/arch/sh/drivers/heartbeat.c
index b76a14f12ce2..ab77b0e0fa0e 100644
--- a/trunk/arch/sh/drivers/heartbeat.c
+++ b/trunk/arch/sh/drivers/heartbeat.c
@@ -93,7 +93,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
}
hd->base = ioremap_nocache(res->start, res->end - res->start + 1);
- if (!unlikely(hd->base)) {
+ if (unlikely(!hd->base)) {
dev_err(&pdev->dev, "ioremap failed\n");
if (!pdev->dev.platform_data)
diff --git a/trunk/arch/sh/drivers/pci/ops-dreamcast.c b/trunk/arch/sh/drivers/pci/ops-dreamcast.c
index 0dac87b19624..e1284fc69361 100644
--- a/trunk/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/trunk/arch/sh/drivers/pci/ops-dreamcast.c
@@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
- case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break;
- case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break;
- case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break;
+ case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
+ case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
+ case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
}
return PCIBIOS_SUCCESSFUL;
@@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int
return PCIBIOS_DEVICE_NOT_FOUND;
switch (size) {
- case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
- case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
- case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
+ case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
}
return PCIBIOS_SUCCESSFUL;
@@ -127,36 +127,36 @@ int __init gapspci_init(void)
*/
for (i=0; i<16; i++)
- idbuf[i] = ctrl_inb(GAPSPCI_REGS+i);
+ idbuf[i] = inb(GAPSPCI_REGS+i);
if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
return -ENODEV;
- ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18);
+ outl(0x5a14a501, GAPSPCI_REGS+0x18);
for (i=0; i<1000000; i++)
;
- if (ctrl_inl(GAPSPCI_REGS+0x18) != 1)
+ if (inl(GAPSPCI_REGS+0x18) != 1)
return -EINVAL;
- ctrl_outl(0x01000000, GAPSPCI_REGS+0x20);
- ctrl_outl(0x01000000, GAPSPCI_REGS+0x24);
+ outl(0x01000000, GAPSPCI_REGS+0x20);
+ outl(0x01000000, GAPSPCI_REGS+0x24);
- ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
- ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
+ outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
+ outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
- ctrl_outl(1, GAPSPCI_REGS+0x14);
- ctrl_outl(1, GAPSPCI_REGS+0x34);
+ outl(1, GAPSPCI_REGS+0x14);
+ outl(1, GAPSPCI_REGS+0x34);
/* Setting Broadband Adapter */
- ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
- ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
- ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
- ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
- ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
- ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
- ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
+ outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
+ outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
+ outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
+ outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
+ outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
+ outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
+ outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
return 0;
}
diff --git a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index b230eb278cef..cc530f4d84d6 100644
--- a/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/trunk/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
enum {
UNUSED = 0,
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
index 3feb95a4fcbc..fb781329848a 100644
--- a/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
+++ b/trunk/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
@@ -21,8 +21,8 @@
#include
#include
-const static int pll1rate[]={8,12,16,0};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
+static const int pll1rate[]={8,12,16,0};
+static const int pfc_divisors[]={1,2,3,4,6,8,12};
#define ifc_divisors pfc_divisors
#if (CONFIG_SH_CLK_MD == 0)
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index db6ef5cecde1..e98dc4450352 100644
--- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
enum {
UNUSED = 0,
diff --git a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index a564425b905f..e6d4ec445dd8 100644
--- a/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/trunk/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
enum {
UNUSED = 0,
diff --git a/trunk/arch/sh/kernel/cpu/sh3/probe.c b/trunk/arch/sh/kernel/cpu/sh3/probe.c
index fcc80bb7bee7..10f2a760c5ee 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/probe.c
+++ b/trunk/arch/sh/kernel/cpu/sh3/probe.c
@@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
boot_cpu_data.dcache.way_incr = (1 << 13);
boot_cpu_data.dcache.entry_mask = 0x1ff0;
boot_cpu_data.dcache.sets = 512;
- ctrl_outl(CCR_CACHE_32KB, CCR3);
+ ctrl_outl(CCR_CACHE_32KB, CCR3_REG);
#else
- ctrl_outl(CCR_CACHE_16KB, CCR3);
+ ctrl_outl(CCR_CACHE_16KB, CCR3_REG);
#endif
#endif
}
diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index dd0a20a685f7..f581534cb732 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
#include
enum {
diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 969804bb523b..d3733b13ea52 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -16,7 +16,7 @@
#include
#include
#include
-#include
+#include
enum {
UNUSED = 0,
@@ -123,15 +123,15 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- .start = 20,
+ .start = 21,
.flags = IORESOURCE_IRQ,
},
[2] = {
- .start = 21,
+ .start = 22,
.flags = IORESOURCE_IRQ,
},
[3] = {
- .start = 22,
+ .start = 20,
.flags = IORESOURCE_IRQ,
},
};
diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 0cc0e2bf135d..7406c9ad9259 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
#include
enum {
diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index 3855ea4c21c8..8028082527c5 100644
--- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -16,7 +16,7 @@
#include
#include
#include
-#include
+#include
#include
#define INTC_ICR1 0xA4140010UL
diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index dab193293f20..7371abf64f80 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index ae3603aca615..ec884039b914 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
static struct resource rtc_resources[] = {
[0] = {
diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 85f81579b97e..254c5c55ab91 100644
--- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
enum {
UNUSED = 0,
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index c0a3f079dfdc..6d4f50cd4aaf 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 967e8b69a2f8..f26b5cdad0d1 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 73c778d40d13..b98b4bc93ec9 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -10,9 +10,9 @@
#include
#include
#include
+#include
#include
#include
-#include
static struct resource usbf_resources[] = {
[0] = {
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index eabd5386812d..07c988dc9de6 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
static struct resource rtc_resources[] = {
[0] = {
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
index 32f4f59a837b..b9cec48b1808 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7770.c
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index 293004b526ff..18dbbe23fea1 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -11,7 +11,7 @@
#include
#include
#include
-#include
+#include
static struct resource rtc_resources[] = {
[0] = {
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 74b60e96cdf4..621e7329ec63 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -10,10 +10,10 @@
#include
#include
#include
+#include
#include
#include
#include
-#include
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 4dc958b6b314..bd35f32534b9 100644
--- a/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -10,9 +10,9 @@
#include
#include
#include
+#include
#include
#include
-#include
static struct plat_sci_port sci_platform_data[] = {
{
diff --git a/trunk/arch/sparc/kernel/Makefile b/trunk/arch/sparc/kernel/Makefile
index e795f282dece..bf1b15d3f6f5 100644
--- a/trunk/arch/sparc/kernel/Makefile
+++ b/trunk/arch/sparc/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $
+#
# Makefile for the linux kernel.
#
@@ -12,7 +12,8 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
sys_sparc.o sunos_asm.o systbls.o \
time.o windows.o cpu.o devices.o sclow.o \
tadpole.o tick14.o ptrace.o sys_solaris.o \
- unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o
+ unaligned.o una_asm.o muldiv.o semaphore.o \
+ prom.o of_device.o devres.o
devres-y = ../../../kernel/irq/devres.o
diff --git a/trunk/arch/sparc/kernel/cpu.c b/trunk/arch/sparc/kernel/cpu.c
index 259a559d4cea..e7a0edfc1a32 100644
--- a/trunk/arch/sparc/kernel/cpu.c
+++ b/trunk/arch/sparc/kernel/cpu.c
@@ -32,7 +32,7 @@ struct cpu_fp_info {
/* In order to get the fpu type correct, you need to take the IDPROM's
* machine type value into consideration too. I will fix this.
*/
-struct cpu_fp_info linux_sparc_fpu[] = {
+static struct cpu_fp_info linux_sparc_fpu[] = {
{ 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"},
{ 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"},
{ 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"},
@@ -76,7 +76,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-struct cpu_iu_info linux_sparc_chips[] = {
+static struct cpu_iu_info linux_sparc_chips[] = {
/* Sun4/100, 4/200, SLC */
{ 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"},
/* borned STP1012PGA */
diff --git a/trunk/arch/sparc/kernel/ebus.c b/trunk/arch/sparc/kernel/ebus.c
index d850785b2080..96344ff2bbe1 100644
--- a/trunk/arch/sparc/kernel/ebus.c
+++ b/trunk/arch/sparc/kernel/ebus.c
@@ -101,7 +101,7 @@ void __init fill_ebus_child(struct device_node *dp,
prom_printf("UGH: property for %s was %d, need < %d\n",
dev->prom_node->name, len,
dev->parent->num_addrs);
- panic(__FUNCTION__);
+ panic(__func__);
}
/* XXX resource */
@@ -162,7 +162,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
dev->prom_node->name, len,
(int)sizeof(struct linux_prom_registers));
- panic(__FUNCTION__);
+ panic(__func__);
}
dev->num_addrs = len / sizeof(struct linux_prom_registers);
@@ -324,7 +324,7 @@ void __init ebus_init(void)
regs = of_get_property(dp, "reg", &len);
if (!regs) {
prom_printf("%s: can't find reg property\n",
- __FUNCTION__);
+ __func__);
prom_halt();
}
nreg = len / sizeof(struct linux_prom_pci_registers);
diff --git a/trunk/arch/sparc/kernel/led.c b/trunk/arch/sparc/kernel/led.c
index 313d1620ae8e..59e9344e7a0d 100644
--- a/trunk/arch/sparc/kernel/led.c
+++ b/trunk/arch/sparc/kernel/led.c
@@ -3,6 +3,9 @@
#include
#include
#include
+#include
+#include
+#include
#include
diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c
index 0bd69d0b5cd7..70c0dd22491d 100644
--- a/trunk/arch/sparc/kernel/process.c
+++ b/trunk/arch/sparc/kernel/process.c
@@ -139,8 +139,6 @@ void cpu_idle(void)
#endif
-extern char reboot_command [];
-
/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
void machine_halt(void)
{
diff --git a/trunk/arch/sparc/kernel/una_asm.S b/trunk/arch/sparc/kernel/una_asm.S
new file mode 100644
index 000000000000..8cc03458eb7e
--- /dev/null
+++ b/trunk/arch/sparc/kernel/una_asm.S
@@ -0,0 +1,153 @@
+/* una_asm.S: Kernel unaligned trap assembler helpers.
+ *
+ * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include
+
+ .text
+
+retl_efault:
+ retl
+ mov -EFAULT, %o0
+
+ /* int __do_int_store(unsigned long *dst_addr, int size,
+ * unsigned long *src_val)
+ *
+ * %o0 = dest_addr
+ * %o1 = size
+ * %o2 = src_val
+ *
+ * Return '0' on success, -EFAULT on failure.
+ */
+ .globl __do_int_store
+__do_int_store:
+ ld [%o2], %g1
+ cmp %1, 2
+ be 2f
+ cmp %1, 4
+ be 1f
+ srl %g1, 24, %g2
+ srl %g1, 16, %g7
+4: stb %g2, [%o0]
+ srl %g1, 8, %g2
+5: stb %g7, [%o0 + 1]
+ ld [%o2 + 4], %g7
+6: stb %g2, [%o0 + 2]
+ srl %g7, 24, %g2
+7: stb %g1, [%o0 + 3]
+ srl %g7, 16, %g1
+8: stb %g2, [%o0 + 4]
+ srl %g7, 8, %g2
+9: stb %g1, [%o0 + 5]
+10: stb %g2, [%o0 + 6]
+ b 0f
+11: stb %g7, [%o0 + 7]
+1: srl %g1, 16, %g7
+12: stb %g2, [%o0]
+ srl %g1, 8, %g2
+13: stb %g7, [%o0 + 1]
+14: stb %g2, [%o0 + 2]
+ b 0f
+15: stb %g1, [%o0 + 3]
+2: srl %g1, 8, %g2
+16: stb %g2, [%o0]
+17: stb %g1, [%o0 + 1]
+0: retl
+ mov 0, %o0
+
+ .section __ex_table,#alloc
+ .word 4b, retl_efault
+ .word 5b, retl_efault
+ .word 6b, retl_efault
+ .word 7b, retl_efault
+ .word 8b, retl_efault
+ .word 9b, retl_efault
+ .word 10b, retl_efault
+ .word 11b, retl_efault
+ .word 12b, retl_efault
+ .word 13b, retl_efault
+ .word 14b, retl_efault
+ .word 15b, retl_efault
+ .word 16b, retl_efault
+ .word 17b, retl_efault
+ .previous
+
+ /* int do_int_load(unsigned long *dest_reg, int size,
+ * unsigned long *saddr, int is_signed)
+ *
+ * %o0 = dest_reg
+ * %o1 = size
+ * %o2 = saddr
+ * %o3 = is_signed
+ *
+ * Return '0' on success, -EFAULT on failure.
+ */
+ .globl do_int_load
+do_int_load:
+ cmp %o1, 8
+ be 9f
+ cmp %o1, 4
+ be 6f
+4: ldub [%o2], %g1
+5: ldub [%o2 + 1], %g2
+ sll %g1, 8, %g1
+ tst %o3
+ be 3f
+ or %g1, %g2, %g1
+ sll %g1, 16, %g1
+ sra %g1, 16, %g1
+3: b 0f
+ st %g1, [%o0]
+6: ldub [%o2 + 1], %g2
+ sll %g1, 24, %g1
+7: ldub [%o2 + 2], %g7
+ sll %g2, 16, %g2
+8: ldub [%o2 + 3], %g3
+ sll %g7, 8, %g7
+ or %g3, %g2, %g3
+ or %g7, %g3, %g7
+ or %g1, %g7, %g1
+ b 0f
+ st %g1, [%o0]
+9: ldub [%o2], %g1
+10: ldub [%o2 + 1], %g2
+ sll %g1, 24, %g1
+11: ldub [%o2 + 2], %g7
+ sll %g2, 16, %g2
+12: ldub [%o2 + 3], %g3
+ sll %g7, 8, %g7
+ or %g1, %g2, %g1
+ or %g7, %g3, %g7
+ or %g1, %g7, %g7
+13: ldub [%o2 + 4], %g1
+ st %g7, [%o0]
+14: ldub [%o2 + 5], %g2
+ sll %g1, 24, %g1
+15: ldub [%o2 + 6], %g7
+ sll %g2, 16, %g2
+16: ldub [%o2 + 7], %g3
+ sll %g7, 8, %g7
+ or %g1, %g2, %g1
+ or %g7, %g3, %g7
+ or %g1, %g7, %g7
+ st %g7, [%o0 + 4]
+0: retl
+ mov 0, %o0
+
+ .section __ex_table,#alloc
+ .word 4b, retl_efault
+ .word 5b, retl_efault
+ .word 6b, retl_efault
+ .word 7b, retl_efault
+ .word 8b, retl_efault
+ .word 9b, retl_efault
+ .word 10b, retl_efault
+ .word 11b, retl_efault
+ .word 12b, retl_efault
+ .word 13b, retl_efault
+ .word 14b, retl_efault
+ .word 15b, retl_efault
+ .word 16b, retl_efault
+ .previous
diff --git a/trunk/arch/sparc/kernel/unaligned.c b/trunk/arch/sparc/kernel/unaligned.c
index a6330fbc9dd9..33857be16661 100644
--- a/trunk/arch/sparc/kernel/unaligned.c
+++ b/trunk/arch/sparc/kernel/unaligned.c
@@ -175,157 +175,31 @@ static void unaligned_panic(char *str)
panic(str);
}
-#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({ \
-__asm__ __volatile__ ( \
- "cmp %1, 8\n\t" \
- "be 9f\n\t" \
- " cmp %1, 4\n\t" \
- "be 6f\n" \
-"4:\t" " ldub [%2], %%l1\n" \
-"5:\t" "ldub [%2 + 1], %%l2\n\t" \
- "sll %%l1, 8, %%l1\n\t" \
- "tst %3\n\t" \
- "be 3f\n\t" \
- " add %%l1, %%l2, %%l1\n\t" \
- "sll %%l1, 16, %%l1\n\t" \
- "sra %%l1, 16, %%l1\n" \
-"3:\t" "b 0f\n\t" \
- " st %%l1, [%0]\n" \
-"6:\t" "ldub [%2 + 1], %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"7:\t" "ldub [%2 + 2], %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"8:\t" "ldub [%2 + 3], %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%l1\n\t" \
- "b 0f\n\t" \
- " st %%l1, [%0]\n" \
-"9:\t" "ldub [%2], %%l1\n" \
-"10:\t" "ldub [%2 + 1], %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"11:\t" "ldub [%2 + 2], %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"12:\t" "ldub [%2 + 3], %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%g7\n" \
-"13:\t" "ldub [%2 + 4], %%l1\n\t" \
- "st %%g7, [%0]\n" \
-"14:\t" "ldub [%2 + 5], %%l2\n\t" \
- "sll %%l1, 24, %%l1\n" \
-"15:\t" "ldub [%2 + 6], %%g7\n\t" \
- "sll %%l2, 16, %%l2\n" \
-"16:\t" "ldub [%2 + 7], %%g1\n\t" \
- "sll %%g7, 8, %%g7\n\t" \
- "or %%l1, %%l2, %%l1\n\t" \
- "or %%g7, %%g1, %%g7\n\t" \
- "or %%l1, %%g7, %%g7\n\t" \
- "st %%g7, [%0 + 4]\n" \
-"0:\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".word 4b, " #errh "\n\t" \
- ".word 5b, " #errh "\n\t" \
- ".word 6b, " #errh "\n\t" \
- ".word 7b, " #errh "\n\t" \
- ".word 8b, " #errh "\n\t" \
- ".word 9b, " #errh "\n\t" \
- ".word 10b, " #errh "\n\t" \
- ".word 11b, " #errh "\n\t" \
- ".word 12b, " #errh "\n\t" \
- ".word 13b, " #errh "\n\t" \
- ".word 14b, " #errh "\n\t" \
- ".word 15b, " #errh "\n\t" \
- ".word 16b, " #errh "\n\n\t" \
- ".previous\n\t" \
- : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \
- : "l1", "l2", "g7", "g1", "cc"); \
-})
-
-#define store_common(dst_addr, size, src_val, errh) ({ \
-__asm__ __volatile__ ( \
- "ld [%2], %%l1\n" \
- "cmp %1, 2\n\t" \
- "be 2f\n\t" \
- " cmp %1, 4\n\t" \
- "be 1f\n\t" \
- " srl %%l1, 24, %%l2\n\t" \
- "srl %%l1, 16, %%g7\n" \
-"4:\t" "stb %%l2, [%0]\n\t" \
- "srl %%l1, 8, %%l2\n" \
-"5:\t" "stb %%g7, [%0 + 1]\n\t" \
- "ld [%2 + 4], %%g7\n" \
-"6:\t" "stb %%l2, [%0 + 2]\n\t" \
- "srl %%g7, 24, %%l2\n" \
-"7:\t" "stb %%l1, [%0 + 3]\n\t" \
- "srl %%g7, 16, %%l1\n" \
-"8:\t" "stb %%l2, [%0 + 4]\n\t" \
- "srl %%g7, 8, %%l2\n" \
-"9:\t" "stb %%l1, [%0 + 5]\n" \
-"10:\t" "stb %%l2, [%0 + 6]\n\t" \
- "b 0f\n" \
-"11:\t" " stb %%g7, [%0 + 7]\n" \
-"1:\t" "srl %%l1, 16, %%g7\n" \
-"12:\t" "stb %%l2, [%0]\n\t" \
- "srl %%l1, 8, %%l2\n" \
-"13:\t" "stb %%g7, [%0 + 1]\n" \
-"14:\t" "stb %%l2, [%0 + 2]\n\t" \
- "b 0f\n" \
-"15:\t" " stb %%l1, [%0 + 3]\n" \
-"2:\t" "srl %%l1, 8, %%l2\n" \
-"16:\t" "stb %%l2, [%0]\n" \
-"17:\t" "stb %%l1, [%0 + 1]\n" \
-"0:\n\n\t" \
- ".section __ex_table,#alloc\n\t" \
- ".word 4b, " #errh "\n\t" \
- ".word 5b, " #errh "\n\t" \
- ".word 6b, " #errh "\n\t" \
- ".word 7b, " #errh "\n\t" \
- ".word 8b, " #errh "\n\t" \
- ".word 9b, " #errh "\n\t" \
- ".word 10b, " #errh "\n\t" \
- ".word 11b, " #errh "\n\t" \
- ".word 12b, " #errh "\n\t" \
- ".word 13b, " #errh "\n\t" \
- ".word 14b, " #errh "\n\t" \
- ".word 15b, " #errh "\n\t" \
- ".word 16b, " #errh "\n\t" \
- ".word 17b, " #errh "\n\n\t" \
- ".previous\n\t" \
- : : "r" (dst_addr), "r" (size), "r" (src_val) \
- : "l1", "l2", "g7", "g1", "cc"); \
-})
-
-#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({ \
- unsigned long *src_val; \
- static unsigned long zero[2] = { 0, }; \
- \
- if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
- else { \
- src_val = &zero[0]; \
- if (size == 8) \
- zero[1] = fetch_reg(1, regs); \
- } \
- store_common(dst_addr, size, src_val, errh); \
-})
+/* una_asm.S */
+extern int do_int_load(unsigned long *dest_reg, int size,
+ unsigned long *saddr, int is_signed);
+extern int __do_int_store(unsigned long *dst_addr, int size,
+ unsigned long *src_val);
+
+static int do_int_store(int reg_num, int size, unsigned long *dst_addr,
+ struct pt_regs *regs)
+{
+ unsigned long zero[2] = { 0, 0 };
+ unsigned long *src_val;
+
+ if (reg_num)
+ src_val = fetch_reg_addr(reg_num, regs);
+ else {
+ src_val = &zero[0];
+ if (size == 8)
+ zero[1] = fetch_reg(1, regs);
+ }
+ return __do_int_store(dst_addr, size, src_val);
+}
extern void smp_capture(void);
extern void smp_release(void);
-#define do_atomic(srcdest_reg, mem, errh) ({ \
- unsigned long flags, tmp; \
- \
- smp_capture(); \
- local_irq_save(flags); \
- tmp = *srcdest_reg; \
- do_integer_load(srcdest_reg, 4, mem, 0, errh); \
- store_common(mem, 4, &tmp, errh); \
- local_irq_restore(flags); \
- smp_release(); \
-})
-
static inline void advance(struct pt_regs *regs)
{
regs->pc = regs->npc;
@@ -342,9 +216,7 @@ static inline int ok_for_kernel(unsigned int insn)
return !floating_point_load_or_store_p(insn);
}
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
-
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
{
unsigned long g2 = regs->u_regs [UREG_G2];
unsigned long fixup = search_extables_range(regs->pc, &g2);
@@ -379,48 +251,34 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
regs->pc);
unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
-
- __asm__ __volatile__ ("\n"
-"kernel_unaligned_trap_fault:\n\t"
- "mov %0, %%o0\n\t"
- "call kernel_mna_trap_fault\n\t"
- " mov %1, %%o1\n\t"
- :
- : "r" (regs), "r" (insn)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
} else {
unsigned long addr = compute_effective_address(regs, insn);
+ int err;
#ifdef DEBUG_MNA
printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
#endif
- switch(dir) {
+ switch (dir) {
case load:
- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
- size, (unsigned long *) addr,
- decode_signedness(insn),
- kernel_unaligned_trap_fault);
+ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
+ regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn));
break;
case store:
- do_integer_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs,
- kernel_unaligned_trap_fault);
+ err = do_int_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs);
break;
-#if 0 /* unsupported */
- case both:
- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
- (unsigned long *) addr,
- kernel_unaligned_trap_fault);
- break;
-#endif
default:
panic("Impossible kernel unaligned trap.");
/* Not reached... */
}
- advance(regs);
+ if (err)
+ kernel_mna_trap_fault(regs, insn);
+ else
+ advance(regs);
}
}
@@ -459,9 +317,7 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
return 0;
}
-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
-
-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
{
siginfo_t info;
@@ -485,7 +341,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
if(!ok_for_user(regs, insn, dir)) {
goto kill_user;
} else {
- int size = decode_access_size(insn);
+ int err, size = decode_access_size(insn);
unsigned long addr;
if(floating_point_load_or_store_p(insn)) {
@@ -496,48 +352,34 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
addr = compute_effective_address(regs, insn);
switch(dir) {
case load:
- do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
- size, (unsigned long *) addr,
- decode_signedness(insn),
- user_unaligned_trap_fault);
+ err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
+ regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn));
break;
case store:
- do_integer_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs,
- user_unaligned_trap_fault);
+ err = do_int_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs);
break;
case both:
-#if 0 /* unsupported */
- do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
- (unsigned long *) addr,
- user_unaligned_trap_fault);
-#else
/*
* This was supported in 2.4. However, we question
* the value of SWAP instruction across word boundaries.
*/
printk("Unaligned SWAP unsupported.\n");
- goto kill_user;
-#endif
+ err = -EFAULT;
break;
default:
unaligned_panic("Impossible user unaligned trap.");
-
- __asm__ __volatile__ ("\n"
-"user_unaligned_trap_fault:\n\t"
- "mov %0, %%o0\n\t"
- "call user_mna_trap_fault\n\t"
- " mov %1, %%o1\n\t"
- :
- : "r" (regs), "r" (insn)
- : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
- "g1", "g2", "g3", "g4", "g5", "g7", "cc");
goto out;
}
- advance(regs);
+ if (err)
+ goto kill_user;
+ else
+ advance(regs);
goto out;
}
diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig
index 3af378ddb6ae..463d1be32c98 100644
--- a/trunk/arch/sparc64/Kconfig
+++ b/trunk/arch/sparc64/Kconfig
@@ -10,6 +10,7 @@ config SPARC
default y
select HAVE_OPROFILE
select HAVE_KPROBES
+ select HAVE_KRETPROBES
config SPARC64
bool
diff --git a/trunk/arch/sparc64/kernel/cpu.c b/trunk/arch/sparc64/kernel/cpu.c
index e43db73f2b91..dd5d28e3d798 100644
--- a/trunk/arch/sparc64/kernel/cpu.c
+++ b/trunk/arch/sparc64/kernel/cpu.c
@@ -30,7 +30,7 @@ struct cpu_fp_info {
char* fp_name;
};
-struct cpu_fp_info linux_sparc_fpu[] = {
+static struct cpu_fp_info linux_sparc_fpu[] = {
{ 0x17, 0x10, 0, "UltraSparc I integrated FPU"},
{ 0x22, 0x10, 0, "UltraSparc I integrated FPU"},
{ 0x17, 0x11, 0, "UltraSparc II integrated FPU"},
@@ -46,7 +46,7 @@ struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-struct cpu_iu_info linux_sparc_chips[] = {
+static struct cpu_iu_info linux_sparc_chips[] = {
{ 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x22, 0x10, "TI UltraSparc I (SpitFire)"},
{ 0x17, 0x11, "TI UltraSparc II (BlackBird)"},
diff --git a/trunk/arch/sparc64/kernel/ds.c b/trunk/arch/sparc64/kernel/ds.c
index eeb5a2fc788d..bd76482077be 100644
--- a/trunk/arch/sparc64/kernel/ds.c
+++ b/trunk/arch/sparc64/kernel/ds.c
@@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
}
}
-static int dr_cpu_configure(struct ds_info *dp,
- struct ds_cap_state *cp,
- u64 req_num,
- cpumask_t *mask)
+static int __cpuinit dr_cpu_configure(struct ds_info *dp,
+ struct ds_cap_state *cp,
+ u64 req_num,
+ cpumask_t *mask)
{
struct ds_data *resp;
int resp_len, ncpus, cpu;
@@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp,
return 0;
}
-static void dr_cpu_data(struct ds_info *dp,
- struct ds_cap_state *cp,
- void *buf, int len)
+static void __cpuinit dr_cpu_data(struct ds_info *dp,
+ struct ds_cap_state *cp,
+ void *buf, int len)
{
struct ds_data *data = buf;
struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
diff --git a/trunk/arch/sparc64/kernel/hvtramp.S b/trunk/arch/sparc64/kernel/hvtramp.S
index b692e044a463..0236c43772fa 100644
--- a/trunk/arch/sparc64/kernel/hvtramp.S
+++ b/trunk/arch/sparc64/kernel/hvtramp.S
@@ -3,6 +3,8 @@
* Copyright (C) 2007 David S. Miller
*/
+#include
+
#include
#include
#include
@@ -13,7 +15,7 @@
#include
#include
- .text
+ __CPUINIT
.align 8
.globl hv_cpu_startup, hv_cpu_startup_end
diff --git a/trunk/arch/sparc64/kernel/iommu.c b/trunk/arch/sparc64/kernel/iommu.c
index 0e347ff812a3..fbaab3497bfd 100644
--- a/trunk/arch/sparc64/kernel/iommu.c
+++ b/trunk/arch/sparc64/kernel/iommu.c
@@ -134,7 +134,8 @@ unsigned long iommu_range_alloc(struct device *dev,
else
boundary_size = ALIGN(1UL << 32, 1 << IO_PAGE_SHIFT);
- n = iommu_area_alloc(arena->map, limit, start, npages, 0,
+ n = iommu_area_alloc(arena->map, limit, start, npages,
+ iommu->page_table_map_base >> IO_PAGE_SHIFT,
boundary_size >> IO_PAGE_SHIFT, 0);
if (n == -1) {
if (likely(pass < 1)) {
diff --git a/trunk/arch/sparc64/kernel/kprobes.c b/trunk/arch/sparc64/kernel/kprobes.c
index 34fc3ddd5002..f43b5d755354 100644
--- a/trunk/arch/sparc64/kernel/kprobes.c
+++ b/trunk/arch/sparc64/kernel/kprobes.c
@@ -465,8 +465,6 @@ void __kprobes jprobe_return(void)
extern void jprobe_return_trap_instruction(void);
-extern void __show_regs(struct pt_regs * regs);
-
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
u32 *addr = (u32 *) regs->tpc;
diff --git a/trunk/arch/sparc64/kernel/mdesc.c b/trunk/arch/sparc64/kernel/mdesc.c
index 856659bb1311..910083589569 100644
--- a/trunk/arch/sparc64/kernel/mdesc.c
+++ b/trunk/arch/sparc64/kernel/mdesc.c
@@ -758,7 +758,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
}
-void __devinit mdesc_fill_in_cpu_data(cpumask_t mask)
+void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
{
struct mdesc_handle *hp = mdesc_grab();
u64 mp;
diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c
index 850cdffdd69c..eae8ca2a6ba5 100644
--- a/trunk/arch/sparc64/kernel/power.c
+++ b/trunk/arch/sparc64/kernel/power.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
@@ -39,8 +40,6 @@ static irqreturn_t power_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-extern void machine_halt(void);
-extern void machine_alt_power_off(void);
static void (*poweroff_method)(void) = machine_alt_power_off;
void machine_power_off(void)
diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c
index 6eceac51ae62..e116e38b160e 100644
--- a/trunk/arch/sparc64/kernel/process.c
+++ b/trunk/arch/sparc64/kernel/process.c
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
@@ -47,6 +48,8 @@
#include
#include
#include
+#include
+#include
/* #define VERBOSE_SHOWREGS */
@@ -111,8 +114,6 @@ void cpu_idle(void)
}
}
-extern char reboot_command [];
-
void machine_halt(void)
{
sstate_halt();
@@ -211,62 +212,6 @@ static void show_regwindow(struct pt_regs *regs)
print_symbol("I7: <%s>\n", rwk->ins[7]);
}
-void show_stackframe(struct sparc_stackf *sf)
-{
- unsigned long size;
- unsigned long *stk;
- int i;
-
- printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
- "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
- "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
- sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
- printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n"
- "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n",
- (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME_SZ;
- stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
- i = 0;
- do {
- printk("s%d: %016lx\n", i++, *stk++);
- } while ((size -= sizeof(unsigned long)));
-}
-
-void show_stackframe32(struct sparc_stackf32 *sf)
-{
- unsigned long size;
- unsigned *stk;
- int i;
-
- printk("l0: %08x l1: %08x l2: %08x l3: %08x\n",
- sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3]);
- printk("l4: %08x l5: %08x l6: %08x l7: %08x\n",
- sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
- printk("i0: %08x i1: %08x i2: %08x i3: %08x\n",
- sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3]);
- printk("i4: %08x i5: %08x fp: %08x ret_pc: %08x\n",
- sf->ins[4], sf->ins[5], sf->fp, sf->callers_pc);
- printk("sp: %08x x0: %08x x1: %08x x2: %08x\n"
- "x3: %08x x4: %08x x5: %08x xx: %08x\n",
- sf->structptr, sf->xargs[0], sf->xargs[1],
- sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
- sf->xxargs[0]);
- size = ((unsigned long)sf->fp) - ((unsigned long)sf);
- size -= STACKFRAME32_SZ;
- stk = (unsigned *)((unsigned long)sf + STACKFRAME32_SZ);
- i = 0;
- do {
- printk("s%d: %08x\n", i++, *stk++);
- } while ((size -= sizeof(unsigned)));
-}
-
#ifdef CONFIG_SMP
static DEFINE_SPINLOCK(regdump_lock);
#endif
@@ -354,24 +299,6 @@ void show_regs(struct pt_regs *regs)
#endif
}
-void show_regs32(struct pt_regs32 *regs)
-{
- printk("PSR: %08x PC: %08x NPC: %08x Y: %08x %s\n", regs->psr,
- regs->pc, regs->npc, regs->y, print_tainted());
- printk("g0: %08x g1: %08x g2: %08x g3: %08x ",
- regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
- regs->u_regs[3]);
- printk("g4: %08x g5: %08x g6: %08x g7: %08x\n",
- regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
- regs->u_regs[7]);
- printk("o0: %08x o1: %08x o2: %08x o3: %08x ",
- regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
- regs->u_regs[11]);
- printk("o4: %08x o5: %08x sp: %08x ret_pc: %08x\n",
- regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
- regs->u_regs[15]);
-}
-
unsigned long thread_saved_pc(struct task_struct *tsk)
{
struct thread_info *ti = task_thread_info(tsk);
diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c
index a8052b76df41..cc454731d879 100644
--- a/trunk/arch/sparc64/kernel/smp.c
+++ b/trunk/arch/sparc64/kernel/smp.c
@@ -86,7 +86,7 @@ extern void setup_sparc64_timer(void);
static volatile unsigned long callin_flag = 0;
-void __devinit smp_callin(void)
+void __cpuinit smp_callin(void)
{
int cpuid = hard_smp_processor_id();
diff --git a/trunk/arch/sparc64/kernel/trampoline.S b/trunk/arch/sparc64/kernel/trampoline.S
index 04e81dda13d0..4ae2e525d68b 100644
--- a/trunk/arch/sparc64/kernel/trampoline.S
+++ b/trunk/arch/sparc64/kernel/trampoline.S
@@ -4,6 +4,8 @@
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
+#include
+
#include
#include
#include
@@ -36,7 +38,7 @@ dtlb_load:
tramp_stack:
.skip TRAMP_STACK_SIZE
- .text
+ __CPUINIT
.align 8
.globl sparc64_cpu_startup, sparc64_cpu_startup_end
sparc64_cpu_startup:
diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c
index 2b6abf633343..007f5317c0de 100644
--- a/trunk/arch/sparc64/kernel/traps.c
+++ b/trunk/arch/sparc64/kernel/traps.c
@@ -1791,8 +1791,6 @@ static const char *sun4v_err_type_to_str(u32 type)
};
}
-extern void __show_regs(struct pt_regs * regs);
-
static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
{
int cnt;
diff --git a/trunk/arch/sparc64/mm/fault.c b/trunk/arch/sparc64/mm/fault.c
index e2027f27c0fe..2650d0d33ac2 100644
--- a/trunk/arch/sparc64/mm/fault.c
+++ b/trunk/arch/sparc64/mm/fault.c
@@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
if (regs->tstate & TSTATE_PRIV) {
const struct exception_table_entry *entry;
- if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
- if (insn & 0x2000)
- asi = (regs->tstate >> 24);
- else
- asi = (insn >> 5);
- }
-
- /* Look in asi.h: All _S asis have LS bit set */
- if ((asi & 0x1) &&
- (entry = search_exception_tables(regs->tpc))) {
+ entry = search_exception_tables(regs->tpc);
+ if (entry) {
regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
return;
@@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
unsigned long tpc = regs->tpc;
/* Sanity check the PC. */
- if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
+ if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
(tpc >= MODULES_VADDR && tpc < MODULES_END)) {
/* Valid, no problems... */
} else {
diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c
index 9e6bca266d88..b5c30416fdac 100644
--- a/trunk/arch/sparc64/mm/init.c
+++ b/trunk/arch/sparc64/mm/init.c
@@ -1010,7 +1010,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata;
static int pall_ents __initdata;
#ifdef CONFIG_DEBUG_PAGEALLOC
-static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot)
+static unsigned long __ref kernel_map_range(unsigned long pstart,
+ unsigned long pend, pgprot_t prot)
{
unsigned long vstart = PAGE_OFFSET + pstart;
unsigned long vend = PAGE_OFFSET + pend;
diff --git a/trunk/arch/sparc64/solaris/conv.h b/trunk/arch/sparc64/solaris/conv.h
index 5faf59a9de39..50e58232cf2b 100644
--- a/trunk/arch/sparc64/solaris/conv.h
+++ b/trunk/arch/sparc64/solaris/conv.h
@@ -28,7 +28,7 @@ extern unsigned sunos_sys_table[];
#define SUNOS(x) ((long)sunos_sys_table[x])
#ifdef DEBUG_SOLARIS
-#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__FUNCTION__,(s))
+#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s))
#define SOLDD(s) printk("solaris: "); printk s
#else
#define SOLD(s)
diff --git a/trunk/arch/sparc64/solaris/timod.c b/trunk/arch/sparc64/solaris/timod.c
index f53123c02c2b..15234fcd191a 100644
--- a/trunk/arch/sparc64/solaris/timod.c
+++ b/trunk/arch/sparc64/solaris/timod.c
@@ -81,7 +81,7 @@ void mykfree(void *p)
#define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
#define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\
- __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0)
+ __FILE__,__LINE__,__func__,(m),(a));}while(0)
#define BUF_OFFSET sizeof(u64)
#define MKCTL_TRAILER sizeof(u64)
diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c
index fc50d2f959d1..e8cb9ff183e9 100644
--- a/trunk/arch/um/kernel/process.c
+++ b/trunk/arch/um/kernel/process.c
@@ -128,8 +128,6 @@ void *get_current(void)
return current;
}
-extern void schedule_tail(struct task_struct *prev);
-
/*
* This is called magically, by its address being stuffed in a jmp_buf
* and being longjmp-d to.
diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig
index 4a88cf7695b4..f41c9538ca30 100644
--- a/trunk/arch/x86/Kconfig
+++ b/trunk/arch/x86/Kconfig
@@ -21,7 +21,8 @@ config X86
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
- select HAVE_KVM
+ select HAVE_KRETPROBES
+ select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
config GENERIC_LOCKBREAK
diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu
index e09a6b73a1aa..9304bfba7d45 100644
--- a/trunk/arch/x86/Kconfig.cpu
+++ b/trunk/arch/x86/Kconfig.cpu
@@ -377,6 +377,19 @@ config X86_OOSTORE
def_bool y
depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
+#
+# P6_NOPs are a relatively minor optimization that require a family >=
+# 6 processor, except that it is broken on certain VIA chips.
+# Furthermore, AMD chips prefer a totally different sequence of NOPs
+# (which work on all CPUs). As a result, disallow these if we're
+# compiling X86_GENERIC but not X86_64 (these NOPs do work on all
+# x86-64 capable chips); the list of processors in the right-hand clause
+# are the cores that benefit from this optimization.
+#
+config X86_P6_NOP
+ def_bool y
+ depends on (X86_64 || !X86_GENERIC) && (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4)
+
config X86_TSC
def_bool y
depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
@@ -390,6 +403,7 @@ config X86_CMOV
config X86_MINIMUM_CPU_FAMILY
int
default "64" if X86_64
+ default "6" if X86_32 && X86_P6_NOP
default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
default "3"
diff --git a/trunk/arch/x86/boot/memory.c b/trunk/arch/x86/boot/memory.c
index 378353956b5d..e77d89f9e8aa 100644
--- a/trunk/arch/x86/boot/memory.c
+++ b/trunk/arch/x86/boot/memory.c
@@ -37,6 +37,12 @@ static int detect_memory_e820(void)
"=m" (*desc)
: "D" (desc), "d" (SMAP), "a" (0xe820));
+ /* BIOSes which terminate the chain with CF = 1 as opposed
+ to %ebx = 0 don't always report the SMAP signature on
+ the final, failing, probe. */
+ if (err)
+ break;
+
/* Some BIOSes stop returning SMAP in the middle of
the search loop. We don't know exactly how the BIOS
screwed up the map at that point, we might have a
@@ -47,9 +53,6 @@ static int detect_memory_e820(void)
break;
}
- if (err)
- break;
-
count++;
desc++;
} while (next && count < E820MAX);
diff --git a/trunk/arch/x86/kernel/asm-offsets_32.c b/trunk/arch/x86/kernel/asm-offsets_32.c
index a33d53017997..8ea040124f7d 100644
--- a/trunk/arch/x86/kernel/asm-offsets_32.c
+++ b/trunk/arch/x86/kernel/asm-offsets_32.c
@@ -128,13 +128,11 @@ void foo(void)
OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending);
#endif
-#ifdef CONFIG_LGUEST_GUEST
+#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE)
BLANK();
OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);
-#endif
-#ifdef CONFIG_LGUEST
BLANK();
OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c
index f86a3c4a2669..a38aafaefc23 100644
--- a/trunk/arch/x86/kernel/cpu/common.c
+++ b/trunk/arch/x86/kernel/cpu/common.c
@@ -504,7 +504,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
/* Clear all flags overriden by options */
for (i = 0; i < NCAPINTS; i++)
- c->x86_capability[i] ^= cleared_cpu_caps[i];
+ c->x86_capability[i] &= ~cleared_cpu_caps[i];
/* Init Machine Check Exception if available. */
mcheck_init(c);
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index 39f8cb18296c..c2f930d86640 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -55,7 +55,6 @@ static int eps_set_state(struct eps_cpu_data *centaur,
{
struct cpufreq_freqs freqs;
u32 lo, hi;
- u8 current_multiplier, current_voltage;
int err = 0;
int i;
@@ -95,6 +94,10 @@ static int eps_set_state(struct eps_cpu_data *centaur,
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
freqs.new = centaur->fsb * ((lo >> 8) & 0xff);
+#ifdef DEBUG
+ {
+ u8 current_multiplier, current_voltage;
+
/* Print voltage and multiplier */
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
current_voltage = lo & 0xff;
@@ -103,7 +106,8 @@ static int eps_set_state(struct eps_cpu_data *centaur,
current_multiplier = (lo >> 8) & 0xff;
printk(KERN_INFO "eps: Current multiplier = %d\n",
current_multiplier);
-
+ }
+#endif
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return err;
}
diff --git a/trunk/arch/x86/kernel/cpu/mtrr/main.c b/trunk/arch/x86/kernel/cpu/mtrr/main.c
index b6e136f23d3d..be83336fddba 100644
--- a/trunk/arch/x86/kernel/cpu/mtrr/main.c
+++ b/trunk/arch/x86/kernel/cpu/mtrr/main.c
@@ -43,6 +43,7 @@
#include
#include
#include
+#include
#include "mtrr.h"
u32 num_var_ranges = 0;
@@ -649,6 +650,7 @@ static __init int amd_special_default_mtrr(void)
/**
* mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
+ * @end_pfn: ending page frame number
*
* Some buggy BIOSes don't setup the MTRRs properly for systems with certain
* memory configurations. This routine checks that the highest MTRR matches
@@ -688,8 +690,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
/* kvm/qemu doesn't have mtrr set right, don't trim them all */
if (!highest_pfn) {
- printk(KERN_WARNING "WARNING: strange, CPU MTRRs all blank?\n");
- WARN_ON(1);
+ if (!kvm_para_available()) {
+ printk(KERN_WARNING
+ "WARNING: strange, CPU MTRRs all blank?\n");
+ WARN_ON(1);
+ }
return 0;
}
diff --git a/trunk/arch/x86/kernel/cpu/transmeta.c b/trunk/arch/x86/kernel/cpu/transmeta.c
index 200fb3f9ebfb..e8b422c1c512 100644
--- a/trunk/arch/x86/kernel/cpu/transmeta.c
+++ b/trunk/arch/x86/kernel/cpu/transmeta.c
@@ -76,13 +76,6 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c)
/* All Transmeta CPUs have a constant TSC */
set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
- /* If we can run i686 user-space code, call us an i686 */
-#define USER686 ((1 << X86_FEATURE_TSC)|\
- (1 << X86_FEATURE_CX8)|\
- (1 << X86_FEATURE_CMOV))
- if (c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686)
- c->x86 = 6;
-
#ifdef CONFIG_SYSCTL
/* randomize_va_space slows us down enormously;
it probably triggers retranslation of x86->native bytecode */
diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S
index 2ad9a1bc6a73..c20c9e7e08dd 100644
--- a/trunk/arch/x86/kernel/entry_64.S
+++ b/trunk/arch/x86/kernel/entry_64.S
@@ -453,6 +453,7 @@ ENTRY(stub_execve)
CFI_REGISTER rip, r11
SAVE_REST
FIXUP_TOP_OF_STACK %r11
+ movq %rsp, %rcx
call sys_execve
RESTORE_TOP_OF_STACK %r11
movq %rax,RAX(%rsp)
@@ -1036,15 +1037,16 @@ ENDPROC(child_rip)
* rdi: name, rsi: argv, rdx: envp
*
* We want to fallback into:
- * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
+ * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
*
* do_sys_execve asm fallback arguments:
- * rdi: name, rsi: argv, rdx: envp, fake frame on the stack
+ * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
*/
ENTRY(kernel_execve)
CFI_STARTPROC
FAKE_STACK_FRAME $0
SAVE_ALL
+ movq %rsp,%rcx
call sys_execve
movq %rax, RAX(%rsp)
RESTORE_REST
diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S
index 25eb98540a41..fd8ca53943a8 100644
--- a/trunk/arch/x86/kernel/head_32.S
+++ b/trunk/arch/x86/kernel/head_32.S
@@ -606,7 +606,7 @@ ENTRY(_stext)
.section ".bss.page_aligned","wa"
.align PAGE_SIZE_asm
#ifdef CONFIG_X86_PAE
-ENTRY(swapper_pg_pmd)
+swapper_pg_pmd:
.fill 1024*KPMDS,4,0
#else
ENTRY(swapper_pg_dir)
diff --git a/trunk/arch/x86/kernel/head_64.S b/trunk/arch/x86/kernel/head_64.S
index eb415043a929..a007454133a3 100644
--- a/trunk/arch/x86/kernel/head_64.S
+++ b/trunk/arch/x86/kernel/head_64.S
@@ -379,18 +379,24 @@ NEXT_PAGE(level2_ident_pgt)
/* Since I easily can, map the first 1G.
* Don't set NX because code runs from these pages.
*/
- PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
+ PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
NEXT_PAGE(level2_kernel_pgt)
- /* 40MB kernel mapping. The kernel code cannot be bigger than that.
- When you change this change KERNEL_TEXT_SIZE in page.h too. */
- /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */
- PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE)
- /* Module mapping starts here */
- .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0
+ /*
+ * 128 MB kernel mapping. We spend a full page on this pagetable
+ * anyway.
+ *
+ * The kernel code+data+bss must not be bigger than that.
+ *
+ * (NOTE: at +128MB starts the module area, see MODULES_VADDR.
+ * If you want to increase this then increase MODULES_VADDR
+ * too.)
+ */
+ PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL,
+ KERNEL_IMAGE_SIZE/PMD_SIZE)
NEXT_PAGE(level2_spare_pgt)
- .fill 512,8,0
+ .fill 512, 8, 0
#undef PMDS
#undef NEXT_PAGE
diff --git a/trunk/arch/x86/kernel/hpet.c b/trunk/arch/x86/kernel/hpet.c
index 429d084e014d..235fd6c77504 100644
--- a/trunk/arch/x86/kernel/hpet.c
+++ b/trunk/arch/x86/kernel/hpet.c
@@ -368,8 +368,8 @@ static int hpet_clocksource_register(void)
return 0;
}
-/*
- * Try to setup the HPET timer
+/**
+ * hpet_enable - Try to setup the HPET timer. Returns 1 on success.
*/
int __init hpet_enable(void)
{
diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c
index 763dfc407232..60fe80157569 100644
--- a/trunk/arch/x86/kernel/i387.c
+++ b/trunk/arch/x86/kernel/i387.c
@@ -132,7 +132,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
if (!cpu_has_fxsr)
return -ENODEV;
- unlazy_fpu(target);
+ init_fpu(target);
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.i387.fxsave, 0, -1);
@@ -147,7 +147,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
if (!cpu_has_fxsr)
return -ENODEV;
- unlazy_fpu(target);
+ init_fpu(target);
set_stopped_child_used_math(target);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
@@ -307,7 +307,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
if (!HAVE_HWFP)
return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
- unlazy_fpu(target);
+ init_fpu(target);
if (!cpu_has_fxsr)
return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
@@ -332,7 +332,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
if (!HAVE_HWFP)
return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
- unlazy_fpu(target);
+ init_fpu(target);
set_stopped_child_used_math(target);
if (!cpu_has_fxsr)
diff --git a/trunk/arch/x86/kernel/init_task.c b/trunk/arch/x86/kernel/init_task.c
index 5b3ce7934363..3d01e47777db 100644
--- a/trunk/arch/x86/kernel/init_task.c
+++ b/trunk/arch/x86/kernel/init_task.c
@@ -15,6 +15,7 @@ static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */
/*
* Initial thread structure.
diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c
index a7d50a547dc2..be3c7a299f02 100644
--- a/trunk/arch/x86/kernel/process_32.c
+++ b/trunk/arch/x86/kernel/process_32.c
@@ -603,11 +603,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
}
#endif
+#ifdef X86_BTS
if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
+#endif
if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c
index b0cc8f0136d8..3baf9b9f4c87 100644
--- a/trunk/arch/x86/kernel/process_64.c
+++ b/trunk/arch/x86/kernel/process_64.c
@@ -604,11 +604,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
}
+#ifdef X86_BTS
if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS);
if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS))
ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES);
+#endif
}
/*
@@ -730,16 +732,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
*/
asmlinkage
long sys_execve(char __user *name, char __user * __user *argv,
- char __user * __user *envp, struct pt_regs regs)
+ char __user * __user *envp, struct pt_regs *regs)
{
long error;
char * filename;
filename = getname(name);
error = PTR_ERR(filename);
- if (IS_ERR(filename))
+ if (IS_ERR(filename))
return error;
- error = do_execve(filename, argv, envp, ®s);
+ error = do_execve(filename, argv, envp, regs);
putname(filename);
return error;
}
diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c
index d862e396b099..f41fdc98efb1 100644
--- a/trunk/arch/x86/kernel/ptrace.c
+++ b/trunk/arch/x86/kernel/ptrace.c
@@ -544,6 +544,8 @@ static int ptrace_set_debugreg(struct task_struct *child,
return 0;
}
+#ifdef X86_BTS
+
static int ptrace_bts_get_size(struct task_struct *child)
{
if (!child->thread.ds_area_msr)
@@ -826,6 +828,7 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk,
ptrace_bts_write_record(tsk, &rec);
}
+#endif /* X86_BTS */
/*
* Called by kernel/ptrace.c when detaching..
@@ -839,7 +842,9 @@ void ptrace_disable(struct task_struct *child)
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
#endif
if (child->thread.ds_area_msr) {
+#ifdef X86_BTS
ptrace_bts_realloc(child, 0, 0);
+#endif
child->thread.debugctlmsr &= ~ds_debugctl_mask();
if (!child->thread.debugctlmsr)
clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
@@ -961,6 +966,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
#endif
+ /*
+ * These bits need more cooking - not enabled yet:
+ */
+#ifdef X86_BTS
case PTRACE_BTS_CONFIG:
ret = ptrace_bts_config
(child, data, (struct ptrace_bts_config __user *)addr);
@@ -988,6 +997,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_bts_drain
(child, data, (struct bts_struct __user *) addr);
break;
+#endif
default:
ret = ptrace_request(child, request, addr, data);
@@ -1226,12 +1236,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SETOPTIONS:
case PTRACE_SET_THREAD_AREA:
case PTRACE_GET_THREAD_AREA:
+#ifdef X86_BTS
case PTRACE_BTS_CONFIG:
case PTRACE_BTS_STATUS:
case PTRACE_BTS_SIZE:
case PTRACE_BTS_GET:
case PTRACE_BTS_CLEAR:
case PTRACE_BTS_DRAIN:
+#endif
return sys_ptrace(request, pid, addr, data);
default:
diff --git a/trunk/arch/x86/kernel/setup_64.c b/trunk/arch/x86/kernel/setup_64.c
index 6fd804f07821..7637dc91c79b 100644
--- a/trunk/arch/x86/kernel/setup_64.c
+++ b/trunk/arch/x86/kernel/setup_64.c
@@ -1021,7 +1021,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
/* Clear all flags overriden by options */
for (i = 0; i < NCAPINTS; i++)
- c->x86_capability[i] ^= cleared_cpu_caps[i];
+ c->x86_capability[i] &= ~cleared_cpu_caps[i];
#ifdef CONFIG_X86_MCE
mcheck_init(c);
diff --git a/trunk/arch/x86/kernel/smpboot_64.c b/trunk/arch/x86/kernel/smpboot_64.c
index d53bd6fcb428..0880f2c388a9 100644
--- a/trunk/arch/x86/kernel/smpboot_64.c
+++ b/trunk/arch/x86/kernel/smpboot_64.c
@@ -554,10 +554,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
int timeout;
unsigned long start_rip;
struct create_idle c_idle = {
- .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
.cpu = cpu,
.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
};
+ INIT_WORK(&c_idle.work, do_fork_idle);
/* allocate memory for gdts of secondary cpus. Hotplug is considered */
if (!cpu_gdt_descr[cpu].address &&
diff --git a/trunk/arch/x86/kernel/stacktrace.c b/trunk/arch/x86/kernel/stacktrace.c
index 02f0f61f5b11..c28c342c162f 100644
--- a/trunk/arch/x86/kernel/stacktrace.c
+++ b/trunk/arch/x86/kernel/stacktrace.c
@@ -25,6 +25,8 @@ static int save_stack_stack(void *data, char *name)
static void save_stack_address(void *data, unsigned long addr, int reliable)
{
struct stack_trace *trace = data;
+ if (!reliable)
+ return;
if (trace->skip > 0) {
trace->skip--;
return;
@@ -37,6 +39,8 @@ static void
save_stack_address_nosched(void *data, unsigned long addr, int reliable)
{
struct stack_trace *trace = (struct stack_trace *)data;
+ if (!reliable)
+ return;
if (in_sched_functions(addr))
return;
if (trace->skip > 0) {
diff --git a/trunk/arch/x86/kernel/tls.c b/trunk/arch/x86/kernel/tls.c
index 6dfd4e76661a..022bcaa3b42e 100644
--- a/trunk/arch/x86/kernel/tls.c
+++ b/trunk/arch/x86/kernel/tls.c
@@ -91,7 +91,9 @@ int do_set_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
{
- return do_set_thread_area(current, -1, u_info, 1);
+ int ret = do_set_thread_area(current, -1, u_info, 1);
+ prevent_tail_call(ret);
+ return ret;
}
@@ -139,7 +141,9 @@ int do_get_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
{
- return do_get_thread_area(current, -1, u_info);
+ int ret = do_get_thread_area(current, -1, u_info);
+ prevent_tail_call(ret);
+ return ret;
}
int regset_tls_active(struct task_struct *target,
diff --git a/trunk/arch/x86/kernel/tsc_32.c b/trunk/arch/x86/kernel/tsc_32.c
index 43517e324be8..f14cfd9d1f94 100644
--- a/trunk/arch/x86/kernel/tsc_32.c
+++ b/trunk/arch/x86/kernel/tsc_32.c
@@ -28,7 +28,8 @@ EXPORT_SYMBOL_GPL(tsc_khz);
static int __init tsc_setup(char *str)
{
printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
- "cannot disable TSC.\n");
+ "cannot disable TSC completely.\n");
+ mark_tsc_unstable("user disabled TSC");
return 1;
}
#else
diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c
index 3f8242774580..edff4c985485 100644
--- a/trunk/arch/x86/kernel/vsyscall_64.c
+++ b/trunk/arch/x86/kernel/vsyscall_64.c
@@ -44,11 +44,6 @@
#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
#define __syscall_clobber "r11","cx","memory"
-#define __pa_vsymbol(x) \
- ({unsigned long v; \
- extern char __vsyscall_0; \
- asm("" : "=r" (v) : "0" (x)); \
- ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
/*
* vsyscall_gtod_data contains data that is :
@@ -102,7 +97,7 @@ static __always_inline void do_get_tz(struct timezone * tz)
static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
{
int ret;
- asm volatile("vsysc2: syscall"
+ asm volatile("syscall"
: "=a" (ret)
: "0" (__NR_gettimeofday),"D" (tv),"S" (tz)
: __syscall_clobber );
@@ -112,7 +107,7 @@ static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
static __always_inline long time_syscall(long *t)
{
long secs;
- asm volatile("vsysc1: syscall"
+ asm volatile("syscall"
: "=a" (secs)
: "0" (__NR_time),"D" (t) : __syscall_clobber);
return secs;
@@ -228,42 +223,11 @@ long __vsyscall(3) venosys_1(void)
#ifdef CONFIG_SYSCTL
-#define SYSCALL 0x050f
-#define NOP2 0x9090
-
-/*
- * NOP out syscall in vsyscall page when not needed.
- */
-static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+static int
+vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
- extern u16 vsysc1, vsysc2;
- u16 __iomem *map1;
- u16 __iomem *map2;
- int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
- if (!write)
- return ret;
- /* gcc has some trouble with __va(__pa()), so just do it this
- way. */
- map1 = ioremap(__pa_vsymbol(&vsysc1), 2);
- if (!map1)
- return -ENOMEM;
- map2 = ioremap(__pa_vsymbol(&vsysc2), 2);
- if (!map2) {
- ret = -ENOMEM;
- goto out;
- }
- if (!vsyscall_gtod_data.sysctl_enabled) {
- writew(SYSCALL, map1);
- writew(SYSCALL, map2);
- } else {
- writew(NOP2, map1);
- writew(NOP2, map2);
- }
- iounmap(map2);
-out:
- iounmap(map1);
- return ret;
+ return proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
}
static ctl_table kernel_table2[] = {
@@ -279,7 +243,6 @@ static ctl_table kernel_root_table2[] = {
.child = kernel_table2 },
{}
};
-
#endif
/* Assume __initcall executes before all user space. Hopefully kmod
diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c
index 2cbee9479ce4..68a6b1511934 100644
--- a/trunk/arch/x86/kvm/lapic.c
+++ b/trunk/arch/x86/kvm/lapic.c
@@ -647,6 +647,10 @@ static void start_apic_timer(struct kvm_lapic *apic)
apic->timer.period = apic_get_reg(apic, APIC_TMICT) *
APIC_BUS_CYCLE_NS * apic->timer.divide_count;
atomic_set(&apic->timer.pending, 0);
+
+ if (!apic->timer.period)
+ return;
+
hrtimer_start(&apic->timer.dev,
ktime_add_ns(now, apic->timer.period),
HRTIMER_MODE_ABS);
diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c
index 8efdcdbebb03..d8172aabc660 100644
--- a/trunk/arch/x86/kvm/mmu.c
+++ b/trunk/arch/x86/kvm/mmu.c
@@ -681,8 +681,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
unsigned level,
int metaphysical,
unsigned access,
- u64 *parent_pte,
- bool *new_page)
+ u64 *parent_pte)
{
union kvm_mmu_page_role role;
unsigned index;
@@ -722,8 +721,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
vcpu->arch.mmu.prefetch_page(vcpu, sp);
if (!metaphysical)
rmap_write_protect(vcpu->kvm, gfn);
- if (new_page)
- *new_page = 1;
return sp;
}
@@ -876,11 +873,18 @@ static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
{
+ struct page *page;
+
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
if (gpa == UNMAPPED_GVA)
return NULL;
- return gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+
+ down_read(¤t->mm->mmap_sem);
+ page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ up_read(¤t->mm->mmap_sem);
+
+ return page;
}
static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
@@ -999,8 +1003,7 @@ static int __nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write,
>> PAGE_SHIFT;
new_table = kvm_mmu_get_page(vcpu, pseudo_gfn,
v, level - 1,
- 1, ACC_ALL, &table[index],
- NULL);
+ 1, ACC_ALL, &table[index]);
if (!new_table) {
pgprintk("nonpaging_map: ENOMEM\n");
kvm_release_page_clean(page);
@@ -1020,15 +1023,18 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
struct page *page;
+ down_read(&vcpu->kvm->slots_lock);
+
down_read(¤t->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, gfn);
+ up_read(¤t->mm->mmap_sem);
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
r = __nonpaging_map(vcpu, v, write, gfn, page);
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return r;
}
@@ -1090,7 +1096,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
ASSERT(!VALID_PAGE(root));
sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
- PT64_ROOT_LEVEL, 0, ACC_ALL, NULL, NULL);
+ PT64_ROOT_LEVEL, 0, ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.root_hpa = root;
@@ -1111,7 +1117,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
root_gfn = 0;
sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
PT32_ROOT_LEVEL, !is_paging(vcpu),
- ACC_ALL, NULL, NULL);
+ ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
@@ -1172,7 +1178,7 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu)
static void paging_new_cr3(struct kvm_vcpu *vcpu)
{
- pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3);
+ pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->arch.cr3);
mmu_free_roots(vcpu);
}
@@ -1362,6 +1368,7 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
gfn_t gfn;
int r;
u64 gpte = 0;
+ struct page *page;
if (bytes != 4 && bytes != 8)
return;
@@ -1389,6 +1396,11 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
if (!is_present_pte(gpte))
return;
gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
+
+ down_read(¤t->mm->mmap_sem);
+ page = gfn_to_page(vcpu->kvm, gfn);
+ up_read(¤t->mm->mmap_sem);
+
vcpu->arch.update_pte.gfn = gfn;
vcpu->arch.update_pte.page = gfn_to_page(vcpu->kvm, gfn);
}
@@ -1496,9 +1508,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
gpa_t gpa;
int r;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
spin_lock(&vcpu->kvm->mmu_lock);
r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
diff --git a/trunk/arch/x86/kvm/paging_tmpl.h b/trunk/arch/x86/kvm/paging_tmpl.h
index 03ba8608fe0f..ecc0856268c4 100644
--- a/trunk/arch/x86/kvm/paging_tmpl.h
+++ b/trunk/arch/x86/kvm/paging_tmpl.h
@@ -91,7 +91,10 @@ static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
pt_element_t *table;
struct page *page;
+ down_read(¤t->mm->mmap_sem);
page = gfn_to_page(kvm, table_gfn);
+ up_read(¤t->mm->mmap_sem);
+
table = kmap_atomic(page, KM_USER0);
ret = CMPXCHG(&table[index], orig_pte, new_pte);
@@ -140,7 +143,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
}
#endif
ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
- (vcpu->cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
+ (vcpu->arch.cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
pt_access = ACC_ALL;
@@ -297,7 +300,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
u64 shadow_pte;
int metaphysical;
gfn_t table_gfn;
- bool new_page = 0;
shadow_ent = ((u64 *)__va(shadow_addr)) + index;
if (level == PT_PAGE_TABLE_LEVEL)
@@ -319,8 +321,8 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
}
shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
metaphysical, access,
- shadow_ent, &new_page);
- if (new_page && !metaphysical) {
+ shadow_ent);
+ if (!metaphysical) {
int r;
pt_element_t curr_pte;
r = kvm_read_guest_atomic(vcpu->kvm,
@@ -378,7 +380,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
if (r)
return r;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
/*
* Look up the shadow pte for the faulting address.
*/
@@ -392,11 +394,13 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
pgprintk("%s: guest page fault\n", __FUNCTION__);
inject_page_fault(vcpu, addr, walker.error_code);
vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 0;
}
+ down_read(¤t->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, walker.gfn);
+ up_read(¤t->mm->mmap_sem);
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
@@ -413,14 +417,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
*/
if (shadow_pte && is_io_pte(*shadow_pte)) {
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 1;
}
++vcpu->stat.pf_fixed;
kvm_mmu_audit(vcpu, "post page fault (fixed)");
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return write_pt;
}
diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c
index de755cb1431d..1a582f1090e8 100644
--- a/trunk/arch/x86/kvm/svm.c
+++ b/trunk/arch/x86/kvm/svm.c
@@ -792,6 +792,10 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
vcpu->arch.cr0 = cr0;
cr0 |= X86_CR0_PG | X86_CR0_WP;
cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
+ if (!vcpu->fpu_active) {
+ svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+ cr0 |= X86_CR0_TS;
+ }
svm->vmcb->save.cr0 = cr0;
}
@@ -1096,6 +1100,24 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
case MSR_IA32_SYSENTER_ESP:
*data = svm->vmcb->save.sysenter_esp;
break;
+ /* Nobody will change the following 5 values in the VMCB so
+ we can safely return them on rdmsr. They will always be 0
+ until LBRV is implemented. */
+ case MSR_IA32_DEBUGCTLMSR:
+ *data = svm->vmcb->save.dbgctl;
+ break;
+ case MSR_IA32_LASTBRANCHFROMIP:
+ *data = svm->vmcb->save.br_from;
+ break;
+ case MSR_IA32_LASTBRANCHTOIP:
+ *data = svm->vmcb->save.br_to;
+ break;
+ case MSR_IA32_LASTINTFROMIP:
+ *data = svm->vmcb->save.last_excp_from;
+ break;
+ case MSR_IA32_LASTINTTOIP:
+ *data = svm->vmcb->save.last_excp_to;
+ break;
default:
return kvm_get_msr_common(vcpu, ecx, data);
}
@@ -1156,6 +1178,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
case MSR_IA32_SYSENTER_ESP:
svm->vmcb->save.sysenter_esp = data;
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n",
+ __FUNCTION__, data);
+ break;
case MSR_K7_EVNTSEL0:
case MSR_K7_EVNTSEL1:
case MSR_K7_EVNTSEL2:
diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c
index ad36447e696e..94ea724638fd 100644
--- a/trunk/arch/x86/kvm/vmx.c
+++ b/trunk/arch/x86/kvm/vmx.c
@@ -638,6 +638,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
{
int save_nmsrs;
+ vmx_load_host_state(vmx);
save_nmsrs = 0;
#ifdef CONFIG_X86_64
if (is_long_mode(&vmx->vcpu)) {
@@ -1477,7 +1478,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0;
- down_write(¤t->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
if (kvm->arch.apic_access_page)
goto out;
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
@@ -1487,9 +1488,12 @@ static int alloc_apic_access_page(struct kvm *kvm)
r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
if (r)
goto out;
+
+ down_read(¤t->mm->mmap_sem);
kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00);
+ up_read(¤t->mm->mmap_sem);
out:
- up_write(¤t->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return r;
}
@@ -1602,9 +1606,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
- if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm))
- if (alloc_apic_access_page(vmx->vcpu.kvm) != 0)
- return -ENOMEM;
return 0;
}
@@ -2534,6 +2535,9 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
put_cpu();
if (err)
goto free_vmcs;
+ if (vm_need_virtualize_apic_accesses(kvm))
+ if (alloc_apic_access_page(kvm) != 0)
+ goto free_vmcs;
return &vmx->vcpu;
diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c
index cf5308148689..6b01552bd1f1 100644
--- a/trunk/arch/x86/kvm/x86.c
+++ b/trunk/arch/x86/kvm/x86.c
@@ -46,6 +46,9 @@
#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
+static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
+ struct kvm_cpuid_entry2 __user *entries);
+
struct kvm_x86_ops *kvm_x86_ops;
struct kvm_stats_debugfs_item debugfs_entries[] = {
@@ -181,7 +184,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
int ret;
u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
offset * sizeof(u64), sizeof(pdpte));
if (ret < 0) {
@@ -198,7 +201,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
out:
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return ret;
}
@@ -212,13 +215,13 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
if (is_long_mode(vcpu) || !is_pae(vcpu))
return false;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
if (r < 0)
goto out;
changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0;
out:
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return changed;
}
@@ -356,7 +359,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
*/
}
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
/*
* Does the new cr3 value map to physical memory? (Note, we
* catch an invalid cr3 even in real-mode, because it would
@@ -372,7 +375,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
vcpu->arch.cr3 = cr3;
vcpu->arch.mmu.new_cr3(vcpu);
}
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
}
EXPORT_SYMBOL_GPL(set_cr3);
@@ -484,6 +487,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n",
__FUNCTION__, data);
break;
+ case MSR_IA32_MCG_CTL:
+ pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n",
+ __FUNCTION__, data);
+ break;
case MSR_IA32_UCODE_REV:
case MSR_IA32_UCODE_WRITE:
case 0x200 ... 0x2ff: /* MTRRs */
@@ -526,6 +533,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_MC0_CTL:
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MCG_CAP:
+ case MSR_IA32_MCG_CTL:
case MSR_IA32_MC0_MISC:
case MSR_IA32_MC0_MISC+4:
case MSR_IA32_MC0_MISC+8:
@@ -727,6 +735,24 @@ long kvm_arch_dev_ioctl(struct file *filp,
r = 0;
break;
}
+ case KVM_GET_SUPPORTED_CPUID: {
+ struct kvm_cpuid2 __user *cpuid_arg = argp;
+ struct kvm_cpuid2 cpuid;
+
+ r = -EFAULT;
+ if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
+ goto out;
+ r = kvm_dev_ioctl_get_supported_cpuid(&cpuid,
+ cpuid_arg->entries);
+ if (r)
+ goto out;
+
+ r = -EFAULT;
+ if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))
+ goto out;
+ r = 0;
+ break;
+ }
default:
r = -EINVAL;
}
@@ -974,8 +1000,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
put_cpu();
}
-static int kvm_vm_ioctl_get_supported_cpuid(struct kvm *kvm,
- struct kvm_cpuid2 *cpuid,
+static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries)
{
struct kvm_cpuid_entry2 *cpuid_entries;
@@ -1207,12 +1232,12 @@ static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
return -EINVAL;
- down_write(¤t->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
- up_write(¤t->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return 0;
}
@@ -1261,7 +1286,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
< alias->target_phys_addr)
goto out;
- down_write(¤t->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
p = &kvm->arch.aliases[alias->slot];
p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
@@ -1275,7 +1300,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
kvm_mmu_zap_all(kvm);
- up_write(¤t->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return 0;
@@ -1351,7 +1376,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_memory_slot *memslot;
int is_dirty = 0;
- down_write(¤t->mm->mmap_sem);
+ down_write(&kvm->slots_lock);
r = kvm_get_dirty_log(kvm, log, &is_dirty);
if (r)
@@ -1367,7 +1392,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
}
r = 0;
out:
- up_write(¤t->mm->mmap_sem);
+ up_write(&kvm->slots_lock);
return r;
}
@@ -1487,24 +1512,6 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = 0;
break;
}
- case KVM_GET_SUPPORTED_CPUID: {
- struct kvm_cpuid2 __user *cpuid_arg = argp;
- struct kvm_cpuid2 cpuid;
-
- r = -EFAULT;
- if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
- goto out;
- r = kvm_vm_ioctl_get_supported_cpuid(kvm, &cpuid,
- cpuid_arg->entries);
- if (r)
- goto out;
-
- r = -EFAULT;
- if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))
- goto out;
- r = 0;
- break;
- }
default:
;
}
@@ -1563,7 +1570,7 @@ int emulator_read_std(unsigned long addr,
void *data = val;
int r = X86EMUL_CONTINUE;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
while (bytes) {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
unsigned offset = addr & (PAGE_SIZE-1);
@@ -1585,7 +1592,7 @@ int emulator_read_std(unsigned long addr,
addr += tocopy;
}
out:
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return r;
}
EXPORT_SYMBOL_GPL(emulator_read_std);
@@ -1604,9 +1611,9 @@ static int emulator_read_emulated(unsigned long addr,
return X86EMUL_CONTINUE;
}
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
/* For APIC access vmexit */
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -1644,14 +1651,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
{
int ret;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
if (ret < 0) {
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 0;
}
kvm_mmu_pte_write(vcpu, gpa, val, bytes);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
return 1;
}
@@ -1663,9 +1670,9 @@ static int emulator_write_emulated_onepage(unsigned long addr,
struct kvm_io_device *mmio_dev;
gpa_t gpa;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
if (gpa == UNMAPPED_GVA) {
kvm_inject_page_fault(vcpu, addr, 2);
@@ -1742,7 +1749,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
char *kaddr;
u64 val;
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
if (gpa == UNMAPPED_GVA ||
@@ -1753,13 +1760,17 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
goto emul_write;
val = *(u64 *)new;
+
+ down_read(¤t->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ up_read(¤t->mm->mmap_sem);
+
kaddr = kmap_atomic(page, KM_USER0);
set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val);
kunmap_atomic(kaddr, KM_USER0);
kvm_release_page_dirty(page);
emul_write:
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
}
#endif
@@ -2152,10 +2163,10 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
kvm_x86_ops->skip_emulated_instruction(vcpu);
for (i = 0; i < nr_pages; ++i) {
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
page = gva_to_page(vcpu, address + i * PAGE_SIZE);
vcpu->arch.pio.guest_pages[i] = page;
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
if (!page) {
kvm_inject_gp(vcpu, 0);
free_pio_guest_pages(vcpu);
@@ -2478,8 +2489,9 @@ static void vapic_enter(struct kvm_vcpu *vcpu)
down_read(¤t->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
- vcpu->arch.apic->vapic_page = page;
up_read(¤t->mm->mmap_sem);
+
+ vcpu->arch.apic->vapic_page = page;
}
static void vapic_exit(struct kvm_vcpu *vcpu)
@@ -2861,8 +2873,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
kvm_x86_ops->decache_cr4_guest_bits(vcpu);
mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0;
- vcpu->arch.cr0 = sregs->cr0;
kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
+ vcpu->arch.cr0 = sregs->cr0;
mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
@@ -2952,9 +2964,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
gpa_t gpa;
vcpu_load(vcpu);
- down_read(¤t->mm->mmap_sem);
+ down_read(&vcpu->kvm->slots_lock);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
- up_read(¤t->mm->mmap_sem);
+ up_read(&vcpu->kvm->slots_lock);
tr->physical_address = gpa;
tr->valid = gpa != UNMAPPED_GVA;
tr->writeable = 1;
@@ -3227,11 +3239,13 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
*/
if (!user_alloc) {
if (npages && !old.rmap) {
+ down_write(¤t->mm->mmap_sem);
memslot->userspace_addr = do_mmap(NULL, 0,
npages * PAGE_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS,
0);
+ up_write(¤t->mm->mmap_sem);
if (IS_ERR((void *)memslot->userspace_addr))
return PTR_ERR((void *)memslot->userspace_addr);
@@ -3239,8 +3253,10 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
if (!old.user_alloc && old.rmap) {
int ret;
+ down_write(¤t->mm->mmap_sem);
ret = do_munmap(current->mm, old.userspace_addr,
old.npages * PAGE_SIZE);
+ up_write(¤t->mm->mmap_sem);
if (ret < 0)
printk(KERN_WARNING
"kvm_vm_ioctl_set_memory_region: "
diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c
index 5afdde4895dc..cccb38a59653 100644
--- a/trunk/arch/x86/lguest/boot.c
+++ b/trunk/arch/x86/lguest/boot.c
@@ -57,6 +57,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -75,15 +76,6 @@
* behaving in simplified but equivalent ways. In particular, the Guest is the
* same kernel as the Host (or at least, built from the same source code). :*/
-/* Declarations for definitions in lguest_guest.S */
-extern char lguest_noirq_start[], lguest_noirq_end[];
-extern const char lgstart_cli[], lgend_cli[];
-extern const char lgstart_sti[], lgend_sti[];
-extern const char lgstart_popf[], lgend_popf[];
-extern const char lgstart_pushf[], lgend_pushf[];
-extern const char lgstart_iret[], lgend_iret[];
-extern void lguest_iret(void);
-
struct lguest_data lguest_data = {
.hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
.noirq_start = (u32)lguest_noirq_start,
@@ -489,7 +481,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
*pmdp = pmdval;
lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK,
- (__pa(pmdp)&(PAGE_SIZE-1))/4, 0);
+ (__pa(pmdp)&(PAGE_SIZE-1)), 0);
}
/* There are a couple of legacy places where the kernel sets a PTE, but we
diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c
index bb652f5a93fb..a02a14f0f324 100644
--- a/trunk/arch/x86/mm/init_64.c
+++ b/trunk/arch/x86/mm/init_64.c
@@ -172,8 +172,9 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
}
/*
- * The head.S code sets up the kernel high mapping from:
- * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE
+ * The head.S code sets up the kernel high mapping:
+ *
+ * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
*
* phys_addr holds the negative offset to the kernel, which is added
* to the compile time generated pmds. This results in invalid pmds up
@@ -515,14 +516,6 @@ void __init mem_init(void)
/* clear_bss() already clear the empty_zero_page */
- /* temporary debugging - double check it's true: */
- {
- int i;
-
- for (i = 0; i < 1024; i++)
- WARN_ON_ONCE(empty_zero_page[i]);
- }
-
reservedpages = 0;
/* this will put all low memory onto the freelists */
diff --git a/trunk/arch/x86/mm/ioremap.c b/trunk/arch/x86/mm/ioremap.c
index 882328efc3db..ac3c959e271d 100644
--- a/trunk/arch/x86/mm/ioremap.c
+++ b/trunk/arch/x86/mm/ioremap.c
@@ -162,7 +162,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
area->phys_addr = phys_addr;
vaddr = (unsigned long) area->addr;
if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
- remove_vm_area((void *)(vaddr & PAGE_MASK));
+ free_vm_area(area);
return NULL;
}
diff --git a/trunk/arch/x86/mm/numa_64.c b/trunk/arch/x86/mm/numa_64.c
index 59898fb0a4aa..8ccfee10f5b5 100644
--- a/trunk/arch/x86/mm/numa_64.c
+++ b/trunk/arch/x86/mm/numa_64.c
@@ -622,13 +622,17 @@ void __init init_cpu_to_node(void)
int i;
for (i = 0; i < NR_CPUS; i++) {
+ int node;
u16 apicid = x86_cpu_to_apicid_init[i];
if (apicid == BAD_APICID)
continue;
- if (apicid_to_node[apicid] == NUMA_NO_NODE)
+ node = apicid_to_node[apicid];
+ if (node == NUMA_NO_NODE)
continue;
- numa_set_node(i, apicid_to_node[apicid]);
+ if (!node_online(node))
+ continue;
+ numa_set_node(i, node);
}
}
diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c
index 464d8fc21ce6..14e48b5a94ba 100644
--- a/trunk/arch/x86/mm/pageattr.c
+++ b/trunk/arch/x86/mm/pageattr.c
@@ -44,6 +44,12 @@ static inline unsigned long highmap_end_pfn(void)
#endif
+#ifdef CONFIG_DEBUG_PAGEALLOC
+# define debug_pagealloc 1
+#else
+# define debug_pagealloc 0
+#endif
+
static inline int
within(unsigned long addr, unsigned long start, unsigned long end)
{
@@ -355,45 +361,48 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
static LIST_HEAD(page_pool);
static unsigned long pool_size, pool_pages, pool_low;
-static unsigned long pool_used, pool_failed, pool_refill;
+static unsigned long pool_used, pool_failed;
-static void cpa_fill_pool(void)
+static void cpa_fill_pool(struct page **ret)
{
- struct page *p;
gfp_t gfp = GFP_KERNEL;
+ unsigned long flags;
+ struct page *p;
- /* Do not allocate from interrupt context */
- if (in_irq() || irqs_disabled())
- return;
/*
- * Check unlocked. I does not matter when we have one more
- * page in the pool. The bit lock avoids recursive pool
- * allocations:
+ * Avoid recursion (on debug-pagealloc) and also signal
+ * our priority to get to these pagetables:
*/
- if (pool_pages >= pool_size || test_and_set_bit_lock(0, &pool_refill))
+ if (current->flags & PF_MEMALLOC)
return;
+ current->flags |= PF_MEMALLOC;
-#ifdef CONFIG_DEBUG_PAGEALLOC
/*
- * We could do:
- * gfp = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
- * but this fails on !PREEMPT kernels
+ * Allocate atomically from atomic contexts:
*/
- gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
-#endif
+ if (in_atomic() || irqs_disabled() || debug_pagealloc)
+ gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
- while (pool_pages < pool_size) {
+ while (pool_pages < pool_size || (ret && !*ret)) {
p = alloc_pages(gfp, 0);
if (!p) {
pool_failed++;
break;
}
- spin_lock_irq(&pgd_lock);
+ /*
+ * If the call site needs a page right now, provide it:
+ */
+ if (ret && !*ret) {
+ *ret = p;
+ continue;
+ }
+ spin_lock_irqsave(&pgd_lock, flags);
list_add(&p->lru, &page_pool);
pool_pages++;
- spin_unlock_irq(&pgd_lock);
+ spin_unlock_irqrestore(&pgd_lock, flags);
}
- clear_bit_unlock(0, &pool_refill);
+
+ current->flags &= ~PF_MEMALLOC;
}
#define SHIFT_MB (20 - PAGE_SHIFT)
@@ -414,11 +423,15 @@ void __init cpa_init(void)
* GiB. Shift MiB to Gib and multiply the result by
* POOL_PAGES_PER_GB:
*/
- gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
- pool_size = POOL_PAGES_PER_GB * gb;
+ if (debug_pagealloc) {
+ gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
+ pool_size = POOL_PAGES_PER_GB * gb;
+ } else {
+ pool_size = 1;
+ }
pool_low = pool_size;
- cpa_fill_pool();
+ cpa_fill_pool(NULL);
printk(KERN_DEBUG
"CPA: page pool initialized %lu of %lu pages preallocated\n",
pool_pages, pool_size);
@@ -440,16 +453,20 @@ static int split_large_page(pte_t *kpte, unsigned long address)
spin_lock_irqsave(&pgd_lock, flags);
if (list_empty(&page_pool)) {
spin_unlock_irqrestore(&pgd_lock, flags);
- return -ENOMEM;
+ base = NULL;
+ cpa_fill_pool(&base);
+ if (!base)
+ return -ENOMEM;
+ spin_lock_irqsave(&pgd_lock, flags);
+ } else {
+ base = list_first_entry(&page_pool, struct page, lru);
+ list_del(&base->lru);
+ pool_pages--;
+
+ if (pool_pages < pool_low)
+ pool_low = pool_pages;
}
- base = list_first_entry(&page_pool, struct page, lru);
- list_del(&base->lru);
- pool_pages--;
-
- if (pool_pages < pool_low)
- pool_low = pool_pages;
-
/*
* Check for races, another CPU might have split this page
* up for us already:
@@ -734,7 +751,8 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
cpa_flush_all(cache);
out:
- cpa_fill_pool();
+ cpa_fill_pool(NULL);
+
return ret;
}
@@ -897,7 +915,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
* Try to refill the page pool here. We can do this only after
* the tlb flush.
*/
- cpa_fill_pool();
+ cpa_fill_pool(NULL);
}
#ifdef CONFIG_HIBERNATION
diff --git a/trunk/arch/x86/vdso/Makefile b/trunk/arch/x86/vdso/Makefile
index f385a4b4a484..0a8f4742ef51 100644
--- a/trunk/arch/x86/vdso/Makefile
+++ b/trunk/arch/x86/vdso/Makefile
@@ -50,7 +50,9 @@ obj-$(VDSO64-y) += vdso-syms.lds
sed-vdsosym := -e 's/^00*/0/' \
-e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p'
quiet_cmd_vdsosym = VDSOSYM $@
- cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
+define cmd_vdsosym
+ $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
+endef
$(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
$(call if_changed,vdsosym)
diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c
index 49e5358f481a..8b9ee27805fd 100644
--- a/trunk/arch/x86/xen/enlighten.c
+++ b/trunk/arch/x86/xen/enlighten.c
@@ -153,6 +153,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
if (*ax == 1)
maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */
(1 << X86_FEATURE_ACPI) | /* disable ACPI */
+ (1 << X86_FEATURE_SEP) | /* disable SEP */
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
asm(XEN_EMULATE_PREFIX "cpuid"
diff --git a/trunk/arch/x86/xen/setup.c b/trunk/arch/x86/xen/setup.c
index 3bad4773a2f3..2341492bf7a0 100644
--- a/trunk/arch/x86/xen/setup.c
+++ b/trunk/arch/x86/xen/setup.c
@@ -38,7 +38,8 @@ char * __init xen_memory_setup(void)
unsigned long max_pfn = xen_start_info->nr_pages;
e820.nr_map = 0;
- add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
+ add_memory_region(0, LOWMEMSIZE(), E820_RAM);
+ add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM);
return "Xen";
}
diff --git a/trunk/block/blk-barrier.c b/trunk/block/blk-barrier.c
index 6901eedeffce..55c5f1fc4f1f 100644
--- a/trunk/block/blk-barrier.c
+++ b/trunk/block/blk-barrier.c
@@ -259,8 +259,11 @@ int blk_do_ordered(struct request_queue *q, struct request **rqp)
static void bio_end_empty_barrier(struct bio *bio, int err)
{
- if (err)
+ if (err) {
+ if (err == -EOPNOTSUPP)
+ set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
clear_bit(BIO_UPTODATE, &bio->bi_flags);
+ }
complete(bio->bi_private);
}
@@ -309,7 +312,9 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
*error_sector = bio->bi_sector;
ret = 0;
- if (!bio_flagged(bio, BIO_UPTODATE))
+ if (bio_flagged(bio, BIO_EOPNOTSUPP))
+ ret = -EOPNOTSUPP;
+ else if (!bio_flagged(bio, BIO_UPTODATE))
ret = -EIO;
bio_put(bio);
diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c
index 775c8516abf5..2a438a93f723 100644
--- a/trunk/block/blk-core.c
+++ b/trunk/block/blk-core.c
@@ -127,7 +127,6 @@ void rq_init(struct request_queue *q, struct request *rq)
rq->nr_hw_segments = 0;
rq->ioprio = 0;
rq->special = NULL;
- rq->raw_data_len = 0;
rq->buffer = NULL;
rq->tag = -1;
rq->errors = 0;
@@ -135,6 +134,7 @@ void rq_init(struct request_queue *q, struct request *rq)
rq->cmd_len = 0;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->data_len = 0;
+ rq->extra_len = 0;
rq->sense_len = 0;
rq->data = NULL;
rq->sense = NULL;
@@ -424,7 +424,6 @@ void blk_put_queue(struct request_queue *q)
{
kobject_put(&q->kobj);
}
-EXPORT_SYMBOL(blk_put_queue);
void blk_cleanup_queue(struct request_queue *q)
{
@@ -592,7 +591,6 @@ int blk_get_queue(struct request_queue *q)
return 1;
}
-EXPORT_SYMBOL(blk_get_queue);
static inline void blk_free_request(struct request_queue *q, struct request *rq)
{
@@ -1768,6 +1766,7 @@ static inline void __end_request(struct request *rq, int uptodate,
/**
* blk_rq_bytes - Returns bytes left to complete in the entire request
+ * @rq: the request being processed
**/
unsigned int blk_rq_bytes(struct request *rq)
{
@@ -1780,6 +1779,7 @@ EXPORT_SYMBOL_GPL(blk_rq_bytes);
/**
* blk_rq_cur_bytes - Returns bytes left to complete in the current segment
+ * @rq: the request being processed
**/
unsigned int blk_rq_cur_bytes(struct request *rq)
{
@@ -2016,7 +2016,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
rq->hard_cur_sectors = rq->current_nr_sectors;
rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
rq->buffer = bio_data(bio);
- rq->raw_data_len = bio->bi_size;
rq->data_len = bio->bi_size;
rq->bio = rq->biotail = bio;
diff --git a/trunk/block/blk-map.c b/trunk/block/blk-map.c
index 09f7fd0bcb73..c07d9c8317f4 100644
--- a/trunk/block/blk-map.c
+++ b/trunk/block/blk-map.c
@@ -19,7 +19,6 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq,
rq->biotail->bi_next = bio;
rq->biotail = bio;
- rq->raw_data_len += bio->bi_size;
rq->data_len += bio->bi_size;
}
return 0;
@@ -44,6 +43,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
void __user *ubuf, unsigned int len)
{
unsigned long uaddr;
+ unsigned int alignment;
struct bio *bio, *orig_bio;
int reading, ret;
@@ -54,8 +54,8 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
* direct dma. else, set up kernel bounce buffers
*/
uaddr = (unsigned long) ubuf;
- if (!(uaddr & queue_dma_alignment(q)) &&
- !(len & queue_dma_alignment(q)))
+ alignment = queue_dma_alignment(q) | q->dma_pad_mask;
+ if (!(uaddr & alignment) && !(len & alignment))
bio = bio_map_user(q, NULL, uaddr, len, reading);
else
bio = bio_copy_user(q, uaddr, len, reading);
@@ -142,20 +142,22 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
/*
* __blk_rq_map_user() copies the buffers if starting address
- * or length isn't aligned. As the copied buffer is always
- * page aligned, we know that there's enough room for padding.
- * Extend the last bio and update rq->data_len accordingly.
+ * or length isn't aligned to dma_pad_mask. As the copied
+ * buffer is always page aligned, we know that there's enough
+ * room for padding. Extend the last bio and update
+ * rq->data_len accordingly.
*
* On unmap, bio_uncopy_user() will use unmodified
* bio_map_data pointed to by bio->bi_private.
*/
- if (len & queue_dma_alignment(q)) {
- unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1;
- struct bio *bio = rq->biotail;
+ if (len & q->dma_pad_mask) {
+ unsigned int pad_len = (q->dma_pad_mask & ~len) + 1;
+ struct bio *tail = rq->biotail;
- bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len;
- bio->bi_size += pad_len;
- rq->data_len += pad_len;
+ tail->bi_io_vec[tail->bi_vcnt - 1].bv_len += pad_len;
+ tail->bi_size += pad_len;
+
+ rq->extra_len += pad_len;
}
rq->buffer = rq->data = NULL;
@@ -215,7 +217,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
rq->buffer = rq->data = NULL;
return 0;
}
-EXPORT_SYMBOL(blk_rq_map_user_iov);
/**
* blk_rq_unmap_user - unmap a request with user data
diff --git a/trunk/block/blk-merge.c b/trunk/block/blk-merge.c
index 7506c4fe0264..0f58616bcd7f 100644
--- a/trunk/block/blk-merge.c
+++ b/trunk/block/blk-merge.c
@@ -231,7 +231,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
((unsigned long)q->dma_drain_buffer) &
(PAGE_SIZE - 1));
nsegs++;
- rq->data_len += q->dma_drain_size;
+ rq->extra_len += q->dma_drain_size;
}
if (sg)
diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c
index 9a8ffdd0ce3d..1344a0ea5cc6 100644
--- a/trunk/block/blk-settings.c
+++ b/trunk/block/blk-settings.c
@@ -140,7 +140,7 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr)
/* Assume anything <= 4GB can be handled by IOMMU.
Actually some IOMMUs can handle everything, but I don't
know of a way to test this here. */
- if (b_pfn < (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
+ if (b_pfn <= (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT))
dma = 1;
q->bounce_pfn = max_low_pfn;
#else
@@ -293,8 +293,24 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
EXPORT_SYMBOL(blk_queue_stack_limits);
/**
- * blk_queue_dma_drain - Set up a drain buffer for excess dma.
+ * blk_queue_dma_pad - set pad mask
+ * @q: the request queue for the device
+ * @mask: pad mask
+ *
+ * Set pad mask. Direct IO requests are padded to the mask specified.
*
+ * Appending pad buffer to a request modifies ->data_len such that it
+ * includes the pad buffer. The original requested data length can be
+ * obtained using blk_rq_raw_data_len().
+ **/
+void blk_queue_dma_pad(struct request_queue *q, unsigned int mask)
+{
+ q->dma_pad_mask = mask;
+}
+EXPORT_SYMBOL(blk_queue_dma_pad);
+
+/**
+ * blk_queue_dma_drain - Set up a drain buffer for excess dma.
* @q: the request queue for the device
* @dma_drain_needed: fn which returns non-zero if drain is necessary
* @buf: physically contiguous buffer
@@ -316,7 +332,7 @@ EXPORT_SYMBOL(blk_queue_stack_limits);
* device can support otherwise there won't be room for the drain
* buffer.
*/
-extern int blk_queue_dma_drain(struct request_queue *q,
+int blk_queue_dma_drain(struct request_queue *q,
dma_drain_needed_fn *dma_drain_needed,
void *buf, unsigned int size)
{
diff --git a/trunk/block/blk-tag.c b/trunk/block/blk-tag.c
index a8c37d4bbb32..4780a46ce234 100644
--- a/trunk/block/blk-tag.c
+++ b/trunk/block/blk-tag.c
@@ -6,6 +6,8 @@
#include
#include
+#include "blk.h"
+
/**
* blk_queue_find_tag - find a request by its tag and queue
* @q: The request queue for the device
diff --git a/trunk/block/blk.h b/trunk/block/blk.h
index ec898dd0c65c..ec9120fb789a 100644
--- a/trunk/block/blk.h
+++ b/trunk/block/blk.h
@@ -32,6 +32,8 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect);
void blk_queue_congestion_threshold(struct request_queue *q);
+int blk_dev_init(void);
+
/*
* Return the threshold (number of used requests) at which the queue is
* considered to be congested. It include a little hysteresis to keep the
diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c
index 7f3c09549e4b..8917c5174dc2 100644
--- a/trunk/block/bsg.c
+++ b/trunk/block/bsg.c
@@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
}
if (rq->next_rq) {
- hdr->dout_resid = rq->raw_data_len;
- hdr->din_resid = rq->next_rq->raw_data_len;
+ hdr->dout_resid = rq->data_len;
+ hdr->din_resid = rq->next_rq->data_len;
blk_rq_unmap_user(bidi_bio);
blk_put_request(rq->next_rq);
} else if (rq_data_dir(rq) == READ)
- hdr->din_resid = rq->raw_data_len;
+ hdr->din_resid = rq->data_len;
else
- hdr->dout_resid = rq->raw_data_len;
+ hdr->dout_resid = rq->data_len;
/*
* If the request generated a negative error number, return it
diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c
index 53f2238e69c8..c44527d16c52 100644
--- a/trunk/block/genhd.c
+++ b/trunk/block/genhd.c
@@ -17,11 +17,15 @@
#include
#include
+#include "blk.h"
+
static DEFINE_MUTEX(block_class_lock);
#ifndef CONFIG_SYSFS_DEPRECATED
struct kobject *block_depr;
#endif
+static struct device_type disk_type;
+
/*
* Can be deleted altogether. Later.
*
@@ -346,8 +350,6 @@ const struct seq_operations partitions_op = {
#endif
-extern int blk_dev_init(void);
-
static struct kobject *base_probe(dev_t devt, int *part, void *data)
{
if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
@@ -502,7 +504,7 @@ struct class block_class = {
.name = "block",
};
-struct device_type disk_type = {
+static struct device_type disk_type = {
.name = "disk",
.groups = disk_attr_groups,
.release = disk_release,
@@ -632,12 +634,14 @@ static void media_change_notify_thread(struct work_struct *work)
put_device(gd->driverfs_dev);
}
+#if 0
void genhd_media_change_notify(struct gendisk *disk)
{
get_device(disk->driverfs_dev);
schedule_work(&disk->async_notify);
}
EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+#endif /* 0 */
dev_t blk_lookup_devt(const char *name)
{
diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c
index e993cac4911d..a2c3a936ebf9 100644
--- a/trunk/block/scsi_ioctl.c
+++ b/trunk/block/scsi_ioctl.c
@@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
hdr->info = 0;
if (hdr->masked_status || hdr->host_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK;
- hdr->resid = rq->raw_data_len;
+ hdr->resid = rq->data_len;
hdr->sb_len_wr = 0;
if (rq->sense_len && hdr->sbp) {
@@ -528,8 +528,8 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, WRITE, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->data = NULL;
- rq->raw_data_len = 0;
rq->data_len = 0;
+ rq->extra_len = 0;
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd[0] = cmd;
diff --git a/trunk/drivers/acorn/char/defkeymap-l7200.c b/trunk/drivers/acorn/char/defkeymap-l7200.c
index 28a5fbc6aa1a..93d80a1c36f9 100644
--- a/trunk/drivers/acorn/char/defkeymap-l7200.c
+++ b/trunk/drivers/acorn/char/defkeymap-l7200.c
@@ -347,40 +347,40 @@ char *func_table[MAX_NR_FUNC] = {
};
struct kbdiacruc accent_table[MAX_DIACR] = {
- {'`', 'A', '\300'}, {'`', 'a', '\340'},
- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
- {'^', 'A', '\302'}, {'^', 'a', '\342'},
- {'~', 'A', '\303'}, {'~', 'a', '\343'},
- {'"', 'A', '\304'}, {'"', 'a', '\344'},
- {'O', 'A', '\305'}, {'o', 'a', '\345'},
- {'0', 'A', '\305'}, {'0', 'a', '\345'},
- {'A', 'A', '\305'}, {'a', 'a', '\345'},
- {'A', 'E', '\306'}, {'a', 'e', '\346'},
- {',', 'C', '\307'}, {',', 'c', '\347'},
- {'`', 'E', '\310'}, {'`', 'e', '\350'},
- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
- {'^', 'E', '\312'}, {'^', 'e', '\352'},
- {'"', 'E', '\313'}, {'"', 'e', '\353'},
- {'`', 'I', '\314'}, {'`', 'i', '\354'},
- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
- {'^', 'I', '\316'}, {'^', 'i', '\356'},
- {'"', 'I', '\317'}, {'"', 'i', '\357'},
- {'-', 'D', '\320'}, {'-', 'd', '\360'},
- {'~', 'N', '\321'}, {'~', 'n', '\361'},
- {'`', 'O', '\322'}, {'`', 'o', '\362'},
- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
- {'^', 'O', '\324'}, {'^', 'o', '\364'},
- {'~', 'O', '\325'}, {'~', 'o', '\365'},
- {'"', 'O', '\326'}, {'"', 'o', '\366'},
- {'/', 'O', '\330'}, {'/', 'o', '\370'},
- {'`', 'U', '\331'}, {'`', 'u', '\371'},
- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
- {'^', 'U', '\333'}, {'^', 'u', '\373'},
- {'"', 'U', '\334'}, {'"', 'u', '\374'},
- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
- {'T', 'H', '\336'}, {'t', 'h', '\376'},
- {'s', 's', '\337'}, {'"', 'y', '\377'},
- {'s', 'z', '\337'}, {'i', 'j', '\377'},
+ {'`', 'A', 0300}, {'`', 'a', 0340},
+ {'\'', 'A', 0301}, {'\'', 'a', 0341},
+ {'^', 'A', 0302}, {'^', 'a', 0342},
+ {'~', 'A', 0303}, {'~', 'a', 0343},
+ {'"', 'A', 0304}, {'"', 'a', 0344},
+ {'O', 'A', 0305}, {'o', 'a', 0345},
+ {'0', 'A', 0305}, {'0', 'a', 0345},
+ {'A', 'A', 0305}, {'a', 'a', 0345},
+ {'A', 'E', 0306}, {'a', 'e', 0346},
+ {',', 'C', 0307}, {',', 'c', 0347},
+ {'`', 'E', 0310}, {'`', 'e', 0350},
+ {'\'', 'E', 0311}, {'\'', 'e', 0351},
+ {'^', 'E', 0312}, {'^', 'e', 0352},
+ {'"', 'E', 0313}, {'"', 'e', 0353},
+ {'`', 'I', 0314}, {'`', 'i', 0354},
+ {'\'', 'I', 0315}, {'\'', 'i', 0355},
+ {'^', 'I', 0316}, {'^', 'i', 0356},
+ {'"', 'I', 0317}, {'"', 'i', 0357},
+ {'-', 'D', 0320}, {'-', 'd', 0360},
+ {'~', 'N', 0321}, {'~', 'n', 0361},
+ {'`', 'O', 0322}, {'`', 'o', 0362},
+ {'\'', 'O', 0323}, {'\'', 'o', 0363},
+ {'^', 'O', 0324}, {'^', 'o', 0364},
+ {'~', 'O', 0325}, {'~', 'o', 0365},
+ {'"', 'O', 0326}, {'"', 'o', 0366},
+ {'/', 'O', 0330}, {'/', 'o', 0370},
+ {'`', 'U', 0331}, {'`', 'u', 0371},
+ {'\'', 'U', 0332}, {'\'', 'u', 0372},
+ {'^', 'U', 0333}, {'^', 'u', 0373},
+ {'"', 'U', 0334}, {'"', 'u', 0374},
+ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
+ {'T', 'H', 0336}, {'t', 'h', 0376},
+ {'s', 's', 0337}, {'"', 'y', 0377},
+ {'s', 'z', 0337}, {'i', 'j', 0377},
};
unsigned int accent_table_size = 68;
diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c
index 6dd12f7019a0..8a49835bd0f8 100644
--- a/trunk/drivers/ata/ahci.c
+++ b/trunk/drivers/ata/ahci.c
@@ -85,6 +85,7 @@ enum {
board_ahci_ign_iferr = 2,
board_ahci_sb600 = 3,
board_ahci_mv = 4,
+ board_ahci_sb700 = 5,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -185,6 +186,7 @@ enum {
AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */
AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */
AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */
+ AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */
/* ap->flags bits */
@@ -254,6 +256,7 @@ static void ahci_vt8251_error_handler(struct ata_port *ap);
static void ahci_p5wdh_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_resume(struct ata_port *ap);
+static void ahci_dev_config(struct ata_device *dev);
static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
@@ -293,6 +296,8 @@ static const struct ata_port_operations ahci_ops = {
.check_altstatus = ahci_check_status,
.dev_select = ata_noop_dev_select,
+ .dev_config = ahci_dev_config,
+
.tf_read = ahci_tf_read,
.qc_defer = sata_pmp_qc_defer_cmd_switch,
@@ -424,7 +429,7 @@ static const struct ata_port_info ahci_port_info[] = {
/* board_ahci_sb600 */
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
- AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_PMP),
+ AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
@@ -442,6 +447,16 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
+ /* board_ahci_sb700 */
+ {
+ AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
+ AHCI_HFLAG_NO_PMP),
+ .flags = AHCI_FLAG_COMMON,
+ .link_flags = AHCI_LFLAG_COMMON,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
};
static const struct pci_device_id ahci_pci_tbl[] = {
@@ -484,12 +499,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* ATI */
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
- { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb600 }, /* ATI SB700/800 */
- { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb600 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */
+ { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
/* VIA */
{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
@@ -1165,6 +1180,14 @@ static void ahci_init_controller(struct ata_host *host)
VPRINTK("HOST_CTL 0x%x\n", tmp);
}
+static void ahci_dev_config(struct ata_device *dev)
+{
+ struct ahci_host_priv *hpriv = dev->link->ap->host->private_data;
+
+ if (hpriv->flags & AHCI_HFLAG_SECT255)
+ dev->max_sectors = 255;
+}
+
static unsigned int ahci_dev_classify(struct ata_port *ap)
{
void __iomem *port_mmio = ahci_port_base(ap);
diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c
index 4cf8662df99e..4fbcce758b04 100644
--- a/trunk/drivers/ata/libata-core.c
+++ b/trunk/drivers/ata/libata-core.c
@@ -113,7 +113,7 @@ int atapi_enabled = 1;
module_param(atapi_enabled, int, 0444);
MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
-int atapi_dmadir = 0;
+static int atapi_dmadir = 0;
module_param(atapi_dmadir, int, 0444);
MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)");
@@ -153,7 +153,7 @@ MODULE_VERSION(DRV_VERSION);
/**
* ata_force_cbl - force cable type according to libata.force
- * @link: ATA link of interest
+ * @ap: ATA port of interest
*
* Force cable type according to libata.force and whine about it.
* The last entry which has matching port number is used, so it
@@ -2396,6 +2396,7 @@ int ata_dev_configure(struct ata_device *dev)
else if (dev->class == ATA_DEV_ATAPI) {
const char *cdb_intr_string = "";
const char *atapi_an_string = "";
+ const char *dma_dir_string = "";
u32 sntf;
rc = atapi_cdb_len(id);
@@ -2436,13 +2437,19 @@ int ata_dev_configure(struct ata_device *dev)
cdb_intr_string = ", CDB intr";
}
+ if (atapi_dmadir || atapi_id_dmadir(dev->id)) {
+ dev->flags |= ATA_DFLAG_DMADIR;
+ dma_dir_string = ", DMADIR";
+ }
+
/* print device info to dmesg */
if (ata_msg_drv(ap) && print_info)
ata_dev_printk(dev, KERN_INFO,
- "ATAPI: %s, %s, max %s%s%s\n",
+ "ATAPI: %s, %s, max %s%s%s%s\n",
modelbuf, fwrevbuf,
ata_mode_string(xfer_mask),
- cdb_intr_string, atapi_an_string);
+ cdb_intr_string, atapi_an_string,
+ dma_dir_string);
}
/* determine max_sectors */
diff --git a/trunk/drivers/ata/libata-pmp.c b/trunk/drivers/ata/libata-pmp.c
index caef2bbd4a8a..d91f5090ba9d 100644
--- a/trunk/drivers/ata/libata-pmp.c
+++ b/trunk/drivers/ata/libata-pmp.c
@@ -35,7 +35,7 @@ static unsigned int sata_pmp_read(struct ata_link *link, int reg, u32 *r_val)
ata_tf_init(pmp_dev, &tf);
tf.command = ATA_CMD_PMP_READ;
tf.protocol = ATA_PROT_NODATA;
- tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
tf.feature = reg;
tf.device = link->pmp;
@@ -71,7 +71,7 @@ static unsigned int sata_pmp_write(struct ata_link *link, int reg, u32 val)
ata_tf_init(pmp_dev, &tf);
tf.command = ATA_CMD_PMP_WRITE;
tf.protocol = ATA_PROT_NODATA;
- tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
tf.feature = reg;
tf.device = link->pmp;
tf.nsect = val & 0xff;
diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c
index f888babc8283..8f0e8f2bc628 100644
--- a/trunk/drivers/ata/libata-scsi.c
+++ b/trunk/drivers/ata/libata-scsi.c
@@ -862,9 +862,10 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
struct request_queue *q = sdev->request_queue;
void *buf;
- /* set the min alignment */
+ /* set the min alignment and padding */
blk_queue_update_dma_alignment(sdev->request_queue,
ATA_DMA_PAD_SZ - 1);
+ blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1);
/* configure draining */
buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
@@ -1694,12 +1695,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
u8 *rbuf;
unsigned int buflen, rc;
struct scsi_cmnd *cmd = args->cmd;
+ unsigned long flags;
+
+ local_irq_save(flags);
buflen = ata_scsi_rbuf_get(cmd, &rbuf);
memset(rbuf, 0, buflen);
rc = actor(args, rbuf, buflen);
ata_scsi_rbuf_put(cmd, rbuf);
+ local_irq_restore(flags);
+
if (rc == 0)
cmd->result = SAM_STAT_GOOD;
args->done(cmd);
@@ -2473,6 +2479,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
u8 *buf = NULL;
unsigned int buflen;
+ unsigned long flags;
+
+ local_irq_save(flags);
buflen = ata_scsi_rbuf_get(cmd, &buf);
@@ -2490,6 +2499,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
}
ata_scsi_rbuf_put(cmd, buf);
+
+ local_irq_restore(flags);
}
cmd->result = SAM_STAT_GOOD;
@@ -2528,7 +2539,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
}
qc->tf.command = ATA_CMD_PACKET;
- qc->nbytes = scsi_bufflen(scmd);
+ qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
/* check whether ATAPI DMA is safe */
if (!using_pio && ata_check_atapi_dma(qc))
@@ -2539,7 +2550,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
* want to set it properly, and for DMA where it is
* effectively meaningless.
*/
- nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024);
+ nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024);
/* Most ATAPI devices which honor transfer chunk size don't
* behave according to the spec when odd chunk size which
@@ -2582,7 +2593,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
qc->tf.protocol = ATAPI_PROT_DMA;
qc->tf.feature |= ATAPI_PKT_DMA;
- if (atapi_dmadir && (scmd->sc_data_direction != DMA_TO_DEVICE))
+ if ((dev->flags & ATA_DFLAG_DMADIR) &&
+ (scmd->sc_data_direction != DMA_TO_DEVICE))
/* some SATA bridges need us to indicate data xfer direction */
qc->tf.feature |= ATAPI_DMADIR;
}
@@ -2864,7 +2876,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nbytes = scsi_bufflen(scmd);
+ qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
/* request result TF and be quiet about device error */
qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h
index 6036dedfe377..aa884f71a12a 100644
--- a/trunk/drivers/ata/libata.h
+++ b/trunk/drivers/ata/libata.h
@@ -56,7 +56,6 @@ enum {
extern unsigned int ata_print_id;
extern struct workqueue_struct *ata_aux_wq;
extern int atapi_enabled;
-extern int atapi_dmadir;
extern int atapi_passthru16;
extern int libata_fua;
extern int libata_noacpi;
diff --git a/trunk/drivers/ata/pata_atiixp.c b/trunk/drivers/ata/pata_atiixp.c
index 9623f5295530..408bdc1a9776 100644
--- a/trunk/drivers/ata/pata_atiixp.c
+++ b/trunk/drivers/ata/pata_atiixp.c
@@ -227,7 +227,7 @@ static struct scsi_host_template atiixp_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -259,7 +259,7 @@ static struct ata_port_operations atiixp_port_ops = {
.bmdma_stop = atiixp_bmdma_stop,
.bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
+ .qc_prep = ata_dumb_qc_prep,
.qc_issue = ata_qc_issue_prot,
.data_xfer = ata_data_xfer,
diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c
index 0713872cf65c..a742efa0da2b 100644
--- a/trunk/drivers/ata/pata_hpt366.c
+++ b/trunk/drivers/ata/pata_hpt366.c
@@ -27,7 +27,7 @@
#include
#define DRV_NAME "pata_hpt366"
-#define DRV_VERSION "0.6.1"
+#define DRV_VERSION "0.6.2"
struct hpt_clock {
u8 xfer_speed;
@@ -180,9 +180,9 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3))
- mask &= ~(0x07 << ATA_SHIFT_UDMA);
+ mask &= ~(0xF8 << ATA_SHIFT_UDMA);
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
- mask &= ~(0x0F << ATA_SHIFT_UDMA);
+ mask &= ~(0xF0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c
index 68eb34929cec..9a10878b2ad8 100644
--- a/trunk/drivers/ata/pata_hpt37x.c
+++ b/trunk/drivers/ata/pata_hpt37x.c
@@ -24,7 +24,7 @@
#include
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.9"
+#define DRV_VERSION "0.6.11"
struct hpt_clock {
u8 xfer_speed;
@@ -281,7 +281,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
mask &= ~ATA_MASK_UDMA;
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
- mask &= ~(0x1F << ATA_SHIFT_UDMA);
+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
@@ -297,7 +297,7 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
{
if (adev->class == ATA_DEV_ATA) {
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
- mask &= ~ (0x1F << ATA_SHIFT_UDMA);
+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/trunk/drivers/ata/pata_serverworks.c b/trunk/drivers/ata/pata_serverworks.c
index 9c523fbf529e..a589c0fa0dbb 100644
--- a/trunk/drivers/ata/pata_serverworks.c
+++ b/trunk/drivers/ata/pata_serverworks.c
@@ -226,7 +226,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo
for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
if (!strcmp(p, model_num))
- mask &= ~(0x1F << ATA_SHIFT_UDMA);
+ mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/trunk/drivers/ata/sata_fsl.c b/trunk/drivers/ata/sata_fsl.c
index 9323dd0c7d8d..07791a7a48a5 100644
--- a/trunk/drivers/ata/sata_fsl.c
+++ b/trunk/drivers/ata/sata_fsl.c
@@ -335,7 +335,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
dma_addr_t indirect_ext_segment_paddr;
unsigned int si;
- VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd);
+ VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p\n", cmd_desc, prd);
indirect_ext_segment_paddr = cmd_desc_paddr +
SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16;
@@ -459,7 +459,8 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n",
ioread32(CE + hcr_base),
ioread32(DE + hcr_base),
- ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base));
+ ioread32(CC + hcr_base),
+ ioread32(COMMANDSTAT + host_priv->csr_base));
return 0;
}
@@ -522,7 +523,8 @@ static void sata_fsl_freeze(struct ata_port *ap)
ioread32(CQ + hcr_base),
ioread32(CA + hcr_base),
ioread32(CE + hcr_base), ioread32(DE + hcr_base));
- VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT));
+ VPRINTK("CmdStat = 0x%x\n",
+ ioread32(host_priv->csr_base + COMMANDSTAT));
/* disable interrupts on the controller/port */
temp = ioread32(hcr_base + HCONTROL);
diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c
index 69f651e0bc98..840d1c4a7850 100644
--- a/trunk/drivers/ata/sata_svw.c
+++ b/trunk/drivers/ata/sata_svw.c
@@ -45,6 +45,8 @@
#include
#include
#include
+#include
+#include
#include
#ifdef CONFIG_PPC_OF
@@ -59,6 +61,7 @@ enum {
/* ap->flags bits */
K2_FLAG_SATA_8_PORTS = (1 << 24),
K2_FLAG_NO_ATAPI_DMA = (1 << 25),
+ K2_FLAG_BAR_POS_3 = (1 << 26),
/* Taskfile registers offsets */
K2_SATA_TF_CMD_OFFSET = 0x00,
@@ -88,8 +91,10 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
- board_svw4 = 0,
- board_svw8 = 1,
+ chip_svw4 = 0,
+ chip_svw8 = 1,
+ chip_svw42 = 2, /* bar 3 */
+ chip_svw43 = 3, /* bar 5 */
};
static u8 k2_stat_check_status(struct ata_port *ap);
@@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap);
static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc)
{
+ u8 cmnd = qc->scsicmd->cmnd[0];
+
if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA)
return -1; /* ATAPI DMA not supported */
+ else {
+ switch (cmnd) {
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
+ return 0;
+
+ default:
+ return -1;
+ }
- return 0;
+ }
}
static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = {
};
static const struct ata_port_info k2_port_info[] = {
- /* board_svw4 */
+ /* chip_svw4 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
@@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
- /* board_svw8 */
+ /* chip_svw8 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
@@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
+ /* chip_svw42 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &k2_sata_ops,
+ },
+ /* chip_svw43 */
+ {
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &k2_sata_ops,
+ },
};
static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
@@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
{ &k2_port_info[ent->driver_data], NULL };
struct ata_host *host;
void __iomem *mmio_base;
- int n_ports, i, rc;
+ int n_ports, i, rc, bar_pos;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
if (!host)
return -ENOMEM;
+ bar_pos = 5;
+ if (ppi[0]->flags & K2_FLAG_BAR_POS_3)
+ bar_pos = 3;
/*
* If this driver happens to only be useful on Apple's K2, then
* we should check that here as it has a normal Serverworks ID
@@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
* Check if we have resources mapped at all (second function may
* have been disabled by firmware)
*/
- if (pci_resource_len(pdev, 5) == 0)
+ if (pci_resource_len(pdev, bar_pos) == 0) {
+ /* In IDE mode we need to pin the device to ensure that
+ pcim_release does not clear the busmaster bit in config
+ space, clearing causes busmaster DMA to fail on
+ ports 3 & 4 */
+ pcim_pin_device(pdev);
return -ENODEV;
+ }
/* Request and iomap PCI regions */
- rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
host->iomap = pcim_iomap_table(pdev);
- mmio_base = host->iomap[5];
+ mmio_base = host->iomap[bar_pos];
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
@@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
* controller
* */
static const struct pci_device_id k2_sata_pci_tbl[] = {
- { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 },
- { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 },
- { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
+ { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 },
{ }
};
diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c
index 9c0070b5bd3e..7de543d1d0b4 100644
--- a/trunk/drivers/base/core.c
+++ b/trunk/drivers/base/core.c
@@ -621,7 +621,8 @@ static struct kobject *get_device_parent(struct device *dev,
static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
{
/* see if we live in a "glue" directory */
- if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
+ if (!glue_dir || !dev->class ||
+ glue_dir->kset != &dev->class->class_dirs)
return;
kobject_put(glue_dir);
@@ -770,17 +771,10 @@ int device_add(struct device *dev)
struct class_interface *class_intf;
int error;
- error = pm_sleep_lock();
- if (error) {
- dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__);
- dump_stack();
- return error;
- }
-
dev = get_device(dev);
if (!dev || !strlen(dev->bus_id)) {
error = -EINVAL;
- goto Error;
+ goto Done;
}
pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__);
@@ -843,11 +837,9 @@ int device_add(struct device *dev)
}
Done:
put_device(dev);
- pm_sleep_unlock();
return error;
BusError:
device_pm_remove(dev);
- dpm_sysfs_remove(dev);
PMError:
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
diff --git a/trunk/drivers/base/power/main.c b/trunk/drivers/base/power/main.c
index ee9d1c8db0d6..d887d5cb5bef 100644
--- a/trunk/drivers/base/power/main.c
+++ b/trunk/drivers/base/power/main.c
@@ -48,7 +48,6 @@
*/
LIST_HEAD(dpm_active);
-static LIST_HEAD(dpm_locked);
static LIST_HEAD(dpm_off);
static LIST_HEAD(dpm_off_irq);
static LIST_HEAD(dpm_destroy);
@@ -81,28 +80,6 @@ void device_pm_add(struct device *dev)
*/
void device_pm_remove(struct device *dev)
{
- /*
- * If this function is called during a suspend, it will be blocked,
- * because we're holding the device's semaphore at that time, which may
- * lead to a deadlock. In that case we want to print a warning.
- * However, it may also be called by unregister_dropped_devices() with
- * the device's semaphore released, in which case the warning should
- * not be printed.
- */
- if (down_trylock(&dev->sem)) {
- if (down_read_trylock(&pm_sleep_rwsem)) {
- /* No suspend in progress, wait on dev->sem */
- down(&dev->sem);
- up_read(&pm_sleep_rwsem);
- } else {
- /* Suspend in progress, we may deadlock */
- dev_warn(dev, "Suspicious %s during suspend\n",
- __FUNCTION__);
- dump_stack();
- /* The user has been warned ... */
- down(&dev->sem);
- }
- }
pr_debug("PM: Removing info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus",
kobject_name(&dev->kobj));
@@ -110,7 +87,6 @@ void device_pm_remove(struct device *dev)
dpm_sysfs_remove(dev);
list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
- up(&dev->sem);
}
/**
@@ -230,6 +206,8 @@ static int resume_device(struct device *dev)
TRACE_DEVICE(dev);
TRACE_RESUME(0);
+ down(&dev->sem);
+
if (dev->bus && dev->bus->resume) {
dev_dbg(dev,"resuming\n");
error = dev->bus->resume(dev);
@@ -245,6 +223,8 @@ static int resume_device(struct device *dev)
error = dev->class->resume(dev);
}
+ up(&dev->sem);
+
TRACE_RESUME(error);
return error;
}
@@ -266,7 +246,7 @@ static void dpm_resume(void)
struct list_head *entry = dpm_off.next;
struct device *dev = to_device(entry);
- list_move_tail(entry, &dpm_locked);
+ list_move_tail(entry, &dpm_active);
mutex_unlock(&dpm_list_mtx);
resume_device(dev);
mutex_lock(&dpm_list_mtx);
@@ -274,25 +254,6 @@ static void dpm_resume(void)
mutex_unlock(&dpm_list_mtx);
}
-/**
- * unlock_all_devices - Release each device's semaphore
- *
- * Go through the dpm_off list. Put each device on the dpm_active
- * list and unlock it.
- */
-static void unlock_all_devices(void)
-{
- mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_locked)) {
- struct list_head *entry = dpm_locked.prev;
- struct device *dev = to_device(entry);
-
- list_move(entry, &dpm_active);
- up(&dev->sem);
- }
- mutex_unlock(&dpm_list_mtx);
-}
-
/**
* unregister_dropped_devices - Unregister devices scheduled for removal
*
@@ -305,7 +266,6 @@ static void unregister_dropped_devices(void)
struct list_head *entry = dpm_destroy.next;
struct device *dev = to_device(entry);
- up(&dev->sem);
mutex_unlock(&dpm_list_mtx);
/* This also removes the device from the list */
device_unregister(dev);
@@ -324,7 +284,6 @@ void device_resume(void)
{
might_sleep();
dpm_resume();
- unlock_all_devices();
unregister_dropped_devices();
up_write(&pm_sleep_rwsem);
}
@@ -388,18 +347,15 @@ int device_power_down(pm_message_t state)
struct list_head *entry = dpm_off.prev;
struct device *dev = to_device(entry);
- list_del_init(&dev->power.entry);
error = suspend_device_late(dev, state);
if (error) {
printk(KERN_ERR "Could not power down device %s: "
"error %d\n",
kobject_name(&dev->kobj), error);
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_off);
break;
}
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_off_irq);
+ if (!list_empty(&dev->power.entry))
+ list_move(&dev->power.entry, &dpm_off_irq);
}
if (!error)
@@ -419,6 +375,8 @@ static int suspend_device(struct device *dev, pm_message_t state)
{
int error = 0;
+ down(&dev->sem);
+
if (dev->power.power_state.event) {
dev_dbg(dev, "PM: suspend %d-->%d\n",
dev->power.power_state.event, state.event);
@@ -441,6 +399,9 @@ static int suspend_device(struct device *dev, pm_message_t state)
error = dev->bus->suspend(dev, state);
suspend_report_result(dev->bus->suspend, error);
}
+
+ up(&dev->sem);
+
return error;
}
@@ -461,13 +422,13 @@ static int dpm_suspend(pm_message_t state)
int error = 0;
mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_locked)) {
- struct list_head *entry = dpm_locked.prev;
+ while (!list_empty(&dpm_active)) {
+ struct list_head *entry = dpm_active.prev;
struct device *dev = to_device(entry);
- list_del_init(&dev->power.entry);
mutex_unlock(&dpm_list_mtx);
error = suspend_device(dev, state);
+ mutex_lock(&dpm_list_mtx);
if (error) {
printk(KERN_ERR "Could not suspend device %s: "
"error %d%s\n",
@@ -476,50 +437,16 @@ static int dpm_suspend(pm_message_t state)
(error == -EAGAIN ?
" (please convert to suspend_late)" :
""));
- mutex_lock(&dpm_list_mtx);
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_locked);
break;
}
- mutex_lock(&dpm_list_mtx);
- if (list_empty(&dev->power.entry))
- list_add(&dev->power.entry, &dpm_off);
+ if (!list_empty(&dev->power.entry))
+ list_move(&dev->power.entry, &dpm_off);
}
mutex_unlock(&dpm_list_mtx);
return error;
}
-/**
- * lock_all_devices - Acquire every device's semaphore
- *
- * Go through the dpm_active list. Carefully lock each device's
- * semaphore and put it in on the dpm_locked list.
- */
-static void lock_all_devices(void)
-{
- mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_active)) {
- struct list_head *entry = dpm_active.next;
- struct device *dev = to_device(entry);
-
- /* Required locking order is dev->sem first,
- * then dpm_list_mutex. Hence this awkward code.
- */
- get_device(dev);
- mutex_unlock(&dpm_list_mtx);
- down(&dev->sem);
- mutex_lock(&dpm_list_mtx);
-
- if (list_empty(entry))
- up(&dev->sem); /* Device was removed */
- else
- list_move_tail(entry, &dpm_locked);
- put_device(dev);
- }
- mutex_unlock(&dpm_list_mtx);
-}
-
/**
* device_suspend - Save state and stop all devices in system.
* @state: new power management state
@@ -533,7 +460,6 @@ int device_suspend(pm_message_t state)
might_sleep();
down_write(&pm_sleep_rwsem);
- lock_all_devices();
error = dpm_suspend(state);
if (error)
device_resume();
diff --git a/trunk/drivers/base/transport_class.c b/trunk/drivers/base/transport_class.c
index f25e7c6b2d27..40bca48abc12 100644
--- a/trunk/drivers/base/transport_class.c
+++ b/trunk/drivers/base/transport_class.c
@@ -126,9 +126,7 @@ static int transport_setup_classdev(struct attribute_container *cont,
}
/**
- * transport_setup_device - declare a new dev for transport class association
- * but don't make it visible yet.
- *
+ * transport_setup_device - declare a new dev for transport class association but don't make it visible yet.
* @dev: the generic device representing the entity being added
*
* Usually, dev represents some component in the HBA system (either
diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c
index 9715be3f2487..55bd35c0f082 100644
--- a/trunk/drivers/block/cciss.c
+++ b/trunk/drivers/block/cciss.c
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -131,7 +132,6 @@ static struct board_type products[] = {
/*define how many times we will try a command because of bus resets */
#define MAX_CMD_RETRIES 3
-#define READ_AHEAD 1024
#define MAX_CTLR 32
/* Originally cciss driver only supports 8 major numbers */
@@ -174,8 +174,6 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
static void fail_all_cmds(unsigned long ctlr);
#ifdef CONFIG_PROC_FS
-static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data);
static void cciss_procinit(int i);
#else
static void cciss_procinit(int i)
@@ -240,24 +238,46 @@ static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
*/
#define ENG_GIG 1000000000
#define ENG_GIG_FACTOR (ENG_GIG/512)
+#define ENGAGE_SCSI "engage scsi"
static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
"UNKNOWN"
};
static struct proc_dir_entry *proc_cciss;
-static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
+static void cciss_seq_show_header(struct seq_file *seq)
{
- off_t pos = 0;
- off_t len = 0;
- int size, i, ctlr;
- ctlr_info_t *h = (ctlr_info_t *) data;
- drive_info_struct *drv;
- unsigned long flags;
- sector_t vol_sz, vol_sz_frac;
+ ctlr_info_t *h = seq->private;
+
+ seq_printf(seq, "%s: HP %s Controller\n"
+ "Board ID: 0x%08lx\n"
+ "Firmware Version: %c%c%c%c\n"
+ "IRQ: %d\n"
+ "Logical drives: %d\n"
+ "Current Q depth: %d\n"
+ "Current # commands on controller: %d\n"
+ "Max Q depth since init: %d\n"
+ "Max # commands on controller since init: %d\n"
+ "Max SG entries since init: %d\n",
+ h->devname,
+ h->product_name,
+ (unsigned long)h->board_id,
+ h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
+ h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT],
+ h->num_luns,
+ h->Qdepth, h->commands_outstanding,
+ h->maxQsinceinit, h->max_outstanding, h->maxSG);
- ctlr = h->ctlr;
+#ifdef CONFIG_CISS_SCSI_TAPE
+ cciss_seq_tape_report(seq, h->ctlr);
+#endif /* CONFIG_CISS_SCSI_TAPE */
+}
+
+static void *cciss_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ ctlr_info_t *h = seq->private;
+ unsigned ctlr = h->ctlr;
+ unsigned long flags;
/* prevent displaying bogus info during configuration
* or deconfiguration of a logical volume
@@ -265,115 +285,155 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (h->busy_configuring) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- return -EBUSY;
+ return ERR_PTR(-EBUSY);
}
h->busy_configuring = 1;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- size = sprintf(buffer, "%s: HP %s Controller\n"
- "Board ID: 0x%08lx\n"
- "Firmware Version: %c%c%c%c\n"
- "IRQ: %d\n"
- "Logical drives: %d\n"
- "Max sectors: %d\n"
- "Current Q depth: %d\n"
- "Current # commands on controller: %d\n"
- "Max Q depth since init: %d\n"
- "Max # commands on controller since init: %d\n"
- "Max SG entries since init: %d\n\n",
- h->devname,
- h->product_name,
- (unsigned long)h->board_id,
- h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
- h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT],
- h->num_luns,
- h->cciss_max_sectors,
- h->Qdepth, h->commands_outstanding,
- h->maxQsinceinit, h->max_outstanding, h->maxSG);
-
- pos += size;
- len += size;
- cciss_proc_tape_report(ctlr, buffer, &pos, &len);
- for (i = 0; i <= h->highest_lun; i++) {
-
- drv = &h->drv[i];
- if (drv->heads == 0)
- continue;
+ if (*pos == 0)
+ cciss_seq_show_header(seq);
- vol_sz = drv->nr_blocks;
- vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR);
- vol_sz_frac *= 100;
- sector_div(vol_sz_frac, ENG_GIG_FACTOR);
+ return pos;
+}
+
+static int cciss_seq_show(struct seq_file *seq, void *v)
+{
+ sector_t vol_sz, vol_sz_frac;
+ ctlr_info_t *h = seq->private;
+ unsigned ctlr = h->ctlr;
+ loff_t *pos = v;
+ drive_info_struct *drv = &h->drv[*pos];
+
+ if (*pos > h->highest_lun)
+ return 0;
+
+ if (drv->heads == 0)
+ return 0;
+
+ vol_sz = drv->nr_blocks;
+ vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR);
+ vol_sz_frac *= 100;
+ sector_div(vol_sz_frac, ENG_GIG_FACTOR);
+
+ if (drv->raid_level > 5)
+ drv->raid_level = RAID_UNKNOWN;
+ seq_printf(seq, "cciss/c%dd%d:"
+ "\t%4u.%02uGB\tRAID %s\n",
+ ctlr, (int) *pos, (int)vol_sz, (int)vol_sz_frac,
+ raid_label[drv->raid_level]);
+ return 0;
+}
+
+static void *cciss_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ctlr_info_t *h = seq->private;
+
+ if (*pos > h->highest_lun)
+ return NULL;
+ *pos += 1;
+
+ return pos;
+}
+
+static void cciss_seq_stop(struct seq_file *seq, void *v)
+{
+ ctlr_info_t *h = seq->private;
+
+ /* Only reset h->busy_configuring if we succeeded in setting
+ * it during cciss_seq_start. */
+ if (v == ERR_PTR(-EBUSY))
+ return;
- if (drv->raid_level > 5)
- drv->raid_level = RAID_UNKNOWN;
- size = sprintf(buffer + len, "cciss/c%dd%d:"
- "\t%4u.%02uGB\tRAID %s\n",
- ctlr, i, (int)vol_sz, (int)vol_sz_frac,
- raid_label[drv->raid_level]);
- pos += size;
- len += size;
- }
-
- *eof = 1;
- *start = buffer + offset;
- len -= offset;
- if (len > length)
- len = length;
h->busy_configuring = 0;
- return len;
}
-static int
-cciss_proc_write(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+static struct seq_operations cciss_seq_ops = {
+ .start = cciss_seq_start,
+ .show = cciss_seq_show,
+ .next = cciss_seq_next,
+ .stop = cciss_seq_stop,
+};
+
+static int cciss_seq_open(struct inode *inode, struct file *file)
{
- unsigned char cmd[80];
- int len;
-#ifdef CONFIG_CISS_SCSI_TAPE
- ctlr_info_t *h = (ctlr_info_t *) data;
- int rc;
+ int ret = seq_open(file, &cciss_seq_ops);
+ struct seq_file *seq = file->private_data;
+
+ if (!ret)
+ seq->private = PDE(inode)->data;
+
+ return ret;
+}
+
+static ssize_t
+cciss_proc_write(struct file *file, const char __user *buf,
+ size_t length, loff_t *ppos)
+{
+ int err;
+ char *buffer;
+
+#ifndef CONFIG_CISS_SCSI_TAPE
+ return -EINVAL;
#endif
- if (count > sizeof(cmd) - 1)
+ if (!buf || length > PAGE_SIZE - 1)
return -EINVAL;
- if (copy_from_user(cmd, buffer, count))
- return -EFAULT;
- cmd[count] = '\0';
- len = strlen(cmd); // above 3 lines ensure safety
- if (len && cmd[len - 1] == '\n')
- cmd[--len] = '\0';
-# ifdef CONFIG_CISS_SCSI_TAPE
- if (strcmp("engage scsi", cmd) == 0) {
+
+ buffer = (char *)__get_free_page(GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ err = -EFAULT;
+ if (copy_from_user(buffer, buf, length))
+ goto out;
+ buffer[length] = '\0';
+
+#ifdef CONFIG_CISS_SCSI_TAPE
+ if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) {
+ struct seq_file *seq = file->private_data;
+ ctlr_info_t *h = seq->private;
+ int rc;
+
rc = cciss_engage_scsi(h->ctlr);
if (rc != 0)
- return -rc;
- return count;
- }
+ err = -rc;
+ else
+ err = length;
+ } else
+#endif /* CONFIG_CISS_SCSI_TAPE */
+ err = -EINVAL;
/* might be nice to have "disengage" too, but it's not
safely possible. (only 1 module use count, lock issues.) */
-# endif
- return -EINVAL;
+
+out:
+ free_page((unsigned long)buffer);
+ return err;
}
-/*
- * Get us a file in /proc/cciss that says something about each controller.
- * Create /proc/cciss if it doesn't exist yet.
- */
+static struct file_operations cciss_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = cciss_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+ .write = cciss_proc_write,
+};
+
static void __devinit cciss_procinit(int i)
{
struct proc_dir_entry *pde;
- if (proc_cciss == NULL) {
+ if (proc_cciss == NULL)
proc_cciss = proc_mkdir("cciss", proc_root_driver);
- if (!proc_cciss)
- return;
- }
+ if (!proc_cciss)
+ return;
+ pde = proc_create(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
+ S_IROTH, proc_cciss,
+ &cciss_proc_fops);
+ if (!pde)
+ return;
- pde = create_proc_read_entry(hba[i]->devname,
- S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH,
- proc_cciss, cciss_proc_get_info, hba[i]);
- pde->write_proc = cciss_proc_write;
+ pde->data = hba[i];
}
#endif /* CONFIG_PROC_FS */
@@ -1341,7 +1401,6 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
disk->private_data = &h->drv[drv_index];
/* Set up queue information */
- disk->queue->backing_dev_info.ra_pages = READ_AHEAD;
blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask);
/* This is a hardware imposed limit. */
@@ -3434,7 +3493,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
}
drv->queue = q;
- q->backing_dev_info.ra_pages = READ_AHEAD;
blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
/* This is a hardware imposed limit. */
diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c
index 55178e9973a0..45ac09300eb3 100644
--- a/trunk/drivers/block/cciss_scsi.c
+++ b/trunk/drivers/block/cciss_scsi.c
@@ -1404,21 +1404,18 @@ cciss_engage_scsi(int ctlr)
}
static void
-cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
+cciss_seq_tape_report(struct seq_file *seq, int ctlr)
{
unsigned long flags;
- int size;
-
- *pos = *pos -1; *len = *len - 1; // cut off the last trailing newline
CPQ_TAPE_LOCK(ctlr, flags);
- size = sprintf(buffer + *len,
+ seq_printf(seq,
"Sequential access devices: %d\n\n",
ccissscsi[ctlr].ndevices);
CPQ_TAPE_UNLOCK(ctlr, flags);
- *pos += size; *len += size;
}
+
/* Need at least one of these error handlers to keep ../scsi/hosts.c from
* complaining. Doing a host- or bus-reset can't do anything good here.
* Despite what it might say in scsi_error.c, there may well be commands
@@ -1498,6 +1495,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
#define cciss_scsi_setup(cntl_num)
#define cciss_unregister_scsi(ctlr)
#define cciss_register_scsi(ctlr)
-#define cciss_proc_tape_report(ctlr, buffer, pos, len)
#endif /* CONFIG_CISS_SCSI_TAPE */
diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c
index 674cd66dcaba..18feb1c7c33b 100644
--- a/trunk/drivers/block/pktcdvd.c
+++ b/trunk/drivers/block/pktcdvd.c
@@ -849,7 +849,8 @@ static int pkt_flush_cache(struct pktcdvd_device *pd)
/*
* speed is given as the normal factor, e.g. 4 for 4x
*/
-static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsigned read_speed)
+static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd,
+ unsigned write_speed, unsigned read_speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -1776,7 +1777,8 @@ static int pkt_get_track_info(struct pktcdvd_device *pd, __u16 track, __u8 type,
return pkt_generic_packet(pd, &cgc);
}
-static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written)
+static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd,
+ long *last_written)
{
disc_information di;
track_information ti;
@@ -1813,7 +1815,7 @@ static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written)
/*
* write mode select package based on pd->settings
*/
-static int pkt_set_write_settings(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
@@ -1972,7 +1974,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
return 1;
}
-static int pkt_probe_settings(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
unsigned char buf[12];
@@ -2071,7 +2073,8 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
/*
* enable/disable write caching on drive
*/
-static int pkt_write_caching(struct pktcdvd_device *pd, int set)
+static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd,
+ int set)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2116,7 +2119,8 @@ static int pkt_lock_door(struct pktcdvd_device *pd, int lockflag)
/*
* Returns drive maximum write speed
*/
-static int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned *write_speed)
+static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd,
+ unsigned *write_speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2177,7 +2181,8 @@ static char us_clv_to_speed[16] = {
/*
* reads the maximum media speed from ATIP
*/
-static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
+static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd,
+ unsigned *speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2249,7 +2254,7 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
}
}
-static int pkt_perform_opc(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c
index db259e60289b..12f5baea439b 100644
--- a/trunk/drivers/cdrom/cdrom.c
+++ b/trunk/drivers/cdrom/cdrom.c
@@ -1152,8 +1152,8 @@ int open_for_data(struct cdrom_device_info * cdi)
/* This code is similar to that in open_for_data. The routine is called
whenever an audio play operation is requested.
*/
-int check_for_audio_disc(struct cdrom_device_info * cdi,
- struct cdrom_device_ops * cdo)
+static int check_for_audio_disc(struct cdrom_device_info * cdi,
+ struct cdrom_device_ops * cdo)
{
int ret;
tracktype tracks;
diff --git a/trunk/drivers/char/defkeymap.c_shipped b/trunk/drivers/char/defkeymap.c_shipped
index 0aa419a61767..d2208dfe3f67 100644
--- a/trunk/drivers/char/defkeymap.c_shipped
+++ b/trunk/drivers/char/defkeymap.c_shipped
@@ -223,40 +223,40 @@ char *func_table[MAX_NR_FUNC] = {
};
struct kbdiacruc accent_table[MAX_DIACR] = {
- {'`', 'A', '\300'}, {'`', 'a', '\340'},
- {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
- {'^', 'A', '\302'}, {'^', 'a', '\342'},
- {'~', 'A', '\303'}, {'~', 'a', '\343'},
- {'"', 'A', '\304'}, {'"', 'a', '\344'},
- {'O', 'A', '\305'}, {'o', 'a', '\345'},
- {'0', 'A', '\305'}, {'0', 'a', '\345'},
- {'A', 'A', '\305'}, {'a', 'a', '\345'},
- {'A', 'E', '\306'}, {'a', 'e', '\346'},
- {',', 'C', '\307'}, {',', 'c', '\347'},
- {'`', 'E', '\310'}, {'`', 'e', '\350'},
- {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
- {'^', 'E', '\312'}, {'^', 'e', '\352'},
- {'"', 'E', '\313'}, {'"', 'e', '\353'},
- {'`', 'I', '\314'}, {'`', 'i', '\354'},
- {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
- {'^', 'I', '\316'}, {'^', 'i', '\356'},
- {'"', 'I', '\317'}, {'"', 'i', '\357'},
- {'-', 'D', '\320'}, {'-', 'd', '\360'},
- {'~', 'N', '\321'}, {'~', 'n', '\361'},
- {'`', 'O', '\322'}, {'`', 'o', '\362'},
- {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
- {'^', 'O', '\324'}, {'^', 'o', '\364'},
- {'~', 'O', '\325'}, {'~', 'o', '\365'},
- {'"', 'O', '\326'}, {'"', 'o', '\366'},
- {'/', 'O', '\330'}, {'/', 'o', '\370'},
- {'`', 'U', '\331'}, {'`', 'u', '\371'},
- {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
- {'^', 'U', '\333'}, {'^', 'u', '\373'},
- {'"', 'U', '\334'}, {'"', 'u', '\374'},
- {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
- {'T', 'H', '\336'}, {'t', 'h', '\376'},
- {'s', 's', '\337'}, {'"', 'y', '\377'},
- {'s', 'z', '\337'}, {'i', 'j', '\377'},
+ {'`', 'A', 0300}, {'`', 'a', 0340},
+ {'\'', 'A', 0301}, {'\'', 'a', 0341},
+ {'^', 'A', 0302}, {'^', 'a', 0342},
+ {'~', 'A', 0303}, {'~', 'a', 0343},
+ {'"', 'A', 0304}, {'"', 'a', 0344},
+ {'O', 'A', 0305}, {'o', 'a', 0345},
+ {'0', 'A', 0305}, {'0', 'a', 0345},
+ {'A', 'A', 0305}, {'a', 'a', 0345},
+ {'A', 'E', 0306}, {'a', 'e', 0346},
+ {',', 'C', 0307}, {',', 'c', 0347},
+ {'`', 'E', 0310}, {'`', 'e', 0350},
+ {'\'', 'E', 0311}, {'\'', 'e', 0351},
+ {'^', 'E', 0312}, {'^', 'e', 0352},
+ {'"', 'E', 0313}, {'"', 'e', 0353},
+ {'`', 'I', 0314}, {'`', 'i', 0354},
+ {'\'', 'I', 0315}, {'\'', 'i', 0355},
+ {'^', 'I', 0316}, {'^', 'i', 0356},
+ {'"', 'I', 0317}, {'"', 'i', 0357},
+ {'-', 'D', 0320}, {'-', 'd', 0360},
+ {'~', 'N', 0321}, {'~', 'n', 0361},
+ {'`', 'O', 0322}, {'`', 'o', 0362},
+ {'\'', 'O', 0323}, {'\'', 'o', 0363},
+ {'^', 'O', 0324}, {'^', 'o', 0364},
+ {'~', 'O', 0325}, {'~', 'o', 0365},
+ {'"', 'O', 0326}, {'"', 'o', 0366},
+ {'/', 'O', 0330}, {'/', 'o', 0370},
+ {'`', 'U', 0331}, {'`', 'u', 0371},
+ {'\'', 'U', 0332}, {'\'', 'u', 0372},
+ {'^', 'U', 0333}, {'^', 'u', 0373},
+ {'"', 'U', 0334}, {'"', 'u', 0374},
+ {'\'', 'Y', 0335}, {'\'', 'y', 0375},
+ {'T', 'H', 0336}, {'t', 'h', 0376},
+ {'s', 's', 0337}, {'"', 'y', 0377},
+ {'s', 'z', 0337}, {'i', 'j', 0377},
};
unsigned int accent_table_size = 68;
diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c
index 85d596a3c18c..eba2883b630e 100644
--- a/trunk/drivers/char/isicom.c
+++ b/trunk/drivers/char/isicom.c
@@ -1527,7 +1527,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
msleep(10);
portcount = inw(base + 0x2);
- if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
+ if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
portcount != 8 && portcount != 16)) {
dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
card + 1);
diff --git a/trunk/drivers/char/pcmcia/ipwireless/network.c b/trunk/drivers/char/pcmcia/ipwireless/network.c
index ff35230058d3..d793e68b3e0d 100644
--- a/trunk/drivers/char/pcmcia/ipwireless/network.c
+++ b/trunk/drivers/char/pcmcia/ipwireless/network.c
@@ -377,13 +377,16 @@ void ipwireless_network_packet_received(struct ipw_network *network,
for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) {
struct ipw_tty *tty = network->associated_ttys[channel_idx][i];
+ if (!tty)
+ continue;
+
/*
* If it's associated with a tty (other than the RAS channel
* when we're online), then send the data to that tty. The RAS
* channel's data is handled above - it always goes through
* ppp_generic.
*/
- if (tty && channel_idx == IPW_CHANNEL_RAS
+ if (channel_idx == IPW_CHANNEL_RAS
&& (network->ras_control_lines &
IPW_CONTROL_LINE_DCD) != 0
&& ipwireless_tty_is_modem(tty)) {
diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c
index 78b151c4d20f..5c3142b6f1fc 100644
--- a/trunk/drivers/char/rtc.c
+++ b/trunk/drivers/char/rtc.c
@@ -110,8 +110,8 @@ static int rtc_has_irq = 1;
#define hpet_set_rtc_irq_bit(arg) 0
#define hpet_rtc_timer_init() do { } while (0)
#define hpet_rtc_dropped_irq() 0
-#define hpet_register_irq_handler(h) 0
-#define hpet_unregister_irq_handler(h) 0
+#define hpet_register_irq_handler(h) ({ 0; })
+#define hpet_unregister_irq_handler(h) ({ 0; })
#ifdef RTC_IRQ
static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
{
diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c
index c0e08c7bca2f..5ff83df67b44 100644
--- a/trunk/drivers/char/specialix.c
+++ b/trunk/drivers/char/specialix.c
@@ -2109,7 +2109,6 @@ static void sx_throttle(struct tty_struct * tty)
sx_out(bp, CD186x_CAR, port_No(port));
spin_unlock_irqrestore(&bp->lock, flags);
if (I_IXOFF(tty)) {
- spin_unlock_irqrestore(&bp->lock, flags);
sx_wait_CCR(bp);
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CCR, CCR_SSCH2);
diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c
index 367be9175061..9b58b894f823 100644
--- a/trunk/drivers/char/vt.c
+++ b/trunk/drivers/char/vt.c
@@ -702,6 +702,7 @@ void redraw_screen(struct vc_data *vc, int is_switch)
if (is_switch) {
set_leds();
compute_shiftstate();
+ notify_update(vc);
}
}
diff --git a/trunk/drivers/char/xilinx_hwicap/buffer_icap.c b/trunk/drivers/char/xilinx_hwicap/buffer_icap.c
index dfea2bde162b..f577daedb630 100644
--- a/trunk/drivers/char/xilinx_hwicap/buffer_icap.c
+++ b/trunk/drivers/char/xilinx_hwicap/buffer_icap.c
@@ -73,8 +73,8 @@
#define XHI_BUFFER_START 0
/**
- * buffer_icap_get_status: Get the contents of the status register.
- * @parameter base_address: is the base address of the device
+ * buffer_icap_get_status - Get the contents of the status register.
+ * @base_address: is the base address of the device
*
* The status register contains the ICAP status and the done bit.
*
@@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address)
}
/**
- * buffer_icap_get_bram: Reads data from the storage buffer bram.
- * @parameter base_address: contains the base address of the component.
- * @parameter offset: The word offset from which the data should be read.
+ * buffer_icap_get_bram - Reads data from the storage buffer bram.
+ * @base_address: contains the base address of the component.
+ * @offset: The word offset from which the data should be read.
*
* A bram is used as a configuration memory cache. One frame of data can
* be stored in this "storage buffer".
@@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address,
}
/**
- * buffer_icap_busy: Return true if the icap device is busy
- * @parameter base_address: is the base address of the device
+ * buffer_icap_busy - Return true if the icap device is busy
+ * @base_address: is the base address of the device
*
* The queries the low order bit of the status register, which
* indicates whether the current configuration or readback operation
@@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address)
}
/**
- * buffer_icap_busy: Return true if the icap device is not busy
- * @parameter base_address: is the base address of the device
+ * buffer_icap_busy - Return true if the icap device is not busy
+ * @base_address: is the base address of the device
*
* The queries the low order bit of the status register, which
* indicates whether the current configuration or readback operation
@@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address)
}
/**
- * buffer_icap_set_size: Set the size register.
- * @parameter base_address: is the base address of the device
- * @parameter data: The size in bytes.
+ * buffer_icap_set_size - Set the size register.
+ * @base_address: is the base address of the device
+ * @data: The size in bytes.
*
* The size register holds the number of 8 bit bytes to transfer between
* bram and the icap (or icap to bram).
@@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address,
}
/**
- * buffer_icap_mSetoffsetReg: Set the bram offset register.
- * @parameter base_address: contains the base address of the device.
- * @parameter data: is the value to be written to the data register.
+ * buffer_icap_set_offset - Set the bram offset register.
+ * @base_address: contains the base address of the device.
+ * @data: is the value to be written to the data register.
*
* The bram offset register holds the starting bram address to transfer
* data from during configuration or write data to during readback.
@@ -162,9 +162,9 @@ static inline void buffer_icap_set_offset(void __iomem *base_address,
}
/**
- * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register.
- * @parameter base_address: contains the base address of the device.
- * @parameter data: is the value to be written to the data register.
+ * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register.
+ * @base_address: contains the base address of the device.
+ * @data: is the value to be written to the data register.
*
* The RNC register determines the direction of the data transfer. It
* controls whether a configuration or readback take place. Writing to
@@ -178,10 +178,10 @@ static inline void buffer_icap_set_rnc(void __iomem *base_address,
}
/**
- * buffer_icap_set_bram: Write data to the storage buffer bram.
- * @parameter base_address: contains the base address of the component.
- * @parameter offset: The word offset at which the data should be written.
- * @parameter data: The value to be written to the bram offset.
+ * buffer_icap_set_bram - Write data to the storage buffer bram.
+ * @base_address: contains the base address of the component.
+ * @offset: The word offset at which the data should be written.
+ * @data: The value to be written to the bram offset.
*
* A bram is used as a configuration memory cache. One frame of data can
* be stored in this "storage buffer".
@@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address,
}
/**
- * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter offset: The storage buffer start address.
- * @parameter count: The number of words (32 bit) to read from the
+ * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer.
+ * @drvdata: a pointer to the drvdata.
+ * @offset: The storage buffer start address.
+ * @count: The number of words (32 bit) to read from the
* device (ICAP).
**/
static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
@@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
};
/**
- * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter offset: The storage buffer start address.
- * @parameter count: The number of words (32 bit) to read from the
+ * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer.
+ * @drvdata: a pointer to the drvdata.
+ * @offset: The storage buffer start address.
+ * @count: The number of words (32 bit) to read from the
* device (ICAP).
**/
static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
@@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
};
/**
- * buffer_icap_reset: Reset the logic of the icap device.
- * @parameter drvdata: a pointer to the drvdata.
+ * buffer_icap_reset - Reset the logic of the icap device.
+ * @drvdata: a pointer to the drvdata.
*
* Writing to the status register resets the ICAP logic in an internal
* version of the core. For the version of the core published in EDK,
@@ -274,10 +274,10 @@ void buffer_icap_reset(struct hwicap_drvdata *drvdata)
}
/**
- * buffer_icap_set_configuration: Load a partial bitstream from system memory.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: Kernel address of the partial bitstream.
- * @parameter size: the size of the partial bitstream in 32 bit words.
+ * buffer_icap_set_configuration - Load a partial bitstream from system memory.
+ * @drvdata: a pointer to the drvdata.
+ * @data: Kernel address of the partial bitstream.
+ * @size: the size of the partial bitstream in 32 bit words.
**/
int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
u32 size)
@@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
};
/**
- * buffer_icap_get_configuration: Read configuration data from the device.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: Address of the data representing the partial bitstream
- * @parameter size: the size of the partial bitstream in 32 bit words.
+ * buffer_icap_get_configuration - Read configuration data from the device.
+ * @drvdata: a pointer to the drvdata.
+ * @data: Address of the data representing the partial bitstream
+ * @size: the size of the partial bitstream in 32 bit words.
**/
int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
u32 size)
diff --git a/trunk/drivers/char/xilinx_hwicap/fifo_icap.c b/trunk/drivers/char/xilinx_hwicap/fifo_icap.c
index 0988314694a6..6f45dbd47125 100644
--- a/trunk/drivers/char/xilinx_hwicap/fifo_icap.c
+++ b/trunk/drivers/char/xilinx_hwicap/fifo_icap.c
@@ -94,9 +94,9 @@
/**
- * fifo_icap_fifo_write: Write data to the write FIFO.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: the 32-bit value to be written to the FIFO.
+ * fifo_icap_fifo_write - Write data to the write FIFO.
+ * @drvdata: a pointer to the drvdata.
+ * @data: the 32-bit value to be written to the FIFO.
*
* This function will silently fail if the fifo is full.
**/
@@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata,
}
/**
- * fifo_icap_fifo_read: Read data from the Read FIFO.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_fifo_read - Read data from the Read FIFO.
+ * @drvdata: a pointer to the drvdata.
*
* This function will silently fail if the fifo is empty.
**/
@@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_set_read_size: Set the the size register.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: the size of the following read transaction, in words.
+ * fifo_icap_set_read_size - Set the the size register.
+ * @drvdata: a pointer to the drvdata.
+ * @data: the size of the following read transaction, in words.
**/
static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
u32 data)
@@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata,
}
/**
- * fifo_icap_start_config: Initiate a configuration (write) to the device.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_start_config - Initiate a configuration (write) to the device.
+ * @drvdata: a pointer to the drvdata.
**/
static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
{
@@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_start_readback: Initiate a readback from the device.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_start_readback - Initiate a readback from the device.
+ * @drvdata: a pointer to the drvdata.
**/
static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
{
@@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_busy: Return true if the ICAP is still processing a transaction.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_busy - Return true if the ICAP is still processing a transaction.
+ * @drvdata: a pointer to the drvdata.
**/
static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
{
@@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_write_fifo_vacancy: Query the write fifo available space.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_write_fifo_vacancy - Query the write fifo available space.
+ * @drvdata: a pointer to the drvdata.
*
* Return the number of words that can be safely pushed into the write fifo.
**/
@@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy(
}
/**
- * fifo_icap_read_fifo_occupancy: Query the read fifo available data.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_read_fifo_occupancy - Query the read fifo available data.
+ * @drvdata: a pointer to the drvdata.
*
* Return the number of words that can be safely read from the read fifo.
**/
@@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy(
}
/**
- * fifo_icap_set_configuration: Send configuration data to the ICAP.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter frame_buffer: a pointer to the data to be written to the
+ * fifo_icap_set_configuration - Send configuration data to the ICAP.
+ * @drvdata: a pointer to the drvdata.
+ * @frame_buffer: a pointer to the data to be written to the
* ICAP device.
- * @parameter num_words: the number of words (32 bit) to write to the ICAP
+ * @num_words: the number of words (32 bit) to write to the ICAP
* device.
* This function writes the given user data to the Write FIFO in
@@ -266,10 +266,10 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata,
}
/**
- * fifo_icap_get_configuration: Read configuration data from the device.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter data: Address of the data representing the partial bitstream
- * @parameter size: the size of the partial bitstream in 32 bit words.
+ * fifo_icap_get_configuration - Read configuration data from the device.
+ * @drvdata: a pointer to the drvdata.
+ * @data: Address of the data representing the partial bitstream
+ * @size: the size of the partial bitstream in 32 bit words.
*
* This function reads the specified number of words from the ICAP device in
* the polled mode.
@@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata,
}
/**
- * buffer_icap_reset: Reset the logic of the icap device.
- * @parameter drvdata: a pointer to the drvdata.
+ * buffer_icap_reset - Reset the logic of the icap device.
+ * @drvdata: a pointer to the drvdata.
*
* This function forces the software reset of the complete HWICAP device.
* All the registers will return to the default value and the FIFO is also
@@ -360,8 +360,8 @@ void fifo_icap_reset(struct hwicap_drvdata *drvdata)
}
/**
- * fifo_icap_flush_fifo: This function flushes the FIFOs in the device.
- * @parameter drvdata: a pointer to the drvdata.
+ * fifo_icap_flush_fifo - This function flushes the FIFOs in the device.
+ * @drvdata: a pointer to the drvdata.
*/
void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata)
{
diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 24f6aef0fd3c..2284fa2a5a57 100644
--- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -84,7 +84,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -119,6 +119,7 @@ module_param(xhwicap_minor, int, S_IRUGO);
/* An array, which is set to true when the device is registered. */
static bool probed_devices[HWICAP_DEVICES];
+static struct mutex icap_sem;
static struct class *icap_class;
@@ -199,14 +200,14 @@ static const struct config_registers v5_config_registers = {
};
/**
- * hwicap_command_desync: Send a DESYNC command to the ICAP port.
- * @parameter drvdata: a pointer to the drvdata.
+ * hwicap_command_desync - Send a DESYNC command to the ICAP port.
+ * @drvdata: a pointer to the drvdata.
*
* This command desynchronizes the ICAP After this command, a
* bitstream containing a NULL packet, followed by a SYNCH packet is
* required before the ICAP will recognize commands.
*/
-int hwicap_command_desync(struct hwicap_drvdata *drvdata)
+static int hwicap_command_desync(struct hwicap_drvdata *drvdata)
{
u32 buffer[4];
u32 index = 0;
@@ -228,51 +229,18 @@ int hwicap_command_desync(struct hwicap_drvdata *drvdata)
}
/**
- * hwicap_command_capture: Send a CAPTURE command to the ICAP port.
- * @parameter drvdata: a pointer to the drvdata.
- *
- * This command captures all of the flip flop states so they will be
- * available during readback. One can use this command instead of
- * enabling the CAPTURE block in the design.
- */
-int hwicap_command_capture(struct hwicap_drvdata *drvdata)
-{
- u32 buffer[7];
- u32 index = 0;
-
- /*
- * Create the data to be written to the ICAP.
- */
- buffer[index++] = XHI_DUMMY_PACKET;
- buffer[index++] = XHI_SYNC_PACKET;
- buffer[index++] = XHI_NOOP_PACKET;
- buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
- buffer[index++] = XHI_CMD_GCAPTURE;
- buffer[index++] = XHI_DUMMY_PACKET;
- buffer[index++] = XHI_DUMMY_PACKET;
-
- /*
- * Write the data to the FIFO and intiate the transfer of data
- * present in the FIFO to the ICAP device.
- */
- return drvdata->config->set_configuration(drvdata,
- &buffer[0], index);
-
-}
-
-/**
- * hwicap_get_configuration_register: Query a configuration register.
- * @parameter drvdata: a pointer to the drvdata.
- * @parameter reg: a constant which represents the configuration
+ * hwicap_get_configuration_register - Query a configuration register.
+ * @drvdata: a pointer to the drvdata.
+ * @reg: a constant which represents the configuration
* register value to be returned.
* Examples: XHI_IDCODE, XHI_FLR.
- * @parameter RegData: returns the value of the register.
+ * @reg_data: returns the value of the register.
*
* Sends a query packet to the ICAP and then receives the response.
* The icap is left in Synched state.
*/
-int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
- u32 reg, u32 *RegData)
+static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
+ u32 reg, u32 *reg_data)
{
int status;
u32 buffer[6];
@@ -300,14 +268,14 @@ int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
/*
* Read the configuration register
*/
- status = drvdata->config->get_configuration(drvdata, RegData, 1);
+ status = drvdata->config->get_configuration(drvdata, reg_data, 1);
if (status)
return status;
return 0;
}
-int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
+static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
{
int status;
u32 idcode;
@@ -344,7 +312,7 @@ int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
}
static ssize_t
-hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
ssize_t bytes_to_read = 0;
@@ -353,8 +321,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
u32 bytes_remaining;
int status;
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ status = mutex_lock_interruptible(&drvdata->sem);
+ if (status)
+ return status;
if (drvdata->read_buffer_in_use) {
/* If there are leftover bytes in the buffer, just */
@@ -370,8 +339,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
goto error;
}
drvdata->read_buffer_in_use -= bytes_to_read;
- memcpy(drvdata->read_buffer + bytes_to_read,
- drvdata->read_buffer, 4 - bytes_to_read);
+ memmove(drvdata->read_buffer,
+ drvdata->read_buffer + bytes_to_read,
+ 4 - bytes_to_read);
} else {
/* Get new data from the ICAP, and return was was requested. */
kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
@@ -414,18 +384,20 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
status = -EFAULT;
goto error;
}
- memcpy(kbuf, drvdata->read_buffer, bytes_remaining);
+ memcpy(drvdata->read_buffer,
+ kbuf,
+ bytes_remaining);
drvdata->read_buffer_in_use = bytes_remaining;
free_page((unsigned long)kbuf);
}
status = bytes_to_read;
error:
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
static ssize_t
-hwicap_write(struct file *file, const char *buf,
+hwicap_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
@@ -435,8 +407,9 @@ hwicap_write(struct file *file, const char *buf,
ssize_t len;
ssize_t status;
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ status = mutex_lock_interruptible(&drvdata->sem);
+ if (status)
+ return status;
left += drvdata->write_buffer_in_use;
@@ -465,7 +438,7 @@ hwicap_write(struct file *file, const char *buf,
memcpy(kbuf, drvdata->write_buffer,
drvdata->write_buffer_in_use);
if (copy_from_user(
- (((char *)kbuf) + (drvdata->write_buffer_in_use)),
+ (((char *)kbuf) + drvdata->write_buffer_in_use),
buf + written,
len - (drvdata->write_buffer_in_use))) {
free_page((unsigned long)kbuf);
@@ -508,7 +481,7 @@ hwicap_write(struct file *file, const char *buf,
free_page((unsigned long)kbuf);
status = written;
error:
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
@@ -519,8 +492,9 @@ static int hwicap_open(struct inode *inode, struct file *file)
drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ status = mutex_lock_interruptible(&drvdata->sem);
+ if (status)
+ return status;
if (drvdata->is_open) {
status = -EBUSY;
@@ -539,7 +513,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
drvdata->is_open = 1;
error:
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
@@ -549,8 +523,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
int i;
int status = 0;
- if (down_interruptible(&drvdata->sem))
- return -ERESTARTSYS;
+ mutex_lock(&drvdata->sem);
if (drvdata->write_buffer_in_use) {
/* Flush write buffer. */
@@ -569,7 +542,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
error:
drvdata->is_open = 0;
- up(&drvdata->sem);
+ mutex_unlock(&drvdata->sem);
return status;
}
@@ -592,31 +565,36 @@ static int __devinit hwicap_setup(struct device *dev, int id,
dev_info(dev, "Xilinx icap port driver\n");
+ mutex_lock(&icap_sem);
+
if (id < 0) {
for (id = 0; id < HWICAP_DEVICES; id++)
if (!probed_devices[id])
break;
}
if (id < 0 || id >= HWICAP_DEVICES) {
+ mutex_unlock(&icap_sem);
dev_err(dev, "%s%i too large\n", DRIVER_NAME, id);
return -EINVAL;
}
if (probed_devices[id]) {
+ mutex_unlock(&icap_sem);
dev_err(dev, "cannot assign to %s%i; it is already in use\n",
DRIVER_NAME, id);
return -EBUSY;
}
probed_devices[id] = 1;
+ mutex_unlock(&icap_sem);
devt = MKDEV(xhwicap_major, xhwicap_minor + id);
- drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
+ drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
if (!drvdata) {
dev_err(dev, "Couldn't allocate device private record\n");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto failed0;
}
- memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));
dev_set_drvdata(dev, (void *)drvdata);
if (!regs_res) {
@@ -648,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
drvdata->config = config;
drvdata->config_regs = config_regs;
- init_MUTEX(&drvdata->sem);
+ mutex_init(&drvdata->sem);
drvdata->is_open = 0;
dev_info(dev, "ioremap %lx to %p with size %x\n",
@@ -663,7 +641,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
goto failed3;
}
/* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
- class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME);
+ device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id);
return 0; /* success */
failed3:
@@ -675,6 +653,11 @@ static int __devinit hwicap_setup(struct device *dev, int id,
failed1:
kfree(drvdata);
+ failed0:
+ mutex_lock(&icap_sem);
+ probed_devices[id] = 0;
+ mutex_unlock(&icap_sem);
+
return retval;
}
@@ -699,14 +682,16 @@ static int __devexit hwicap_remove(struct device *dev)
if (!drvdata)
return 0;
- class_device_destroy(icap_class, drvdata->devt);
+ device_destroy(icap_class, drvdata->devt);
cdev_del(&drvdata->cdev);
iounmap(drvdata->base_address);
release_mem_region(drvdata->mem_start, drvdata->mem_size);
kfree(drvdata);
dev_set_drvdata(dev, NULL);
- probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
+ mutex_lock(&icap_sem);
+ probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
+ mutex_unlock(&icap_sem);
return 0; /* success */
}
@@ -821,28 +806,29 @@ static struct of_platform_driver hwicap_of_driver = {
};
/* Registration helpers to keep the number of #ifdefs to a minimum */
-static inline int __devinit hwicap_of_register(void)
+static inline int __init hwicap_of_register(void)
{
pr_debug("hwicap: calling of_register_platform_driver()\n");
return of_register_platform_driver(&hwicap_of_driver);
}
-static inline void __devexit hwicap_of_unregister(void)
+static inline void __exit hwicap_of_unregister(void)
{
of_unregister_platform_driver(&hwicap_of_driver);
}
#else /* CONFIG_OF */
/* CONFIG_OF not enabled; do nothing helpers */
-static inline int __devinit hwicap_of_register(void) { return 0; }
-static inline void __devexit hwicap_of_unregister(void) { }
+static inline int __init hwicap_of_register(void) { return 0; }
+static inline void __exit hwicap_of_unregister(void) { }
#endif /* CONFIG_OF */
-static int __devinit hwicap_module_init(void)
+static int __init hwicap_module_init(void)
{
dev_t devt;
int retval;
icap_class = class_create(THIS_MODULE, "xilinx_config");
+ mutex_init(&icap_sem);
if (xhwicap_major) {
devt = MKDEV(xhwicap_major, xhwicap_minor);
@@ -883,7 +869,7 @@ static int __devinit hwicap_module_init(void)
return retval;
}
-static void __devexit hwicap_module_cleanup(void)
+static void __exit hwicap_module_cleanup(void)
{
dev_t devt = MKDEV(xhwicap_major, xhwicap_minor);
diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h
index ae771cac1629..405fee7e189b 100644
--- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h
+++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.h
@@ -48,9 +48,9 @@ struct hwicap_drvdata {
u8 write_buffer[4];
u32 read_buffer_in_use; /* Always in [0,3] */
u8 read_buffer[4];
- u32 mem_start; /* phys. address of the control registers */
- u32 mem_end; /* phys. address of the control registers */
- u32 mem_size;
+ resource_size_t mem_start;/* phys. address of the control registers */
+ resource_size_t mem_end; /* phys. address of the control registers */
+ resource_size_t mem_size;
void __iomem *base_address;/* virt. address of the control registers */
struct device *dev;
@@ -61,7 +61,7 @@ struct hwicap_drvdata {
const struct config_registers *config_regs;
void *private_data;
bool is_open;
- struct semaphore sem;
+ struct mutex sem;
};
struct hwicap_driver_config {
@@ -164,29 +164,29 @@ struct config_registers {
#define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL
/**
- * hwicap_type_1_read: Generates a Type 1 read packet header.
- * @parameter: Register is the address of the register to be read back.
+ * hwicap_type_1_read - Generates a Type 1 read packet header.
+ * @reg: is the address of the register to be read back.
*
* Generates a Type 1 read packet header, which is used to indirectly
* read registers in the configuration logic. This packet must then
* be sent through the icap device, and a return packet received with
* the information.
**/
-static inline u32 hwicap_type_1_read(u32 Register)
+static inline u32 hwicap_type_1_read(u32 reg)
{
return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
- (Register << XHI_REGISTER_SHIFT) |
+ (reg << XHI_REGISTER_SHIFT) |
(XHI_OP_READ << XHI_OP_SHIFT);
}
/**
- * hwicap_type_1_write: Generates a Type 1 write packet header
- * @parameter: Register is the address of the register to be read back.
+ * hwicap_type_1_write - Generates a Type 1 write packet header
+ * @reg: is the address of the register to be read back.
**/
-static inline u32 hwicap_type_1_write(u32 Register)
+static inline u32 hwicap_type_1_write(u32 reg)
{
return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
- (Register << XHI_REGISTER_SHIFT) |
+ (reg << XHI_REGISTER_SHIFT) |
(XHI_OP_WRITE << XHI_OP_SHIFT);
}
diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c
index fea2d3ed9cbd..85e2ba7fcfba 100644
--- a/trunk/drivers/connector/connector.c
+++ b/trunk/drivers/connector/connector.c
@@ -47,7 +47,7 @@ static LIST_HEAD(notify_list);
static struct cn_dev cdev;
-int cn_already_initialized = 0;
+static int cn_already_initialized;
/*
* msg->seq and msg->ack are used to determine message genealogy.
diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c
index 89a29cd93783..35a26a3e5f68 100644
--- a/trunk/drivers/cpufreq/cpufreq.c
+++ b/trunk/drivers/cpufreq/cpufreq.c
@@ -671,13 +671,13 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
{
struct cpufreq_policy * policy = to_policy(kobj);
struct freq_attr * fattr = to_attr(attr);
- ssize_t ret;
+ ssize_t ret = -EINVAL;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
- return -EINVAL;
+ goto no_policy;
if (lock_policy_rwsem_read(policy->cpu) < 0)
- return -EINVAL;
+ goto fail;
if (fattr->show)
ret = fattr->show(policy, buf);
@@ -685,8 +685,9 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
ret = -EIO;
unlock_policy_rwsem_read(policy->cpu);
-
+fail:
cpufreq_cpu_put(policy);
+no_policy:
return ret;
}
@@ -695,13 +696,13 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
{
struct cpufreq_policy * policy = to_policy(kobj);
struct freq_attr * fattr = to_attr(attr);
- ssize_t ret;
+ ssize_t ret = -EINVAL;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
- return -EINVAL;
+ goto no_policy;
if (lock_policy_rwsem_write(policy->cpu) < 0)
- return -EINVAL;
+ goto fail;
if (fattr->store)
ret = fattr->store(policy, buf, count);
@@ -709,8 +710,9 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
ret = -EIO;
unlock_policy_rwsem_write(policy->cpu);
-
+fail:
cpufreq_cpu_put(policy);
+no_policy:
return ret;
}
@@ -1775,7 +1777,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block __cpuinitdata cpufreq_cpu_notifier =
+static struct notifier_block __refdata cpufreq_cpu_notifier =
{
.notifier_call = cpufreq_cpu_callback,
};
diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c
index 1b8312b02006..070421a5480e 100644
--- a/trunk/drivers/cpufreq/cpufreq_stats.c
+++ b/trunk/drivers/cpufreq/cpufreq_stats.c
@@ -323,7 +323,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata =
+static struct notifier_block cpufreq_stat_cpu_notifier __refdata =
{
.notifier_call = cpufreq_stat_cpu_callback,
};
diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig
index a703deffb795..27340a7b19dd 100644
--- a/trunk/drivers/dma/Kconfig
+++ b/trunk/drivers/dma/Kconfig
@@ -4,7 +4,7 @@
menuconfig DMADEVICES
bool "DMA Engine support"
- depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
+ depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || PPC
depends on !HIGHMEM64G
help
DMA engines can do asynchronous data transfers without
@@ -37,6 +37,23 @@ config INTEL_IOP_ADMA
help
Enable support for the Intel(R) IOP Series RAID engines.
+config FSL_DMA
+ bool "Freescale MPC85xx/MPC83xx DMA support"
+ depends on PPC
+ select DMA_ENGINE
+ ---help---
+ Enable support for the Freescale DMA engine. Now, it support
+ MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.
+ The MPC8349, MPC8360 is also supported.
+
+config FSL_DMA_SELFTEST
+ bool "Enable the self test for each DMA channel"
+ depends on FSL_DMA
+ default y
+ ---help---
+ Enable the self test for each DMA channel. A self test will be
+ performed after the channel probed to ensure the DMA works well.
+
config DMA_ENGINE
bool
diff --git a/trunk/drivers/dma/Makefile b/trunk/drivers/dma/Makefile
index b152cd84e123..c8036d945902 100644
--- a/trunk/drivers/dma/Makefile
+++ b/trunk/drivers/dma/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_NET_DMA) += iovlock.o
obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
+obj-$(CONFIG_FSL_DMA) += fsldma.o
diff --git a/trunk/drivers/dma/fsldma.c b/trunk/drivers/dma/fsldma.c
new file mode 100644
index 000000000000..cc9a68158d99
--- /dev/null
+++ b/trunk/drivers/dma/fsldma.c
@@ -0,0 +1,1067 @@
+/*
+ * Freescale MPC85xx, MPC83xx DMA Engine support
+ *
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ * Zhang Wei , Jul 2007
+ * Ebony Zhu , May 2007
+ *
+ * Description:
+ * DMA engine driver for Freescale MPC8540 DMA controller, which is
+ * also fit for MPC8560, MPC8555, MPC8548, MPC8641, and etc.
+ * The support for MPC8349 DMA contorller is also added.
+ *
+ * This 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.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "fsldma.h"
+
+static void dma_init(struct fsl_dma_chan *fsl_chan)
+{
+ /* Reset the channel */
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, 0, 32);
+
+ switch (fsl_chan->feature & FSL_DMA_IP_MASK) {
+ case FSL_DMA_IP_85XX:
+ /* Set the channel to below modes:
+ * EIE - Error interrupt enable
+ * EOSIE - End of segments interrupt enable (basic mode)
+ * EOLNIE - End of links interrupt enable
+ */
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EIE
+ | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+ break;
+ case FSL_DMA_IP_83XX:
+ /* Set the channel to below modes:
+ * EOTIE - End-of-transfer interrupt enable
+ */
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EOTIE,
+ 32);
+ break;
+ }
+
+}
+
+static void set_sr(struct fsl_dma_chan *fsl_chan, dma_addr_t val)
+{
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32);
+}
+
+static dma_addr_t get_sr(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->sr, 32);
+}
+
+static void set_desc_cnt(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, u32 count)
+{
+ hw->count = CPU_TO_DMA(fsl_chan, count, 32);
+}
+
+static void set_desc_src(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, dma_addr_t src)
+{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
+ ? ((u64)FSL_DMA_SATR_SREADTYPE_SNOOP_READ << 32) : 0;
+ hw->src_addr = CPU_TO_DMA(fsl_chan, snoop_bits | src, 64);
+}
+
+static void set_desc_dest(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, dma_addr_t dest)
+{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX)
+ ? ((u64)FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE << 32) : 0;
+ hw->dst_addr = CPU_TO_DMA(fsl_chan, snoop_bits | dest, 64);
+}
+
+static void set_desc_next(struct fsl_dma_chan *fsl_chan,
+ struct fsl_dma_ld_hw *hw, dma_addr_t next)
+{
+ u64 snoop_bits;
+
+ snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+ ? FSL_DMA_SNEN : 0;
+ hw->next_ln_addr = CPU_TO_DMA(fsl_chan, snoop_bits | next, 64);
+}
+
+static void set_cdar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+{
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->cdar, addr | FSL_DMA_SNEN, 64);
+}
+
+static dma_addr_t get_cdar(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->cdar, 64) & ~FSL_DMA_SNEN;
+}
+
+static void set_ndar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr)
+{
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->ndar, addr, 64);
+}
+
+static dma_addr_t get_ndar(struct fsl_dma_chan *fsl_chan)
+{
+ return DMA_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64);
+}
+
+static int dma_is_idle(struct fsl_dma_chan *fsl_chan)
+{
+ u32 sr = get_sr(fsl_chan);
+ return (!(sr & FSL_DMA_SR_CB)) || (sr & FSL_DMA_SR_CH);
+}
+
+static void dma_start(struct fsl_dma_chan *fsl_chan)
+{
+ u32 mr_set = 0;;
+
+ if (fsl_chan->feature & FSL_DMA_CHAN_PAUSE_EXT) {
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->bcr, 0, 32);
+ mr_set |= FSL_DMA_MR_EMP_EN;
+ } else
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
+ & ~FSL_DMA_MR_EMP_EN, 32);
+
+ if (fsl_chan->feature & FSL_DMA_CHAN_START_EXT)
+ mr_set |= FSL_DMA_MR_EMS_EN;
+ else
+ mr_set |= FSL_DMA_MR_CS;
+
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
+ | mr_set, 32);
+}
+
+static void dma_halt(struct fsl_dma_chan *fsl_chan)
+{
+ int i = 0;
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CA,
+ 32);
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~(FSL_DMA_MR_CS
+ | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA), 32);
+
+ while (!dma_is_idle(fsl_chan) && (i++ < 100))
+ udelay(10);
+ if (i >= 100 && !dma_is_idle(fsl_chan))
+ dev_err(fsl_chan->dev, "DMA halt timeout!\n");
+}
+
+static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
+ struct fsl_desc_sw *desc)
+{
+ desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
+ DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL,
+ 64);
+}
+
+static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
+ struct fsl_desc_sw *new_desc)
+{
+ struct fsl_desc_sw *queue_tail = to_fsl_desc(fsl_chan->ld_queue.prev);
+
+ if (list_empty(&fsl_chan->ld_queue))
+ return;
+
+ /* Link to the new descriptor physical address and
+ * Enable End-of-segment interrupt for
+ * the last link descriptor.
+ * (the previous node's next link descriptor)
+ *
+ * For FSL_DMA_IP_83xx, the snoop enable bit need be set.
+ */
+ queue_tail->hw.next_ln_addr = CPU_TO_DMA(fsl_chan,
+ new_desc->async_tx.phys | FSL_DMA_EOSIE |
+ (((fsl_chan->feature & FSL_DMA_IP_MASK)
+ == FSL_DMA_IP_83XX) ? FSL_DMA_SNEN : 0), 64);
+}
+
+/**
+ * fsl_chan_set_src_loop_size - Set source address hold transfer size
+ * @fsl_chan : Freescale DMA channel
+ * @size : Address loop size, 0 for disable loop
+ *
+ * The set source address hold transfer size. The source
+ * address hold or loop transfer size is when the DMA transfer
+ * data from source address (SA), if the loop size is 4, the DMA will
+ * read data from SA, SA + 1, SA + 2, SA + 3, then loop back to SA,
+ * SA + 1 ... and so on.
+ */
+static void fsl_chan_set_src_loop_size(struct fsl_dma_chan *fsl_chan, int size)
+{
+ switch (size) {
+ case 0:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) &
+ (~FSL_DMA_MR_SAHE), 32);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) |
+ FSL_DMA_MR_SAHE | (__ilog2(size) << 14),
+ 32);
+ break;
+ }
+}
+
+/**
+ * fsl_chan_set_dest_loop_size - Set destination address hold transfer size
+ * @fsl_chan : Freescale DMA channel
+ * @size : Address loop size, 0 for disable loop
+ *
+ * The set destination address hold transfer size. The destination
+ * address hold or loop transfer size is when the DMA transfer
+ * data to destination address (TA), if the loop size is 4, the DMA will
+ * write data to TA, TA + 1, TA + 2, TA + 3, then loop back to TA,
+ * TA + 1 ... and so on.
+ */
+static void fsl_chan_set_dest_loop_size(struct fsl_dma_chan *fsl_chan, int size)
+{
+ switch (size) {
+ case 0:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) &
+ (~FSL_DMA_MR_DAHE), 32);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) |
+ FSL_DMA_MR_DAHE | (__ilog2(size) << 16),
+ 32);
+ break;
+ }
+}
+
+/**
+ * fsl_chan_toggle_ext_pause - Toggle channel external pause status
+ * @fsl_chan : Freescale DMA channel
+ * @size : Pause control size, 0 for disable external pause control.
+ * The maximum is 1024.
+ *
+ * The Freescale DMA channel can be controlled by the external
+ * signal DREQ#. The pause control size is how many bytes are allowed
+ * to transfer before pausing the channel, after which a new assertion
+ * of DREQ# resumes channel operation.
+ */
+static void fsl_chan_toggle_ext_pause(struct fsl_dma_chan *fsl_chan, int size)
+{
+ if (size > 1024)
+ return;
+
+ if (size) {
+ DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr,
+ DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32)
+ | ((__ilog2(size) << 24) & 0x0f000000),
+ 32);
+ fsl_chan->feature |= FSL_DMA_CHAN_PAUSE_EXT;
+ } else
+ fsl_chan->feature &= ~FSL_DMA_CHAN_PAUSE_EXT;
+}
+
+/**
+ * fsl_chan_toggle_ext_start - Toggle channel external start status
+ * @fsl_chan : Freescale DMA channel
+ * @enable : 0 is disabled, 1 is enabled.
+ *
+ * If enable the external start, the channel can be started by an
+ * external DMA start pin. So the dma_start() does not start the
+ * transfer immediately. The DMA channel will wait for the
+ * control pin asserted.
+ */
+static void fsl_chan_toggle_ext_start(struct fsl_dma_chan *fsl_chan, int enable)
+{
+ if (enable)
+ fsl_chan->feature |= FSL_DMA_CHAN_START_EXT;
+ else
+ fsl_chan->feature &= ~FSL_DMA_CHAN_START_EXT;
+}
+
+static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan);
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+ /* cookie increment and adding to ld_queue must be atomic */
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ cookie = fsl_chan->common.cookie;
+ cookie++;
+ if (cookie < 0)
+ cookie = 1;
+ desc->async_tx.cookie = cookie;
+ fsl_chan->common.cookie = desc->async_tx.cookie;
+
+ append_ld_queue(fsl_chan, desc);
+ list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev);
+
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+ return cookie;
+}
+
+/**
+ * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool.
+ * @fsl_chan : Freescale DMA channel
+ *
+ * Return - The descriptor allocated. NULL for failed.
+ */
+static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
+ struct fsl_dma_chan *fsl_chan)
+{
+ dma_addr_t pdesc;
+ struct fsl_desc_sw *desc_sw;
+
+ desc_sw = dma_pool_alloc(fsl_chan->desc_pool, GFP_ATOMIC, &pdesc);
+ if (desc_sw) {
+ memset(desc_sw, 0, sizeof(struct fsl_desc_sw));
+ dma_async_tx_descriptor_init(&desc_sw->async_tx,
+ &fsl_chan->common);
+ desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
+ INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
+ desc_sw->async_tx.phys = pdesc;
+ }
+
+ return desc_sw;
+}
+
+
+/**
+ * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel.
+ * @fsl_chan : Freescale DMA channel
+ *
+ * This function will create a dma pool for descriptor allocation.
+ *
+ * Return - The number of descriptors allocated.
+ */
+static int fsl_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ LIST_HEAD(tmp_list);
+
+ /* We need the descriptor to be aligned to 32bytes
+ * for meeting FSL DMA specification requirement.
+ */
+ fsl_chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool",
+ fsl_chan->dev, sizeof(struct fsl_desc_sw),
+ 32, 0);
+ if (!fsl_chan->desc_pool) {
+ dev_err(fsl_chan->dev, "No memory for channel %d "
+ "descriptor dma pool.\n", fsl_chan->id);
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * fsl_dma_free_chan_resources - Free all resources of the channel.
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ struct fsl_desc_sw *desc, *_desc;
+ unsigned long flags;
+
+ dev_dbg(fsl_chan->dev, "Free all channel resources.\n");
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->dev,
+ "LD %p will be released.\n", desc);
+#endif
+ list_del(&desc->node);
+ /* free link descriptor */
+ dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ dma_pool_destroy(fsl_chan->desc_pool);
+}
+
+static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
+ struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
+ size_t len, unsigned long flags)
+{
+ struct fsl_dma_chan *fsl_chan;
+ struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
+ size_t copy;
+ LIST_HEAD(link_chain);
+
+ if (!chan)
+ return NULL;
+
+ if (!len)
+ return NULL;
+
+ fsl_chan = to_fsl_chan(chan);
+
+ do {
+
+ /* Allocate the link descriptor from DMA pool */
+ new = fsl_dma_alloc_descriptor(fsl_chan);
+ if (!new) {
+ dev_err(fsl_chan->dev,
+ "No free memory for link descriptor\n");
+ return NULL;
+ }
+#ifdef FSL_DMA_LD_DEBUG
+ dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
+#endif
+
+ copy = min(len, FSL_DMA_BCR_MAX_CNT);
+
+ set_desc_cnt(fsl_chan, &new->hw, copy);
+ set_desc_src(fsl_chan, &new->hw, dma_src);
+ set_desc_dest(fsl_chan, &new->hw, dma_dest);
+
+ if (!first)
+ first = new;
+ else
+ set_desc_next(fsl_chan, &prev->hw, new->async_tx.phys);
+
+ new->async_tx.cookie = 0;
+ new->async_tx.ack = 1;
+
+ prev = new;
+ len -= copy;
+ dma_src += copy;
+ dma_dest += copy;
+
+ /* Insert the link descriptor to the LD ring */
+ list_add_tail(&new->node, &first->async_tx.tx_list);
+ } while (len);
+
+ new->async_tx.ack = 0; /* client is in control of this ack */
+ new->async_tx.cookie = -EBUSY;
+
+ /* Set End-of-link to the last link descriptor of new list*/
+ set_ld_eol(fsl_chan, new);
+
+ return first ? &first->async_tx : NULL;
+}
+
+/**
+ * fsl_dma_update_completed_cookie - Update the completed cookie.
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_dma_update_completed_cookie(struct fsl_dma_chan *fsl_chan)
+{
+ struct fsl_desc_sw *cur_desc, *desc;
+ dma_addr_t ld_phy;
+
+ ld_phy = get_cdar(fsl_chan) & FSL_DMA_NLDA_MASK;
+
+ if (ld_phy) {
+ cur_desc = NULL;
+ list_for_each_entry(desc, &fsl_chan->ld_queue, node)
+ if (desc->async_tx.phys == ld_phy) {
+ cur_desc = desc;
+ break;
+ }
+
+ if (cur_desc && cur_desc->async_tx.cookie) {
+ if (dma_is_idle(fsl_chan))
+ fsl_chan->completed_cookie =
+ cur_desc->async_tx.cookie;
+ else
+ fsl_chan->completed_cookie =
+ cur_desc->async_tx.cookie - 1;
+ }
+ }
+}
+
+/**
+ * fsl_chan_ld_cleanup - Clean up link descriptors
+ * @fsl_chan : Freescale DMA channel
+ *
+ * This function clean up the ld_queue of DMA channel.
+ * If 'in_intr' is set, the function will move the link descriptor to
+ * the recycle list. Otherwise, free it directly.
+ */
+static void fsl_chan_ld_cleanup(struct fsl_dma_chan *fsl_chan)
+{
+ struct fsl_desc_sw *desc, *_desc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ fsl_dma_update_completed_cookie(fsl_chan);
+ dev_dbg(fsl_chan->dev, "chan completed_cookie = %d\n",
+ fsl_chan->completed_cookie);
+ list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) {
+ dma_async_tx_callback callback;
+ void *callback_param;
+
+ if (dma_async_is_complete(desc->async_tx.cookie,
+ fsl_chan->completed_cookie, fsl_chan->common.cookie)
+ == DMA_IN_PROGRESS)
+ break;
+
+ callback = desc->async_tx.callback;
+ callback_param = desc->async_tx.callback_param;
+
+ /* Remove from ld_queue list */
+ list_del(&desc->node);
+
+ dev_dbg(fsl_chan->dev, "link descriptor %p will be recycle.\n",
+ desc);
+ dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys);
+
+ /* Run the link descriptor callback function */
+ if (callback) {
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ dev_dbg(fsl_chan->dev, "link descriptor %p callback\n",
+ desc);
+ callback(callback_param);
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ }
+ }
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+}
+
+/**
+ * fsl_chan_xfer_ld_queue - Transfer link descriptors in channel ld_queue.
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
+{
+ struct list_head *ld_node;
+ dma_addr_t next_dest_addr;
+ unsigned long flags;
+
+ if (!dma_is_idle(fsl_chan))
+ return;
+
+ dma_halt(fsl_chan);
+
+ /* If there are some link descriptors
+ * not transfered in queue. We need to start it.
+ */
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
+ /* Find the first un-transfer desciptor */
+ for (ld_node = fsl_chan->ld_queue.next;
+ (ld_node != &fsl_chan->ld_queue)
+ && (dma_async_is_complete(
+ to_fsl_desc(ld_node)->async_tx.cookie,
+ fsl_chan->completed_cookie,
+ fsl_chan->common.cookie) == DMA_SUCCESS);
+ ld_node = ld_node->next);
+
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+
+ if (ld_node != &fsl_chan->ld_queue) {
+ /* Get the ld start address from ld_queue */
+ next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys;
+ dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%016llx\n",
+ (u64)next_dest_addr);
+ set_cdar(fsl_chan, next_dest_addr);
+ dma_start(fsl_chan);
+ } else {
+ set_cdar(fsl_chan, 0);
+ set_ndar(fsl_chan, 0);
+ }
+}
+
+/**
+ * fsl_dma_memcpy_issue_pending - Issue the DMA start command
+ * @fsl_chan : Freescale DMA channel
+ */
+static void fsl_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+#ifdef FSL_DMA_LD_DEBUG
+ struct fsl_desc_sw *ld;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+ if (list_empty(&fsl_chan->ld_queue)) {
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+ return;
+ }
+
+ dev_dbg(fsl_chan->dev, "--memcpy issue--\n");
+ list_for_each_entry(ld, &fsl_chan->ld_queue, node) {
+ int i;
+ dev_dbg(fsl_chan->dev, "Ch %d, LD %08x\n",
+ fsl_chan->id, ld->async_tx.phys);
+ for (i = 0; i < 8; i++)
+ dev_dbg(fsl_chan->dev, "LD offset %d: %08x\n",
+ i, *(((u32 *)&ld->hw) + i));
+ }
+ dev_dbg(fsl_chan->dev, "----------------\n");
+ spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
+#endif
+
+ fsl_chan_xfer_ld_queue(fsl_chan);
+}
+
+static void fsl_dma_dependency_added(struct dma_chan *chan)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+
+ fsl_chan_ld_cleanup(fsl_chan);
+}
+
+/**
+ * fsl_dma_is_complete - Determine the DMA status
+ * @fsl_chan : Freescale DMA channel
+ */
+static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ dma_cookie_t *done,
+ dma_cookie_t *used)
+{
+ struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+
+ fsl_chan_ld_cleanup(fsl_chan);
+
+ last_used = chan->cookie;
+ last_complete = fsl_chan->completed_cookie;
+
+ if (done)
+ *done = last_complete;
+
+ if (used)
+ *used = last_used;
+
+ return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
+{
+ struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
+ dma_addr_t stat;
+
+ stat = get_sr(fsl_chan);
+ dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n",
+ fsl_chan->id, stat);
+ set_sr(fsl_chan, stat); /* Clear the event register */
+
+ stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
+ if (!stat)
+ return IRQ_NONE;
+
+ if (stat & FSL_DMA_SR_TE)
+ dev_err(fsl_chan->dev, "Transfer Error!\n");
+
+ /* If the link descriptor segment transfer finishes,
+ * we will recycle the used descriptor.
+ */
+ if (stat & FSL_DMA_SR_EOSI) {
+ dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
+ dev_dbg(fsl_chan->dev, "event: clndar 0x%016llx, "
+ "nlndar 0x%016llx\n", (u64)get_cdar(fsl_chan),
+ (u64)get_ndar(fsl_chan));
+ stat &= ~FSL_DMA_SR_EOSI;
+ }
+
+ /* If it current transfer is the end-of-transfer,
+ * we should clear the Channel Start bit for
+ * prepare next transfer.
+ */
+ if (stat & (FSL_DMA_SR_EOLNI | FSL_DMA_SR_EOCDI)) {
+ dev_dbg(fsl_chan->dev, "event: End-of-link INT\n");
+ stat &= ~FSL_DMA_SR_EOLNI;
+ fsl_chan_xfer_ld_queue(fsl_chan);
+ }
+
+ if (stat)
+ dev_dbg(fsl_chan->dev, "event: unhandled sr 0x%02x\n",
+ stat);
+
+ dev_dbg(fsl_chan->dev, "event: Exit\n");
+ tasklet_schedule(&fsl_chan->tasklet);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fsl_dma_do_interrupt(int irq, void *data)
+{
+ struct fsl_dma_device *fdev = (struct fsl_dma_device *)data;
+ u32 gsr;
+ int ch_nr;
+
+ gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->reg_base)
+ : in_le32(fdev->reg_base);
+ ch_nr = (32 - ffs(gsr)) / 8;
+
+ return fdev->chan[ch_nr] ? fsl_dma_chan_do_interrupt(irq,
+ fdev->chan[ch_nr]) : IRQ_NONE;
+}
+
+static void dma_do_tasklet(unsigned long data)
+{
+ struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data;
+ fsl_chan_ld_cleanup(fsl_chan);
+}
+
+static void fsl_dma_callback_test(struct fsl_dma_chan *fsl_chan)
+{
+ if (fsl_chan)
+ dev_info(fsl_chan->dev, "selftest: callback is ok!\n");
+}
+
+static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
+{
+ struct dma_chan *chan;
+ int err = 0;
+ dma_addr_t dma_dest, dma_src;
+ dma_cookie_t cookie;
+ u8 *src, *dest;
+ int i;
+ size_t test_size;
+ struct dma_async_tx_descriptor *tx1, *tx2, *tx3;
+
+ test_size = 4096;
+
+ src = kmalloc(test_size * 2, GFP_KERNEL);
+ if (!src) {
+ dev_err(fsl_chan->dev,
+ "selftest: Cannot alloc memory for test!\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ dest = src + test_size;
+
+ for (i = 0; i < test_size; i++)
+ src[i] = (u8) i;
+
+ chan = &fsl_chan->common;
+
+ if (fsl_dma_alloc_chan_resources(chan) < 1) {
+ dev_err(fsl_chan->dev,
+ "selftest: Cannot alloc resources for DMA\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* TX 1 */
+ dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2,
+ DMA_TO_DEVICE);
+ dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2,
+ DMA_FROM_DEVICE);
+ tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0);
+ async_tx_ack(tx1);
+
+ cookie = fsl_dma_tx_submit(tx1);
+ fsl_dma_memcpy_issue_pending(chan);
+ msleep(2);
+
+ if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+ dev_err(fsl_chan->dev, "selftest: Time out!\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* Test free and re-alloc channel resources */
+ fsl_dma_free_chan_resources(chan);
+
+ if (fsl_dma_alloc_chan_resources(chan) < 1) {
+ dev_err(fsl_chan->dev,
+ "selftest: Cannot alloc resources for DMA\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+
+ /* Continue to test
+ * TX 2
+ */
+ dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2,
+ test_size / 4, DMA_TO_DEVICE);
+ dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2,
+ test_size / 4, DMA_FROM_DEVICE);
+ tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
+ async_tx_ack(tx2);
+
+ /* TX 3 */
+ dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4,
+ test_size / 4, DMA_TO_DEVICE);
+ dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4,
+ test_size / 4, DMA_FROM_DEVICE);
+ tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
+ async_tx_ack(tx3);
+
+ /* Test exchanging the prepared tx sort */
+ cookie = fsl_dma_tx_submit(tx3);
+ cookie = fsl_dma_tx_submit(tx2);
+
+#ifdef FSL_DMA_CALLBACKTEST
+ if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *)
+ dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) {
+ tx3->callback = fsl_dma_callback_test;
+ tx3->callback_param = fsl_chan;
+ }
+#endif
+ fsl_dma_memcpy_issue_pending(chan);
+ msleep(2);
+
+ if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+ dev_err(fsl_chan->dev, "selftest: Time out!\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+
+ err = memcmp(src, dest, test_size);
+ if (err) {
+ for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
+ i++);
+ dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%d is "
+ "error! src 0x%x, dest 0x%x\n",
+ i, test_size, *(src + i), *(dest + i));
+ }
+
+free_resources:
+ fsl_dma_free_chan_resources(chan);
+out:
+ kfree(src);
+ return err;
+}
+
+static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ struct fsl_dma_device *fdev;
+ struct fsl_dma_chan *new_fsl_chan;
+ int err;
+
+ fdev = dev_get_drvdata(dev->dev.parent);
+ BUG_ON(!fdev);
+
+ /* alloc channel */
+ new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);
+ if (!new_fsl_chan) {
+ dev_err(&dev->dev, "No free memory for allocating "
+ "dma channels!\n");
+ err = -ENOMEM;
+ goto err;
+ }
+
+ /* get dma channel register base */
+ err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg);
+ if (err) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ dev->node->full_name);
+ goto err;
+ }
+
+ new_fsl_chan->feature = *(u32 *)match->data;
+
+ if (!fdev->feature)
+ fdev->feature = new_fsl_chan->feature;
+
+ /* If the DMA device's feature is different than its channels',
+ * report the bug.
+ */
+ WARN_ON(fdev->feature != new_fsl_chan->feature);
+
+ new_fsl_chan->dev = &dev->dev;
+ new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
+ new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
+
+ new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
+ if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {
+ dev_err(&dev->dev, "There is no %d channel!\n",
+ new_fsl_chan->id);
+ err = -EINVAL;
+ goto err;
+ }
+ fdev->chan[new_fsl_chan->id] = new_fsl_chan;
+ tasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet,
+ (unsigned long)new_fsl_chan);
+
+ /* Init the channel */
+ dma_init(new_fsl_chan);
+
+ /* Clear cdar registers */
+ set_cdar(new_fsl_chan, 0);
+
+ switch (new_fsl_chan->feature & FSL_DMA_IP_MASK) {
+ case FSL_DMA_IP_85XX:
+ new_fsl_chan->toggle_ext_start = fsl_chan_toggle_ext_start;
+ new_fsl_chan->toggle_ext_pause = fsl_chan_toggle_ext_pause;
+ case FSL_DMA_IP_83XX:
+ new_fsl_chan->set_src_loop_size = fsl_chan_set_src_loop_size;
+ new_fsl_chan->set_dest_loop_size = fsl_chan_set_dest_loop_size;
+ }
+
+ spin_lock_init(&new_fsl_chan->desc_lock);
+ INIT_LIST_HEAD(&new_fsl_chan->ld_queue);
+
+ new_fsl_chan->common.device = &fdev->common;
+
+ /* Add the channel to DMA device channel list */
+ list_add_tail(&new_fsl_chan->common.device_node,
+ &fdev->common.channels);
+ fdev->common.chancnt++;
+
+ new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0);
+ if (new_fsl_chan->irq != NO_IRQ) {
+ err = request_irq(new_fsl_chan->irq,
+ &fsl_dma_chan_do_interrupt, IRQF_SHARED,
+ "fsldma-channel", new_fsl_chan);
+ if (err) {
+ dev_err(&dev->dev, "DMA channel %s request_irq error "
+ "with return %d\n", dev->node->full_name, err);
+ goto err;
+ }
+ }
+
+#ifdef CONFIG_FSL_DMA_SELFTEST
+ err = fsl_dma_self_test(new_fsl_chan);
+ if (err)
+ goto err;
+#endif
+
+ dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
+ match->compatible, new_fsl_chan->irq);
+
+ return 0;
+err:
+ dma_halt(new_fsl_chan);
+ iounmap(new_fsl_chan->reg_base);
+ free_irq(new_fsl_chan->irq, new_fsl_chan);
+ list_del(&new_fsl_chan->common.device_node);
+ kfree(new_fsl_chan);
+ return err;
+}
+
+const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN;
+const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN;
+
+static struct of_device_id of_fsl_dma_chan_ids[] = {
+ {
+ .compatible = "fsl,mpc8540-dma-channel",
+ .data = (void *)&mpc8540_dma_ip_feature,
+ },
+ {
+ .compatible = "fsl,mpc8349-dma-channel",
+ .data = (void *)&mpc8349_dma_ip_feature,
+ },
+ {}
+};
+
+static struct of_platform_driver of_fsl_dma_chan_driver = {
+ .name = "of-fsl-dma-channel",
+ .match_table = of_fsl_dma_chan_ids,
+ .probe = of_fsl_dma_chan_probe,
+};
+
+static __init int of_fsl_dma_chan_init(void)
+{
+ return of_register_platform_driver(&of_fsl_dma_chan_driver);
+}
+
+static int __devinit of_fsl_dma_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ int err;
+ unsigned int irq;
+ struct fsl_dma_device *fdev;
+
+ fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
+ if (!fdev) {
+ dev_err(&dev->dev, "No enough memory for 'priv'\n");
+ err = -ENOMEM;
+ goto err;
+ }
+ fdev->dev = &dev->dev;
+ INIT_LIST_HEAD(&fdev->common.channels);
+
+ /* get DMA controller register base */
+ err = of_address_to_resource(dev->node, 0, &fdev->reg);
+ if (err) {
+ dev_err(&dev->dev, "Can't get %s property 'reg'\n",
+ dev->node->full_name);
+ goto err;
+ }
+
+ dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
+ "controller at 0x%08x...\n",
+ match->compatible, fdev->reg.start);
+ fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
+ - fdev->reg.start + 1);
+
+ dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
+ fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
+ fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
+ fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
+ fdev->common.device_is_tx_complete = fsl_dma_is_complete;
+ fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
+ fdev->common.device_dependency_added = fsl_dma_dependency_added;
+ fdev->common.dev = &dev->dev;
+
+ irq = irq_of_parse_and_map(dev->node, 0);
+ if (irq != NO_IRQ) {
+ err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED,
+ "fsldma-device", fdev);
+ if (err) {
+ dev_err(&dev->dev, "DMA device request_irq error "
+ "with return %d\n", err);
+ goto err;
+ }
+ }
+
+ dev_set_drvdata(&(dev->dev), fdev);
+ of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev);
+
+ dma_async_device_register(&fdev->common);
+ return 0;
+
+err:
+ iounmap(fdev->reg_base);
+ kfree(fdev);
+ return err;
+}
+
+static struct of_device_id of_fsl_dma_ids[] = {
+ { .compatible = "fsl,mpc8540-dma", },
+ { .compatible = "fsl,mpc8349-dma", },
+ {}
+};
+
+static struct of_platform_driver of_fsl_dma_driver = {
+ .name = "of-fsl-dma",
+ .match_table = of_fsl_dma_ids,
+ .probe = of_fsl_dma_probe,
+};
+
+static __init int of_fsl_dma_init(void)
+{
+ return of_register_platform_driver(&of_fsl_dma_driver);
+}
+
+subsys_initcall(of_fsl_dma_chan_init);
+subsys_initcall(of_fsl_dma_init);
diff --git a/trunk/drivers/dma/fsldma.h b/trunk/drivers/dma/fsldma.h
new file mode 100644
index 000000000000..ba78c42121ba
--- /dev/null
+++ b/trunk/drivers/dma/fsldma.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author:
+ * Zhang Wei , Jul 2007
+ * Ebony Zhu , May 2007
+ *
+ * This 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.
+ *
+ */
+#ifndef __DMA_FSLDMA_H
+#define __DMA_FSLDMA_H
+
+#include
+#include
+#include
+
+/* Define data structures needed by Freescale
+ * MPC8540 and MPC8349 DMA controller.
+ */
+#define FSL_DMA_MR_CS 0x00000001
+#define FSL_DMA_MR_CC 0x00000002
+#define FSL_DMA_MR_CA 0x00000008
+#define FSL_DMA_MR_EIE 0x00000040
+#define FSL_DMA_MR_XFE 0x00000020
+#define FSL_DMA_MR_EOLNIE 0x00000100
+#define FSL_DMA_MR_EOLSIE 0x00000080
+#define FSL_DMA_MR_EOSIE 0x00000200
+#define FSL_DMA_MR_CDSM 0x00000010
+#define FSL_DMA_MR_CTM 0x00000004
+#define FSL_DMA_MR_EMP_EN 0x00200000
+#define FSL_DMA_MR_EMS_EN 0x00040000
+#define FSL_DMA_MR_DAHE 0x00002000
+#define FSL_DMA_MR_SAHE 0x00001000
+
+/* Special MR definition for MPC8349 */
+#define FSL_DMA_MR_EOTIE 0x00000080
+
+#define FSL_DMA_SR_CH 0x00000020
+#define FSL_DMA_SR_CB 0x00000004
+#define FSL_DMA_SR_TE 0x00000080
+#define FSL_DMA_SR_EOSI 0x00000002
+#define FSL_DMA_SR_EOLSI 0x00000001
+#define FSL_DMA_SR_EOCDI 0x00000001
+#define FSL_DMA_SR_EOLNI 0x00000008
+
+#define FSL_DMA_SATR_SBPATMU 0x20000000
+#define FSL_DMA_SATR_STRANSINT_RIO 0x00c00000
+#define FSL_DMA_SATR_SREADTYPE_SNOOP_READ 0x00050000
+#define FSL_DMA_SATR_SREADTYPE_BP_IORH 0x00020000
+#define FSL_DMA_SATR_SREADTYPE_BP_NREAD 0x00040000
+#define FSL_DMA_SATR_SREADTYPE_BP_MREAD 0x00070000
+
+#define FSL_DMA_DATR_DBPATMU 0x20000000
+#define FSL_DMA_DATR_DTRANSINT_RIO 0x00c00000
+#define FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE 0x00050000
+#define FSL_DMA_DATR_DWRITETYPE_BP_FLUSH 0x00010000
+
+#define FSL_DMA_EOL ((u64)0x1)
+#define FSL_DMA_SNEN ((u64)0x10)
+#define FSL_DMA_EOSIE 0x8
+#define FSL_DMA_NLDA_MASK (~(u64)0x1f)
+
+#define FSL_DMA_BCR_MAX_CNT 0x03ffffffu
+
+#define FSL_DMA_DGSR_TE 0x80
+#define FSL_DMA_DGSR_CH 0x20
+#define FSL_DMA_DGSR_PE 0x10
+#define FSL_DMA_DGSR_EOLNI 0x08
+#define FSL_DMA_DGSR_CB 0x04
+#define FSL_DMA_DGSR_EOSI 0x02
+#define FSL_DMA_DGSR_EOLSI 0x01
+
+struct fsl_dma_ld_hw {
+ u64 __bitwise src_addr;
+ u64 __bitwise dst_addr;
+ u64 __bitwise next_ln_addr;
+ u32 __bitwise count;
+ u32 __bitwise reserve;
+} __attribute__((aligned(32)));
+
+struct fsl_desc_sw {
+ struct fsl_dma_ld_hw hw;
+ struct list_head node;
+ struct dma_async_tx_descriptor async_tx;
+ struct list_head *ld;
+ void *priv;
+} __attribute__((aligned(32)));
+
+struct fsl_dma_chan_regs {
+ u32 __bitwise mr; /* 0x00 - Mode Register */
+ u32 __bitwise sr; /* 0x04 - Status Register */
+ u64 __bitwise cdar; /* 0x08 - Current descriptor address register */
+ u64 __bitwise sar; /* 0x10 - Source Address Register */
+ u64 __bitwise dar; /* 0x18 - Destination Address Register */
+ u32 __bitwise bcr; /* 0x20 - Byte Count Register */
+ u64 __bitwise ndar; /* 0x24 - Next Descriptor Address Register */
+};
+
+struct fsl_dma_chan;
+#define FSL_DMA_MAX_CHANS_PER_DEVICE 4
+
+struct fsl_dma_device {
+ void __iomem *reg_base; /* DGSR register base */
+ struct resource reg; /* Resource for register */
+ struct device *dev;
+ struct dma_device common;
+ struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
+ u32 feature; /* The same as DMA channels */
+};
+
+/* Define macros for fsl_dma_chan->feature property */
+#define FSL_DMA_LITTLE_ENDIAN 0x00000000
+#define FSL_DMA_BIG_ENDIAN 0x00000001
+
+#define FSL_DMA_IP_MASK 0x00000ff0
+#define FSL_DMA_IP_85XX 0x00000010
+#define FSL_DMA_IP_83XX 0x00000020
+
+#define FSL_DMA_CHAN_PAUSE_EXT 0x00001000
+#define FSL_DMA_CHAN_START_EXT 0x00002000
+
+struct fsl_dma_chan {
+ struct fsl_dma_chan_regs __iomem *reg_base;
+ dma_cookie_t completed_cookie; /* The maximum cookie completed */
+ spinlock_t desc_lock; /* Descriptor operation lock */
+ struct list_head ld_queue; /* Link descriptors queue */
+ struct dma_chan common; /* DMA common channel */
+ struct dma_pool *desc_pool; /* Descriptors pool */
+ struct device *dev; /* Channel device */
+ struct resource reg; /* Resource for register */
+ int irq; /* Channel IRQ */
+ int id; /* Raw id of this channel */
+ struct tasklet_struct tasklet;
+ u32 feature;
+
+ void (*toggle_ext_pause)(struct fsl_dma_chan *fsl_chan, int size);
+ void (*toggle_ext_start)(struct fsl_dma_chan *fsl_chan, int enable);
+ void (*set_src_loop_size)(struct fsl_dma_chan *fsl_chan, int size);
+ void (*set_dest_loop_size)(struct fsl_dma_chan *fsl_chan, int size);
+};
+
+#define to_fsl_chan(chan) container_of(chan, struct fsl_dma_chan, common)
+#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node)
+#define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx)
+
+#ifndef __powerpc64__
+static u64 in_be64(const u64 __iomem *addr)
+{
+ return ((u64)in_be32((u32 *)addr) << 32) | (in_be32((u32 *)addr + 1));
+}
+
+static void out_be64(u64 __iomem *addr, u64 val)
+{
+ out_be32((u32 *)addr, val >> 32);
+ out_be32((u32 *)addr + 1, (u32)val);
+}
+
+/* There is no asm instructions for 64 bits reverse loads and stores */
+static u64 in_le64(const u64 __iomem *addr)
+{
+ return ((u64)in_le32((u32 *)addr + 1) << 32) | (in_le32((u32 *)addr));
+}
+
+static void out_le64(u64 __iomem *addr, u64 val)
+{
+ out_le32((u32 *)addr + 1, val >> 32);
+ out_le32((u32 *)addr, (u32)val);
+}
+#endif
+
+#define DMA_IN(fsl_chan, addr, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ in_be##width(addr) : in_le##width(addr))
+#define DMA_OUT(fsl_chan, addr, val, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ out_be##width(addr, val) : out_le##width(addr, val))
+
+#define DMA_TO_CPU(fsl_chan, d, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ be##width##_to_cpu(d) : le##width##_to_cpu(d))
+#define CPU_TO_DMA(fsl_chan, c, width) \
+ (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \
+ cpu_to_be##width(c) : cpu_to_le##width(c))
+
+#endif /* __DMA_FSLDMA_H */
diff --git a/trunk/drivers/dma/ioat_dma.c b/trunk/drivers/dma/ioat_dma.c
index dff38accc5c1..4017d9e7acd2 100644
--- a/trunk/drivers/dma/ioat_dma.c
+++ b/trunk/drivers/dma/ioat_dma.c
@@ -714,6 +714,7 @@ static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy(
new->len = len;
new->dst = dma_dest;
new->src = dma_src;
+ new->async_tx.ack = 0;
return &new->async_tx;
} else
return NULL;
@@ -741,6 +742,7 @@ static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
new->len = len;
new->dst = dma_dest;
new->src = dma_src;
+ new->async_tx.ack = 0;
return &new->async_tx;
} else
return NULL;
diff --git a/trunk/drivers/firewire/fw-card.c b/trunk/drivers/firewire/fw-card.c
index 3e9719948a8e..a03462750b95 100644
--- a/trunk/drivers/firewire/fw-card.c
+++ b/trunk/drivers/firewire/fw-card.c
@@ -18,6 +18,7 @@
#include