diff --git a/[refs] b/[refs]
index 463a10d6a7c9..6ef501c4cea9 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 4a0d3f3afddf01dfcfdcc826f0b706dbc01f4ef4
+refs/heads/master: fc398769ac5cbfdf4dc16a7ba657b284abcc92f5
diff --git a/trunk/.gitignore b/trunk/.gitignore
index fdcce40226d7..8363e48cdcdc 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -53,5 +53,3 @@ cscope.*
*.orig
*.rej
-*~
-\#*#
diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl
index dc0f30c3e571..f31601e8bd89 100644
--- a/trunk/Documentation/DocBook/kernel-api.tmpl
+++ b/trunk/Documentation/DocBook/kernel-api.tmpl
@@ -361,14 +361,12 @@ 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 866b9cd9a959..6015347b41e2 100644
--- a/trunk/Documentation/controllers/memory.txt
+++ b/trunk/Documentation/controllers/memory.txt
@@ -1,8 +1,4 @@
-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.
+Memory Controller
Salient features
@@ -156,7 +152,7 @@ The memory controller uses the following hierarchy
a. Enable CONFIG_CGROUPS
b. Enable CONFIG_RESOURCE_COUNTERS
-c. Enable CONFIG_CGROUP_MEM_RES_CTLR
+c. Enable CONFIG_CGROUP_MEM_CONT
1. Prepare the cgroups
# mkdir -p /cgroups
@@ -168,7 +164,7 @@ c. Enable CONFIG_CGROUP_MEM_RES_CTLR
Since now we're in the 0 cgroup,
We can alter the memory limit:
-# echo 4M > /cgroups/0/memory.limit_in_bytes
+# echo -n 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.
@@ -189,7 +185,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 1 > memory.limit_in_bytes
+# echo -n 1 > memory.limit_in_bytes
# cat memory.limit_in_bytes
4096
@@ -201,7 +197,7 @@ caches, RSS and Active pages/Inactive pages are shown.
The memory.force_empty gives an interface to drop *all* charges by force.
-# echo 1 > memory.force_empty
+# echo -n 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 c360d4e91b48..de4804e8b396 100644
--- a/trunk/Documentation/debugging-via-ohci1394.txt
+++ b/trunk/Documentation/debugging-via-ohci1394.txt
@@ -36,15 +36,14 @@ available (notebooks) or too slow for extensive debug information (like ACPI).
Drivers
-------
-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()
+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(),
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 c1d1fd0c299b..4d3aa519eadf 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -172,16 +172,6 @@ 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
@@ -316,15 +306,3 @@ 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 54630095aa3c..8da724e2a0ff 100644
--- a/trunk/Documentation/gpio.txt
+++ b/trunk/Documentation/gpio.txt
@@ -2,9 +2,6 @@ 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?
===============
@@ -72,13 +69,11 @@ 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 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:
+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:
- #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.
@@ -321,9 +316,6 @@ 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/ide.txt b/trunk/Documentation/ide.txt
index bcd7cd1278ef..94e2e3b9e77f 100644
--- a/trunk/Documentation/ide.txt
+++ b/trunk/Documentation/ide.txt
@@ -258,6 +258,8 @@ 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
@@ -305,6 +307,53 @@ 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 be89f393274f..83f515c2905a 100644
--- a/trunk/Documentation/kprobes.txt
+++ b/trunk/Documentation/kprobes.txt
@@ -192,8 +192,7 @@ 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 files in the samples/kprobes/ sub-directory
-for examples.
+that you'll write. See the latter half of this document for examples.
4.1 register_kprobe
@@ -421,15 +420,249 @@ e. Watchpoint probes (which fire on data references).
8. Kprobes Example
-See samples/kprobes/kprobe_example.c
+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.
9. Jprobes Example
-See samples/kprobes/jprobe_example.c
+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.)
10. Kretprobes Example
-See samples/kprobes/kretprobe_example.c
+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.)
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 bb7bd27d4682..72b20c639596 100644
--- a/trunk/Documentation/pci.txt
+++ b/trunk/Documentation/pci.txt
@@ -123,8 +123,7 @@ 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; use of the macro DECLARE_PCI_DEVICE_TABLE is the preferred
-method of declaring the table. Each entry consists of:
+all-zero entry. Each entry consists of:
vendor,device Vendor and device ID to match (or PCI_ANY_ID)
@@ -192,8 +191,7 @@ 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 __devinitconst; this is done
- automatically if the table is declared with DECLARE_PCI_DEVICE_TABLE().
+ o The ID table array should be marked __devinitdata.
o The probe() and remove() functions should be marked __devinit
and __devexit respectively. All initialization functions
diff --git a/trunk/Documentation/scsi/ChangeLog.arcmsr b/trunk/Documentation/scsi/ChangeLog.arcmsr
index 038a3e6ecaa4..de2bcacfa870 100644
--- a/trunk/Documentation/scsi/ChangeLog.arcmsr
+++ b/trunk/Documentation/scsi/ChangeLog.arcmsr
@@ -109,10 +109,4 @@
** 8.replace pci_alloc_consistent()/pci_free_consistent() with kmalloc()/kfree() in arcmsr_iop_message_xfer()
** 9. fix the release of dma memory for type B in arcmsr_free_ccb_pool()
** 10.fix the arcmsr_polling_hbb_ccbdone()
-** 1.20.00.15 02/27/2008 Erich Chen & Nick Cheng
-** 1.arcmsr_iop_message_xfer() is called from atomic context under the
-** queuecommand scsi_host_template handler. James Bottomley pointed out
-** that the current GFP_KERNEL|GFP_DMA flags are wrong: firstly we are in
-** atomic context, secondly this memory is not used for DMA.
-** Also removed some unneeded casts. Thanks to Daniel Drake
**************************************************************************
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 558636e3a954..36c7bc641dba 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -767,14 +767,14 @@ S: Maintained
BLACKFIN ARCHITECTURE
P: Bryan Wu
-M: cooloney@kernel.org
+M: bryan.wu@analog.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
BLACKFIN EMAC DRIVER
P: Bryan Wu
-M: cooloney@kernel.org
+M: bryan.wu@analog.com
L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
W: http://blackfin.uclinux.org
S: Supported
@@ -982,12 +982,6 @@ 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
@@ -1138,12 +1132,6 @@ 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
@@ -1595,13 +1583,6 @@ 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
@@ -2639,17 +2620,6 @@ 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
@@ -2774,8 +2744,6 @@ 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
@@ -3916,13 +3884,10 @@ M: trivial@kernel.org
L: linux-kernel@vger.kernel.org
S: Maintained
-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
+TULIP NETWORK DRIVER
+L: tulip-users@lists.sourceforge.net
+W: http://sourceforge.net/projects/tulip/
+S: Orphan
TUN/TAP driver
P: Maxim Krasnyansky
diff --git a/trunk/Makefile b/trunk/Makefile
index ae78a31a9de2..a22978413b65 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 25
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc3
NAME = Funky Weasel is Jiggy wit it
# *DOCUMENTATION*
diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig
index 694c9af520bb..3d72dc3fc8f5 100644
--- a/trunk/arch/Kconfig
+++ b/trunk/arch/Kconfig
@@ -27,12 +27,5 @@ 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 be6fa105cd34..26d3789dfdd0 100644
--- a/trunk/arch/alpha/kernel/pci_iommu.c
+++ b/trunk/arch/alpha/kernel/pci_iommu.c
@@ -31,6 +31,7 @@
#endif
#define DEBUG_NODIRECT 0
+#define DEBUG_FORCEDAC 0
#define ISA_DMA_MASK 0x00ffffff
@@ -125,67 +126,39 @@ 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 device *dev, struct pci_iommu_arena *arena,
- long n, long mask)
+iommu_arena_find_pages(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 = ALIGN(arena->next_entry, mask + 1);
+ p = (arena->next_entry + mask) & ~mask;
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 = ALIGN(p + i + 1, mask + 1), i = 0;
+ 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
+ /* 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)
return -1;
}
@@ -195,8 +168,7 @@ iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena,
}
static long
-iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n,
- unsigned int align)
+iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align)
{
unsigned long flags;
unsigned long *ptes;
@@ -207,7 +179,7 @@ iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n,
/* Search for N empty ptes */
ptes = arena->ptes;
mask = max(align, arena->align_entry) - 1;
- p = iommu_arena_find_pages(dev, arena, n, mask);
+ p = iommu_arena_find_pages(arena, n, mask);
if (p < 0) {
spin_unlock_irqrestore(&arena->lock, flags);
return -1;
@@ -257,7 +229,6 @@ 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);
@@ -305,7 +276,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(dev, arena, npages, align);
+ dma_ofs = iommu_arena_alloc(arena, npages, align);
if (dma_ofs < 0) {
printk(KERN_WARNING "pci_map_single failed: "
"could not allocate dma page tables\n");
@@ -592,7 +563,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(dev, arena, npages, 0);
+ dma_ofs = iommu_arena_alloc(arena, npages, 0);
if (dma_ofs < 0) {
/* If we attempted a direct map above but failed, die. */
if (leader->dma_address == 0)
@@ -859,7 +830,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(NULL, arena, pg_count, align_mask);
+ p = iommu_arena_find_pages(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 955fc53c1c01..9619c43783ff 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -12,7 +12,6 @@ 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
@@ -940,8 +939,7 @@ config KEXEC
config ATAGS_PROC
bool "Export atags in procfs"
- depends on KEXEC
- default y
+ default n
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-pxa/cpu-pxa.c b/trunk/arch/arm/mach-pxa/cpu-pxa.c
index 4b21479332ae..939a3867f77c 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_param(freq_debug, uint, 0);
+MODULE_PARM(freq_debug, "i");
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 35f25fdaeba3..7cd9ef8deb02 100644
--- a/trunk/arch/arm/mach-pxa/pxa3xx.c
+++ b/trunk/arch/arm/mach-pxa/pxa3xx.c
@@ -129,20 +129,28 @@ 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 afd2cbfca0d9..7731d50dd86c 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) || defined(CONFIG_FB_PXA_MODULE)
+#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
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 3f6dc40b8353..2728b0e7d2bb 100644
--- a/trunk/arch/arm/mm/mmap.c
+++ b/trunk/arch/arm/mm/mmap.c
@@ -120,8 +120,6 @@ 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 e0f19ab91163..500c9610ab30 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;
- pgtable_t pte;
+ struct page *pte;
if (!pgd)
return;
@@ -90,8 +90,10 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
goto free;
}
- pte = pmd_pgtable(*pmd);
+ pte = pmd_page(*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 e765a8652b3e..5a77030e07a0 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_ATSTK100X_SW2_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK1002_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 7f4af0b1e111..eaaa69bbdc38 100644
--- a/trunk/arch/avr32/kernel/process.c
+++ b/trunk/arch/avr32/kernel/process.c
@@ -11,7 +11,6 @@
#include
#include
#include
-#include
#include
#include
@@ -31,10 +30,8 @@ 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();
@@ -348,7 +345,6 @@ 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 ce4e4296b954..6560cb18b4e3 100644
--- a/trunk/arch/avr32/mm/fault.c
+++ b/trunk/arch/avr32/mm/fault.c
@@ -189,8 +189,6 @@ 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 75eba2ca7881..fe254f886a6e 100644
--- a/trunk/arch/blackfin/Makefile
+++ b/trunk/arch/blackfin/Makefile
@@ -98,11 +98,8 @@ 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
- @$($(quiet)show_mach_symlink)
+ @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
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 ae320dcfedef..d59ee1530bd4 100644
--- a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -1,6 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22.16
+# Linux kernel version: 2.6.22.14
+# Thu Nov 29 17:32:47 2007
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -115,10 +116,7 @@ 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
@@ -308,7 +306,6 @@ 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
@@ -357,7 +354,6 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# Networking
@@ -500,6 +496,7 @@ 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
@@ -509,6 +506,9 @@ 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,6 +684,7 @@ 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
#
@@ -701,12 +702,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
@@ -771,6 +772,7 @@ 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 9621caa60b5f..811711f59a25 100644
--- a/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -322,9 +322,10 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_BFIN_SLEEP_DEEPER=y
-# CONFIG_PM_BFIN_SLEEP is not set
+CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
# 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
@@ -696,6 +697,7 @@ 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 b51e76ce7f4f..198f4123af4b 100644
--- a/trunk/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/trunk/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -323,9 +323,10 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_BFIN_SLEEP_DEEPER=y
-# CONFIG_PM_BFIN_SLEEP is not set
+CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
# 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
@@ -713,6 +714,7 @@ 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 d45fa535dad7..b37ccc681e7a 100644
--- a/trunk/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/trunk/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -330,9 +330,10 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
# CONFIG_PM_SYSFS_DEPRECATED is not set
-CONFIG_PM_BFIN_SLEEP_DEEPER=y
-# CONFIG_PM_BFIN_SLEEP is not set
+CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
# 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
@@ -1012,7 +1013,6 @@ 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 c9707f7665ad..fd702161ef59 100644
--- a/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -396,7 +396,6 @@ CONFIG_BINFMT_ZFLAT=y
# Power management options
#
# CONFIG_PM is not set
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -1076,7 +1075,6 @@ 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 4d8a63331309..8546994939fb 100644
--- a/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/trunk/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -367,7 +367,6 @@ 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 8fd5d22cec34..5453bc3664fc 100644
--- a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -105,14 +105,13 @@ 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) {
- 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);
- }
+ 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);
#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 1904d8b53328..5cf4bdb1df3b 100644
--- a/trunk/arch/blackfin/kernel/gptimers.c
+++ b/trunk/arch/blackfin/kernel/gptimers.c
@@ -1,9 +1,9 @@
/*
- * gptimers.c - Blackfin General Purpose Timer core API
+ * bfin_gptimers.c - derived from bf53x_timers.c
+ * Driver for General Purpose Timer functions on the Blackfin processor
*
- * Copyright (c) 2005-2008 Analog Devices Inc.
- * Copyright (C) 2005 John DeHority
- * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ * 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 2255c289a714..8229b1090eb9 100644
--- a/trunk/arch/blackfin/kernel/setup.c
+++ b/trunk/arch/blackfin/kernel/setup.c
@@ -32,7 +32,6 @@
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;
@@ -515,7 +514,6 @@ 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"
@@ -529,8 +527,7 @@ static __init void memory_setup(void)
#if DMA_UNCACHED_REGION > 0
KERN_INFO " DMA Zone = 0x%p-0x%p\n"
#endif
- , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END,
- _stext, _etext,
+ , _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 cb01a9de2680..aed832540b3b 100644
--- a/trunk/arch/blackfin/kernel/vmlinux.lds.S
+++ b/trunk/arch/blackfin/kernel/vmlinux.lds.S
@@ -147,64 +147,44 @@ 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 = .;
- LDS_L1_CODE
+ *(.l1.text)
+
. = 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 = .;
- LDS_L1_A_DATA
+ *(.l1.data)
__edata_l1 = .;
. = ALIGN(4);
__sbss_l1 = .;
- LDS_L1_A_BSS
+ *(.l1.bss)
. = ALIGN(32);
- LDS_L1_A_CACHE
+ *(.data_l1.cacheline_aligned)
. = 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 = .;
- LDS_L1_B_DATA
+ *(.l1.data.B)
__edata_b_l1 = .;
. = ALIGN(4);
__sbss_b_l1 = .;
- LDS_L1_B_BSS
+ *(.l1.bss.B)
. = 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 cf4bc0d83355..337515fba612 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 = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
+ .offset = 4 * SIZE_1M,
+ .size = (256 - 4) * SIZE_1M,
},
};
@@ -422,11 +422,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = {
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = MTDPART_OFS_APPEND,
+ .offset = 0x20000
}, {
.name = "file system",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
+ .size = 0x700000,
+ .offset = 0x00100000,
}
};
@@ -484,6 +484,13 @@ 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,
@@ -604,6 +611,17 @@ 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",
@@ -800,19 +818,6 @@ 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,
@@ -890,8 +895,6 @@ 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)
@@ -918,18 +921,13 @@ 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)
{
- /* 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];
- }
+ *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC);
+ *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4);
}
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 241b5a20a36a..2b09aa39f565 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 = MTDPART_OFS_APPEND,
+ .offset = 0x20000
}, {
.name = "file system",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
+ .size = 0x700000,
+ .offset = 0x00100000,
}
};
@@ -298,19 +298,6 @@ 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
@@ -363,8 +350,6 @@ 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 b2ac4816ae62..a645f6fd091b 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 = 0x40000,
+ .size = 0x20000,
.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 = 0x00040000,
+ .size = 0x00020000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = MTDPART_OFS_APPEND,
+ .offset = 0x20000
}, {
.name = "file system",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
+ .size = 0x700000,
+ .offset = 0x00100000,
}
};
@@ -212,6 +212,13 @@ 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,
@@ -301,6 +308,17 @@ 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",
@@ -439,19 +457,6 @@ 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
@@ -513,8 +518,6 @@ 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 c95395ba7bfa..8a3397db1d21 100644
--- a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/trunk/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -371,6 +371,13 @@ 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,
@@ -476,6 +483,17 @@ 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 ea83148993da..9e2277e0d25c 100644
--- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c
@@ -128,19 +128,6 @@ 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[] = {
{
@@ -356,7 +343,7 @@ static struct platform_device net2272_bfin_device = {
static struct mtd_partition stamp_partitions[] = {
{
.name = "Bootloader",
- .size = 0x40000,
+ .size = 0x20000,
.offset = 0,
}, {
.name = "Kernel",
@@ -364,7 +351,7 @@ static struct mtd_partition stamp_partitions[] = {
.offset = MTDPART_OFS_APPEND,
}, {
.name = "RootFS",
- .size = 0x400000 - 0x40000 - 0xE0000 - 0x10000,
+ .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "MAC Address",
@@ -404,17 +391,17 @@ static struct platform_device stamp_flash_device = {
static struct mtd_partition bfin_spi_flash_partitions[] = {
{
.name = "bootloader",
- .size = 0x00040000,
+ .size = 0x00020000,
.offset = 0,
.mask_flags = MTD_CAP_ROM
}, {
.name = "kernel",
.size = 0xe0000,
- .offset = MTDPART_OFS_APPEND,
+ .offset = 0x20000
}, {
.name = "file system",
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
+ .size = 0x700000,
+ .offset = 0x00100000,
}
};
@@ -472,6 +459,13 @@ 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,
@@ -584,6 +578,17 @@ 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",
@@ -816,8 +821,6 @@ 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 a0950c1fd800..916e963e83ba 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 = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
+ .offset = 4 * SIZE_1M,
+ .size = (256 - 4) * SIZE_1M,
},
};
@@ -333,7 +333,7 @@ static struct platform_device bf54x_sdh_device = {
static struct mtd_partition ezkit_partitions[] = {
{
.name = "Bootloader",
- .size = 0x40000,
+ .size = 0x20000,
.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 = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
+ .size = 0x1c0000,
+ .offset = 0x40000
}
};
@@ -594,19 +594,6 @@ 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,
@@ -659,8 +646,6 @@ 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 f5479298bb79..374803a8d2e8 100644
--- a/trunk/arch/blackfin/mach-bf548/dma.c
+++ b/trunk/arch/blackfin/mach-bf548/dma.c
@@ -27,8 +27,6 @@
* 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 46222a75321a..74fe258421a5 100644
--- a/trunk/arch/blackfin/mach-bf548/head.S
+++ b/trunk/arch/blackfin/mach-bf548/head.S
@@ -28,7 +28,6 @@
*/
#include
-#include
#include
#include
#if CONFIG_BFIN_KERNEL_CLOCK
@@ -45,9 +44,10 @@
#define INITIAL_STACK 0xFFB01000
-__INIT
+.text
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,7 +213,6 @@ ENTRY(__start)
.LWAIT_HERE:
jump .LWAIT_HERE;
-ENDPROC(__start)
ENTRY(_real_start)
[ -- sp ] = reti;
@@ -286,9 +285,6 @@ ENTRY(_real_start)
call _start_kernel;
.L_exit:
jump.s .L_exit;
-ENDPROC(_real_start)
-
-__FINIT
.section .l1.text
#if CONFIG_BFIN_KERNEL_CLOCK
@@ -454,7 +450,6 @@ 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 d357f648d963..43c1b0982819 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 = 0x40000,
+ .size = 0x20000,
.offset = 0,
}, {
.name = "Kernel",
@@ -389,19 +389,6 @@ 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
@@ -459,7 +446,6 @@ 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 9d45aa3265b1..b80ddd8b232d 100644
--- a/trunk/arch/blackfin/mach-common/dpmc.S
+++ b/trunk/arch/blackfin/mach-common/dpmc.S
@@ -31,6 +31,140 @@
#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
@@ -325,12 +459,10 @@ 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)
@@ -341,3 +473,4 @@ 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 225ef14af75e..880595afe98d 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-bf5xx/irq.h */
+ /* irq number for request_irq, available in mach-bf533/irq.h */
unsigned int irqno;
/* corresponding bit in the SIC_ISR register */
unsigned int isrflag;
@@ -86,6 +86,7 @@ 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
@@ -119,10 +120,10 @@ static void __init search_IAR(void)
}
/*
- * This is for core internal IRQs
+ * This is for BF533 internal IRQs
*/
-static void bfin_ack_noop(unsigned int irq)
+static void ack_noop(unsigned int irq)
{
/* Dummy function. */
}
@@ -155,11 +156,11 @@ static void bfin_internal_mask_irq(unsigned int irq)
{
#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
- ~(1 << SIC_SYSIRQ(irq)));
+ ~(1 << (irq - (IRQ_CORETMR + 1))));
#else
unsigned mask_bank, mask_bit;
- mask_bank = SIC_SYSIRQ(irq) / 32;
- mask_bit = SIC_SYSIRQ(irq) % 32;
+ mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
+ mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
~(1 << mask_bit));
#endif
@@ -170,11 +171,11 @@ static void bfin_internal_unmask_irq(unsigned int irq)
{
#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
- (1 << SIC_SYSIRQ(irq)));
+ (1 << (irq - (IRQ_CORETMR + 1))));
#else
unsigned mask_bank, mask_bit;
- mask_bank = SIC_SYSIRQ(irq) / 32;
- mask_bit = SIC_SYSIRQ(irq) % 32;
+ mask_bank = (irq - (IRQ_CORETMR + 1)) / 32;
+ mask_bit = (irq - (IRQ_CORETMR + 1)) % 32;
bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) |
(1 << mask_bit));
#endif
@@ -186,8 +187,8 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
{
unsigned bank, bit;
unsigned long flags;
- bank = SIC_SYSIRQ(irq) / 32;
- bit = SIC_SYSIRQ(irq) % 32;
+ bank = (irq - (IRQ_CORETMR + 1)) / 32;
+ bit = (irq - (IRQ_CORETMR + 1)) % 32;
local_irq_save(flags);
@@ -203,18 +204,15 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
#endif
static struct irq_chip bfin_core_irqchip = {
- .ack = bfin_ack_noop,
+ .ack = ack_noop,
.mask = bfin_core_mask_irq,
.unmask = bfin_core_unmask_irq,
};
static struct irq_chip bfin_internal_irqchip = {
- .ack = bfin_ack_noop,
+ .ack = 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
@@ -223,23 +221,38 @@ 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)
- bfin_internal_mask_irq(IRQ_GENERIC_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();
+ }
}
static void bfin_generic_error_unmask_irq(unsigned int irq)
{
- bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
+ local_irq_disable();
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 <<
+ (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1)));
+ SSYNC();
+ local_irq_enable();
+
error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
}
static struct irq_chip bfin_generic_error_irqchip = {
- .ack = bfin_ack_noop,
- .mask_ack = bfin_generic_error_mask_irq,
+ .ack = bfin_generic_error_ack_irq,
.mask = bfin_generic_error_mask_irq,
.unmask = bfin_generic_error_unmask_irq,
};
@@ -595,7 +608,7 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = {
(struct pin_int_t *)PINT3_MASK_SET,
};
-inline unsigned short get_irq_base(u8 bank, u8 bmap)
+unsigned short get_irq_base(u8 bank, u8 bmap)
{
u16 irq_base;
@@ -956,12 +969,17 @@ 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();
@@ -983,53 +1001,90 @@ 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:
+ case IRQ_PROG_INTA:
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
- case IRQ_MAC_RX:
+ case IRQ_MAC_RX:
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
# endif
#elif defined(CONFIG_BF54x)
- case IRQ_PINT0:
- case IRQ_PINT1:
- case IRQ_PINT2:
- case IRQ_PINT3:
+ 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;
#elif defined(CONFIG_BF52x)
- case IRQ_PORTF_INTA:
- case IRQ_PORTG_INTA:
- case IRQ_PORTH_INTA:
+ 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;
#elif defined(CONFIG_BF561)
- case IRQ_PROG0_INTA:
- case IRQ_PROG1_INTA:
- case IRQ_PROG2_INTA:
+ 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;
#endif
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
- break;
+ default:
+ set_irq_handler(irq, handle_simple_irq);
+ break;
+ }
+
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- case IRQ_GENERIC_ERROR:
+ } else {
set_irq_handler(irq, bfin_demux_error_irq);
-
- break;
-#endif
- default:
- set_irq_handler(irq, handle_simple_irq);
- break;
}
+#endif
}
-
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
- for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
- set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
- handle_level_irq);
+ 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);
+ }
#endif
- /* 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);
+ for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; 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();
@@ -1051,16 +1106,6 @@ 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;
}
@@ -1077,6 +1122,7 @@ 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
@@ -1092,7 +1138,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 ec3141fefd20..1f516c55bde6 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 void __init free_init_pages(const char *what, unsigned long begin, unsigned long end)
+static __init void 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_refok free_initmem(void)
+void __init 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 525483f0ddf8..9310a7b476e9 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 c7bd6ebdc93c..7161a2bef4fe 100644
--- a/trunk/arch/cris/arch-v10/lib/string.c
+++ b/trunk/arch/cris/arch-v10/lib/string.c
@@ -1,59 +1,55 @@
-/* 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)
+/*#************************************************************************#*/
+/*#-------------------------------------------------------------------------*/
+/*# */
+/*# 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)
{
- /* Now we want the parameters put in special registers.
+ /* Ok. 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 allright, it really would need no temporaries, and no
- stack space to save stuff on. */
+ If gcc was alright, it really would need no temporaries, and no
+ stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
- register unsigned char *dst __asm__ ("r13") = pdst;
- register unsigned const char *src __asm__ ("r11") = psrc;
+ register char *dst __asm__ ("r13") = pdst;
+ register 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. */
@@ -63,174 +59,167 @@ memcpy(void *pdst, const void *psrc, size_t pn)
&& n >= 3)
{
if ((unsigned long) dst & 1)
- {
- n--;
- *dst = *src;
- src++;
- dst++;
- }
+ {
+ n--;
+ *(char*)dst = *(char*)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 >= 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\
+ /* 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\
\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\
-"
-#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\
+ movem [$r11+],$r10 \n\
+ subq 44,$r12 \n\
+ bge 0b \n\
+ movem $r10,[$r13+] \n\
\n\
- ;; Compensate for last loop underflowing n. \n\
- addq 44,r12 \n\
+ addq 44,$r12 ;; compensate for last loop underflowing n \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)
+ /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
+ /* Inputs */ : "0" (dst), "1" (src), "2" (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;
-
- n -= 16;
- }
+ while ( n >= 16 )
+ {
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ 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:
- *dst = *src;
+ *(char*)dst = *(char*)src;
break;
-
case 2:
- *(short *) dst = *(short *) src;
+ *(short*)dst = *(short*)src;
break;
-
case 3:
- *(short *) dst = *(short *) src; dst += 2; src += 2;
- *dst = *src;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 4:
- *(long *) dst = *(long *) src;
+ *((long*)dst)++ = *((long*)src)++;
break;
-
case 5:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *dst = *src;
+ *((long*)dst)++ = *((long*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 6:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(short *) dst = *(short *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *(short*)dst = *(short*)src;
break;
-
case 7:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(short *) dst = *(short *) src; dst += 2; src += 2;
- *dst = *src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 8:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
break;
-
case 9:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *dst = *src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 10:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(short *) dst = *(short *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(short*)dst = *(short*)src;
break;
-
case 11:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 12:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
break;
-
case 13:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 14:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(short*)dst = *(short*)src;
break;
-
case 15:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
- }
+ }
- return return_dst;
-}
+ return return_dst; /* destination pointer. */
+} /* memcpy() */
diff --git a/trunk/arch/cris/arch-v10/lib/usercopy.c b/trunk/arch/cris/arch-v10/lib/usercopy.c
index b0a608da7bd1..b8e6c0430e5b 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 *pdst, const void __user *psrc, unsigned long pn)
+__copy_user_zeroing (void __user *pdst, const void *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 c7bd6ebdc93c..6740b2cebae5 100644
--- a/trunk/arch/cris/arch-v32/lib/string.c
+++ b/trunk/arch/cris/arch-v32/lib/string.c
@@ -1,59 +1,55 @@
-/* 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)
+/*#************************************************************************#*/
+/*#-------------------------------------------------------------------------*/
+/*# */
+/*# 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)
{
- /* Now we want the parameters put in special registers.
+ /* Ok. 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 allright, it really would need no temporaries, and no
- stack space to save stuff on. */
+ If gcc was alright, it really would need no temporaries, and no
+ stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
- register unsigned char *dst __asm__ ("r13") = pdst;
- register unsigned const char *src __asm__ ("r11") = psrc;
+ register char *dst __asm__ ("r13") = pdst;
+ register 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. */
@@ -63,174 +59,161 @@ memcpy(void *pdst, const void *psrc, size_t pn)
&& n >= 3)
{
if ((unsigned long) dst & 1)
- {
- n--;
- *dst = *src;
- src++;
- dst++;
- }
+ {
+ n--;
+ *(char*)dst = *(char*)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 >= 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\
+ /* 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\
- ;; on the stack. \n\
- subq 11*4,sp \n\
- movem r10,[sp] \n\
+ ;; Save the registers we'll use in the movem process \n\
\n\
- ;; Now we've got this: \n\
- ;; r11 - src \n\
- ;; r13 - dst \n\
- ;; r12 - n \n\
+ ;; on the stack. \n\
+ subq 11*4,$sp \n\
+ movem $r10,[$sp] \n\
\n\
- ;; Update n for the first loop. \n\
- subq 44,r12 \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\
0: \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\
+ movem [$r11+],$r10 \n\
+ subq 44,$r12 \n\
+ bge 0b \n\
+ movem $r10,[$r13+] \n\
\n\
- ;; Compensate for last loop underflowing n. \n\
- addq 44,r12 \n\
+ addq 44,$r12 ;; compensate for last loop underflowing n \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)
+ /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
+ /* Inputs */ : "0" (dst), "1" (src), "2" (n));
- /* Inputs. */
- : "0" (dst), "1" (src), "2" (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;
+ /* 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. */
- n -= 16;
- }
+ while ( n >= 16 )
+ {
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ 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:
- *dst = *src;
+ *(char*)dst = *(char*)src;
break;
-
case 2:
- *(short *) dst = *(short *) src;
+ *(short*)dst = *(short*)src;
break;
-
case 3:
- *(short *) dst = *(short *) src; dst += 2; src += 2;
- *dst = *src;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 4:
- *(long *) dst = *(long *) src;
+ *((long*)dst)++ = *((long*)src)++;
break;
-
case 5:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *dst = *src;
+ *((long*)dst)++ = *((long*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 6:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(short *) dst = *(short *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *(short*)dst = *(short*)src;
break;
-
case 7:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(short *) dst = *(short *) src; dst += 2; src += 2;
- *dst = *src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 8:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
break;
-
case 9:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *dst = *src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 10:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(short *) dst = *(short *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(short*)dst = *(short*)src;
break;
-
case 11:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 12:
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src; dst += 4; src += 4;
- *(long *) dst = *(long *) src;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
break;
-
case 13:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(char*)dst = *(char*)src;
break;
-
case 14:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *(short*)dst = *(short*)src;
break;
-
case 15:
- *(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;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((long*)dst)++ = *((long*)src)++;
+ *((short*)dst)++ = *((short*)src)++;
+ *(char*)dst = *(char*)src;
break;
- }
+ }
- return return_dst;
-}
+ return return_dst; /* destination pointer. */
+} /* memcpy() */
diff --git a/trunk/arch/cris/arch-v32/lib/usercopy.c b/trunk/arch/cris/arch-v32/lib/usercopy.c
index 0b5b70d5f58a..04d0cf35a276 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 *pdst, const void __user *psrc, unsigned long pn)
+__copy_user_zeroing (void __user *pdst, const void *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 8fa3faf5ef1b..dff9edfc7465 100644
--- a/trunk/arch/ia64/Kconfig
+++ b/trunk/arch/ia64/Kconfig
@@ -18,7 +18,6 @@ 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
@@ -156,8 +155,6 @@ 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 f1645c4f7039..b916ccfdef84 100644
--- a/trunk/arch/ia64/Makefile
+++ b/trunk/arch/ia64/Makefile
@@ -11,8 +11,6 @@
# 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/configs/generic_defconfig b/trunk/arch/ia64/defconfig
similarity index 100%
rename from trunk/arch/ia64/configs/generic_defconfig
rename to trunk/arch/ia64/defconfig
diff --git a/trunk/arch/ia64/ia32/ia32_signal.c b/trunk/arch/ia64/ia32/ia32_signal.c
index 256a7faeda07..85e82f32e480 100644
--- a/trunk/arch/ia64/ia32/ia32_signal.c
+++ b/trunk/arch/ia64/ia32/ia32_signal.c
@@ -766,19 +766,8 @@ 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) {
- int onstack = sas_ss_flags(esp);
-
- if (onstack == 0)
+ if (!on_sig_stack(esp))
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 7b3292282dea..398e2fd1cd25 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 (irq_prepare_move(irq, first_cpu(mask)))
+ if (reassign_irq_vector(irq, first_cpu(mask)))
return;
dest = cpu_physical_id(first_cpu(mask));
@@ -397,7 +397,6 @@ 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);
@@ -451,7 +450,6 @@ 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 2b8cf6e85af4..0b52f19ed046 100644
--- a/trunk/arch/ia64/kernel/irq_ia64.c
+++ b/trunk/arch/ia64/kernel/irq_ia64.c
@@ -260,8 +260,6 @@ 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
@@ -274,101 +272,6 @@ 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)
@@ -400,6 +303,36 @@ 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
*/
@@ -645,13 +578,6 @@ 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 615c3d2b6348..b618487cdc85 100644
--- a/trunk/arch/ia64/kernel/kprobes.c
+++ b/trunk/arch/ia64/kernel/kprobes.c
@@ -1001,11 +1001,6 @@ 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 60c6ef67ebb2..e86d02959794 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 (irq_prepare_move(irq, cpu))
+ if (reassign_irq_vector(irq, cpu))
return;
read_msi_msg(irq, &msg);
@@ -119,7 +119,6 @@ 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 a3022dc48ef8..f44fe8412162 100644
--- a/trunk/arch/ia64/kernel/sal.c
+++ b/trunk/arch/ia64/kernel/sal.c
@@ -109,13 +109,6 @@ 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 5740296c35af..309da3567bc8 100644
--- a/trunk/arch/ia64/kernel/signal.c
+++ b/trunk/arch/ia64/kernel/signal.c
@@ -342,33 +342,15 @@ 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) {
- 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);
- }
+ 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);
}
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 18a9c5f4b00d..6dfa3b3c0e2a 100644
--- a/trunk/arch/m68k/kernel/entry.S
+++ b/trunk/arch/m68k/kernel/entry.S
@@ -742,9 +742,7 @@ sys_call_table:
.long sys_epoll_pwait /* 315 */
.long sys_utimensat
.long sys_signalfd
- .long sys_timerfd_create
+ .long sys_ni_syscall
.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 670b0a99cfa0..648113075f97 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.25-rc3
-# Mon Feb 25 15:03:00 2008
+# Linux kernel version: 2.6.23
+# Thu Oct 18 13:17:38 2007
#
CONFIG_M68K=y
# CONFIG_MMU is not set
@@ -15,10 +15,8 @@ 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"
#
@@ -33,14 +31,12 @@ 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
@@ -52,22 +48,15 @@ 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
@@ -94,8 +83,6 @@ 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
@@ -134,7 +121,6 @@ CONFIG_M5272C3=y
# CONFIG_MOD5272 is not set
CONFIG_FREESCALE=y
CONFIG_4KSTACKS=y
-CONFIG_HZ=100
#
# RAM configuration
@@ -161,7 +147,6 @@ 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
@@ -173,6 +158,10 @@ CONFIG_VIRT_TO_BUS=y
# CONFIG_PCI is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+
#
# Executable file formats
#
@@ -216,7 +205,6 @@ 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
@@ -241,6 +229,10 @@ 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
#
@@ -248,7 +240,6 @@ 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
@@ -292,7 +283,6 @@ 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
@@ -349,11 +339,10 @@ CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# 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
#
@@ -371,15 +360,9 @@ 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
@@ -394,7 +377,7 @@ CONFIG_FEC=y
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_ASYNC is not set
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
@@ -403,6 +386,7 @@ CONFIG_PPP_ASYNC=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
@@ -434,16 +418,12 @@ CONFIG_SLHC=y
#
# Non-8250 serial port support
#
-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_SERIAL_COLDFIRE=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
@@ -459,14 +439,6 @@ 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
@@ -478,20 +450,20 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
+CONFIG_DAB=y
#
# 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
@@ -499,10 +471,22 @@ CONFIG_SSB_POSSIBLE=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
#
@@ -521,9 +505,11 @@ CONFIG_EXT2_FS=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_DNOTIFY is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
# 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
@@ -549,6 +535,7 @@ 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
#
@@ -564,27 +551,42 @@ CONFIG_SYSFS=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
-# CONFIG_NETWORK_FILESYSTEMS 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
#
# 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
@@ -592,7 +594,6 @@ CONFIG_ENABLE_WARN_DEPRECATED=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
@@ -604,7 +605,6 @@ CONFIG_ENABLE_WARN_DEPRECATED=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 fca2e49917a3..1b02b8820068 100644
--- a/trunk/arch/m68knommu/kernel/syscalltable.S
+++ b/trunk/arch/m68knommu/kernel/syscalltable.S
@@ -336,11 +336,9 @@ ENTRY(sys_call_table)
.long sys_epoll_pwait /* 315 */
.long sys_utimensat
.long sys_signalfd
- .long sys_timerfd_create
+ .long sys_ni_syscall
.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 6bafefa546e5..9159fd05c9ac 100644
--- a/trunk/arch/m68knommu/platform/68328/timers.c
+++ b/trunk/arch/m68knommu/platform/68328/timers.c
@@ -67,6 +67,16 @@ 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 1189d8d6170d..5b8d8382b762 100644
--- a/trunk/arch/powerpc/Kconfig
+++ b/trunk/arch/powerpc/Kconfig
@@ -90,7 +90,6 @@ 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 b5c30f766c40..900c7ff2b7e9 100644
--- a/trunk/arch/powerpc/boot/cuboot-bamboo.c
+++ b/trunk/arch/powerpc/boot/cuboot-bamboo.c
@@ -17,7 +17,6 @@
#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 56564ba37f62..c5f37ce172ea 100644
--- a/trunk/arch/powerpc/boot/cuboot-ebony.c
+++ b/trunk/arch/powerpc/boot/cuboot-ebony.c
@@ -17,7 +17,6 @@
#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 5434d70b5660..c021167f9381 100644
--- a/trunk/arch/powerpc/boot/cuboot-katmai.c
+++ b/trunk/arch/powerpc/boot/cuboot-katmai.c
@@ -22,7 +22,6 @@
#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 b55b80467eed..f66455a45ab1 100644
--- a/trunk/arch/powerpc/boot/cuboot-taishan.c
+++ b/trunk/arch/powerpc/boot/cuboot-taishan.c
@@ -21,9 +21,7 @@
#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 3db93e85e9ea..bdedebe1bc14 100644
--- a/trunk/arch/powerpc/boot/cuboot-warp.c
+++ b/trunk/arch/powerpc/boot/cuboot-warp.c
@@ -11,7 +11,6 @@
#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 ae68fefc01b6..5dd3d15f0feb 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-405ex", "ibm,plb-pciex";
+ compatible = "ibm,plb-pciex-405exr", "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 = <8000>;
- d-cache-size = <8000>;
+ i-cache-size = <20000>;
+ d-cache-size = <20000>;
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 9eed1f68fcab..13929771bee7 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_ext_sample(pc, regs, i, is_kernel);
+ oprofile_add_pc(pc, is_kernel, i);
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 4d5fd1dbd400..9aa4425d80b2 100644
--- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -199,7 +199,6 @@ 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 20ea0e118f24..edab631a8dcb 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(shift) (IO_SEGMENT_SHIFT - (shift))
+#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT)
/* The high bit needs to be set on every DMA address */
#define SPIDER_DMA_OFFSET 0x80000000ul
@@ -123,6 +123,7 @@ struct iommu_window {
struct cbe_iommu *iommu;
unsigned long offset;
unsigned long size;
+ unsigned long pte_offset;
unsigned int ioid;
struct iommu_table table;
};
@@ -199,7 +200,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 - tbl->it_offset);
+ io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
@@ -231,7 +232,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 - tbl->it_offset);
+ io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
for (i = 0; i < npages; i++)
io_pte[i] = pte;
@@ -306,84 +307,76 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base)
return -ENODEV;
}
-static void cell_iommu_setup_stab(struct cbe_iommu *iommu,
+static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu,
unsigned long dbase, unsigned long dsize,
unsigned long fbase, unsigned long fsize)
{
struct page *page;
- unsigned long segments, stab_size;
+ 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);
segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT;
+ pages_per_segment = 1ull << IO_PAGENO_BITS;
- pr_debug("%s: iommu[%d]: segments: %lu\n",
- __FUNCTION__, iommu->nid, segments);
+ pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n",
+ __FUNCTION__, iommu->nid, segments, pages_per_segment);
/* 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);
- 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));
+ clear_page(iommu->stab);
+ /* ... 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);
- ptab = page_address(page);
- memset(ptab, 0, ptab_size);
+ iommu->ptab = page_address(page);
+ memset(iommu->ptab, 0, ptab_size);
- /* number of 4K pages needed for a page table */
- n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12;
+ /* 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;
pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
- __FUNCTION__, iommu->nid, iommu->stab, ptab,
+ __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab,
n_pte_pages);
/* initialise the STEs */
reg = IOSTE_V | ((n_pte_pages - 1) << 5);
- 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();
+ 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();
}
- gap_base = gap_base >> IO_SEGMENT_SHIFT;
- gap_size = gap_size >> IO_SEGMENT_SHIFT;
-
pr_debug("Setting up IOMMU stab:\n");
- 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));
+ for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) {
+ iommu->stab[i] = reg |
+ (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
}
-
- return ptab;
}
static void cell_iommu_enable_hardware(struct cbe_iommu *iommu)
@@ -430,9 +423,7 @@ 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_stab(iommu, base, size, 0, 0);
- iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0,
- IOMMU_PAGE_SHIFT);
+ cell_iommu_setup_page_tables(iommu, base, size, 0, 0);
cell_iommu_enable_hardware(iommu);
}
@@ -473,7 +464,6 @@ 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);
@@ -485,11 +475,13 @@ 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) + pte_offset;
+ window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
+ window->pte_offset;
window->table.it_size = size >> IOMMU_PAGE_SHIFT;
iommu_init_table(&window->table, iommu->nid);
@@ -512,11 +504,6 @@ 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);
@@ -562,7 +549,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
archdata->dma_data = &window->table;
}
-static void cell_dma_dev_setup_fixed(struct device *dev);
+static void cell_dma_dev_setup_static(struct device *dev);
static void cell_dma_dev_setup(struct device *dev)
{
@@ -570,7 +557,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_fixed(dev);
+ cell_dma_dev_setup_static(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)
@@ -871,7 +858,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
return 0;
}
-static void cell_dma_dev_setup_fixed(struct device *dev)
+static void cell_dma_dev_setup_static(struct device *dev)
{
struct dev_archdata *archdata = &dev->archdata;
u64 addr;
@@ -882,45 +869,35 @@ static void cell_dma_dev_setup_fixed(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, ioaddr, *ptab;
-
- ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24);
+ unsigned long base_pte, uaddr, *io_pte;
+ int i;
dma_iommu_fixed_base = fbase;
+ /* 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;
+
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);
- for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
+ uaddr = 0;
+ for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) {
/* Don't touch the dynamic region */
- ioaddr = uaddr + fbase;
- if (ioaddr >= dbase && ioaddr < (dbase + dsize)) {
- pr_debug("iommu: fixed/dynamic overlap, skipping\n");
+ if (i >= dbase && i < (dbase + dsize)) {
+ pr_debug("iommu: static/dynamic overlap, skipping\n");
continue;
}
-
- insert_16M_pte(uaddr, ptab, base_pte);
+ io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
}
mb();
@@ -1018,9 +995,7 @@ 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_stab(iommu, dbase, dsize, fbase, fsize);
- iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0,
- IOMMU_PAGE_SHIFT);
+ cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
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 dda34650cb07..a7f609b3b876 100644
--- a/trunk/arch/powerpc/platforms/cell/setup.c
+++ b/trunk/arch/powerpc/platforms/cell/setup.c
@@ -149,11 +149,6 @@ 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
@@ -163,8 +158,6 @@ 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 712001f6b7da..87eb07f94c5f 100644
--- a/trunk/arch/powerpc/platforms/cell/spu_base.c
+++ b/trunk/arch/powerpc/platforms/cell/spu_base.c
@@ -81,12 +81,9 @@ 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);
@@ -151,11 +148,7 @@ 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);
}
@@ -297,11 +290,9 @@ 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);
@@ -346,14 +337,13 @@ 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);
-
- 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_SEGMENT_FAULT_INTR)
+ __spu_trap_data_seg(spu, dar);
+
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 cf6c2c89211d..133995ed5cc7 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/context.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c
@@ -109,12 +109,13 @@ 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, and we don't
- * want this context to be rescheduled on release.
+ * we don't acquire the state mutex interruptible.
*/
mutex_lock(&ctx->state_mutex);
- if (ctx->state != SPU_STATE_SAVED)
+ if (ctx->state != SPU_STATE_SAVED) {
+ set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
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 f7a7e8635fb6..c66c3756970d 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/file.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c
@@ -366,13 +366,6 @@ 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
@@ -382,7 +375,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
* hanged.
*/
if (spu_acquire(ctx))
- goto refault;
+ return NOPFN_REFAULT;
if (ctx->state == SPU_STATE_SAVED) {
up_read(¤t->mm->mmap_sem);
@@ -398,9 +391,6 @@ 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 5d5f680cd0b8..3a5972117de7 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_USER);
+ spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
}
/*
diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c b/trunk/arch/powerpc/platforms/cell/spufs/sputrace.c
index 79aa773f3c99..01974f7776e1 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 (ctxthread = %d, spu = %d)\n",
+ "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n",
(unsigned long) tv.tv_sec,
(unsigned long) tv.tv_nsec,
- t->curr_tid,
- t->name,
t->owner_tid,
+ t->name,
+ t->curr_tid,
t->number);
}
@@ -188,7 +188,6 @@ 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 e9dc7a55d1b9..6f5886c7b1f9 100644
--- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c
@@ -34,7 +34,6 @@
#include
#include
-#include
#include
#include
#include
@@ -118,8 +117,6 @@ 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) {
@@ -132,9 +129,6 @@ 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 ac82ac35b991..b2e292df13ca 100644
--- a/trunk/arch/powerpc/platforms/celleb/beat.h
+++ b/trunk/arch/powerpc/platforms/celleb/beat.h
@@ -21,6 +21,9 @@
#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 1831833c430e..b21444b681b6 100644
--- a/trunk/arch/s390/Kconfig
+++ b/trunk/arch/s390/Kconfig
@@ -61,7 +61,6 @@ config S390
def_bool y
select HAVE_OPROFILE
select HAVE_KPROBES
- select HAVE_KRETPROBES
source "init/Kconfig"
@@ -351,10 +350,6 @@ 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 62f6b5a606dd..39921f3a9685 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.25-rc4
-# Wed Mar 5 11:22:59 2008
+# Linux kernel version: 2.6.24
+# Sat Feb 9 12:13:01 2008
#
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
@@ -43,15 +43,12 @@ 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_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_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
@@ -88,9 +85,7 @@ 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
@@ -190,7 +185,6 @@ 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
@@ -441,7 +435,6 @@ 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
@@ -600,7 +593,6 @@ CONFIG_S390_VMUR=m
#
# Sonics Silicon Backplane
#
-# CONFIG_MEMSTICK is not set
#
# File systems
@@ -758,6 +750,7 @@ 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
@@ -766,7 +759,6 @@ CONFIG_DEBUG_BUGVERBOSE=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 4d3e38392cb1..b3b650a93c7c 100644
--- a/trunk/arch/s390/kernel/Makefile
+++ b/trunk/arch/s390/kernel/Makefile
@@ -4,11 +4,6 @@
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 01832c440636..9f7b73b180f0 100644
--- a/trunk/arch/s390/kernel/early.c
+++ b/trunk/arch/s390/kernel/early.c
@@ -88,17 +88,13 @@ static noinline __init void create_kernel_nss(void)
__cpcmd(defsys_cmd, NULL, 0, &response);
- if (response != 0) {
- kernel_nss_name[0] = '\0';
+ if (response != 0)
return;
- }
__cpcmd(savesys_cmd, NULL, 0, &response);
- if (response != strlen(savesys_cmd)) {
- kernel_nss_name[0] = '\0';
+ if (response != strlen(savesys_cmd))
return;
- }
ipl_flags = IPL_NSS_VALID;
}
diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c
index 375232c46c7a..60acdc266db1 100644
--- a/trunk/arch/s390/kernel/ipl.c
+++ b/trunk/arch/s390/kernel/ipl.c
@@ -704,7 +704,6 @@ 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 ce203154d8ce..1c59ec161cf8 100644
--- a/trunk/arch/s390/kernel/process.c
+++ b/trunk/arch/s390/kernel/process.c
@@ -152,10 +152,6 @@ 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 8f894d380a62..818bd09c0260 100644
--- a/trunk/arch/s390/kernel/smp.c
+++ b/trunk/arch/s390/kernel/smp.c
@@ -629,8 +629,14 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
panic_stack = __get_free_page(GFP_KERNEL);
if (!panic_stack || !async_stack)
goto out;
- memcpy(lowcore, &S390_lowcore, 512);
- memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
+ /*
+ * 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);
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 cb232c155360..76a5dd1b4ce9 100644
--- a/trunk/arch/s390/kernel/time.c
+++ b/trunk/arch/s390/kernel/time.c
@@ -209,6 +209,8 @@ 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 783cfbbf87ca..b3400b5ad5c6 100644
--- a/trunk/arch/sh/Kconfig
+++ b/trunk/arch/sh/Kconfig
@@ -330,7 +330,6 @@ 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 71ff3d6f26e2..5c3359756a92 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 ab77b0e0fa0e..b76a14f12ce2 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 e1284fc69361..0dac87b19624 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 = inb(GAPSPCI_BBA_CONFIG+where); break;
- case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
- case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
+ 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;
}
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: 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;
+ 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;
}
return PCIBIOS_SUCCESSFUL;
@@ -127,36 +127,36 @@ int __init gapspci_init(void)
*/
for (i=0; i<16; i++)
- idbuf[i] = inb(GAPSPCI_REGS+i);
+ idbuf[i] = ctrl_inb(GAPSPCI_REGS+i);
if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
return -ENODEV;
- outl(0x5a14a501, GAPSPCI_REGS+0x18);
+ ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18);
for (i=0; i<1000000; i++)
;
- if (inl(GAPSPCI_REGS+0x18) != 1)
+ if (ctrl_inl(GAPSPCI_REGS+0x18) != 1)
return -EINVAL;
- outl(0x01000000, GAPSPCI_REGS+0x20);
- outl(0x01000000, GAPSPCI_REGS+0x24);
+ ctrl_outl(0x01000000, GAPSPCI_REGS+0x20);
+ ctrl_outl(0x01000000, GAPSPCI_REGS+0x24);
- outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
- outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
+ ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
+ ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
- outl(1, GAPSPCI_REGS+0x14);
- outl(1, GAPSPCI_REGS+0x34);
+ ctrl_outl(1, GAPSPCI_REGS+0x14);
+ ctrl_outl(1, GAPSPCI_REGS+0x34);
/* Setting Broadband Adapter */
- 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);
+ 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);
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 cc530f4d84d6..b230eb278cef 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 fb781329848a..3feb95a4fcbc 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
-static const int pll1rate[]={8,12,16,0};
-static const int pfc_divisors[]={1,2,3,4,6,8,12};
+const static int pll1rate[]={8,12,16,0};
+const static 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 e98dc4450352..db6ef5cecde1 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 e6d4ec445dd8..a564425b905f 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 10f2a760c5ee..fcc80bb7bee7 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_REG);
+ ctrl_outl(CCR_CACHE_32KB, CCR3);
#else
- ctrl_outl(CCR_CACHE_16KB, CCR3_REG);
+ ctrl_outl(CCR_CACHE_16KB, CCR3);
#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 f581534cb732..dd0a20a685f7 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 d3733b13ea52..969804bb523b 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 = 21,
+ .start = 20,
.flags = IORESOURCE_IRQ,
},
[2] = {
- .start = 22,
+ .start = 21,
.flags = IORESOURCE_IRQ,
},
[3] = {
- .start = 20,
+ .start = 22,
.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 7406c9ad9259..0cc0e2bf135d 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 8028082527c5..3855ea4c21c8 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 7371abf64f80..dab193293f20 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 ec884039b914..ae3603aca615 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 254c5c55ab91..85f81579b97e 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 6d4f50cd4aaf..c0a3f079dfdc 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 f26b5cdad0d1..967e8b69a2f8 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 b98b4bc93ec9..73c778d40d13 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 07c988dc9de6..eabd5386812d 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 b9cec48b1808..32f4f59a837b 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 18dbbe23fea1..293004b526ff 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 621e7329ec63..74b60e96cdf4 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 bd35f32534b9..4dc958b6b314 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 bf1b15d3f6f5..e795f282dece 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,8 +12,7 @@ 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 una_asm.o muldiv.o semaphore.o \
- prom.o of_device.o devres.o
+ unaligned.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 e7a0edfc1a32..259a559d4cea 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.
*/
-static struct cpu_fp_info linux_sparc_fpu[] = {
+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 @@ static struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-static struct cpu_iu_info linux_sparc_chips[] = {
+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 96344ff2bbe1..d850785b2080 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(__func__);
+ panic(__FUNCTION__);
}
/* 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(__func__);
+ panic(__FUNCTION__);
}
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",
- __func__);
+ __FUNCTION__);
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 59e9344e7a0d..313d1620ae8e 100644
--- a/trunk/arch/sparc/kernel/led.c
+++ b/trunk/arch/sparc/kernel/led.c
@@ -3,9 +3,6 @@
#include
#include
#include
-#include
-#include
-#include
#include
diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c
index 70c0dd22491d..0bd69d0b5cd7 100644
--- a/trunk/arch/sparc/kernel/process.c
+++ b/trunk/arch/sparc/kernel/process.c
@@ -139,6 +139,8 @@ 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
deleted file mode 100644
index 8cc03458eb7e..000000000000
--- a/trunk/arch/sparc/kernel/una_asm.S
+++ /dev/null
@@ -1,153 +0,0 @@
-/* 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 33857be16661..a6330fbc9dd9 100644
--- a/trunk/arch/sparc/kernel/unaligned.c
+++ b/trunk/arch/sparc/kernel/unaligned.c
@@ -175,31 +175,157 @@ static void unaligned_panic(char *str)
panic(str);
}
-/* 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);
-}
+#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); \
+})
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;
@@ -216,7 +342,9 @@ static inline int ok_for_kernel(unsigned int insn)
return !floating_point_load_or_store_p(insn);
}
-static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int 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)
{
unsigned long g2 = regs->u_regs [UREG_G2];
unsigned long fixup = search_extables_range(regs->pc, &g2);
@@ -251,34 +379,48 @@ 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:
- err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
- regs),
- size, (unsigned long *) addr,
- decode_signedness(insn));
+ do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn),
+ kernel_unaligned_trap_fault);
break;
case store:
- err = do_int_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs);
+ do_integer_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs,
+ kernel_unaligned_trap_fault);
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... */
}
- if (err)
- kernel_mna_trap_fault(regs, insn);
- else
- advance(regs);
+ advance(regs);
}
}
@@ -317,7 +459,9 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
return 0;
}
-static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+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)
{
siginfo_t info;
@@ -341,7 +485,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 err, size = decode_access_size(insn);
+ int size = decode_access_size(insn);
unsigned long addr;
if(floating_point_load_or_store_p(insn)) {
@@ -352,34 +496,48 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
addr = compute_effective_address(regs, insn);
switch(dir) {
case load:
- err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
- regs),
- size, (unsigned long *) addr,
- decode_signedness(insn));
+ do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn),
+ user_unaligned_trap_fault);
break;
case store:
- err = do_int_store(((insn>>25)&0x1f), size,
- (unsigned long *) addr, regs);
+ do_integer_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs,
+ user_unaligned_trap_fault);
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");
- err = -EFAULT;
+ goto kill_user;
+#endif
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;
}
- if (err)
- goto kill_user;
- else
- advance(regs);
+ advance(regs);
goto out;
}
diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig
index 463d1be32c98..3af378ddb6ae 100644
--- a/trunk/arch/sparc64/Kconfig
+++ b/trunk/arch/sparc64/Kconfig
@@ -10,7 +10,6 @@ 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 dd5d28e3d798..e43db73f2b91 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;
};
-static struct cpu_fp_info linux_sparc_fpu[] = {
+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 @@ static struct cpu_fp_info linux_sparc_fpu[] = {
#define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
-static struct cpu_iu_info linux_sparc_chips[] = {
+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 bd76482077be..eeb5a2fc788d 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 __cpuinit dr_cpu_configure(struct ds_info *dp,
- struct ds_cap_state *cp,
- u64 req_num,
- cpumask_t *mask)
+static int 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 __cpuinit dr_cpu_data(struct ds_info *dp,
- struct ds_cap_state *cp,
- void *buf, int len)
+static void 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/mdesc.c b/trunk/arch/sparc64/kernel/mdesc.c
index 910083589569..856659bb1311 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 __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
+void __devinit mdesc_fill_in_cpu_data(cpumask_t mask)
{
struct mdesc_handle *hp = mdesc_grab();
u64 mp;
diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c
index e116e38b160e..2aafce7dfc0e 100644
--- a/trunk/arch/sparc64/kernel/process.c
+++ b/trunk/arch/sparc64/kernel/process.c
@@ -114,6 +114,8 @@ void cpu_idle(void)
}
}
+extern char reboot_command [];
+
void machine_halt(void)
{
sstate_halt();
diff --git a/trunk/arch/sparc64/mm/fault.c b/trunk/arch/sparc64/mm/fault.c
index 2650d0d33ac2..e2027f27c0fe 100644
--- a/trunk/arch/sparc64/mm/fault.c
+++ b/trunk/arch/sparc64/mm/fault.c
@@ -244,8 +244,16 @@ 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;
- entry = search_exception_tables(regs->tpc);
- if (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))) {
regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
return;
@@ -286,7 +294,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) __init_end) ||
+ if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
(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 b5c30416fdac..9e6bca266d88 100644
--- a/trunk/arch/sparc64/mm/init.c
+++ b/trunk/arch/sparc64/mm/init.c
@@ -1010,8 +1010,7 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata;
static int pall_ents __initdata;
#ifdef CONFIG_DEBUG_PAGEALLOC
-static unsigned long __ref kernel_map_range(unsigned long pstart,
- unsigned long pend, pgprot_t prot)
+static unsigned long 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 50e58232cf2b..5faf59a9de39 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__,__func__,(s))
+#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__FUNCTION__,(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 15234fcd191a..f53123c02c2b 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__,__func__,(m),(a));}while(0)
+ __FILE__,__LINE__,__FUNCTION__,(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 e8cb9ff183e9..fc50d2f959d1 100644
--- a/trunk/arch/um/kernel/process.c
+++ b/trunk/arch/um/kernel/process.c
@@ -128,6 +128,8 @@ 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 f41c9538ca30..4a88cf7695b4 100644
--- a/trunk/arch/x86/Kconfig
+++ b/trunk/arch/x86/Kconfig
@@ -21,8 +21,7 @@ config X86
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_KPROBES
- select HAVE_KRETPROBES
- select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
+ select HAVE_KVM
config GENERIC_LOCKBREAK
diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu
index 9304bfba7d45..e09a6b73a1aa 100644
--- a/trunk/arch/x86/Kconfig.cpu
+++ b/trunk/arch/x86/Kconfig.cpu
@@ -377,19 +377,6 @@ 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
@@ -403,7 +390,6 @@ 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 e77d89f9e8aa..378353956b5d 100644
--- a/trunk/arch/x86/boot/memory.c
+++ b/trunk/arch/x86/boot/memory.c
@@ -37,12 +37,6 @@ 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
@@ -53,6 +47,9 @@ 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 8ea040124f7d..a33d53017997 100644
--- a/trunk/arch/x86/kernel/asm-offsets_32.c
+++ b/trunk/arch/x86/kernel/asm-offsets_32.c
@@ -128,11 +128,13 @@ void foo(void)
OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending);
#endif
-#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE)
+#ifdef CONFIG_LGUEST_GUEST
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 a38aafaefc23..f86a3c4a2669 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 c2f930d86640..39f8cb18296c 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -55,6 +55,7 @@ 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;
@@ -94,10 +95,6 @@ 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;
@@ -106,8 +103,7 @@ 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 be83336fddba..b6e136f23d3d 100644
--- a/trunk/arch/x86/kernel/cpu/mtrr/main.c
+++ b/trunk/arch/x86/kernel/cpu/mtrr/main.c
@@ -43,7 +43,6 @@
#include
#include
#include
-#include
#include "mtrr.h"
u32 num_var_ranges = 0;
@@ -650,7 +649,6 @@ 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
@@ -690,11 +688,8 @@ 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) {
- if (!kvm_para_available()) {
- printk(KERN_WARNING
- "WARNING: strange, CPU MTRRs all blank?\n");
- WARN_ON(1);
- }
+ 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 e8b422c1c512..200fb3f9ebfb 100644
--- a/trunk/arch/x86/kernel/cpu/transmeta.c
+++ b/trunk/arch/x86/kernel/cpu/transmeta.c
@@ -76,6 +76,13 @@ 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 c20c9e7e08dd..2ad9a1bc6a73 100644
--- a/trunk/arch/x86/kernel/entry_64.S
+++ b/trunk/arch/x86/kernel/entry_64.S
@@ -453,7 +453,6 @@ 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)
@@ -1037,16 +1036,15 @@ 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, rcx: fake frame on the stack
+ * rdi: name, rsi: argv, rdx: envp, 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 fd8ca53943a8..25eb98540a41 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
-swapper_pg_pmd:
+ENTRY(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 a007454133a3..eb415043a929 100644
--- a/trunk/arch/x86/kernel/head_64.S
+++ b/trunk/arch/x86/kernel/head_64.S
@@ -379,24 +379,18 @@ NEXT_PAGE(level2_ident_pgt)
/* Since I easily can, map the first 1G.
* Don't set NX because code runs from these pages.
*/
- PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
+ PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD)
NEXT_PAGE(level2_kernel_pgt)
- /*
- * 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)
+ /* 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
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 235fd6c77504..429d084e014d 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;
}
-/**
- * hpet_enable - Try to setup the HPET timer. Returns 1 on success.
+/*
+ * Try to setup the HPET timer
*/
int __init hpet_enable(void)
{
diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c
index 60fe80157569..763dfc407232 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;
- init_fpu(target);
+ unlazy_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;
- init_fpu(target);
+ unlazy_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);
- init_fpu(target);
+ unlazy_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);
- init_fpu(target);
+ unlazy_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 3d01e47777db..5b3ce7934363 100644
--- a/trunk/arch/x86/kernel/init_task.c
+++ b/trunk/arch/x86/kernel/init_task.c
@@ -15,7 +15,6 @@ 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 be3c7a299f02..a7d50a547dc2 100644
--- a/trunk/arch/x86/kernel/process_32.c
+++ b/trunk/arch/x86/kernel/process_32.c
@@ -603,13 +603,11 @@ __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 3baf9b9f4c87..b0cc8f0136d8 100644
--- a/trunk/arch/x86/kernel/process_64.c
+++ b/trunk/arch/x86/kernel/process_64.c
@@ -604,13 +604,11 @@ 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
}
/*
@@ -732,16 +730,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, regs);
+ error = do_execve(filename, argv, envp, ®s);
putname(filename);
return error;
}
diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c
index f41fdc98efb1..d862e396b099 100644
--- a/trunk/arch/x86/kernel/ptrace.c
+++ b/trunk/arch/x86/kernel/ptrace.c
@@ -544,8 +544,6 @@ 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)
@@ -828,7 +826,6 @@ 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..
@@ -842,9 +839,7 @@ 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);
@@ -966,10 +961,6 @@ 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);
@@ -997,7 +988,6 @@ 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);
@@ -1236,14 +1226,12 @@ 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 7637dc91c79b..6fd804f07821 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 0880f2c388a9..d53bd6fcb428 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 c28c342c162f..02f0f61f5b11 100644
--- a/trunk/arch/x86/kernel/stacktrace.c
+++ b/trunk/arch/x86/kernel/stacktrace.c
@@ -25,8 +25,6 @@ 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;
@@ -39,8 +37,6 @@ 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 022bcaa3b42e..6dfd4e76661a 100644
--- a/trunk/arch/x86/kernel/tls.c
+++ b/trunk/arch/x86/kernel/tls.c
@@ -91,9 +91,7 @@ int do_set_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
{
- int ret = do_set_thread_area(current, -1, u_info, 1);
- prevent_tail_call(ret);
- return ret;
+ return do_set_thread_area(current, -1, u_info, 1);
}
@@ -141,9 +139,7 @@ int do_get_thread_area(struct task_struct *p, int idx,
asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
{
- int ret = do_get_thread_area(current, -1, u_info);
- prevent_tail_call(ret);
- return ret;
+ return do_get_thread_area(current, -1, u_info);
}
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 f14cfd9d1f94..43517e324be8 100644
--- a/trunk/arch/x86/kernel/tsc_32.c
+++ b/trunk/arch/x86/kernel/tsc_32.c
@@ -28,8 +28,7 @@ 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 completely.\n");
- mark_tsc_unstable("user disabled TSC");
+ "cannot disable TSC.\n");
return 1;
}
#else
diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c
index edff4c985485..3f8242774580 100644
--- a/trunk/arch/x86/kernel/vsyscall_64.c
+++ b/trunk/arch/x86/kernel/vsyscall_64.c
@@ -44,6 +44,11 @@
#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 :
@@ -97,7 +102,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("syscall"
+ asm volatile("vsysc2: syscall"
: "=a" (ret)
: "0" (__NR_gettimeofday),"D" (tv),"S" (tz)
: __syscall_clobber );
@@ -107,7 +112,7 @@ static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
static __always_inline long time_syscall(long *t)
{
long secs;
- asm volatile("syscall"
+ asm volatile("vsysc1: syscall"
: "=a" (secs)
: "0" (__NR_time),"D" (t) : __syscall_clobber);
return secs;
@@ -223,11 +228,42 @@ long __vsyscall(3) venosys_1(void)
#ifdef CONFIG_SYSCTL
-static int
-vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+#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)
{
- return proc_dointvec(ctl, write, filp, buffer, lenp, 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;
}
static ctl_table kernel_table2[] = {
@@ -243,6 +279,7 @@ 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 68a6b1511934..2cbee9479ce4 100644
--- a/trunk/arch/x86/kvm/lapic.c
+++ b/trunk/arch/x86/kvm/lapic.c
@@ -647,10 +647,6 @@ 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 d8172aabc660..8efdcdbebb03 100644
--- a/trunk/arch/x86/kvm/mmu.c
+++ b/trunk/arch/x86/kvm/mmu.c
@@ -681,7 +681,8 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
unsigned level,
int metaphysical,
unsigned access,
- u64 *parent_pte)
+ u64 *parent_pte,
+ bool *new_page)
{
union kvm_mmu_page_role role;
unsigned index;
@@ -721,6 +722,8 @@ 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;
}
@@ -873,18 +876,11 @@ 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;
-
- down_read(¤t->mm->mmap_sem);
- page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
- up_read(¤t->mm->mmap_sem);
-
- return page;
+ return gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
}
static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
@@ -1003,7 +999,8 @@ 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]);
+ 1, ACC_ALL, &table[index],
+ NULL);
if (!new_table) {
pgprintk("nonpaging_map: ENOMEM\n");
kvm_release_page_clean(page);
@@ -1023,18 +1020,15 @@ 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(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return r;
}
@@ -1096,7 +1090,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);
+ PT64_ROOT_LEVEL, 0, ACC_ALL, NULL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.root_hpa = root;
@@ -1117,7 +1111,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);
+ ACC_ALL, NULL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
@@ -1178,7 +1172,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->arch.cr3);
+ pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3);
mmu_free_roots(vcpu);
}
@@ -1368,7 +1362,6 @@ 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;
@@ -1396,11 +1389,6 @@ 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);
}
@@ -1508,9 +1496,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
gpa_t gpa;
int r;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
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 ecc0856268c4..03ba8608fe0f 100644
--- a/trunk/arch/x86/kvm/paging_tmpl.h
+++ b/trunk/arch/x86/kvm/paging_tmpl.h
@@ -91,10 +91,7 @@ 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);
@@ -143,7 +140,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
}
#endif
ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) ||
- (vcpu->arch.cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
+ (vcpu->cr3 & CR3_NONPAE_RESERVED_BITS) == 0);
pt_access = ACC_ALL;
@@ -300,6 +297,7 @@ 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)
@@ -321,8 +319,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);
- if (!metaphysical) {
+ shadow_ent, &new_page);
+ if (new_page && !metaphysical) {
int r;
pt_element_t curr_pte;
r = kvm_read_guest_atomic(vcpu->kvm,
@@ -380,7 +378,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
if (r)
return r;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
/*
* Look up the shadow pte for the faulting address.
*/
@@ -394,13 +392,11 @@ 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(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
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);
@@ -417,14 +413,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(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return 1;
}
++vcpu->stat.pf_fixed;
kvm_mmu_audit(vcpu, "post page fault (fixed)");
spin_unlock(&vcpu->kvm->mmu_lock);
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return write_pt;
}
diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c
index 1a582f1090e8..de755cb1431d 100644
--- a/trunk/arch/x86/kvm/svm.c
+++ b/trunk/arch/x86/kvm/svm.c
@@ -792,10 +792,6 @@ 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;
}
@@ -1100,24 +1096,6 @@ 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);
}
@@ -1178,10 +1156,6 @@ 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 94ea724638fd..ad36447e696e 100644
--- a/trunk/arch/x86/kvm/vmx.c
+++ b/trunk/arch/x86/kvm/vmx.c
@@ -638,7 +638,6 @@ 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)) {
@@ -1478,7 +1477,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
struct kvm_userspace_memory_region kvm_userspace_mem;
int r = 0;
- down_write(&kvm->slots_lock);
+ down_write(¤t->mm->mmap_sem);
if (kvm->arch.apic_access_page)
goto out;
kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT;
@@ -1488,12 +1487,9 @@ 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(&kvm->slots_lock);
+ up_write(¤t->mm->mmap_sem);
return r;
}
@@ -1606,6 +1602,9 @@ 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;
}
@@ -2535,9 +2534,6 @@ 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 6b01552bd1f1..cf5308148689 100644
--- a/trunk/arch/x86/kvm/x86.c
+++ b/trunk/arch/x86/kvm/x86.c
@@ -46,9 +46,6 @@
#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[] = {
@@ -184,7 +181,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
int ret;
u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
offset * sizeof(u64), sizeof(pdpte));
if (ret < 0) {
@@ -201,7 +198,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
out:
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return ret;
}
@@ -215,13 +212,13 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
if (is_long_mode(vcpu) || !is_pae(vcpu))
return false;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
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(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return changed;
}
@@ -359,7 +356,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
*/
}
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
/*
* Does the new cr3 value map to physical memory? (Note, we
* catch an invalid cr3 even in real-mode, because it would
@@ -375,7 +372,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
vcpu->arch.cr3 = cr3;
vcpu->arch.mmu.new_cr3(vcpu);
}
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
}
EXPORT_SYMBOL_GPL(set_cr3);
@@ -487,10 +484,6 @@ 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 */
@@ -533,7 +526,6 @@ 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:
@@ -735,24 +727,6 @@ 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;
}
@@ -1000,7 +974,8 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
put_cpu();
}
-static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
+static int kvm_vm_ioctl_get_supported_cpuid(struct kvm *kvm,
+ struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries)
{
struct kvm_cpuid_entry2 *cpuid_entries;
@@ -1232,12 +1207,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(&kvm->slots_lock);
+ down_write(¤t->mm->mmap_sem);
kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
- up_write(&kvm->slots_lock);
+ up_write(¤t->mm->mmap_sem);
return 0;
}
@@ -1286,7 +1261,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
< alias->target_phys_addr)
goto out;
- down_write(&kvm->slots_lock);
+ down_write(¤t->mm->mmap_sem);
p = &kvm->arch.aliases[alias->slot];
p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
@@ -1300,7 +1275,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
kvm_mmu_zap_all(kvm);
- up_write(&kvm->slots_lock);
+ up_write(¤t->mm->mmap_sem);
return 0;
@@ -1376,7 +1351,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_memory_slot *memslot;
int is_dirty = 0;
- down_write(&kvm->slots_lock);
+ down_write(¤t->mm->mmap_sem);
r = kvm_get_dirty_log(kvm, log, &is_dirty);
if (r)
@@ -1392,7 +1367,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
}
r = 0;
out:
- up_write(&kvm->slots_lock);
+ up_write(¤t->mm->mmap_sem);
return r;
}
@@ -1512,6 +1487,24 @@ 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:
;
}
@@ -1570,7 +1563,7 @@ int emulator_read_std(unsigned long addr,
void *data = val;
int r = X86EMUL_CONTINUE;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
while (bytes) {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
unsigned offset = addr & (PAGE_SIZE-1);
@@ -1592,7 +1585,7 @@ int emulator_read_std(unsigned long addr,
addr += tocopy;
}
out:
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return r;
}
EXPORT_SYMBOL_GPL(emulator_read_std);
@@ -1611,9 +1604,9 @@ static int emulator_read_emulated(unsigned long addr,
return X86EMUL_CONTINUE;
}
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
/* For APIC access vmexit */
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -1651,14 +1644,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
{
int ret;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
if (ret < 0) {
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return 0;
}
kvm_mmu_pte_write(vcpu, gpa, val, bytes);
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
return 1;
}
@@ -1670,9 +1663,9 @@ static int emulator_write_emulated_onepage(unsigned long addr,
struct kvm_io_device *mmio_dev;
gpa_t gpa;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
if (gpa == UNMAPPED_GVA) {
kvm_inject_page_fault(vcpu, addr, 2);
@@ -1749,7 +1742,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
char *kaddr;
u64 val;
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
if (gpa == UNMAPPED_GVA ||
@@ -1760,17 +1753,13 @@ 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(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
}
#endif
@@ -2163,10 +2152,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(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
page = gva_to_page(vcpu, address + i * PAGE_SIZE);
vcpu->arch.pio.guest_pages[i] = page;
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
if (!page) {
kvm_inject_gp(vcpu, 0);
free_pio_guest_pages(vcpu);
@@ -2489,9 +2478,8 @@ 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);
- up_read(¤t->mm->mmap_sem);
-
vcpu->arch.apic->vapic_page = page;
+ up_read(¤t->mm->mmap_sem);
}
static void vapic_exit(struct kvm_vcpu *vcpu)
@@ -2873,8 +2861,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;
- kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
vcpu->arch.cr0 = sregs->cr0;
+ kvm_x86_ops->set_cr0(vcpu, sregs->cr0);
mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
@@ -2964,9 +2952,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
gpa_t gpa;
vcpu_load(vcpu);
- down_read(&vcpu->kvm->slots_lock);
+ down_read(¤t->mm->mmap_sem);
gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
- up_read(&vcpu->kvm->slots_lock);
+ up_read(¤t->mm->mmap_sem);
tr->physical_address = gpa;
tr->valid = gpa != UNMAPPED_GVA;
tr->writeable = 1;
@@ -3239,13 +3227,11 @@ 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);
@@ -3253,10 +3239,8 @@ 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 cccb38a59653..5afdde4895dc 100644
--- a/trunk/arch/x86/lguest/boot.c
+++ b/trunk/arch/x86/lguest/boot.c
@@ -57,7 +57,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -76,6 +75,15 @@
* 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,
@@ -481,7 +489,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)), 0);
+ (__pa(pmdp)&(PAGE_SIZE-1))/4, 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 a02a14f0f324..bb652f5a93fb 100644
--- a/trunk/arch/x86/mm/init_64.c
+++ b/trunk/arch/x86/mm/init_64.c
@@ -172,9 +172,8 @@ 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 + size (== _end-_text)
+ * The head.S code sets up the kernel high mapping from:
+ * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE
*
* phys_addr holds the negative offset to the kernel, which is added
* to the compile time generated pmds. This results in invalid pmds up
@@ -516,6 +515,14 @@ 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 ac3c959e271d..882328efc3db 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)) {
- free_vm_area(area);
+ remove_vm_area((void *)(vaddr & PAGE_MASK));
return NULL;
}
diff --git a/trunk/arch/x86/mm/numa_64.c b/trunk/arch/x86/mm/numa_64.c
index 8ccfee10f5b5..59898fb0a4aa 100644
--- a/trunk/arch/x86/mm/numa_64.c
+++ b/trunk/arch/x86/mm/numa_64.c
@@ -622,17 +622,13 @@ 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;
- node = apicid_to_node[apicid];
- if (node == NUMA_NO_NODE)
+ if (apicid_to_node[apicid] == NUMA_NO_NODE)
continue;
- if (!node_online(node))
- continue;
- numa_set_node(i, node);
+ numa_set_node(i, apicid_to_node[apicid]);
}
}
diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c
index 14e48b5a94ba..464d8fc21ce6 100644
--- a/trunk/arch/x86/mm/pageattr.c
+++ b/trunk/arch/x86/mm/pageattr.c
@@ -44,12 +44,6 @@ 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)
{
@@ -361,48 +355,45 @@ 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;
+static unsigned long pool_used, pool_failed, pool_refill;
-static void cpa_fill_pool(struct page **ret)
+static void cpa_fill_pool(void)
{
- gfp_t gfp = GFP_KERNEL;
- unsigned long flags;
struct page *p;
+ gfp_t gfp = GFP_KERNEL;
+ /* Do not allocate from interrupt context */
+ if (in_irq() || irqs_disabled())
+ return;
/*
- * Avoid recursion (on debug-pagealloc) and also signal
- * our priority to get to these pagetables:
+ * Check unlocked. I does not matter when we have one more
+ * page in the pool. The bit lock avoids recursive pool
+ * allocations:
*/
- if (current->flags & PF_MEMALLOC)
+ if (pool_pages >= pool_size || test_and_set_bit_lock(0, &pool_refill))
return;
- current->flags |= PF_MEMALLOC;
+#ifdef CONFIG_DEBUG_PAGEALLOC
/*
- * Allocate atomically from atomic contexts:
+ * We could do:
+ * gfp = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+ * but this fails on !PREEMPT kernels
*/
- if (in_atomic() || irqs_disabled() || debug_pagealloc)
- gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
+ gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
+#endif
- while (pool_pages < pool_size || (ret && !*ret)) {
+ while (pool_pages < pool_size) {
p = alloc_pages(gfp, 0);
if (!p) {
pool_failed++;
break;
}
- /*
- * If the call site needs a page right now, provide it:
- */
- if (ret && !*ret) {
- *ret = p;
- continue;
- }
- spin_lock_irqsave(&pgd_lock, flags);
+ spin_lock_irq(&pgd_lock);
list_add(&p->lru, &page_pool);
pool_pages++;
- spin_unlock_irqrestore(&pgd_lock, flags);
+ spin_unlock_irq(&pgd_lock);
}
-
- current->flags &= ~PF_MEMALLOC;
+ clear_bit_unlock(0, &pool_refill);
}
#define SHIFT_MB (20 - PAGE_SHIFT)
@@ -423,15 +414,11 @@ void __init cpa_init(void)
* GiB. Shift MiB to Gib and multiply the result by
* POOL_PAGES_PER_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;
- }
+ gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB;
+ pool_size = POOL_PAGES_PER_GB * gb;
pool_low = pool_size;
- cpa_fill_pool(NULL);
+ cpa_fill_pool();
printk(KERN_DEBUG
"CPA: page pool initialized %lu of %lu pages preallocated\n",
pool_pages, pool_size);
@@ -453,20 +440,16 @@ 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);
- 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;
+ return -ENOMEM;
}
+ 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:
@@ -751,8 +734,7 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
cpa_flush_all(cache);
out:
- cpa_fill_pool(NULL);
-
+ cpa_fill_pool();
return ret;
}
@@ -915,7 +897,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(NULL);
+ cpa_fill_pool();
}
#ifdef CONFIG_HIBERNATION
diff --git a/trunk/arch/x86/vdso/Makefile b/trunk/arch/x86/vdso/Makefile
index 0a8f4742ef51..f385a4b4a484 100644
--- a/trunk/arch/x86/vdso/Makefile
+++ b/trunk/arch/x86/vdso/Makefile
@@ -50,9 +50,7 @@ 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 $@
-define cmd_vdsosym
- $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
-endef
+ cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@
$(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 8b9ee27805fd..49e5358f481a 100644
--- a/trunk/arch/x86/xen/enlighten.c
+++ b/trunk/arch/x86/xen/enlighten.c
@@ -153,7 +153,6 @@ 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 2341492bf7a0..3bad4773a2f3 100644
--- a/trunk/arch/x86/xen/setup.c
+++ b/trunk/arch/x86/xen/setup.c
@@ -38,8 +38,7 @@ char * __init xen_memory_setup(void)
unsigned long max_pfn = xen_start_info->nr_pages;
e820.nr_map = 0;
- add_memory_region(0, LOWMEMSIZE(), E820_RAM);
- add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM);
+ add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM);
return "Xen";
}
diff --git a/trunk/block/blk-barrier.c b/trunk/block/blk-barrier.c
index 55c5f1fc4f1f..6901eedeffce 100644
--- a/trunk/block/blk-barrier.c
+++ b/trunk/block/blk-barrier.c
@@ -259,11 +259,8 @@ 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 == -EOPNOTSUPP)
- set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
+ if (err)
clear_bit(BIO_UPTODATE, &bio->bi_flags);
- }
complete(bio->bi_private);
}
@@ -312,9 +309,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
*error_sector = bio->bi_sector;
ret = 0;
- if (bio_flagged(bio, BIO_EOPNOTSUPP))
- ret = -EOPNOTSUPP;
- else if (!bio_flagged(bio, BIO_UPTODATE))
+ 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 2a438a93f723..775c8516abf5 100644
--- a/trunk/block/blk-core.c
+++ b/trunk/block/blk-core.c
@@ -127,6 +127,7 @@ 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;
@@ -134,7 +135,6 @@ 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,6 +424,7 @@ 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)
{
@@ -591,6 +592,7 @@ 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)
{
@@ -1766,7 +1768,6 @@ 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)
{
@@ -1779,7 +1780,6 @@ 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,6 +2016,7 @@ 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 c07d9c8317f4..09f7fd0bcb73 100644
--- a/trunk/block/blk-map.c
+++ b/trunk/block/blk-map.c
@@ -19,6 +19,7 @@ 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;
@@ -43,7 +44,6 @@ 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;
- alignment = queue_dma_alignment(q) | q->dma_pad_mask;
- if (!(uaddr & alignment) && !(len & alignment))
+ if (!(uaddr & queue_dma_alignment(q)) &&
+ !(len & queue_dma_alignment(q)))
bio = bio_map_user(q, NULL, uaddr, len, reading);
else
bio = bio_copy_user(q, uaddr, len, reading);
@@ -142,22 +142,20 @@ 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 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.
+ * 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.
*
* On unmap, bio_uncopy_user() will use unmodified
* bio_map_data pointed to by bio->bi_private.
*/
- if (len & q->dma_pad_mask) {
- unsigned int pad_len = (q->dma_pad_mask & ~len) + 1;
- struct bio *tail = rq->biotail;
+ if (len & queue_dma_alignment(q)) {
+ unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1;
+ struct bio *bio = rq->biotail;
- tail->bi_io_vec[tail->bi_vcnt - 1].bv_len += pad_len;
- tail->bi_size += pad_len;
-
- rq->extra_len += pad_len;
+ bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len;
+ bio->bi_size += pad_len;
+ rq->data_len += pad_len;
}
rq->buffer = rq->data = NULL;
@@ -217,6 +215,7 @@ 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 0f58616bcd7f..7506c4fe0264 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->extra_len += q->dma_drain_size;
+ rq->data_len += q->dma_drain_size;
}
if (sg)
diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c
index 1344a0ea5cc6..9a8ffdd0ce3d 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
@@ -292,25 +292,9 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
}
EXPORT_SYMBOL(blk_queue_stack_limits);
-/**
- * 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
@@ -332,7 +316,7 @@ EXPORT_SYMBOL(blk_queue_dma_pad);
* device can support otherwise there won't be room for the drain
* buffer.
*/
-int blk_queue_dma_drain(struct request_queue *q,
+extern 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 4780a46ce234..a8c37d4bbb32 100644
--- a/trunk/block/blk-tag.c
+++ b/trunk/block/blk-tag.c
@@ -6,8 +6,6 @@
#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 ec9120fb789a..ec898dd0c65c 100644
--- a/trunk/block/blk.h
+++ b/trunk/block/blk.h
@@ -32,8 +32,6 @@ 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 8917c5174dc2..7f3c09549e4b 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->data_len;
- hdr->din_resid = rq->next_rq->data_len;
+ hdr->dout_resid = rq->raw_data_len;
+ hdr->din_resid = rq->next_rq->raw_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->data_len;
+ hdr->din_resid = rq->raw_data_len;
else
- hdr->dout_resid = rq->data_len;
+ hdr->dout_resid = rq->raw_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 c44527d16c52..53f2238e69c8 100644
--- a/trunk/block/genhd.c
+++ b/trunk/block/genhd.c
@@ -17,15 +17,11 @@
#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.
*
@@ -350,6 +346,8 @@ 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)
@@ -504,7 +502,7 @@ struct class block_class = {
.name = "block",
};
-static struct device_type disk_type = {
+struct device_type disk_type = {
.name = "disk",
.groups = disk_attr_groups,
.release = disk_release,
@@ -634,14 +632,12 @@ 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 a2c3a936ebf9..e993cac4911d 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->data_len;
+ hdr->resid = rq->raw_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 93d80a1c36f9..28a5fbc6aa1a 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', 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},
+ {'`', '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'},
};
unsigned int accent_table_size = 68;
diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c
index 8a49835bd0f8..1db93b619074 100644
--- a/trunk/drivers/ata/ahci.c
+++ b/trunk/drivers/ata/ahci.c
@@ -186,7 +186,6 @@ 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 */
@@ -256,7 +255,6 @@ 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);
@@ -296,8 +294,6 @@ 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,
@@ -429,7 +425,7 @@ static const struct ata_port_info ahci_port_info[] = {
/* board_ahci_sb600 */
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
- AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
+ AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
.link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
@@ -1180,14 +1176,6 @@ 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 4fbcce758b04..fbc24358ada0 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)");
-static int atapi_dmadir = 0;
+int atapi_dmadir = 0;
module_param(atapi_dmadir, int, 0444);
MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)");
@@ -6567,8 +6567,6 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
ata_lpm_enable(host);
rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
- if (rc == 0)
- host->dev->power.power_state = mesg;
return rc;
}
@@ -6587,7 +6585,6 @@ void ata_host_resume(struct ata_host *host)
{
ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
- host->dev->power.power_state = PMSG_ON;
/* reenable link pm */
ata_lpm_disable(host);
diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c
index 8f0e8f2bc628..0562b0a49f3b 100644
--- a/trunk/drivers/ata/libata-scsi.c
+++ b/trunk/drivers/ata/libata-scsi.c
@@ -862,10 +862,9 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
struct request_queue *q = sdev->request_queue;
void *buf;
- /* set the min alignment and padding */
+ /* set the min alignment */
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);
@@ -1695,17 +1694,12 @@ 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);
@@ -2479,9 +2473,6 @@ 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);
@@ -2499,8 +2490,6 @@ 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;
@@ -2539,7 +2528,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
}
qc->tf.command = ATA_CMD_PACKET;
- qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
+ qc->nbytes = scsi_bufflen(scmd);
/* check whether ATAPI DMA is safe */
if (!using_pio && ata_check_atapi_dma(qc))
@@ -2550,7 +2539,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->data_len, (unsigned int)63 * 1024);
+ nbytes = min(scmd->request->raw_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
@@ -2876,7 +2865,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) + scmd->request->extra_len;
+ qc->nbytes = scsi_bufflen(scmd);
/* 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 aa884f71a12a..6036dedfe377 100644
--- a/trunk/drivers/ata/libata.h
+++ b/trunk/drivers/ata/libata.h
@@ -56,6 +56,7 @@ 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_hpt366.c b/trunk/drivers/ata/pata_hpt366.c
index a742efa0da2b..0713872cf65c 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.2"
+#define DRV_VERSION "0.6.1"
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 &= ~(0xF8 << ATA_SHIFT_UDMA);
+ mask &= ~(0x07 << ATA_SHIFT_UDMA);
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
- mask &= ~(0xF0 << ATA_SHIFT_UDMA);
+ mask &= ~(0x0F << 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 9a10878b2ad8..68eb34929cec 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.11"
+#define DRV_VERSION "0.6.9"
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 &= ~(0xE0 << ATA_SHIFT_UDMA);
+ mask &= ~(0x1F << 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 &= ~(0xE0 << ATA_SHIFT_UDMA);
+ mask &= ~ (0x1F << 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 a589c0fa0dbb..9c523fbf529e 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 &= ~(0xE0 << ATA_SHIFT_UDMA);
+ mask &= ~(0x1F << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(adev, mask);
}
diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c
index 840d1c4a7850..69f651e0bc98 100644
--- a/trunk/drivers/ata/sata_svw.c
+++ b/trunk/drivers/ata/sata_svw.c
@@ -45,8 +45,6 @@
#include
#include
#include
-#include
-#include
#include
#ifdef CONFIG_PPC_OF
@@ -61,7 +59,6 @@ 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,
@@ -91,10 +88,8 @@ enum {
/* Port stride */
K2_SATA_PORT_OFFSET = 0x100,
- chip_svw4 = 0,
- chip_svw8 = 1,
- chip_svw42 = 2, /* bar 3 */
- chip_svw43 = 3, /* bar 5 */
+ board_svw4 = 0,
+ board_svw8 = 1,
};
static u8 k2_stat_check_status(struct ata_port *ap);
@@ -102,25 +97,10 @@ 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)
@@ -374,7 +354,7 @@ static const struct ata_port_operations k2_sata_ops = {
};
static const struct ata_port_info k2_port_info[] = {
- /* chip_svw4 */
+ /* board_svw4 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
@@ -383,7 +363,7 @@ static const struct ata_port_info k2_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
- /* chip_svw8 */
+ /* board_svw8 */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
@@ -393,24 +373,6 @@ 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)
@@ -440,7 +402,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, bar_pos;
+ int n_ports, i, rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -454,9 +416,6 @@ 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
@@ -469,23 +428,17 @@ 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, 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);
+ if (pci_resource_len(pdev, 5) == 0)
return -ENODEV;
- }
/* Request and iomap PCI regions */
- rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
host->iomap = pcim_iomap_table(pdev);
- mmio_base = host->iomap[bar_pos];
+ mmio_base = host->iomap[5];
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
@@ -530,13 +483,11 @@ 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), 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 },
+ { 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 },
{ }
};
diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c
index 7de543d1d0b4..9c0070b5bd3e 100644
--- a/trunk/drivers/base/core.c
+++ b/trunk/drivers/base/core.c
@@ -621,8 +621,7 @@ 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 (!glue_dir || !dev->class ||
- glue_dir->kset != &dev->class->class_dirs)
+ if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
return;
kobject_put(glue_dir);
@@ -771,10 +770,17 @@ 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 Done;
+ goto Error;
}
pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__);
@@ -837,9 +843,11 @@ 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 d887d5cb5bef..ee9d1c8db0d6 100644
--- a/trunk/drivers/base/power/main.c
+++ b/trunk/drivers/base/power/main.c
@@ -48,6 +48,7 @@
*/
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);
@@ -80,6 +81,28 @@ 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));
@@ -87,6 +110,7 @@ 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);
}
/**
@@ -206,8 +230,6 @@ 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);
@@ -223,8 +245,6 @@ static int resume_device(struct device *dev)
error = dev->class->resume(dev);
}
- up(&dev->sem);
-
TRACE_RESUME(error);
return error;
}
@@ -246,7 +266,7 @@ static void dpm_resume(void)
struct list_head *entry = dpm_off.next;
struct device *dev = to_device(entry);
- list_move_tail(entry, &dpm_active);
+ list_move_tail(entry, &dpm_locked);
mutex_unlock(&dpm_list_mtx);
resume_device(dev);
mutex_lock(&dpm_list_mtx);
@@ -254,6 +274,25 @@ 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
*
@@ -266,6 +305,7 @@ 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);
@@ -284,6 +324,7 @@ void device_resume(void)
{
might_sleep();
dpm_resume();
+ unlock_all_devices();
unregister_dropped_devices();
up_write(&pm_sleep_rwsem);
}
@@ -347,15 +388,18 @@ 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_move(&dev->power.entry, &dpm_off_irq);
+ if (list_empty(&dev->power.entry))
+ list_add(&dev->power.entry, &dpm_off_irq);
}
if (!error)
@@ -375,8 +419,6 @@ 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);
@@ -399,9 +441,6 @@ 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;
}
@@ -422,13 +461,13 @@ static int dpm_suspend(pm_message_t state)
int error = 0;
mutex_lock(&dpm_list_mtx);
- while (!list_empty(&dpm_active)) {
- struct list_head *entry = dpm_active.prev;
+ while (!list_empty(&dpm_locked)) {
+ struct list_head *entry = dpm_locked.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",
@@ -437,16 +476,50 @@ 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;
}
- if (!list_empty(&dev->power.entry))
- list_move(&dev->power.entry, &dpm_off);
+ mutex_lock(&dpm_list_mtx);
+ if (list_empty(&dev->power.entry))
+ list_add(&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
@@ -460,6 +533,7 @@ 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 40bca48abc12..f25e7c6b2d27 100644
--- a/trunk/drivers/base/transport_class.c
+++ b/trunk/drivers/base/transport_class.c
@@ -126,7 +126,9 @@ 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 55bd35c0f082..9715be3f2487 100644
--- a/trunk/drivers/block/cciss.c
+++ b/trunk/drivers/block/cciss.c
@@ -33,7 +33,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -132,6 +131,7 @@ 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,6 +174,8 @@ 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)
@@ -238,46 +240,24 @@ 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 void cciss_seq_show_header(struct seq_file *seq)
+static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
+ int length, int *eof, void *data)
{
- 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);
-
-#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;
+ 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 = h->ctlr;
/* prevent displaying bogus info during configuration
* or deconfiguration of a logical volume
@@ -285,155 +265,115 @@ static void *cciss_seq_start(struct seq_file *seq, loff_t *pos)
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
if (h->busy_configuring) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- return ERR_PTR(-EBUSY);
+ return -EBUSY;
}
h->busy_configuring = 1;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
- if (*pos == 0)
- cciss_seq_show_header(seq);
-
- 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;
+ 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;
- /* Only reset h->busy_configuring if we succeeded in setting
- * it during cciss_seq_start. */
- if (v == ERR_PTR(-EBUSY))
- return;
+ 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;
+ 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 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)
+static int
+cciss_proc_write(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
- 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;
+ unsigned char cmd[80];
+ int len;
+#ifdef CONFIG_CISS_SCSI_TAPE
+ ctlr_info_t *h = (ctlr_info_t *) data;
+ int rc;
#endif
- if (!buf || length > PAGE_SIZE - 1)
+ if (count > sizeof(cmd) - 1)
return -EINVAL;
-
- 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;
-
+ 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) {
rc = cciss_engage_scsi(h->ctlr);
if (rc != 0)
- err = -rc;
- else
- err = length;
- } else
-#endif /* CONFIG_CISS_SCSI_TAPE */
- err = -EINVAL;
+ return -rc;
+ return count;
+ }
/* might be nice to have "disengage" too, but it's not
safely possible. (only 1 module use count, lock issues.) */
-
-out:
- free_page((unsigned long)buffer);
- return err;
+# endif
+ return -EINVAL;
}
-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,
-};
-
+/*
+ * Get us a file in /proc/cciss that says something about each controller.
+ * Create /proc/cciss if it doesn't exist yet.
+ */
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;
- pde = proc_create(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
- S_IROTH, proc_cciss,
- &cciss_proc_fops);
- if (!pde)
- return;
+ if (!proc_cciss)
+ return;
+ }
- pde->data = hba[i];
+ 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;
}
#endif /* CONFIG_PROC_FS */
@@ -1401,6 +1341,7 @@ 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. */
@@ -3493,6 +3434,7 @@ 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 45ac09300eb3..55178e9973a0 100644
--- a/trunk/drivers/block/cciss_scsi.c
+++ b/trunk/drivers/block/cciss_scsi.c
@@ -1404,18 +1404,21 @@ cciss_engage_scsi(int ctlr)
}
static void
-cciss_seq_tape_report(struct seq_file *seq, int ctlr)
+cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len)
{
unsigned long flags;
+ int size;
+
+ *pos = *pos -1; *len = *len - 1; // cut off the last trailing newline
CPQ_TAPE_LOCK(ctlr, flags);
- seq_printf(seq,
+ size = sprintf(buffer + *len,
"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
@@ -1495,5 +1498,6 @@ 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 18feb1c7c33b..674cd66dcaba 100644
--- a/trunk/drivers/block/pktcdvd.c
+++ b/trunk/drivers/block/pktcdvd.c
@@ -849,8 +849,7 @@ static int pkt_flush_cache(struct pktcdvd_device *pd)
/*
* speed is given as the normal factor, e.g. 4 for 4x
*/
-static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd,
- unsigned write_speed, unsigned read_speed)
+static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsigned read_speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -1777,8 +1776,7 @@ static int pkt_get_track_info(struct pktcdvd_device *pd, __u16 track, __u8 type,
return pkt_generic_packet(pd, &cgc);
}
-static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd,
- long *last_written)
+static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written)
{
disc_information di;
track_information ti;
@@ -1815,7 +1813,7 @@ static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd,
/*
* write mode select package based on pd->settings
*/
-static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd)
+static int pkt_set_write_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
@@ -1974,7 +1972,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
return 1;
}
-static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd)
+static int pkt_probe_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
unsigned char buf[12];
@@ -2073,8 +2071,7 @@ static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd)
/*
* enable/disable write caching on drive
*/
-static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd,
- int set)
+static int pkt_write_caching(struct pktcdvd_device *pd, int set)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2119,8 +2116,7 @@ static int pkt_lock_door(struct pktcdvd_device *pd, int lockflag)
/*
* Returns drive maximum write speed
*/
-static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd,
- unsigned *write_speed)
+static int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned *write_speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2181,8 +2177,7 @@ static char us_clv_to_speed[16] = {
/*
* reads the maximum media speed from ATIP
*/
-static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd,
- unsigned *speed)
+static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
{
struct packet_command cgc;
struct request_sense sense;
@@ -2254,7 +2249,7 @@ static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd,
}
}
-static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd)
+static 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 12f5baea439b..db259e60289b 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.
*/
-static int check_for_audio_disc(struct cdrom_device_info * cdi,
- struct cdrom_device_ops * cdo)
+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 d2208dfe3f67..0aa419a61767 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', 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},
+ {'`', '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'},
};
unsigned int accent_table_size = 68;
diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c
index eba2883b630e..85d596a3c18c 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 d793e68b3e0d..ff35230058d3 100644
--- a/trunk/drivers/char/pcmcia/ipwireless/network.c
+++ b/trunk/drivers/char/pcmcia/ipwireless/network.c
@@ -377,16 +377,13 @@ 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 (channel_idx == IPW_CHANNEL_RAS
+ if (tty && 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 5c3142b6f1fc..78b151c4d20f 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 5ff83df67b44..c0e08c7bca2f 100644
--- a/trunk/drivers/char/specialix.c
+++ b/trunk/drivers/char/specialix.c
@@ -2109,6 +2109,7 @@ 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 9b58b894f823..367be9175061 100644
--- a/trunk/drivers/char/vt.c
+++ b/trunk/drivers/char/vt.c
@@ -702,7 +702,6 @@ 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 f577daedb630..dfea2bde162b 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.
- * @base_address: is the base address of the device
+ * buffer_icap_get_status: Get the contents of the status register.
+ * @parameter 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.
- * @base_address: contains the base address of the component.
- * @offset: The word offset from which the data should be read.
+ * 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.
*
* 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
- * @base_address: is the base address of the device
+ * buffer_icap_busy: Return true if the icap device is busy
+ * @parameter 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
- * @base_address: is the base address of the device
+ * buffer_icap_busy: Return true if the icap device is not busy
+ * @parameter 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.
- * @base_address: is the base address of the device
- * @data: The size in bytes.
+ * buffer_icap_set_size: Set the size register.
+ * @parameter base_address: is the base address of the device
+ * @parameter 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_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.
+ * 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.
*
* 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.
- * @base_address: contains the base address of the device.
- * @data: is the value to be written to the data register.
+ * 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.
*
* 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.
- * @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.
+ * 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.
*
* 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.
- * @drvdata: a pointer to the drvdata.
- * @offset: The storage buffer start address.
- * @count: The number of words (32 bit) to read from the
+ * 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
* 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.
- * @drvdata: a pointer to the drvdata.
- * @offset: The storage buffer start address.
- * @count: The number of words (32 bit) to read from the
+ * 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
* 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.
- * @drvdata: a pointer to the drvdata.
+ * buffer_icap_reset: Reset the logic of the icap device.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
- * @data: Kernel address of the partial bitstream.
- * @size: the size of the partial bitstream in 32 bit words.
+ * 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.
**/
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.
- * @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.
+ * 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.
**/
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 6f45dbd47125..0988314694a6 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.
- * @drvdata: a pointer to the drvdata.
- * @data: the 32-bit value to be written to the FIFO.
+ * 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.
*
* 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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_fifo_read: Read data from the Read FIFO.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
- * @data: the size of the following read transaction, in words.
+ * 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.
**/
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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_start_config: Initiate a configuration (write) to the device.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_start_readback: Initiate a readback from the device.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_busy: Return true if the ICAP is still processing a transaction.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_write_fifo_vacancy: Query the write fifo available space.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_read_fifo_occupancy: Query the read fifo available data.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
- * @frame_buffer: a pointer to the data to be written to the
+ * 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
* ICAP device.
- * @num_words: the number of words (32 bit) to write to the ICAP
+ * @parameter 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.
- * @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.
+ * 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.
*
* 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.
- * @drvdata: a pointer to the drvdata.
+ * buffer_icap_reset: Reset the logic of the icap device.
+ * @parameter 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.
- * @drvdata: a pointer to the drvdata.
+ * fifo_icap_flush_fifo: This function flushes the FIFOs in the device.
+ * @parameter 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 2284fa2a5a57..24f6aef0fd3c 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,7 +119,6 @@ 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;
@@ -200,14 +199,14 @@ static const struct config_registers v5_config_registers = {
};
/**
- * hwicap_command_desync - Send a DESYNC command to the ICAP port.
- * @drvdata: a pointer to the drvdata.
+ * hwicap_command_desync: Send a DESYNC command to the ICAP port.
+ * @parameter 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.
*/
-static int hwicap_command_desync(struct hwicap_drvdata *drvdata)
+int hwicap_command_desync(struct hwicap_drvdata *drvdata)
{
u32 buffer[4];
u32 index = 0;
@@ -229,18 +228,51 @@ static int hwicap_command_desync(struct hwicap_drvdata *drvdata)
}
/**
- * hwicap_get_configuration_register - Query a configuration register.
- * @drvdata: a pointer to the drvdata.
- * @reg: a constant which represents the configuration
+ * 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
* register value to be returned.
* Examples: XHI_IDCODE, XHI_FLR.
- * @reg_data: returns the value of the register.
+ * @parameter RegData: 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.
*/
-static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
- u32 reg, u32 *reg_data)
+int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
+ u32 reg, u32 *RegData)
{
int status;
u32 buffer[6];
@@ -268,14 +300,14 @@ static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
/*
* Read the configuration register
*/
- status = drvdata->config->get_configuration(drvdata, reg_data, 1);
+ status = drvdata->config->get_configuration(drvdata, RegData, 1);
if (status)
return status;
return 0;
}
-static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
+int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
{
int status;
u32 idcode;
@@ -312,7 +344,7 @@ static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
}
static ssize_t
-hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
ssize_t bytes_to_read = 0;
@@ -321,9 +353,8 @@ hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
u32 bytes_remaining;
int status;
- status = mutex_lock_interruptible(&drvdata->sem);
- if (status)
- return status;
+ if (down_interruptible(&drvdata->sem))
+ return -ERESTARTSYS;
if (drvdata->read_buffer_in_use) {
/* If there are leftover bytes in the buffer, just */
@@ -339,9 +370,8 @@ hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
goto error;
}
drvdata->read_buffer_in_use -= bytes_to_read;
- memmove(drvdata->read_buffer,
- drvdata->read_buffer + bytes_to_read,
- 4 - bytes_to_read);
+ memcpy(drvdata->read_buffer + bytes_to_read,
+ drvdata->read_buffer, 4 - bytes_to_read);
} else {
/* Get new data from the ICAP, and return was was requested. */
kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
@@ -384,20 +414,18 @@ hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
status = -EFAULT;
goto error;
}
- memcpy(drvdata->read_buffer,
- kbuf,
- bytes_remaining);
+ memcpy(kbuf, drvdata->read_buffer, bytes_remaining);
drvdata->read_buffer_in_use = bytes_remaining;
free_page((unsigned long)kbuf);
}
status = bytes_to_read;
error:
- mutex_unlock(&drvdata->sem);
+ up(&drvdata->sem);
return status;
}
static ssize_t
-hwicap_write(struct file *file, const char __user *buf,
+hwicap_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
@@ -407,9 +435,8 @@ hwicap_write(struct file *file, const char __user *buf,
ssize_t len;
ssize_t status;
- status = mutex_lock_interruptible(&drvdata->sem);
- if (status)
- return status;
+ if (down_interruptible(&drvdata->sem))
+ return -ERESTARTSYS;
left += drvdata->write_buffer_in_use;
@@ -438,7 +465,7 @@ hwicap_write(struct file *file, const char __user *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);
@@ -481,7 +508,7 @@ hwicap_write(struct file *file, const char __user *buf,
free_page((unsigned long)kbuf);
status = written;
error:
- mutex_unlock(&drvdata->sem);
+ up(&drvdata->sem);
return status;
}
@@ -492,9 +519,8 @@ static int hwicap_open(struct inode *inode, struct file *file)
drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
- status = mutex_lock_interruptible(&drvdata->sem);
- if (status)
- return status;
+ if (down_interruptible(&drvdata->sem))
+ return -ERESTARTSYS;
if (drvdata->is_open) {
status = -EBUSY;
@@ -513,7 +539,7 @@ static int hwicap_open(struct inode *inode, struct file *file)
drvdata->is_open = 1;
error:
- mutex_unlock(&drvdata->sem);
+ up(&drvdata->sem);
return status;
}
@@ -523,7 +549,8 @@ static int hwicap_release(struct inode *inode, struct file *file)
int i;
int status = 0;
- mutex_lock(&drvdata->sem);
+ if (down_interruptible(&drvdata->sem))
+ return -ERESTARTSYS;
if (drvdata->write_buffer_in_use) {
/* Flush write buffer. */
@@ -542,7 +569,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
error:
drvdata->is_open = 0;
- mutex_unlock(&drvdata->sem);
+ up(&drvdata->sem);
return status;
}
@@ -565,36 +592,31 @@ 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 = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
+ drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
if (!drvdata) {
dev_err(dev, "Couldn't allocate device private record\n");
- retval = -ENOMEM;
- goto failed0;
+ return -ENOMEM;
}
+ memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata));
dev_set_drvdata(dev, (void *)drvdata);
if (!regs_res) {
@@ -626,7 +648,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
drvdata->config = config;
drvdata->config_regs = config_regs;
- mutex_init(&drvdata->sem);
+ init_MUTEX(&drvdata->sem);
drvdata->is_open = 0;
dev_info(dev, "ioremap %lx to %p with size %x\n",
@@ -641,7 +663,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); */
- device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id);
+ class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME);
return 0; /* success */
failed3:
@@ -653,11 +675,6 @@ 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;
}
@@ -682,16 +699,14 @@ static int __devexit hwicap_remove(struct device *dev)
if (!drvdata)
return 0;
- device_destroy(icap_class, drvdata->devt);
+ class_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);
-
- mutex_lock(&icap_sem);
probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0;
- mutex_unlock(&icap_sem);
+
return 0; /* success */
}
@@ -806,29 +821,28 @@ static struct of_platform_driver hwicap_of_driver = {
};
/* Registration helpers to keep the number of #ifdefs to a minimum */
-static inline int __init hwicap_of_register(void)
+static inline int __devinit hwicap_of_register(void)
{
pr_debug("hwicap: calling of_register_platform_driver()\n");
return of_register_platform_driver(&hwicap_of_driver);
}
-static inline void __exit hwicap_of_unregister(void)
+static inline void __devexit hwicap_of_unregister(void)
{
of_unregister_platform_driver(&hwicap_of_driver);
}
#else /* CONFIG_OF */
/* CONFIG_OF not enabled; do nothing helpers */
-static inline int __init hwicap_of_register(void) { return 0; }
-static inline void __exit hwicap_of_unregister(void) { }
+static inline int __devinit hwicap_of_register(void) { return 0; }
+static inline void __devexit hwicap_of_unregister(void) { }
#endif /* CONFIG_OF */
-static int __init hwicap_module_init(void)
+static int __devinit 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);
@@ -869,7 +883,7 @@ static int __init hwicap_module_init(void)
return retval;
}
-static void __exit hwicap_module_cleanup(void)
+static void __devexit 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 405fee7e189b..ae771cac1629 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];
- 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;
+ u32 mem_start; /* phys. address of the control registers */
+ u32 mem_end; /* phys. address of the control registers */
+ u32 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 mutex sem;
+ struct semaphore 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.
- * @reg: is the address of the register to be read back.
+ * hwicap_type_1_read: Generates a Type 1 read packet header.
+ * @parameter: Register 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 reg)
+static inline u32 hwicap_type_1_read(u32 Register)
{
return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
- (reg << XHI_REGISTER_SHIFT) |
+ (Register << XHI_REGISTER_SHIFT) |
(XHI_OP_READ << XHI_OP_SHIFT);
}
/**
- * hwicap_type_1_write - Generates a Type 1 write packet header
- * @reg: is the address of the register to be read back.
+ * hwicap_type_1_write: Generates a Type 1 write packet header
+ * @parameter: Register is the address of the register to be read back.
**/
-static inline u32 hwicap_type_1_write(u32 reg)
+static inline u32 hwicap_type_1_write(u32 Register)
{
return (XHI_TYPE_1 << XHI_TYPE_SHIFT) |
- (reg << XHI_REGISTER_SHIFT) |
+ (Register << XHI_REGISTER_SHIFT) |
(XHI_OP_WRITE << XHI_OP_SHIFT);
}
diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c
index 85e2ba7fcfba..fea2d3ed9cbd 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;
-static int cn_already_initialized;
+int cn_already_initialized = 0;
/*
* 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 35a26a3e5f68..89a29cd93783 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 = -EINVAL;
+ ssize_t ret;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
- goto no_policy;
+ return -EINVAL;
if (lock_policy_rwsem_read(policy->cpu) < 0)
- goto fail;
+ return -EINVAL;
if (fattr->show)
ret = fattr->show(policy, buf);
@@ -685,9 +685,8 @@ 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;
}
@@ -696,13 +695,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 = -EINVAL;
+ ssize_t ret;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
- goto no_policy;
+ return -EINVAL;
if (lock_policy_rwsem_write(policy->cpu) < 0)
- goto fail;
+ return -EINVAL;
if (fattr->store)
ret = fattr->store(policy, buf, count);
@@ -710,9 +709,8 @@ 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;
}
@@ -1777,7 +1775,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static struct notifier_block __refdata cpufreq_cpu_notifier =
+static struct notifier_block __cpuinitdata 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 070421a5480e..1b8312b02006 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 __refdata =
+static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata =
{
.notifier_call = cpufreq_stat_cpu_callback,
};
diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig
index 27340a7b19dd..a703deffb795 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 || PPC
+ depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
depends on !HIGHMEM64G
help
DMA engines can do asynchronous data transfers without
@@ -37,23 +37,6 @@ 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 c8036d945902..b152cd84e123 100644
--- a/trunk/drivers/dma/Makefile
+++ b/trunk/drivers/dma/Makefile
@@ -3,4 +3,3 @@ 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
deleted file mode 100644
index cc9a68158d99..000000000000
--- a/trunk/drivers/dma/fsldma.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ba78c42121ba..000000000000
--- a/trunk/drivers/dma/fsldma.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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 4017d9e7acd2..dff38accc5c1 100644
--- a/trunk/drivers/dma/ioat_dma.c
+++ b/trunk/drivers/dma/ioat_dma.c
@@ -714,7 +714,6 @@ 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;
@@ -742,7 +741,6 @@ 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 a03462750b95..3e9719948a8e 100644
--- a/trunk/drivers/firewire/fw-card.c
+++ b/trunk/drivers/firewire/fw-card.c
@@ -18,7 +18,6 @@
#include
#include
-#include
#include
#include
#include
@@ -215,29 +214,17 @@ static void
fw_card_bm_work(struct work_struct *work)
{
struct fw_card *card = container_of(work, struct fw_card, work.work);
- struct fw_device *root_device;
- struct fw_node *root_node, *local_node;
+ struct fw_device *root;
struct bm_data bmd;
unsigned long flags;
int root_id, new_root_id, irm_id, gap_count, generation, grace;
int do_reset = 0;
spin_lock_irqsave(&card->lock, flags);
- local_node = card->local_node;
- root_node = card->root_node;
-
- if (local_node == NULL) {
- spin_unlock_irqrestore(&card->lock, flags);
- return;
- }
- fw_node_get(local_node);
- fw_node_get(root_node);
generation = card->generation;
- root_device = root_node->data;
- if (root_device)
- fw_device_get(root_device);
- root_id = root_node->node_id;
+ root = card->root_node->data;
+ root_id = card->root_node->node_id;
grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
if (card->bm_generation + 1 == generation ||
@@ -256,14 +243,14 @@ fw_card_bm_work(struct work_struct *work)
irm_id = card->irm_node->node_id;
if (!card->irm_node->link_on) {
- new_root_id = local_node->node_id;
+ new_root_id = card->local_node->node_id;
fw_notify("IRM has link off, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
}
bmd.lock.arg = cpu_to_be32(0x3f);
- bmd.lock.data = cpu_to_be32(local_node->node_id);
+ bmd.lock.data = cpu_to_be32(card->local_node->node_id);
spin_unlock_irqrestore(&card->lock, flags);
@@ -280,12 +267,12 @@ fw_card_bm_work(struct work_struct *work)
* Another bus reset happened. Just return,
* the BM work has been rescheduled.
*/
- goto out;
+ return;
}
if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f)
/* Somebody else is BM, let them do the work. */
- goto out;
+ return;
spin_lock_irqsave(&card->lock, flags);
if (bmd.rcode != RCODE_COMPLETE) {
@@ -295,7 +282,7 @@ fw_card_bm_work(struct work_struct *work)
* do a bus reset and pick the local node as
* root, and thus, IRM.
*/
- new_root_id = local_node->node_id;
+ new_root_id = card->local_node->node_id;
fw_notify("BM lock failed, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
@@ -308,7 +295,7 @@ fw_card_bm_work(struct work_struct *work)
*/
spin_unlock_irqrestore(&card->lock, flags);
schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10));
- goto out;
+ return;
}
/*
@@ -318,20 +305,20 @@ fw_card_bm_work(struct work_struct *work)
*/
card->bm_generation = generation;
- if (root_device == NULL) {
+ if (root == NULL) {
/*
* Either link_on is false, or we failed to read the
* config rom. In either case, pick another root.
*/
- new_root_id = local_node->node_id;
- } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) {
+ new_root_id = card->local_node->node_id;
+ } else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) {
/*
* If we haven't probed this device yet, bail out now
* and let's try again once that's done.
*/
spin_unlock_irqrestore(&card->lock, flags);
- goto out;
- } else if (root_device->config_rom[2] & BIB_CMC) {
+ return;
+ } else if (root->config_rom[2] & BIB_CMC) {
/*
* FIXME: I suppose we should set the cmstr bit in the
* STATE_CLEAR register of this node, as described in
@@ -345,7 +332,7 @@ fw_card_bm_work(struct work_struct *work)
* successfully read the config rom, but it's not
* cycle master capable.
*/
- new_root_id = local_node->node_id;
+ new_root_id = card->local_node->node_id;
}
pick_me:
@@ -354,8 +341,8 @@ fw_card_bm_work(struct work_struct *work)
* the typically much larger 1394b beta repeater delays though.
*/
if (!card->beta_repeaters_present &&
- root_node->max_hops < ARRAY_SIZE(gap_count_table))
- gap_count = gap_count_table[root_node->max_hops];
+ card->root_node->max_hops < ARRAY_SIZE(gap_count_table))
+ gap_count = gap_count_table[card->root_node->max_hops];
else
gap_count = 63;
@@ -377,11 +364,6 @@ fw_card_bm_work(struct work_struct *work)
fw_send_phy_config(card, new_root_id, generation, gap_count);
fw_core_initiate_bus_reset(card, 1);
}
- out:
- if (root_device)
- fw_device_put(root_device);
- fw_node_put(root_node);
- fw_node_put(local_node);
}
static void
@@ -399,7 +381,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
static atomic_t index = ATOMIC_INIT(-1);
kref_init(&card->kref);
- atomic_set(&card->device_count, 0);
card->index = atomic_inc_return(&index);
card->driver = driver;
card->device = device;
@@ -530,14 +511,8 @@ fw_core_remove_card(struct fw_card *card)
card->driver = &dummy_driver;
fw_destroy_nodes(card);
- /*
- * Wait for all device workqueue jobs to finish. Otherwise the
- * firewire-core module could be unloaded before the jobs ran.
- */
- while (atomic_read(&card->device_count) > 0)
- msleep(100);
+ flush_scheduled_work();
- cancel_delayed_work_sync(&card->work);
fw_flush_transactions(card);
del_timer_sync(&card->flush_timer);
diff --git a/trunk/drivers/firewire/fw-cdev.c b/trunk/drivers/firewire/fw-cdev.c
index 46bc197a047f..7e73cbaa4121 100644
--- a/trunk/drivers/firewire/fw-cdev.c
+++ b/trunk/drivers/firewire/fw-cdev.c
@@ -109,17 +109,15 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
struct client *client;
unsigned long flags;
- device = fw_device_get_by_devt(inode->i_rdev);
+ device = fw_device_from_devt(inode->i_rdev);
if (device == NULL)
return -ENODEV;
client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL) {
- fw_device_put(device);
+ if (client == NULL)
return -ENOMEM;
- }
- client->device = device;
+ client->device = fw_device_get(device);
INIT_LIST_HEAD(&client->event_list);
INIT_LIST_HEAD(&client->resource_list);
spin_lock_init(&client->lock);
@@ -646,10 +644,6 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
struct fw_cdev_create_iso_context *request = buffer;
struct fw_iso_context *context;
- /* We only support one context at this time. */
- if (client->iso_context != NULL)
- return -EBUSY;
-
if (request->channel > 63)
return -EINVAL;
@@ -796,9 +790,8 @@ static int ioctl_start_iso(struct client *client, void *buffer)
{
struct fw_cdev_start_iso *request = buffer;
- if (client->iso_context == NULL || request->handle != 0)
+ if (request->handle != 0)
return -EINVAL;
-
if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) {
if (request->tags == 0 || request->tags > 15)
return -EINVAL;
@@ -815,7 +808,7 @@ static int ioctl_stop_iso(struct client *client, void *buffer)
{
struct fw_cdev_stop_iso *request = buffer;
- if (client->iso_context == NULL || request->handle != 0)
+ if (request->handle != 0)
return -EINVAL;
return fw_iso_context_stop(client->iso_context);
diff --git a/trunk/drivers/firewire/fw-device.c b/trunk/drivers/firewire/fw-device.c
index 870125a3638e..de9066e69adf 100644
--- a/trunk/drivers/firewire/fw-device.c
+++ b/trunk/drivers/firewire/fw-device.c
@@ -150,10 +150,21 @@ struct bus_type fw_bus_type = {
};
EXPORT_SYMBOL(fw_bus_type);
+struct fw_device *fw_device_get(struct fw_device *device)
+{
+ get_device(&device->device);
+
+ return device;
+}
+
+void fw_device_put(struct fw_device *device)
+{
+ put_device(&device->device);
+}
+
static void fw_device_release(struct device *dev)
{
struct fw_device *device = fw_device(dev);
- struct fw_card *card = device->card;
unsigned long flags;
/*
@@ -165,9 +176,9 @@ static void fw_device_release(struct device *dev)
spin_unlock_irqrestore(&device->card->lock, flags);
fw_node_put(device->node);
+ fw_card_put(device->card);
kfree(device->config_rom);
kfree(device);
- atomic_dec(&card->device_count);
}
int fw_device_enable_phys_dma(struct fw_device *device)
@@ -347,9 +358,12 @@ static ssize_t
guid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct fw_device *device = fw_device(dev);
+ u64 guid;
+
+ guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4];
- return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n",
- device->config_rom[3], device->config_rom[4]);
+ return snprintf(buf, PAGE_SIZE, "0x%016llx\n",
+ (unsigned long long)guid);
}
static struct device_attribute fw_device_attributes[] = {
@@ -596,14 +610,12 @@ static DECLARE_RWSEM(idr_rwsem);
static DEFINE_IDR(fw_device_idr);
int fw_cdev_major;
-struct fw_device *fw_device_get_by_devt(dev_t devt)
+struct fw_device *fw_device_from_devt(dev_t devt)
{
struct fw_device *device;
down_read(&idr_rwsem);
device = idr_find(&fw_device_idr, MINOR(devt));
- if (device)
- fw_device_get(device);
up_read(&idr_rwsem);
return device;
@@ -615,14 +627,13 @@ static void fw_device_shutdown(struct work_struct *work)
container_of(work, struct fw_device, work.work);
int minor = MINOR(device->device.devt);
- fw_device_cdev_remove(device);
- device_for_each_child(&device->device, NULL, shutdown_unit);
- device_unregister(&device->device);
-
down_write(&idr_rwsem);
idr_remove(&fw_device_idr, minor);
up_write(&idr_rwsem);
- fw_device_put(device);
+
+ fw_device_cdev_remove(device);
+ device_for_each_child(&device->device, NULL, shutdown_unit);
+ device_unregister(&device->device);
}
static struct device_type fw_device_type = {
@@ -657,8 +668,7 @@ static void fw_device_init(struct work_struct *work)
*/
if (read_bus_info_block(device, device->generation) < 0) {
- if (device->config_rom_retries < MAX_RETRIES &&
- atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
+ if (device->config_rom_retries < MAX_RETRIES) {
device->config_rom_retries++;
schedule_delayed_work(&device->work, RETRY_DELAY);
} else {
@@ -672,13 +682,10 @@ static void fw_device_init(struct work_struct *work)
}
err = -ENOMEM;
-
- fw_device_get(device);
down_write(&idr_rwsem);
if (idr_pre_get(&fw_device_idr, GFP_KERNEL))
err = idr_get_new(&fw_device_idr, device, &minor);
up_write(&idr_rwsem);
-
if (err < 0)
goto error;
@@ -710,22 +717,13 @@ static void fw_device_init(struct work_struct *work)
*/
if (atomic_cmpxchg(&device->state,
FW_DEVICE_INITIALIZING,
- FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) {
+ FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN)
fw_device_shutdown(&device->work.work);
- } else {
- if (device->config_rom_retries)
- fw_notify("created device %s: GUID %08x%08x, S%d00, "
- "%d config ROM retries\n",
- device->device.bus_id,
- device->config_rom[3], device->config_rom[4],
- 1 << device->max_speed,
- device->config_rom_retries);
- else
- fw_notify("created device %s: GUID %08x%08x, S%d00\n",
- device->device.bus_id,
- device->config_rom[3], device->config_rom[4],
- 1 << device->max_speed);
- }
+ else
+ fw_notify("created new fw device %s "
+ "(%d config rom retries, S%d00)\n",
+ device->device.bus_id, device->config_rom_retries,
+ 1 << device->max_speed);
/*
* Reschedule the IRM work if we just finished reading the
@@ -743,9 +741,7 @@ static void fw_device_init(struct work_struct *work)
idr_remove(&fw_device_idr, minor);
up_write(&idr_rwsem);
error:
- fw_device_put(device); /* fw_device_idr's reference */
-
- put_device(&device->device); /* our reference */
+ put_device(&device->device);
}
static int update_unit(struct device *dev, void *data)
@@ -795,8 +791,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
*/
device_initialize(&device->device);
atomic_set(&device->state, FW_DEVICE_INITIALIZING);
- atomic_inc(&card->device_count);
- device->card = card;
+ device->card = fw_card_get(card);
device->node = fw_node_get(node);
device->node_id = node->node_id;
device->generation = card->generation;
diff --git a/trunk/drivers/firewire/fw-device.h b/trunk/drivers/firewire/fw-device.h
index 78ecd3991b7f..0854fe2bc110 100644
--- a/trunk/drivers/firewire/fw-device.h
+++ b/trunk/drivers/firewire/fw-device.h
@@ -76,26 +76,14 @@ fw_device_is_shutdown(struct fw_device *device)
return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN;
}
-static inline struct fw_device *
-fw_device_get(struct fw_device *device)
-{
- get_device(&device->device);
-
- return device;
-}
-
-static inline void
-fw_device_put(struct fw_device *device)
-{
- put_device(&device->device);
-}
-
-struct fw_device *fw_device_get_by_devt(dev_t devt);
+struct fw_device *fw_device_get(struct fw_device *device);
+void fw_device_put(struct fw_device *device);
int fw_device_enable_phys_dma(struct fw_device *device);
void fw_device_cdev_update(struct fw_device *device);
void fw_device_cdev_remove(struct fw_device *device);
+struct fw_device *fw_device_from_devt(dev_t devt);
extern int fw_cdev_major;
struct fw_unit {
diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c
index 03069a454c07..19ece9b6d742 100644
--- a/trunk/drivers/firewire/fw-sbp2.c
+++ b/trunk/drivers/firewire/fw-sbp2.c
@@ -28,15 +28,14 @@
* and many others.
*/
-#include
-#include
-#include
-#include
#include
-#include
#include
#include
+#include
+#include
#include
+#include
+#include
#include
#include
#include
@@ -48,9 +47,9 @@
#include
#include
-#include "fw-device.h"
-#include "fw-topology.h"
#include "fw-transaction.h"
+#include "fw-topology.h"
+#include "fw-device.h"
/*
* So far only bridges from Oxford Semiconductor are known to support
@@ -83,9 +82,6 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
* Avoids access beyond actual disk limits on devices with an off-by-one bug.
* Don't use this with devices which don't have this bug.
*
- * - delay inquiry
- * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
- *
* - override internal blacklist
* Instead of adding to the built-in blacklist, use only the workarounds
* specified in the module load parameter.
@@ -95,8 +91,6 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
#define SBP2_WORKAROUND_INQUIRY_36 0x2
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
-#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
-#define SBP2_INQUIRY_DELAY 12
#define SBP2_WORKAROUND_OVERRIDE 0x100
static int sbp2_param_workarounds;
@@ -106,7 +100,6 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
- ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
", or a combination)");
@@ -122,6 +115,7 @@ static const char sbp2_driver_name[] = "sbp2";
struct sbp2_logical_unit {
struct sbp2_target *tgt;
struct list_head link;
+ struct scsi_device *sdev;
struct fw_address_handler address_handler;
struct list_head orb_list;
@@ -138,8 +132,6 @@ struct sbp2_logical_unit {
int generation;
int retries;
struct delayed_work work;
- bool has_sdev;
- bool blocked;
};
/*
@@ -149,18 +141,16 @@ struct sbp2_logical_unit {
struct sbp2_target {
struct kref kref;
struct fw_unit *unit;
- const char *bus_id;
- struct list_head lu_list;
u64 management_agent_address;
int directory_id;
int node_id;
int address_high;
- unsigned int workarounds;
- unsigned int mgt_orb_timeout;
- int dont_block; /* counter for each logical unit */
- int blocked; /* ditto */
+ unsigned workarounds;
+ struct list_head lu_list;
+
+ unsigned int mgt_orb_timeout;
};
/*
@@ -170,7 +160,7 @@ struct sbp2_target {
*/
#define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */
#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
-#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
+#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
#define SBP2_ORB_NULL 0x80000000
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
@@ -307,7 +297,7 @@ struct sbp2_command_orb {
static const struct {
u32 firmware_revision;
u32 model;
- unsigned int workarounds;
+ unsigned workarounds;
} sbp2_workarounds_table[] = {
/* DViCO Momobay CX-1 with TSB42AA9 bridge */ {
.firmware_revision = 0x002800,
@@ -315,11 +305,6 @@ static const struct {
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
SBP2_WORKAROUND_MODE_SENSE_8,
},
- /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
- .firmware_revision = 0x002800,
- .model = 0x000000,
- .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
- },
/* Initio bridges, actually only needed for some older ones */ {
.firmware_revision = 0x000200,
.model = ~0,
@@ -516,9 +501,6 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
unsigned int timeout;
int retval = -ENOMEM;
- if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device))
- return 0;
-
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
if (orb == NULL)
return -ENOMEM;
@@ -571,20 +553,20 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
retval = -EIO;
if (sbp2_cancel_orbs(lu) == 0) {
- fw_error("%s: orb reply timed out, rcode=0x%02x\n",
- lu->tgt->bus_id, orb->base.rcode);
+ fw_error("orb reply timed out, rcode=0x%02x\n",
+ orb->base.rcode);
goto out;
}
if (orb->base.rcode != RCODE_COMPLETE) {
- fw_error("%s: management write failed, rcode 0x%02x\n",
- lu->tgt->bus_id, orb->base.rcode);
+ fw_error("management write failed, rcode 0x%02x\n",
+ orb->base.rcode);
goto out;
}
if (STATUS_GET_RESPONSE(orb->status) != 0 ||
STATUS_GET_SBP_STATUS(orb->status) != 0) {
- fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id,
+ fw_error("error status: %d:%d\n",
STATUS_GET_RESPONSE(orb->status),
STATUS_GET_SBP_STATUS(orb->status));
goto out;
@@ -608,158 +590,29 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
static void
complete_agent_reset_write(struct fw_card *card, int rcode,
- void *payload, size_t length, void *done)
+ void *payload, size_t length, void *data)
{
- complete(done);
-}
+ struct fw_transaction *t = data;
-static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
-{
- struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- DECLARE_COMPLETION_ONSTACK(done);
- struct fw_transaction t;
- static u32 z;
-
- fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
- lu->tgt->node_id, lu->generation, device->max_speed,
- lu->command_block_agent_address + SBP2_AGENT_RESET,
- &z, sizeof(z), complete_agent_reset_write, &done);
- wait_for_completion(&done);
-}
-
-static void
-complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
-{
- kfree(data);
+ kfree(t);
}
-static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
+static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_transaction *t;
- static u32 z;
+ static u32 zero;
- t = kmalloc(sizeof(*t), GFP_ATOMIC);
+ t = kzalloc(sizeof(*t), GFP_ATOMIC);
if (t == NULL)
- return;
+ return -ENOMEM;
fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
lu->command_block_agent_address + SBP2_AGENT_RESET,
- &z, sizeof(z), complete_agent_reset_write_no_wait, t);
-}
-
-static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
-{
- struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card;
- unsigned long flags;
-
- /* serialize with comparisons of lu->generation and card->generation */
- spin_lock_irqsave(&card->lock, flags);
- lu->generation = generation;
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
-{
- /*
- * We may access dont_block without taking card->lock here:
- * All callers of sbp2_allow_block() and all callers of sbp2_unblock()
- * are currently serialized against each other.
- * And a wrong result in sbp2_conditionally_block()'s access of
- * dont_block is rather harmless, it simply misses its first chance.
- */
- --lu->tgt->dont_block;
-}
-
-/*
- * Blocks lu->tgt if all of the following conditions are met:
- * - Login, INQUIRY, and high-level SCSI setup of all of the target's
- * logical units have been finished (indicated by dont_block == 0).
- * - lu->generation is stale.
- *
- * Note, scsi_block_requests() must be called while holding card->lock,
- * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to
- * unblock the target.
- */
-static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
-{
- struct sbp2_target *tgt = lu->tgt;
- struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
- struct Scsi_Host *shost =
- container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- if (!tgt->dont_block && !lu->blocked &&
- lu->generation != card->generation) {
- lu->blocked = true;
- if (++tgt->blocked == 1) {
- scsi_block_requests(shost);
- fw_notify("blocked %s\n", lu->tgt->bus_id);
- }
- }
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/*
- * Unblocks lu->tgt as soon as all its logical units can be unblocked.
- * Note, it is harmless to run scsi_unblock_requests() outside the
- * card->lock protected section. On the other hand, running it inside
- * the section might clash with shost->host_lock.
- */
-static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
-{
- struct sbp2_target *tgt = lu->tgt;
- struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
- struct Scsi_Host *shost =
- container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
- unsigned long flags;
- bool unblock = false;
-
- spin_lock_irqsave(&card->lock, flags);
- if (lu->blocked && lu->generation == card->generation) {
- lu->blocked = false;
- unblock = --tgt->blocked == 0;
- }
- spin_unlock_irqrestore(&card->lock, flags);
-
- if (unblock) {
- scsi_unblock_requests(shost);
- fw_notify("unblocked %s\n", lu->tgt->bus_id);
- }
-}
-
-/*
- * Prevents future blocking of tgt and unblocks it.
- * Note, it is harmless to run scsi_unblock_requests() outside the
- * card->lock protected section. On the other hand, running it inside
- * the section might clash with shost->host_lock.
- */
-static void sbp2_unblock(struct sbp2_target *tgt)
-{
- struct fw_card *card = fw_device(tgt->unit->device.parent)->card;
- struct Scsi_Host *shost =
- container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- ++tgt->dont_block;
- spin_unlock_irqrestore(&card->lock, flags);
+ &zero, sizeof(zero), complete_agent_reset_write, t);
- scsi_unblock_requests(shost);
-}
-
-static int sbp2_lun2int(u16 lun)
-{
- struct scsi_lun eight_bytes_lun;
-
- memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
- eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff;
- eight_bytes_lun.scsi_lun[1] = lun & 0xff;
-
- return scsilun_to_int(&eight_bytes_lun);
+ return 0;
}
static void sbp2_release_target(struct kref *kref)
@@ -768,31 +621,26 @@ static void sbp2_release_target(struct kref *kref)
struct sbp2_logical_unit *lu, *next;
struct Scsi_Host *shost =
container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
- struct scsi_device *sdev;
struct fw_device *device = fw_device(tgt->unit->device.parent);
- /* prevent deadlocks */
- sbp2_unblock(tgt);
-
list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
- sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun));
- if (sdev) {
- scsi_remove_device(sdev);
- scsi_device_put(sdev);
- }
- sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+ if (lu->sdev)
+ scsi_remove_device(lu->sdev);
+
+ if (!fw_device_is_shutdown(device))
+ sbp2_send_management_orb(lu, tgt->node_id,
+ lu->generation, SBP2_LOGOUT_REQUEST,
+ lu->login_id, NULL);
fw_core_remove_address_handler(&lu->address_handler);
list_del(&lu->link);
kfree(lu);
}
scsi_remove_host(shost);
- fw_notify("released %s\n", tgt->bus_id);
+ fw_notify("released %s\n", tgt->unit->device.bus_id);
put_device(&tgt->unit->device);
scsi_host_put(shost);
- fw_device_put(device);
}
static struct workqueue_struct *sbp2_wq;
@@ -818,42 +666,33 @@ static void sbp2_login(struct work_struct *work)
{
struct sbp2_logical_unit *lu =
container_of(work, struct sbp2_logical_unit, work.work);
- struct sbp2_target *tgt = lu->tgt;
- struct fw_device *device = fw_device(tgt->unit->device.parent);
- struct Scsi_Host *shost;
+ struct Scsi_Host *shost =
+ container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
struct scsi_device *sdev;
+ struct scsi_lun eight_bytes_lun;
+ struct fw_unit *unit = lu->tgt->unit;
+ struct fw_device *device = fw_device(unit->device.parent);
struct sbp2_login_response response;
int generation, node_id, local_node_id;
- if (fw_device_is_shutdown(device))
- goto out;
-
generation = device->generation;
smp_rmb(); /* node_id must not be older than generation */
node_id = device->node_id;
local_node_id = device->card->node_id;
- /* If this is a re-login attempt, log out, or we might be rejected. */
- if (lu->has_sdev)
- sbp2_send_management_orb(lu, device->node_id, generation,
- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
-
if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
- if (lu->retries++ < 5) {
+ if (lu->retries++ < 5)
sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
- } else {
- fw_error("%s: failed to login to LUN %04x\n",
- tgt->bus_id, lu->lun);
- /* Let any waiting I/O fail from now on. */
- sbp2_unblock(lu->tgt);
- }
+ else
+ fw_error("failed to login to %s LUN %04x\n",
+ unit->device.bus_id, lu->lun);
goto out;
}
- tgt->node_id = node_id;
- tgt->address_high = local_node_id << 16;
- sbp2_set_generation(lu, generation);
+ lu->generation = generation;
+ lu->tgt->node_id = node_id;
+ lu->tgt->address_high = local_node_id << 16;
/* Get command block agent offset and login id. */
lu->command_block_agent_address =
@@ -861,8 +700,8 @@ static void sbp2_login(struct work_struct *work)
response.command_block_agent.low;
lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
- fw_notify("%s: logged in to LUN %04x (%d retries)\n",
- tgt->bus_id, lu->lun, lu->retries);
+ fw_notify("logged in to %s LUN %04x (%d retries)\n",
+ unit->device.bus_id, lu->lun, lu->retries);
#if 0
/* FIXME: The linux1394 sbp2 does this last step. */
@@ -872,58 +711,26 @@ static void sbp2_login(struct work_struct *work)
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
sbp2_agent_reset(lu);
- /* This was a re-login. */
- if (lu->has_sdev) {
- sbp2_cancel_orbs(lu);
- sbp2_conditionally_unblock(lu);
- goto out;
- }
-
- if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
- ssleep(SBP2_INQUIRY_DELAY);
-
- shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
- sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu);
- /*
- * FIXME: We are unable to perform reconnects while in sbp2_login().
- * Therefore __scsi_add_device() will get into trouble if a bus reset
- * happens in parallel. It will either fail or leave us with an
- * unusable sdev. As a workaround we check for this and retry the
- * whole login and SCSI probing.
- */
-
- /* Reported error during __scsi_add_device() */
- if (IS_ERR(sdev))
- goto out_logout_login;
+ memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
+ eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
+ eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
- /* Unreported error during __scsi_add_device() */
- smp_rmb(); /* get current card generation */
- if (generation != device->card->generation) {
- scsi_remove_device(sdev);
+ sdev = __scsi_add_device(shost, 0, 0,
+ scsilun_to_int(&eight_bytes_lun), lu);
+ if (IS_ERR(sdev)) {
+ sbp2_send_management_orb(lu, node_id, generation,
+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+ /*
+ * Set this back to sbp2_login so we fall back and
+ * retry login on bus reset.
+ */
+ PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
+ } else {
+ lu->sdev = sdev;
scsi_device_put(sdev);
- goto out_logout_login;
}
-
- /* No error during __scsi_add_device() */
- lu->has_sdev = true;
- scsi_device_put(sdev);
- sbp2_allow_block(lu);
- goto out;
-
- out_logout_login:
- smp_rmb(); /* generation may have changed */
- generation = device->generation;
- smp_rmb(); /* node_id must not be older than generation */
-
- sbp2_send_management_orb(lu, device->node_id, generation,
- SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
- /*
- * If a bus reset happened, sbp2_update will have requeued
- * lu->work already. Reset the work from reconnect to login.
- */
- PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
out:
- sbp2_target_put(tgt);
+ sbp2_target_put(lu->tgt);
}
static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
@@ -944,12 +751,10 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
return -ENOMEM;
}
- lu->tgt = tgt;
- lu->lun = lun_entry & 0xffff;
- lu->retries = 0;
- lu->has_sdev = false;
- lu->blocked = false;
- ++tgt->dont_block;
+ lu->tgt = tgt;
+ lu->sdev = NULL;
+ lu->lun = lun_entry & 0xffff;
+ lu->retries = 0;
INIT_LIST_HEAD(&lu->orb_list);
INIT_DELAYED_WORK(&lu->work, sbp2_login);
@@ -1008,7 +813,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
if (timeout > tgt->mgt_orb_timeout)
fw_notify("%s: config rom contains %ds "
"management ORB timeout, limiting "
- "to %ds\n", tgt->bus_id,
+ "to %ds\n", tgt->unit->device.bus_id,
timeout / 1000,
tgt->mgt_orb_timeout / 1000);
break;
@@ -1031,12 +836,12 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
u32 firmware_revision)
{
int i;
- unsigned int w = sbp2_param_workarounds;
+ unsigned w = sbp2_param_workarounds;
if (w)
fw_notify("Please notify linux1394-devel@lists.sourceforge.net "
"if you need the workarounds parameter for %s\n",
- tgt->bus_id);
+ tgt->unit->device.bus_id);
if (w & SBP2_WORKAROUND_OVERRIDE)
goto out;
@@ -1058,7 +863,8 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
if (w)
fw_notify("Workarounds for %s: 0x%x "
"(firmware_revision 0x%06x, model_id 0x%06x)\n",
- tgt->bus_id, w, firmware_revision, model);
+ tgt->unit->device.bus_id,
+ w, firmware_revision, model);
tgt->workarounds = w;
}
@@ -1082,7 +888,6 @@ static int sbp2_probe(struct device *dev)
tgt->unit = unit;
kref_init(&tgt->kref);
INIT_LIST_HEAD(&tgt->lu_list);
- tgt->bus_id = unit->device.bus_id;
if (fw_device_enable_phys_dma(device) < 0)
goto fail_shost_put;
@@ -1090,8 +895,6 @@ static int sbp2_probe(struct device *dev)
if (scsi_add_host(shost, &unit->device) < 0)
goto fail_shost_put;
- fw_device_get(device);
-
/* Initialize to values that won't match anything in our table. */
firmware_revision = 0xff000000;
model = 0xff000000;
@@ -1135,13 +938,10 @@ static void sbp2_reconnect(struct work_struct *work)
{
struct sbp2_logical_unit *lu =
container_of(work, struct sbp2_logical_unit, work.work);
- struct sbp2_target *tgt = lu->tgt;
- struct fw_device *device = fw_device(tgt->unit->device.parent);
+ struct fw_unit *unit = lu->tgt->unit;
+ struct fw_device *device = fw_device(unit->device.parent);
int generation, node_id, local_node_id;
- if (fw_device_is_shutdown(device))
- goto out;
-
generation = device->generation;
smp_rmb(); /* node_id must not be older than generation */
node_id = device->node_id;
@@ -1150,17 +950,10 @@ static void sbp2_reconnect(struct work_struct *work)
if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_RECONNECT_REQUEST,
lu->login_id, NULL) < 0) {
- /*
- * If reconnect was impossible even though we are in the
- * current generation, fall back and try to log in again.
- *
- * We could check for "Function rejected" status, but
- * looking at the bus generation as simpler and more general.
- */
- smp_rmb(); /* get current card generation */
- if (generation == device->card->generation ||
- lu->retries++ >= 5) {
- fw_error("%s: failed to reconnect\n", tgt->bus_id);
+ if (lu->retries++ >= 5) {
+ fw_error("failed to reconnect to %s\n",
+ unit->device.bus_id);
+ /* Fall back and try to log in again. */
lu->retries = 0;
PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
}
@@ -1168,18 +961,17 @@ static void sbp2_reconnect(struct work_struct *work)
goto out;
}
- tgt->node_id = node_id;
- tgt->address_high = local_node_id << 16;
- sbp2_set_generation(lu, generation);
+ lu->generation = generation;
+ lu->tgt->node_id = node_id;
+ lu->tgt->address_high = local_node_id << 16;
- fw_notify("%s: reconnected to LUN %04x (%d retries)\n",
- tgt->bus_id, lu->lun, lu->retries);
+ fw_notify("reconnected to %s LUN %04x (%d retries)\n",
+ unit->device.bus_id, lu->lun, lu->retries);
sbp2_agent_reset(lu);
sbp2_cancel_orbs(lu);
- sbp2_conditionally_unblock(lu);
out:
- sbp2_target_put(tgt);
+ sbp2_target_put(lu->tgt);
}
static void sbp2_update(struct fw_unit *unit)
@@ -1194,7 +986,6 @@ static void sbp2_update(struct fw_unit *unit)
* Iteration over tgt->lu_list is therefore safe here.
*/
list_for_each_entry(lu, &tgt->lu_list, link) {
- sbp2_conditionally_block(lu);
lu->retries = 0;
sbp2_queue_work(lu, 0);
}
@@ -1272,7 +1063,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
if (status != NULL) {
if (STATUS_GET_DEAD(*status))
- sbp2_agent_reset_no_wait(orb->lu);
+ sbp2_agent_reset(orb->lu);
switch (STATUS_GET_RESPONSE(*status)) {
case SBP2_STATUS_REQUEST_COMPLETE:
@@ -1298,7 +1089,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
* or when sending the write (less likely).
*/
result = DID_BUS_BUSY << 16;
- sbp2_conditionally_block(orb->lu);
}
dma_unmap_single(device->card->device, orb->base.request_bus,
@@ -1407,7 +1197,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct sbp2_logical_unit *lu = cmd->device->hostdata;
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
- unsigned int max_payload;
+ unsigned max_payload;
int retval = SCSI_MLQUEUE_HOST_BUSY;
/*
@@ -1485,10 +1275,6 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
{
struct sbp2_logical_unit *lu = sdev->hostdata;
- /* (Re-)Adding logical units via the SCSI stack is not supported. */
- if (!lu)
- return -ENOSYS;
-
sdev->allow_restart = 1;
/*
@@ -1533,7 +1319,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
{
struct sbp2_logical_unit *lu = cmd->device->hostdata;
- fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id);
+ fw_notify("sbp2_scsi_abort\n");
sbp2_agent_reset(lu);
sbp2_cancel_orbs(lu);
diff --git a/trunk/drivers/firewire/fw-topology.c b/trunk/drivers/firewire/fw-topology.c
index e47bb040197a..172c1867e9aa 100644
--- a/trunk/drivers/firewire/fw-topology.c
+++ b/trunk/drivers/firewire/fw-topology.c
@@ -383,7 +383,6 @@ void fw_destroy_nodes(struct fw_card *card)
card->color++;
if (card->local_node != NULL)
for_each_fw_node(card, card->local_node, report_lost_node);
- card->local_node = NULL;
spin_unlock_irqrestore(&card->lock, flags);
}
diff --git a/trunk/drivers/firewire/fw-transaction.h b/trunk/drivers/firewire/fw-transaction.h
index 09cb72870454..fa7967b57408 100644
--- a/trunk/drivers/firewire/fw-transaction.h
+++ b/trunk/drivers/firewire/fw-transaction.h
@@ -26,7 +26,6 @@
#include
#include
#include