Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 May 2009 15:04:15 +0000 (08:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 May 2009 15:04:15 +0000 (08:04 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
  nilfs2: fix bh leak in nilfs_cpfile_delete_checkpoints function

184 files changed:
Documentation/input/multi-touch-protocol.txt
Documentation/kernel-parameters.txt
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/sound/alsa/Procfile.txt
MAINTAINERS
arch/arm/include/asm/assembler.h
arch/arm/include/asm/atomic.h
arch/arm/include/asm/flat.h
arch/arm/include/asm/system.h
arch/arm/kernel/elf.c
arch/arm/kernel/entry-armv.S
arch/arm/lib/bitops.h
arch/arm/mach-gemini/include/mach/hardware.h
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/ts219-setup.c
arch/arm/mach-loki/common.c
arch/arm/mach-mmp/include/mach/mfp-pxa168.h
arch/arm/mach-mmp/include/mach/mfp-pxa910.h
arch/arm/mach-mmp/include/mach/mfp.h
arch/arm/mach-mmp/time.c
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-pxa/ezx.c
arch/arm/mach-pxa/include/mach/reset.h
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmt5.c
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/reset.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/tosa.c
arch/arm/tools/mach-types
arch/blackfin/include/asm/.gitignore [deleted file]
arch/blackfin/include/asm/flat.h
arch/blackfin/include/asm/unistd.h
arch/blackfin/kernel/.gitignore [new file with mode: 0644]
arch/blackfin/lib/strncmp.c
arch/blackfin/mach-common/entry.S
arch/h8300/include/asm/flat.h
arch/m32r/include/asm/flat.h
arch/m68k/include/asm/flat.h
arch/powerpc/Kconfig
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/fixmap.h
arch/powerpc/include/asm/pgtable-ppc32.h
arch/powerpc/kernel/dma.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/dma-noncoherent.c [deleted file]
arch/powerpc/mm/Makefile
arch/powerpc/mm/dma-noncoherent.c [new file with mode: 0644]
arch/powerpc/mm/init_32.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/pgtable_32.c
arch/sh/include/asm/flat.h
arch/x86/boot/compressed/relocs.c
arch/x86/boot/memory.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
arch/x86/kernel/cpu/cpufreq/powernow-k7.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup_percpu.c
arch/x86/kvm/mmu.c
arch/x86/kvm/x86.c
arch/x86/mm/hugetlbpage.c
arch/x86/mm/pageattr.c
drivers/acpi/pci_bind.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_perflib.c
drivers/acpi/processor_throttling.c
drivers/acpi/video.c
drivers/base/bus.c
drivers/base/core.c
drivers/base/driver.c
drivers/base/power/main.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/dma/fsldma.c
drivers/dma/ioat_dma.c
drivers/edac/Kconfig
drivers/edac/Makefile
drivers/edac/amd8111_edac.c
drivers/edac/amd8131_edac.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_bios.h
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/idle/i7300_idle.c
drivers/input/input.c
drivers/input/serio/libps2.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/isdn/gigaset/isocdata.c
drivers/lguest/x86/core.c
drivers/md/bitmap.c
drivers/md/md.c
drivers/md/raid5.c
drivers/mtd/nand/mxc_nand.c
drivers/net/Makefile
drivers/net/gianfar.c
drivers/net/mac8390.c
drivers/net/r8169.c
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/airo.c
drivers/net/wireless/ath5k/phy.c
drivers/net/wireless/ath5k/reset.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/rt2x00/rt2x00debug.c
drivers/oprofile/cpu_buffer.c
drivers/parport/parport_gsc.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_glue.c
drivers/serial/8250.c
drivers/serial/8250_gsc.c
drivers/serial/mpc52xx_uart.c
drivers/usb/Makefile
drivers/usb/class/cdc-acm.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/serial/usb-serial.c
drivers/video/atmel_lcdfb.c
drivers/video/s3c-fb.c
fs/binfmt_flat.c
fs/cachefiles/internal.h
fs/fscache/internal.h
fs/jffs2/erase.c
fs/nfs/nfs4proc.c
fs/nfs/nfsroot.c
fs/nfsd/vfs.c
fs/proc/base.c
fs/sysfs/file.c
include/drm/drmP.h
include/linux/cred.h
include/linux/i7300_idle.h
include/linux/input.h
include/linux/swap.h
init/main.c
kernel/async.c
kernel/kexec.c
kernel/kmod.c
kernel/power/disk.c
kernel/power/main.c
mm/filemap.c
mm/hugetlb.c
mm/memcontrol.c
mm/oom_kill.c
mm/swap_state.c
mm/truncate.c
mm/vmscan.c
net/core/pktgen.c
net/ipv4/fib_trie.c
net/ipv4/route.c
net/ipv4/tcp_vegas.c
net/ipv6/route.c
net/rxrpc/ar-connection.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/verbs.c
net/wireless/reg.c
net/wireless/wext.c
security/tomoyo/tomoyo.c
sound/core/pcm_lib.c
sound/core/pcm_native.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/usb/usbaudio.c
sound/usb/usbaudio.h
sound/usb/usbmidi.c
sound/usb/usbquirks.h

index 9f09557aea39c5e80b6b9810ab170fddd32b1c91..a12ea3b586e6e15ecb66322c78bf5d6cb3e03f79 100644 (file)
@@ -18,8 +18,12 @@ Usage
 Anonymous finger details are sent sequentially as separate packets of ABS
 events. Only the ABS_MT events are recognized as part of a finger
 packet. The end of a packet is marked by calling the input_mt_sync()
-function, which generates a SYN_MT_REPORT event. The end of multi-touch
-transfer is marked by calling the usual input_sync() function.
+function, which generates a SYN_MT_REPORT event. This instructs the
+receiver to accept the data for the current finger and prepare to receive
+another. The end of a multi-touch transfer is marked by calling the usual
+input_sync() function. This instructs the receiver to act upon events
+accumulated since last EV_SYN/SYN_REPORT and prepare to receive a new
+set of events/packets.
 
 A set of ABS_MT events with the desired properties is defined. The events
 are divided into categories, to allow for partial implementation.  The
@@ -27,11 +31,26 @@ minimum set consists of ABS_MT_TOUCH_MAJOR, ABS_MT_POSITION_X and
 ABS_MT_POSITION_Y, which allows for multiple fingers to be tracked.  If the
 device supports it, the ABS_MT_WIDTH_MAJOR may be used to provide the size
 of the approaching finger. Anisotropy and direction may be specified with
-ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION. Devices with
-more granular information may specify general shapes as blobs, i.e., as a
-sequence of rectangular shapes grouped together by an
-ABS_MT_BLOB_ID. Finally, the ABS_MT_TOOL_TYPE may be used to specify
-whether the touching tool is a finger or a pen or something else.
+ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION.  The
+ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
+finger or a pen or something else.  Devices with more granular information
+may specify general shapes as blobs, i.e., as a sequence of rectangular
+shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices
+that currently support it, the ABS_MT_TRACKING_ID event may be used to
+report finger tracking from hardware [5].
+
+Here is what a minimal event sequence for a two-finger touch would look
+like:
+
+   ABS_MT_TOUCH_MAJOR
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   ABS_MT_TOUCH_MAJOR
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   SYN_REPORT
 
 
 Event Semantics
@@ -44,24 +63,24 @@ ABS_MT_TOUCH_MAJOR
 
 The length of the major axis of the contact. The length should be given in
 surface units. If the surface has an X times Y resolution, the largest
-possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal.
+possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal [4].
 
 ABS_MT_TOUCH_MINOR
 
 The length, in surface units, of the minor axis of the contact. If the
-contact is circular, this event can be omitted.
+contact is circular, this event can be omitted [4].
 
 ABS_MT_WIDTH_MAJOR
 
 The length, in surface units, of the major axis of the approaching
 tool. This should be understood as the size of the tool itself. The
 orientation of the contact and the approaching tool are assumed to be the
-same.
+same [4].
 
 ABS_MT_WIDTH_MINOR
 
 The length, in surface units, of the minor axis of the approaching
-tool. Omit if circular.
+tool. Omit if circular [4].
 
 The above four values can be used to derive additional information about
 the contact. The ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR approximates
@@ -70,14 +89,17 @@ different characteristic widths [1].
 
 ABS_MT_ORIENTATION
 
-The orientation of the ellipse. The value should describe half a revolution
-clockwise around the touch center. The scale of the value is arbitrary, but
-zero should be returned for an ellipse aligned along the Y axis of the
-surface. As an example, an index finger placed straight onto the axis could
-return zero orientation, something negative when twisted to the left, and
-something positive when twisted to the right. This value can be omitted if
-the touching object is circular, or if the information is not available in
-the kernel driver.
+The orientation of the ellipse. The value should describe a signed quarter
+of a revolution clockwise around the touch center. The signed value range
+is arbitrary, but zero should be returned for a finger aligned along the Y
+axis of the surface, a negative value when finger is turned to the left, and
+a positive value when finger turned to the right. When completely aligned with
+the X axis, the range max should be returned.  Orientation can be omitted
+if the touching object is circular, or if the information is not available
+in the kernel driver. Partial orientation support is possible if the device
+can distinguish between the two axis, but not (uniquely) any values in
+between. In such cases, the range of ABS_MT_ORIENTATION should be [0, 1]
+[4].
 
 ABS_MT_POSITION_X
 
@@ -98,8 +120,35 @@ ABS_MT_BLOB_ID
 
 The BLOB_ID groups several packets together into one arbitrarily shaped
 contact. This is a low-level anonymous grouping, and should not be confused
-with the high-level contactID, explained below. Most kernel drivers will
-not have this capability, and can safely omit the event.
+with the high-level trackingID [5]. Most kernel drivers will not have blob
+capability, and can safely omit the event.
+
+ABS_MT_TRACKING_ID
+
+The TRACKING_ID identifies an initiated contact throughout its life cycle
+[5]. There are currently only a few devices that support it, so this event
+should normally be omitted.
+
+
+Event Computation
+-----------------
+
+The flora of different hardware unavoidably leads to some devices fitting
+better to the MT protocol than others. To simplify and unify the mapping,
+this section gives recipes for how to compute certain events.
+
+For devices reporting contacts as rectangular shapes, signed orientation
+cannot be obtained. Assuming X and Y are the lengths of the sides of the
+touching rectangle, here is a simple formula that retains the most
+information possible:
+
+   ABS_MT_TOUCH_MAJOR := max(X, Y)
+   ABS_MT_TOUCH_MINOR := min(X, Y)
+   ABS_MT_ORIENTATION := bool(X > Y)
+
+The range of ABS_MT_ORIENTATION should be set to [0, 1], to indicate that
+the device can distinguish between a finger along the Y axis (0) and a
+finger along the X axis (1).
 
 
 Finger Tracking
@@ -109,14 +158,18 @@ The kernel driver should generate an arbitrary enumeration of the set of
 anonymous contacts currently on the surface. The order in which the packets
 appear in the event stream is not important.
 
-The process of finger tracking, i.e., to assign a unique contactID to each
+The process of finger tracking, i.e., to assign a unique trackingID to each
 initiated contact on the surface, is left to user space; preferably the
-multi-touch X driver [3]. In that driver, the contactID stays the same and
+multi-touch X driver [3]. In that driver, the trackingID stays the same and
 unique until the contact vanishes (when the finger leaves the surface). The
 problem of assigning a set of anonymous fingers to a set of identified
 fingers is a euclidian bipartite matching problem at each event update, and
 relies on a sufficiently rapid update rate.
 
+There are a few devices that support trackingID in hardware. User space can
+make use of these native identifiers to reduce bandwidth and cpu usage.
+
+
 Notes
 -----
 
@@ -136,5 +189,7 @@ could be used to derive tilt.
 time of writing (April 2009), the MT protocol is not yet merged, and the
 prototype implements finger matching, basic mouse support and two-finger
 scrolling. The project aims at improving the quality of current multi-touch
-functionality available in the synaptics X driver, and in addition
+functionality available in the Synaptics X driver, and in addition
 implement more advanced gestures.
+[4] See the section on event computation.
+[5] See the section on finger tracking.
index e87bdbfbcc75e236124a526d4456ddf3c6afc4e3..fd5cac013037defc68c3ef118ed70b476debee71 100644 (file)
@@ -1535,6 +1535,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        register save and restore. The kernel will only save
                        legacy floating-point registers on task switch.
 
+       noxsave         [BUGS=X86] Disables x86 extended register state save
+                       and restore using xsave. The kernel will fallback to
+                       enabling legacy floating-point and sse state.
+
        nohlt           [BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
                        wfi(ARM) instruction doesn't work correctly and not to
                        use it. This is also useful when using JTAG debugger.
index 8eec05bc079ebfcc0af9e030ceee652e0a9bf024..322869fc8a9e867e3b21073d64378c82c6e8aad7 100644 (file)
@@ -334,6 +334,7 @@ STAC9227/9228/9229/927x
   ref-no-jd    Reference board without HP/Mic jack detection
   3stack       D965 3stack
   5stack       D965 5stack + SPDIF
+  5stack-no-fp D965 5stack without front panel
   dell-3stack  Dell Dimension E520
   dell-bios    Fixes with Dell BIOS setup
   auto         BIOS setup (default)
index bba2dbb79d81c10d71bbc5b0879f6d3745d1543d..cfac20cf9e33fa150a6cf69f4e6d624e8116caa9 100644 (file)
@@ -104,6 +104,11 @@ card*/pcm*/xrun_debug
        When this value is greater than 1, the driver will show the
        stack trace additionally.  This may help the debugging.
 
+       Since 2.6.30, this option also enables the hwptr check using
+       jiffies.  This detects spontaneous invalid pointer callback
+       values, but can be lead to too much corrections for a (mostly
+       buggy) hardware that doesn't give smooth pointer updates.
+
 card*/pcm*/sub*/info
        The general information of this PCM sub-stream.
 
index 77cbfb1a696c7c676d0b1526b05155674d4b3cd7..873ca1fce020ba28d370d456683e544a87a04c38 100644 (file)
@@ -434,7 +434,7 @@ F:  arch/alpha/
 
 AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
 P:     Thomas Dahlmann
-M:     thomas.dahlmann@amd.com
+M:     dahlmann.thomas@arcor.de
 L:     linux-geode@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/usb/gadget/amd5536udc.*
@@ -624,6 +624,7 @@ M:  paulius.zaleckas@teltonika.lt
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 T:     git git://gitorious.org/linux-gemini/mainline.git
 S:     Maintained
+F:     arch/arm/mach-gemini/
 
 ARM/EBSA110 MACHINE SUPPORT
 P:     Russell King
@@ -650,6 +651,7 @@ P:  Paulius Zaleckas
 M:     paulius.zaleckas@teltonika.lt
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
+F:     arch/arm/mm/*-fa*
 
 ARM/FOOTBRIDGE ARCHITECTURE
 P:     Russell King
@@ -1132,17 +1134,17 @@ F:      fs/bfs/
 F:     include/linux/bfs_fs.h
 
 BLACKFIN ARCHITECTURE
-P:     Bryan Wu
-M:     cooloney@kernel.org
+P:     Mike Frysinger
+M:     vapier@gentoo.org
 L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org
 S:     Supported
 F:     arch/blackfin/
 
 BLACKFIN EMAC DRIVER
-P:     Bryan Wu
-M:     cooloney@kernel.org
-L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+P:     Michael Hennerich
+M:     michael.hennerich@analog.com
+L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org
 S:     Supported
 F:     drivers/net/bfin_mac.*
@@ -1150,7 +1152,7 @@ F:        drivers/net/bfin_mac.*
 BLACKFIN RTC DRIVER
 P:     Mike Frysinger
 M:     vapier.adi@gmail.com
-L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org
 S:     Supported
 F:     drivers/rtc/rtc-bfin.c
@@ -1158,7 +1160,7 @@ F:        drivers/rtc/rtc-bfin.c
 BLACKFIN SERIAL DRIVER
 P:     Sonic Zhang
 M:     sonic.zhang@analog.com
-L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org
 S:     Supported
 F:     drivers/serial/bfin_5xx.c
@@ -1166,7 +1168,7 @@ F:        drivers/serial/bfin_5xx.c
 BLACKFIN WATCHDOG DRIVER
 P:     Mike Frysinger
 M:     vapier.adi@gmail.com
-L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org
 S:     Supported
 F:     drivers/watchdog/bfin_wdt.c
@@ -1174,7 +1176,7 @@ F:        drivers/watchdog/bfin_wdt.c
 BLACKFIN I2C TWI DRIVER
 P:     Sonic Zhang
 M:     sonic.zhang@analog.com
-L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+L:     uclinux-dist-devel@blackfin.uclinux.org
 W:     http://blackfin.uclinux.org/
 S:     Supported
 F:     drivers/i2c/busses/i2c-bfin-twi.c
@@ -1971,8 +1973,8 @@ F:        include/linux/edac.h
 
 EDAC-E752X
 P:     Mark Gross
-P:     Doug Thompson
 M:     mark.gross@intel.com
+P:     Doug Thompson
 M:     dougthompson@xmission.com
 L:     bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers)
 W:     bluesmoke.sourceforge.net
@@ -2249,7 +2251,7 @@ P:        Li Yang
 M:     leoli@freescale.com
 P:     Zhang Wei
 M:     zw@zh-kernel.org
-L:     linuxppc-embedded@ozlabs.org
+L:     linuxppc-dev@ozlabs.org
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 F:     drivers/dma/fsldma.*
index 6116e4893c0ade4bc478996a82c316ce5c99a64e..15f8a092b700acc82754f9f9011524b068cb0db8 100644 (file)
        .align  3;                              \
        .long   9999b,9001f;                    \
        .previous
+
+/*
+ * SMP data memory barrier
+ */
+       .macro  smp_dmb
+#ifdef CONFIG_SMP
+#if __LINUX_ARM_ARCH__ >= 7
+       dmb
+#elif __LINUX_ARM_ARCH__ == 6
+       mcr     p15, 0, r0, c7, c10, 5  @ dmb
+#endif
+#endif
+       .endm
index ee99723b3a6c4899283a76ba26c7140c08a146dd..16b52f397983f7ead8079769a772265cab71657f 100644 (file)
@@ -44,11 +44,29 @@ static inline void atomic_set(atomic_t *v, int i)
        : "cc");
 }
 
+static inline void atomic_add(int i, atomic_t *v)
+{
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__("@ atomic_add\n"
+"1:    ldrex   %0, [%2]\n"
+"      add     %0, %0, %3\n"
+"      strex   %1, %0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter), "Ir" (i)
+       : "cc");
+}
+
 static inline int atomic_add_return(int i, atomic_t *v)
 {
        unsigned long tmp;
        int result;
 
+       smp_mb();
+
        __asm__ __volatile__("@ atomic_add_return\n"
 "1:    ldrex   %0, [%2]\n"
 "      add     %0, %0, %3\n"
@@ -59,14 +77,34 @@ static inline int atomic_add_return(int i, atomic_t *v)
        : "r" (&v->counter), "Ir" (i)
        : "cc");
 
+       smp_mb();
+
        return result;
 }
 
+static inline void atomic_sub(int i, atomic_t *v)
+{
+       unsigned long tmp;
+       int result;
+
+       __asm__ __volatile__("@ atomic_sub\n"
+"1:    ldrex   %0, [%2]\n"
+"      sub     %0, %0, %3\n"
+"      strex   %1, %0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter), "Ir" (i)
+       : "cc");
+}
+
 static inline int atomic_sub_return(int i, atomic_t *v)
 {
        unsigned long tmp;
        int result;
 
+       smp_mb();
+
        __asm__ __volatile__("@ atomic_sub_return\n"
 "1:    ldrex   %0, [%2]\n"
 "      sub     %0, %0, %3\n"
@@ -77,6 +115,8 @@ static inline int atomic_sub_return(int i, atomic_t *v)
        : "r" (&v->counter), "Ir" (i)
        : "cc");
 
+       smp_mb();
+
        return result;
 }
 
@@ -84,6 +124,8 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
 {
        unsigned long oldval, res;
 
+       smp_mb();
+
        do {
                __asm__ __volatile__("@ atomic_cmpxchg\n"
                "ldrex  %1, [%2]\n"
@@ -95,6 +137,8 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
                    : "cc");
        } while (res);
 
+       smp_mb();
+
        return oldval;
 }
 
@@ -135,6 +179,7 @@ static inline int atomic_add_return(int i, atomic_t *v)
 
        return val;
 }
+#define atomic_add(i, v)       (void) atomic_add_return(i, v)
 
 static inline int atomic_sub_return(int i, atomic_t *v)
 {
@@ -148,6 +193,7 @@ static inline int atomic_sub_return(int i, atomic_t *v)
 
        return val;
 }
+#define atomic_sub(i, v)       (void) atomic_sub_return(i, v)
 
 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
@@ -187,10 +233,8 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 }
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-#define atomic_add(i, v)       (void) atomic_add_return(i, v)
-#define atomic_inc(v)          (void) atomic_add_return(1, v)
-#define atomic_sub(i, v)       (void) atomic_sub_return(i, v)
-#define atomic_dec(v)          (void) atomic_sub_return(1, v)
+#define atomic_inc(v)          atomic_add(1, v)
+#define atomic_dec(v)          atomic_sub(1, v)
 
 #define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
 #define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
@@ -200,11 +244,10 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 
 #define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
 
-/* Atomic operations are already serializing on ARM */
-#define smp_mb__before_atomic_dec()    barrier()
-#define smp_mb__after_atomic_dec()     barrier()
-#define smp_mb__before_atomic_inc()    barrier()
-#define smp_mb__after_atomic_inc()     barrier()
+#define smp_mb__before_atomic_dec()    smp_mb()
+#define smp_mb__after_atomic_dec()     smp_mb()
+#define smp_mb__before_atomic_inc()    smp_mb()
+#define smp_mb__after_atomic_inc()     smp_mb()
 
 #include <asm-generic/atomic.h>
 #endif
index 1d77e51907f6ddb70f5aa8123583827bffaa676c..59426a4595c9cb90bcb765843f89295bd20f6797 100644 (file)
@@ -5,9 +5,6 @@
 #ifndef __ARM_FLAT_H__
 #define __ARM_FLAT_H__
 
-/* An odd number of words will be pushed after this alignment, so
-   deliberately misalign the value.  */
-#define        flat_stack_align(sp)    sp = (void *)(((unsigned long)(sp) - 4) | 4)
 #define        flat_argvp_envp_on_stack()              1
 #define        flat_old_ram_flag(flags)                (flags)
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
index bd4dc8ed53d59ebbfb1ac4d6fa547a93874278f7..d65b2f5bf41f60cfd21163ef0e5b92e76bc58db8 100644 (file)
@@ -248,6 +248,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
        unsigned int tmp;
 #endif
 
+       smp_mb();
+
        switch (size) {
 #if __LINUX_ARM_ARCH__ >= 6
        case 1:
@@ -307,6 +309,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
                __bad_xchg(ptr, size), ret = 0;
                break;
        }
+       smp_mb();
 
        return ret;
 }
@@ -316,6 +319,12 @@ extern void enable_hlt(void);
 
 #include <asm-generic/cmpxchg-local.h>
 
+#if __LINUX_ARM_ARCH__ < 6
+
+#ifdef CONFIG_SMP
+#error "SMP is not supported on this platform"
+#endif
+
 /*
  * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
  * them available.
@@ -329,6 +338,173 @@ extern void enable_hlt(void);
 #include <asm-generic/cmpxchg.h>
 #endif
 
+#else  /* __LINUX_ARM_ARCH__ >= 6 */
+
+extern void __bad_cmpxchg(volatile void *ptr, int size);
+
+/*
+ * cmpxchg only support 32-bits operands on ARMv6.
+ */
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+                                     unsigned long new, int size)
+{
+       unsigned long oldval, res;
+
+       switch (size) {
+#ifdef CONFIG_CPU_32v6K
+       case 1:
+               do {
+                       asm volatile("@ __cmpxchg1\n"
+                       "       ldrexb  %1, [%2]\n"
+                       "       mov     %0, #0\n"
+                       "       teq     %1, %3\n"
+                       "       strexbeq %0, %4, [%2]\n"
+                               : "=&r" (res), "=&r" (oldval)
+                               : "r" (ptr), "Ir" (old), "r" (new)
+                               : "memory", "cc");
+               } while (res);
+               break;
+       case 2:
+               do {
+                       asm volatile("@ __cmpxchg1\n"
+                       "       ldrexh  %1, [%2]\n"
+                       "       mov     %0, #0\n"
+                       "       teq     %1, %3\n"
+                       "       strexheq %0, %4, [%2]\n"
+                               : "=&r" (res), "=&r" (oldval)
+                               : "r" (ptr), "Ir" (old), "r" (new)
+                               : "memory", "cc");
+               } while (res);
+               break;
+#endif /* CONFIG_CPU_32v6K */
+       case 4:
+               do {
+                       asm volatile("@ __cmpxchg4\n"
+                       "       ldrex   %1, [%2]\n"
+                       "       mov     %0, #0\n"
+                       "       teq     %1, %3\n"
+                       "       strexeq %0, %4, [%2]\n"
+                               : "=&r" (res), "=&r" (oldval)
+                               : "r" (ptr), "Ir" (old), "r" (new)
+                               : "memory", "cc");
+               } while (res);
+               break;
+       default:
+               __bad_cmpxchg(ptr, size);
+               oldval = 0;
+       }
+
+       return oldval;
+}
+
+static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
+                                        unsigned long new, int size)
+{
+       unsigned long ret;
+
+       smp_mb();
+       ret = __cmpxchg(ptr, old, new, size);
+       smp_mb();
+
+       return ret;
+}
+
+#define cmpxchg(ptr,o,n)                                               \
+       ((__typeof__(*(ptr)))__cmpxchg_mb((ptr),                        \
+                                         (unsigned long)(o),           \
+                                         (unsigned long)(n),           \
+                                         sizeof(*(ptr))))
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+                                           unsigned long old,
+                                           unsigned long new, int size)
+{
+       unsigned long ret;
+
+       switch (size) {
+#ifndef CONFIG_CPU_32v6K
+       case 1:
+       case 2:
+               ret = __cmpxchg_local_generic(ptr, old, new, size);
+               break;
+#endif /* !CONFIG_CPU_32v6K */
+       default:
+               ret = __cmpxchg(ptr, old, new, size);
+       }
+
+       return ret;
+}
+
+#define cmpxchg_local(ptr,o,n)                                         \
+       ((__typeof__(*(ptr)))__cmpxchg_local((ptr),                     \
+                                      (unsigned long)(o),              \
+                                      (unsigned long)(n),              \
+                                      sizeof(*(ptr))))
+
+#ifdef CONFIG_CPU_32v6K
+
+/*
+ * Note : ARMv7-M (currently unsupported by Linux) does not support
+ * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should
+ * not be allowed to use __cmpxchg64.
+ */
+static inline unsigned long long __cmpxchg64(volatile void *ptr,
+                                            unsigned long long old,
+                                            unsigned long long new)
+{
+       register unsigned long long oldval asm("r0");
+       register unsigned long long __old asm("r2") = old;
+       register unsigned long long __new asm("r4") = new;
+       unsigned long res;
+
+       do {
+               asm volatile(
+               "       @ __cmpxchg8\n"
+               "       ldrexd  %1, %H1, [%2]\n"
+               "       mov     %0, #0\n"
+               "       teq     %1, %3\n"
+               "       teqeq   %H1, %H3\n"
+               "       strexdeq %0, %4, %H4, [%2]\n"
+                       : "=&r" (res), "=&r" (oldval)
+                       : "r" (ptr), "Ir" (__old), "r" (__new)
+                       : "memory", "cc");
+       } while (res);
+
+       return oldval;
+}
+
+static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
+                                               unsigned long long old,
+                                               unsigned long long new)
+{
+       unsigned long long ret;
+
+       smp_mb();
+       ret = __cmpxchg64(ptr, old, new);
+       smp_mb();
+
+       return ret;
+}
+
+#define cmpxchg64(ptr,o,n)                                             \
+       ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr),                      \
+                                           (unsigned long long)(o),    \
+                                           (unsigned long long)(n)))
+
+#define cmpxchg64_local(ptr,o,n)                                       \
+       ((__typeof__(*(ptr)))__cmpxchg64((ptr),                         \
+                                        (unsigned long long)(o),       \
+                                        (unsigned long long)(n)))
+
+#else  /* !CONFIG_CPU_32v6K */
+
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif /* CONFIG_CPU_32v6K */
+
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
index d4a0da1e48f40988bb7f92ce34664d86adb74a32..950391f194c4a9198927b4977fa49d52e08c80de 100644 (file)
@@ -78,6 +78,15 @@ int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
                return 1;
        if (cpu_architecture() < CPU_ARCH_ARMv6)
                return 1;
+#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
+       /*
+        * If we have support for OABI programs, we can never allow NX
+        * support - our signal syscall restart mechanism relies upon
+        * being able to execute code placed on the user stack.
+        */
+       return 1;
+#else
        return 0;
+#endif
 }
 EXPORT_SYMBOL(arm_elf_read_implies_exec);
index d662a2f1fd85e20ec7fc1af48461689f86fe6745..83b1da6b7baaa44cbfd220876503b9d755c1acd3 100644 (file)
@@ -815,10 +815,7 @@ __kuser_helper_start:
  */
 
 __kuser_memory_barrier:                                @ 0xffff0fa0
-
-#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP)
-       mcr     p15, 0, r0, c7, c10, 5  @ dmb
-#endif
+       smp_dmb
        usr_ret lr
 
        .align  5
index 2e787d40d59992c96bb6d546c2d31cc7a485c251..c7f2627385e719749a08241fcd0732e0d4e15996 100644 (file)
        mov     r2, #1
        add     r1, r1, r0, lsr #3      @ Get byte offset
        mov     r3, r2, lsl r3          @ create mask
+       smp_dmb
 1:     ldrexb  r2, [r1]
        ands    r0, r2, r3              @ save old value of bit
        \instr  r2, r2, r3                      @ toggle bit
        strexb  ip, r2, [r1]
        cmp     ip, #0
        bne     1b
+       smp_dmb
        cmp     r0, #0
        movne   r0, #1
 2:     mov     pc, lr
index de6752674c056d7248afbff274f739f9d3f44356..213a4fcfeb1cc451f0c7775b36493c9c57070412 100644 (file)
 /*
  * Memory Map definitions
  */
-/* FIXME: Does it really swap SRAM like this? */
 #ifdef CONFIG_GEMINI_MEM_SWAP
 # define GEMINI_DRAM_BASE      0x00000000
-# define GEMINI_SRAM_BASE      0x20000000
+# define GEMINI_SRAM_BASE      0x70000000
 #else
 # define GEMINI_SRAM_BASE      0x00000000
 # define GEMINI_DRAM_BASE      0x10000000
index eeb00240d7841656df8f742e5c38fefb79dfe126..be1ca28fed3fb9eceb03394338eaaf5166821a06 100644 (file)
@@ -144,6 +144,9 @@ static struct platform_device kirkwood_ge00 = {
        .id             = 0,
        .num_resources  = 1,
        .resource       = kirkwood_ge00_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
@@ -202,6 +205,9 @@ static struct platform_device kirkwood_ge01 = {
        .id             = 1,
        .num_resources  = 1,
        .resource       = kirkwood_ge01_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
@@ -386,12 +392,10 @@ static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata = {
 
 static struct resource kirkwood_i2c_resources[] = {
        {
-               .name   = "i2c",
                .start  = I2C_PHYS_BASE,
                .end    = I2C_PHYS_BASE + 0x1f,
                .flags  = IORESOURCE_MEM,
        }, {
-               .name   = "i2c",
                .start  = IRQ_KIRKWOOD_TWSI,
                .end    = IRQ_KIRKWOOD_TWSI,
                .flags  = IORESOURCE_IRQ,
index dda5743cf3e023b84fc2d04dd1248d1e06c73d35..01aa213c0a6ffda67086c8c3aaac24dbfd4b5113 100644 (file)
@@ -142,6 +142,8 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = {
        MPP1_SPI_MOSI,
        MPP2_SPI_SCK,
        MPP3_SPI_MISO,
+       MPP4_SATA1_ACTn,
+       MPP5_SATA0_ACTn,
        MPP8_TW_SDA,
        MPP9_TW_SCK,
        MPP10_UART0_TXD,
@@ -150,10 +152,6 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = {
        MPP14_UART1_RXD,        /* PIC controller */
        MPP15_GPIO,             /* USB Copy button */
        MPP16_GPIO,             /* Reset button */
-       MPP20_SATA1_ACTn,
-       MPP21_SATA0_ACTn,
-       MPP22_SATA1_PRESENTn,
-       MPP23_SATA0_PRESENTn,
        0
 };
 
index c0d2d9d12e743bccb39644c713a0e6661c538078..818f19d7ab1f6af7ef050d5a167e14b85b3df921 100644 (file)
@@ -82,6 +82,9 @@ static struct platform_device loki_ge0 = {
        .id             = 0,
        .num_resources  = 1,
        .resource       = loki_ge0_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init loki_ge0_init(struct mv643xx_eth_platform_data *eth_data)
@@ -136,6 +139,9 @@ static struct platform_device loki_ge1 = {
        .id             = 1,
        .num_resources  = 1,
        .resource       = loki_ge1_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init loki_ge1_init(struct mv643xx_eth_platform_data *eth_data)
index d0bdb6e3682bdcc8e21862f5be8000e574e36b9e..2e914649b9e44075d5af3b17d147c793b5134375 100644 (file)
@@ -3,6 +3,11 @@
 
 #include <mach/mfp.h>
 
+#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
+#define MFP_DRIVE_SLOW         (0x1 << 13)
+#define MFP_DRIVE_MEDIUM       (0x2 << 13)
+#define MFP_DRIVE_FAST         (0x3 << 13)
+
 /* GPIO */
 #define GPIO0_GPIO             MFP_CFG(GPIO0, AF5)
 #define GPIO1_GPIO             MFP_CFG(GPIO1, AF5)
index 48a1cbc7c56b0bdd15bcc9d289301dcdcaf8134f..d97de36c50adbf75016a047f8b87f86f1385c313 100644 (file)
@@ -3,6 +3,11 @@
 
 #include <mach/mfp.h>
 
+#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
+#define MFP_DRIVE_SLOW         (0x2 << 13)
+#define MFP_DRIVE_MEDIUM       (0x4 << 13)
+#define MFP_DRIVE_FAST         (0x8 << 13)
+
 /* UART2 */
 #define GPIO47_UART2_RXD       MFP_CFG(GPIO47, AF6)
 #define GPIO48_UART2_TXD       MFP_CFG(GPIO48, AF6)
index 277ea4cd0f9f5ca1d49674cb70ad235d108fc603..62e510e80a58099bfefb363253a2fdae92537837 100644 (file)
  * possible, we make the following compromise:
  *
  * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT)
- * 2. DRIVE strength definitions redefined to include the reserved bit10
+ * 2. DRIVE strength definitions redefined to include the reserved bit
+ *    - the reserved bit differs between pxa168 and pxa910, and the
+ *      MFP_DRIVE_* macros are individually defined in mfp-pxa{168,910}.h
  * 3. Override MFP_CFG() and MFP_CFG_DRV()
  * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X()
  */
 
-#define MFP_DRIVE_VERY_SLOW    (0x0 << 13)
-#define MFP_DRIVE_SLOW         (0x2 << 13)
-#define MFP_DRIVE_MEDIUM       (0x4 << 13)
-#define MFP_DRIVE_FAST         (0x8 << 13)
-
 #undef MFP_CFG
 #undef MFP_CFG_DRV
 #undef MFP_CFG_LPM
index b03a6eda7419278c79f8d1c9617ba456d19297bb..a8400bb891e7017f21661830b7da4bfca7af9d7f 100644 (file)
@@ -136,7 +136,7 @@ static struct clock_event_device ckevt = {
        .set_mode       = timer_set_mode,
 };
 
-static cycle_t clksrc_read(void)
+static cycle_t clksrc_read(struct clocksource *cs)
 {
        return timer_read();
 }
index 9ba595083dab9ac8a175998d7dc59de529f2d091..1b22e4af8791ff16cd238c7852d68a9aa4f12740 100644 (file)
@@ -321,6 +321,9 @@ static struct platform_device mv78xx0_ge00 = {
        .id             = 0,
        .num_resources  = 1,
        .resource       = mv78xx0_ge00_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
@@ -375,6 +378,9 @@ static struct platform_device mv78xx0_ge01 = {
        .id             = 1,
        .num_resources  = 1,
        .resource       = mv78xx0_ge01_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
@@ -429,6 +435,9 @@ static struct platform_device mv78xx0_ge10 = {
        .id             = 2,
        .num_resources  = 1,
        .resource       = mv78xx0_ge10_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
@@ -496,6 +505,9 @@ static struct platform_device mv78xx0_ge11 = {
        .id             = 3,
        .num_resources  = 1,
        .resource       = mv78xx0_ge11_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
@@ -532,12 +544,10 @@ static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
 
 static struct resource mv78xx0_i2c_0_resources[] = {
        {
-               .name   = "i2c 0 base",
                .start  = I2C_0_PHYS_BASE,
                .end    = I2C_0_PHYS_BASE + 0x1f,
                .flags  = IORESOURCE_MEM,
        }, {
-               .name   = "i2c 0 irq",
                .start  = IRQ_MV78XX0_I2C_0,
                .end    = IRQ_MV78XX0_I2C_0,
                .flags  = IORESOURCE_IRQ,
@@ -567,12 +577,10 @@ static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
 
 static struct resource mv78xx0_i2c_1_resources[] = {
        {
-               .name   = "i2c 1 base",
                .start  = I2C_1_PHYS_BASE,
                .end    = I2C_1_PHYS_BASE + 0x1f,
                .flags  = IORESOURCE_MEM,
        }, {
-               .name   = "i2c 1 irq",
                .start  = IRQ_MV78XX0_I2C_1,
                .end    = IRQ_MV78XX0_I2C_1,
                .flags  = IORESOURCE_IRQ,
index 6af99ddabdfb92e0159ba96252654549dc04b9ce..b1c7778d9f96ebef4700e3887138802edc625282 100644 (file)
@@ -188,6 +188,9 @@ static struct platform_device orion5x_eth = {
        .id             = 0,
        .num_resources  = 1,
        .resource       = orion5x_eth_resources,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
 };
 
 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
@@ -248,12 +251,10 @@ static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
 
 static struct resource orion5x_i2c_resources[] = {
        {
-               .name   = "i2c base",
                .start  = I2C_PHYS_BASE,
                .end    = I2C_PHYS_BASE + 0x1f,
                .flags  = IORESOURCE_MEM,
        }, {
-               .name   = "i2c irq",
                .start  = IRQ_ORION5X_I2C,
                .end    = IRQ_ORION5X_I2C,
                .flags  = IORESOURCE_IRQ,
index 92ba16e1b6fc6e042cf8c2aedb684f58cbdb1a6e..7db966dc29ce50f2e7815e26723794c8e1da639c 100644 (file)
@@ -111,9 +111,9 @@ static unsigned long ezx_pin_config[] __initdata = {
        GPIO25_SSP1_TXD,
        GPIO26_SSP1_RXD,
        GPIO24_GPIO,                            /* pcap chip select */
-       GPIO1_GPIO,                             /* pcap interrupt */
-       GPIO4_GPIO,                             /* WDI_AP */
-       GPIO55_GPIO,                            /* SYS_RESTART */
+       GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,       /* pcap interrupt */
+       GPIO4_GPIO | MFP_LPM_DRIVE_HIGH,        /* WDI_AP */
+       GPIO55_GPIO | MFP_LPM_DRIVE_HIGH,       /* SYS_RESTART */
 
        /* MMC */
        GPIO32_MMC_CLK,
@@ -144,20 +144,20 @@ static unsigned long ezx_pin_config[] __initdata = {
 #if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680)
 static unsigned long gen1_pin_config[] __initdata = {
        /* flip / lockswitch */
-       GPIO12_GPIO,
+       GPIO12_GPIO | WAKEUP_ON_EDGE_BOTH,
 
        /* bluetooth (bcm2035) */
-       GPIO14_GPIO | WAKEUP_ON_LEVEL_HIGH,     /* HOSTWAKE */
+       GPIO14_GPIO | WAKEUP_ON_EDGE_RISE,      /* HOSTWAKE */
        GPIO48_GPIO,                            /* RESET */
        GPIO28_GPIO,                            /* WAKEUP */
 
        /* Neptune handshake */
-       GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH,      /* BP_RDY */
-       GPIO57_GPIO,                            /* AP_RDY */
-       GPIO13_GPIO | WAKEUP_ON_LEVEL_HIGH,     /* WDI */
-       GPIO3_GPIO | WAKEUP_ON_LEVEL_HIGH,      /* WDI2 */
-       GPIO82_GPIO,                            /* RESET */
-       GPIO99_GPIO,                            /* TC_MM_EN */
+       GPIO0_GPIO | WAKEUP_ON_EDGE_FALL,       /* BP_RDY */
+       GPIO57_GPIO | MFP_LPM_DRIVE_HIGH,       /* AP_RDY */
+       GPIO13_GPIO | WAKEUP_ON_EDGE_BOTH,      /* WDI */
+       GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH,       /* WDI2 */
+       GPIO82_GPIO | MFP_LPM_DRIVE_HIGH,       /* RESET */
+       GPIO99_GPIO | MFP_LPM_DRIVE_HIGH,       /* TC_MM_EN */
 
        /* sound */
        GPIO52_SSP3_SCLK,
@@ -199,21 +199,21 @@ static unsigned long gen1_pin_config[] __initdata = {
        defined(CONFIG_MACH_EZX_E2) || defined(CONFIG_MACH_EZX_E6)
 static unsigned long gen2_pin_config[] __initdata = {
        /* flip / lockswitch */
-       GPIO15_GPIO,
+       GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,
 
        /* EOC */
-       GPIO10_GPIO,
+       GPIO10_GPIO | WAKEUP_ON_EDGE_RISE,
 
        /* bluetooth (bcm2045) */
-       GPIO13_GPIO | WAKEUP_ON_LEVEL_HIGH,     /* HOSTWAKE */
+       GPIO13_GPIO | WAKEUP_ON_EDGE_RISE,      /* HOSTWAKE */
        GPIO37_GPIO,                            /* RESET */
        GPIO57_GPIO,                            /* WAKEUP */
 
        /* Neptune handshake */
-       GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH,      /* BP_RDY */
-       GPIO96_GPIO,                            /* AP_RDY */
-       GPIO3_GPIO | WAKEUP_ON_LEVEL_HIGH,      /* WDI */
-       GPIO116_GPIO,                           /* RESET */
+       GPIO0_GPIO | WAKEUP_ON_EDGE_FALL,       /* BP_RDY */
+       GPIO96_GPIO | MFP_LPM_DRIVE_HIGH,       /* AP_RDY */
+       GPIO3_GPIO | WAKEUP_ON_EDGE_FALL,       /* WDI */
+       GPIO116_GPIO | MFP_LPM_DRIVE_HIGH,      /* RESET */
        GPIO41_GPIO,                            /* BP_FLASH */
 
        /* sound */
index 31e6a7b6ad80d27f055b9ce49da0b7e036e06755..b6c10556fbc7931ab2382fee61fa73e9c8291081 100644 (file)
@@ -13,8 +13,9 @@ extern void clear_reset_status(unsigned int mask);
 /**
  * init_gpio_reset() - register GPIO as reset generator
  * @gpio: gpio nr
- * @output: set gpio as out/low instead of input during normal work
+ * @output: set gpio as output instead of input during normal work
+ * @level: output level
  */
-extern int init_gpio_reset(int gpio, int output);
+extern int init_gpio_reset(int gpio, int output, int level);
 
 #endif /* __ASM_ARCH_RESET_H */
index 7ffb91d64c39733e39e6cc9d8518f2ae5f67a379..cf6b720c055f5f5c51136c918975a4f736f6c9ed 100644 (file)
@@ -322,6 +322,7 @@ static inline void pxa27x_mfp_init(void) {}
 #ifdef CONFIG_PM
 static unsigned long saved_gafr[2][4];
 static unsigned long saved_gpdr[4];
+static unsigned long saved_pgsr[4];
 
 static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
 {
@@ -332,6 +333,7 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
                saved_gafr[0][i] = GAFR_L(i);
                saved_gafr[1][i] = GAFR_U(i);
                saved_gpdr[i] = GPDR(i * 32);
+               saved_pgsr[i] = PGSR(i);
 
                GPDR(i * 32) = gpdr_lpm[i];
        }
@@ -346,6 +348,7 @@ static int pxa2xx_mfp_resume(struct sys_device *d)
                GAFR_L(i) = saved_gafr[0][i];
                GAFR_U(i) = saved_gafr[1][i];
                GPDR(i * 32) = saved_gpdr[i];
+               PGSR(i) = saved_pgsr[i];
        }
        PSSR = PSSR_RDH | PSSR_PH;
        return 0;
@@ -374,6 +377,9 @@ static int __init pxa2xx_mfp_init(void)
        if (cpu_is_pxa27x())
                pxa27x_mfp_init();
 
+       /* clear RDH bit to enable GPIO receivers after reset/sleep exit */
+       PSSR = PSSR_RDH;
+
        /* initialize gafr_run[], pgsr_lpm[] from existing values */
        for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
                gpdr_lpm[i] = GPDR(i * 32);
index 1cec1806f002e270bbdf146cc14d56e5b6f17608..471a853e548b9bd861280b4a9ede88c4d1156be5 100644 (file)
@@ -62,6 +62,8 @@ static unsigned long palmld_pin_config[] __initdata = {
        GPIO29_AC97_SDATA_IN_0,
        GPIO30_AC97_SDATA_OUT,
        GPIO31_AC97_SYNC,
+       GPIO89_AC97_SYSCLK,
+       GPIO95_AC97_nRESET,
 
        /* IrDA */
        GPIO108_GPIO,   /* ir disable */
index 30662363907b88da99e5d2f7c979849d657f6134..05bf979b78a668d3a4a9c256944bdbaeb7dc1de3 100644 (file)
@@ -64,6 +64,7 @@ static unsigned long palmt5_pin_config[] __initdata = {
        GPIO29_AC97_SDATA_IN_0,
        GPIO30_AC97_SDATA_OUT,
        GPIO31_AC97_SYNC,
+       GPIO89_AC97_SYSCLK,
        GPIO95_AC97_nRESET,
 
        /* IrDA */
index e2d44b1a8a9b9111c3daeb2f06ba6c682dc224e8..e99a893c58a78b2589fefae2345b019cab98b92f 100644 (file)
@@ -65,6 +65,7 @@ static unsigned long palmtx_pin_config[] __initdata = {
        GPIO29_AC97_SDATA_IN_0,
        GPIO30_AC97_SDATA_OUT,
        GPIO31_AC97_SYNC,
+       GPIO89_AC97_SYSCLK,
        GPIO95_AC97_nRESET,
 
        /* IrDA */
index df29d45fb4e72db6cabbe06332018071fbe1774d..01e9d643394a9d28160a98ccaee118761d8fb75f 100644 (file)
@@ -20,7 +20,7 @@ static void do_hw_reset(void);
 
 static int reset_gpio = -1;
 
-int init_gpio_reset(int gpio, int output)
+int init_gpio_reset(int gpio, int output, int level)
 {
        int rc;
 
@@ -31,7 +31,7 @@ int init_gpio_reset(int gpio, int output)
        }
 
        if (output)
-               rc = gpio_direction_output(gpio, 0);
+               rc = gpio_direction_output(gpio, level);
        else
                rc = gpio_direction_input(gpio);
        if (rc) {
index c18e34acafcb427563f874a2a59804a952a3b2b5..5a45fe340a1057729a7e7a31442af85da9426595 100644 (file)
@@ -531,9 +531,15 @@ static int spitz_ohci_init(struct device *dev)
        return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
 }
 
+static void spitz_ohci_exit(struct device *dev)
+{
+       gpio_free(SPITZ_GPIO_USB_HOST);
+}
+
 static struct pxaohci_platform_data spitz_ohci_platform_data = {
        .port_mode      = PMM_NPS_MODE,
        .init           = spitz_ohci_init,
+       .exit           = spitz_ohci_exit,
        .flags          = ENABLE_PORT_ALL | NO_OC_PROTECTION,
        .power_budget   = 150,
 };
@@ -731,7 +737,7 @@ static void spitz_restart(char mode, const char *cmd)
 
 static void __init common_init(void)
 {
-       init_gpio_reset(SPITZ_GPIO_ON_RESET, 1);
+       init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
        pm_power_off = spitz_poweroff;
        arm_pm_restart = spitz_restart;
 
index afac5b6d3d78e50212afbca1df72579f57de00e4..a0bd46ef5d30de6fb09cda7fc96371a344c95207 100644 (file)
@@ -897,7 +897,7 @@ static void __init tosa_init(void)
        gpio_set_wake(MFP_PIN_GPIO1, 1);
        /* We can't pass to gpio-keys since it will drop the Reset altfunc */
 
-       init_gpio_reset(TOSA_GPIO_ON_RESET, 0);
+       init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0);
 
        pm_power_off = tosa_poweroff;
        arm_pm_restart = tosa_restart;
index 945e0d237a1dfc6c3016090972813d7d32ba128e..fec64678a63aae2f6bd3b9200a0175599d90b64a 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Mon Mar 23 20:09:01 2009
+# Last update: Fri May 29 10:14:20 2009
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -916,7 +916,7 @@ nxdb500                     MACH_NXDB500            NXDB500                 905
 apf9328                        MACH_APF9328            APF9328                 906
 omap_wipoq             MACH_OMAP_WIPOQ         OMAP_WIPOQ              907
 omap_twip              MACH_OMAP_TWIP          OMAP_TWIP               908
-palmt650               MACH_PALMT650           PALMT650                909
+treo650                        MACH_TREO650            TREO650                 909
 acumen                 MACH_ACUMEN             ACUMEN                  910
 xp100                  MACH_XP100              XP100                   911
 fs2410                 MACH_FS2410             FS2410                  912
@@ -1232,7 +1232,7 @@ ql202b                    MACH_QL202B             QL202B                  1226
 vpac270                        MACH_VPAC270            VPAC270                 1227
 rd129                  MACH_RD129              RD129                   1228
 htcwizard              MACH_HTCWIZARD          HTCWIZARD               1229
-xscale_treo680         MACH_XSCALE_TREO680     XSCALE_TREO680          1230
+treo680                        MACH_TREO680            TREO680                 1230
 tecon_tmezon           MACH_TECON_TMEZON       TECON_TMEZON            1231
 zylonite               MACH_ZYLONITE           ZYLONITE                1233
 gene1270               MACH_GENE1270           GENE1270                1234
@@ -1418,10 +1418,10 @@ looxc550                MACH_LOOXC550           LOOXC550                1417
 cnty_titan             MACH_CNTY_TITAN         CNTY_TITAN              1418
 app3xx                 MACH_APP3XX             APP3XX                  1419
 sideoatsgrama          MACH_SIDEOATSGRAMA      SIDEOATSGRAMA           1420
-palmtreo700p           MACH_PALMTREO700P       PALMTREO700P            1421
-palmtreo700w           MACH_PALMTREO700W       PALMTREO700W            1422
-palmtreo750            MACH_PALMTREO750        PALMTREO750             1423
-palmtreo755p           MACH_PALMTREO755P       PALMTREO755P            1424
+treo700p               MACH_TREO700P           TREO700P                1421
+treo700w               MACH_TREO700W           TREO700W                1422
+treo750                        MACH_TREO750            TREO750                 1423
+treo755p               MACH_TREO755P           TREO755P                1424
 ezreganut9200          MACH_EZREGANUT9200      EZREGANUT9200           1425
 sarge                  MACH_SARGE              SARGE                   1426
 a696                   MACH_A696               A696                    1427
@@ -1721,7 +1721,7 @@ sapphire          MACH_SAPPHIRE           SAPPHIRE                1729
 csb637xo               MACH_CSB637XO           CSB637XO                1730
 evisiong               MACH_EVISIONG           EVISIONG                1731
 stmp37xx               MACH_STMP37XX           STMP37XX                1732
-stmp378x               MACH_STMP38XX           STMP38XX                1733
+stmp378x               MACH_STMP378X           STMP378X                1733
 tnt                    MACH_TNT                TNT                     1734
 tbxt                   MACH_TBXT               TBXT                    1735
 playmate               MACH_PLAYMATE           PLAYMATE                1736
@@ -1817,7 +1817,7 @@ smdkc100          MACH_SMDKC100           SMDKC100                1826
 tavorevb               MACH_TAVOREVB           TAVOREVB                1827
 saar                   MACH_SAAR               SAAR                    1828
 deister_eyecam         MACH_DEISTER_EYECAM     DEISTER_EYECAM          1829
-at91sam9m10ek          MACH_AT91SAM9M10EK      AT91SAM9M10EK           1830
+at91sam9m10g45ek       MACH_AT91SAM9M10G45EK   AT91SAM9M10G45EK        1830
 linkstation_produo     MACH_LINKSTATION_PRODUO LINKSTATION_PRODUO      1831
 hit_b0                 MACH_HIT_B0             HIT_B0                  1832
 adx_rmu                        MACH_ADX_RMU            ADX_RMU                 1833
@@ -2132,3 +2132,116 @@ apollo                  MACH_APOLLO             APOLLO                  2141
 at91cap9stk            MACH_AT91CAP9STK        AT91CAP9STK             2142
 spc300                 MACH_SPC300             SPC300                  2143
 eko                    MACH_EKO                EKO                     2144
+ccw9m2443              MACH_CCW9M2443          CCW9M2443               2145
+ccw9m2443js            MACH_CCW9M2443JS        CCW9M2443JS             2146
+m2m_router_device      MACH_M2M_ROUTER_DEVICE  M2M_ROUTER_DEVICE       2147
+str9104nas             MACH_STAR9104NAS        STAR9104NAS             2148
+pca100                 MACH_PCA100             PCA100                  2149
+z3_dm365_mod_01                MACH_Z3_DM365_MOD_01    Z3_DM365_MOD_01         2150
+hipox                  MACH_HIPOX              HIPOX                   2151
+omap3_piteds           MACH_OMAP3_PITEDS       OMAP3_PITEDS            2152
+bm150r                 MACH_BM150R             BM150R                  2153
+tbone                  MACH_TBONE              TBONE                   2154
+merlin                 MACH_MERLIN             MERLIN                  2155
+falcon                 MACH_FALCON             FALCON                  2156
+davinci_da850_evm      MACH_DAVINCI_DA850_EVM  DAVINCI_DA850_EVM       2157
+s5p6440                        MACH_S5P6440            S5P6440                 2158
+at91sam9g10ek          MACH_AT91SAM9G10EK      AT91SAM9G10EK           2159
+omap_4430sdp           MACH_OMAP_4430SDP       OMAP_4430SDP            2160
+lpc313x                        MACH_LPC313X            LPC313X                 2161
+magx_zn5               MACH_MAGX_ZN5           MAGX_ZN5                2162
+magx_em30              MACH_MAGX_EM30          MAGX_EM30               2163
+magx_ve66              MACH_MAGX_VE66          MAGX_VE66               2164
+meesc                  MACH_MEESC              MEESC                   2165
+otc570                 MACH_OTC570             OTC570                  2166
+bcu2412                        MACH_BCU2412            BCU2412                 2167
+beacon                 MACH_BEACON             BEACON                  2168
+actia_tgw              MACH_ACTIA_TGW          ACTIA_TGW               2169
+e4430                  MACH_E4430              E4430                   2170
+ql300                  MACH_QL300              QL300                   2171
+btmavb101              MACH_BTMAVB101          BTMAVB101               2172
+btmawb101              MACH_BTMAWB101          BTMAWB101               2173
+sq201                  MACH_SQ201              SQ201                   2174
+quatro45xx             MACH_QUATRO45XX         QUATRO45XX              2175
+openpad                        MACH_OPENPAD            OPENPAD                 2176
+tx25                   MACH_TX25               TX25                    2177
+omap3_torpedo          MACH_OMAP3_TORPEDO      OMAP3_TORPEDO           2178
+htcraphael_k           MACH_HTCRAPHAEL_K       HTCRAPHAEL_K            2179
+lal43                  MACH_LAL43              LAL43                   2181
+htcraphael_cdma500     MACH_HTCRAPHAEL_CDMA500 HTCRAPHAEL_CDMA500      2182
+anw6410                        MACH_ANW6410            ANW6410                 2183
+htcprophet             MACH_HTCPROPHET         HTCPROPHET              2185
+cfa_10022              MACH_CFA_10022          CFA_10022               2186
+imx27_visstrim_m10     MACH_IMX27_VISSTRIM_M10 IMX27_VISSTRIM_M10      2187
+px2imx27               MACH_PX2IMX27           PX2IMX27                2188
+stm3210e_eval          MACH_STM3210E_EVAL      STM3210E_EVAL           2189
+dvs10                  MACH_DVS10              DVS10                   2190
+portuxg20              MACH_PORTUXG20          PORTUXG20               2191
+arm_spv                        MACH_ARM_SPV            ARM_SPV                 2192
+smdkc110               MACH_SMDKC110           SMDKC110                2193
+cabespresso            MACH_CABESPRESSO        CABESPRESSO             2194
+hmc800                 MACH_HMC800             HMC800                  2195
+sholes                 MACH_SHOLES             SHOLES                  2196
+btmxc31                        MACH_BTMXC31            BTMXC31                 2197
+dt501                  MACH_DT501              DT501                   2198
+ktx                    MACH_KTX                KTX                     2199
+omap3517evm            MACH_OMAP3517EVM        OMAP3517EVM             2200
+netspace_v2            MACH_NETSPACE_V2        NETSPACE_V2             2201
+netspace_max_v2                MACH_NETSPACE_MAX_V2    NETSPACE_MAX_V2         2202
+d2net_v2               MACH_D2NET_V2           D2NET_V2                2203
+net2big_v2             MACH_NET2BIG_V2         NET2BIG_V2              2204
+net4big_v2             MACH_NET4BIG_V2         NET4BIG_V2              2205
+net5big_v2             MACH_NET5BIG_V2         NET5BIG_V2              2206
+endb2443               MACH_ENDB2443           ENDB2443                2207
+inetspace_v2           MACH_INETSPACE_V2       INETSPACE_V2            2208
+tros                   MACH_TROS               TROS                    2209
+pelco_homer            MACH_PELCO_HOMER        PELCO_HOMER             2210
+ofsp8                  MACH_OFSP8              OFSP8                   2211
+at91sam9g45ekes                MACH_AT91SAM9G45EKES    AT91SAM9G45EKES         2212
+guf_cupid              MACH_GUF_CUPID          GUF_CUPID               2213
+eab1r                  MACH_EAB1R              EAB1R                   2214
+desirec                        MACH_DESIREC            DESIREC                 2215
+cordoba                        MACH_CORDOBA            CORDOBA                 2216
+irvine                 MACH_IRVINE             IRVINE                  2217
+sff772                 MACH_SFF772             SFF772                  2218
+pelco_milano           MACH_PELCO_MILANO       PELCO_MILANO            2219
+pc7302                 MACH_PC7302             PC7302                  2220
+bip6000                        MACH_BIP6000            BIP6000                 2221
+silvermoon             MACH_SILVERMOON         SILVERMOON              2222
+vc0830                 MACH_VC0830             VC0830                  2223
+dt430                  MACH_DT430              DT430                   2224
+ji42pf                 MACH_JI42PF             JI42PF                  2225
+gnet_ksm               MACH_GNET_KSM           GNET_KSM                2226
+gnet_sgm               MACH_GNET_SGM           GNET_SGM                2227
+gnet_sgr               MACH_GNET_SGR           GNET_SGR                2228
+omap3_icetekevm                MACH_OMAP3_ICETEKEVM    OMAP3_ICETEKEVM         2229
+pnp                    MACH_PNP                PNP                     2230
+ctera_2bay_k           MACH_CTERA_2BAY_K       CTERA_2BAY_K            2231
+ctera_2bay_u           MACH_CTERA_2BAY_U       CTERA_2BAY_U            2232
+sas_c                  MACH_SAS_C              SAS_C                   2233
+vma2315                        MACH_VMA2315            VMA2315                 2234
+vcs                    MACH_VCS                VCS                     2235
+spear600               MACH_SPEAR600           SPEAR600                2236
+spear300               MACH_SPEAR300           SPEAR300                2237
+spear1300              MACH_SPEAR1300          SPEAR1300               2238
+lilly1131              MACH_LILLY1131          LILLY1131               2239
+arvoo_ax301            MACH_ARVOO_AX301        ARVOO_AX301             2240
+mapphone               MACH_MAPPHONE           MAPPHONE                2241
+legend                 MACH_LEGEND             LEGEND                  2242
+salsa                  MACH_SALSA              SALSA                   2243
+lounge                 MACH_LOUNGE             LOUNGE                  2244
+vision                 MACH_VISION             VISION                  2245
+vmb20                  MACH_VMB20              VMB20                   2246
+hy2410                 MACH_HY2410             HY2410                  2247
+hy9315                 MACH_HY9315             HY9315                  2248
+bullwinkle             MACH_BULLWINKLE         BULLWINKLE              2249
+arm_ultimator2         MACH_ARM_ULTIMATOR2     ARM_ULTIMATOR2          2250
+vs_v210                        MACH_VS_V210            VS_V210                 2252
+vs_v212                        MACH_VS_V212            VS_V212                 2253
+hmt                    MACH_HMT                HMT                     2254
+suen3                  MACH_SUEN3              SUEN3                   2255
+vesper                 MACH_VESPER             VESPER                  2256
+str9                   MACH_STR9               STR9                    2257
+omap3_wl_ff            MACH_OMAP3_WL_FF        OMAP3_WL_FF             2258
+simcom                 MACH_SIMCOM             SIMCOM                  2259
+mcwebio                        MACH_MCWEBIO            MCWEBIO                 2260
diff --git a/arch/blackfin/include/asm/.gitignore b/arch/blackfin/include/asm/.gitignore
deleted file mode 100644 (file)
index 7858564..0000000
+++ /dev/null
@@ -1 +0,0 @@
-+mach
index e70074e05f4ef095e33beb1cf28ede8ae817f980..733a178d782d0dd8e77e2c619f7b67d3271d2500 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <asm/unaligned.h>
 
-#define        flat_stack_align(sp)    /* nothing needed */
 #define        flat_argvp_envp_on_stack()              0
 #define        flat_old_ram_flag(flags)                (flags)
 
index 1e57b636e0bc6985f298486b972336b687bf93c0..cf5066d3efd2b79f6e9f287de452ec8efd96385a 100644 (file)
 #define __NR_dup3              363
 #define __NR_pipe2             364
 #define __NR_inotify_init1     365
+#define __NR_preadv            366
+#define __NR_pwritev           367
 
-#define __NR_syscall           366
+#define __NR_syscall           368
 #define NR_syscalls            __NR_syscall
 
 /* Old optional stuff no one actually uses */
diff --git a/arch/blackfin/kernel/.gitignore b/arch/blackfin/kernel/.gitignore
new file mode 100644 (file)
index 0000000..c5f676c
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.lds
index 2aaae78a68e0ae3ef345442b2467d30dd50c82ab..46518b1d29831bae0184daa34b2b45889563448f 100644 (file)
@@ -8,9 +8,8 @@
 
 #define strncmp __inline_strncmp
 #include <asm/string.h>
-#undef strncmp
-
 #include <linux/module.h>
+#undef strncmp
 
 int strncmp(const char *cs, const char *ct, size_t count)
 {
index 21e65a339a22aacb857d1a76cdbe93863743298b..a063a434f7e35e5235f343a570a8ef60ded304a1 100644 (file)
@@ -1581,6 +1581,8 @@ ENTRY(_sys_call_table)
        .long _sys_dup3
        .long _sys_pipe2
        .long _sys_inotify_init1        /* 365 */
+       .long _sys_preadv
+       .long _sys_pwritev
 
        .rept NR_syscalls-(.-_sys_call_table)/4
        .long _sys_ni_syscall
index 2a873508a9a101b359483ebbf086f84aa769f0f0..bd12b31b90e60b3df56b0d8080e4bd86df98ce79 100644 (file)
@@ -5,7 +5,6 @@
 #ifndef __H8300_FLAT_H__
 #define __H8300_FLAT_H__
 
-#define        flat_stack_align(sp)                    /* nothing needed */
 #define        flat_argvp_envp_on_stack()              1
 #define        flat_old_ram_flag(flags)                1
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
index d851cf0c4aa5ecff7902da7a54fdab618eccdad4..5d711c4688fb9f8162fd017a7e35451ad4c41da6 100644 (file)
@@ -12,7 +12,6 @@
 #ifndef __ASM_M32R_FLAT_H
 #define __ASM_M32R_FLAT_H
 
-#define        flat_stack_align(sp)            (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
 #define        flat_argvp_envp_on_stack()              0
 #define        flat_old_ram_flag(flags)                (flags)
 #define        flat_set_persistent(relval, p)          0
index 814b5174a8e0ffb623aa96e65f9b2a1b52a4ddad..a0e290793978b35dd89586eba50c4e1f7950f1ca 100644 (file)
@@ -5,7 +5,6 @@
 #ifndef __M68KNOMMU_FLAT_H__
 #define __M68KNOMMU_FLAT_H__
 
-#define        flat_stack_align(sp)                    /* nothing needed */
 #define        flat_argvp_envp_on_stack()              1
 #define        flat_old_ram_flag(flags)                (flags)
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
index a0d1146a057851096e00c52dd092128709d99554..cdc9a6ff4be823a356521e00b7d35eb15b28e013 100644 (file)
@@ -868,6 +868,18 @@ config TASK_SIZE
        default "0x80000000" if PPC_PREP || PPC_8xx
        default "0xc0000000"
 
+config CONSISTENT_SIZE_BOOL
+       bool "Set custom consistent memory pool size"
+       depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
+       help
+         This option allows you to set the size of the
+         consistent memory pool.  This pool of virtual memory
+         is used to make consistent memory allocations.
+
+config CONSISTENT_SIZE
+       hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
+       default "0x00200000" if NOT_COHERENT_CACHE
+
 config PIN_TLB
        bool "Pinned Kernel TLBs (860 ONLY)"
        depends on ADVANCED_OPTIONS && 8xx
index c69f2b5f0cc40035877ccea1f363c3de6711fc61..cb448d68452c9e01918937952cb1517563538927 100644 (file)
@@ -26,7 +26,9 @@
  * allocate the space "normally" and use the cache management functions
  * to ensure it is consistent.
  */
-extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp);
+struct device;
+extern void *__dma_alloc_coherent(struct device *dev, size_t size,
+                                 dma_addr_t *handle, gfp_t gfp);
 extern void __dma_free_coherent(size_t size, void *vaddr);
 extern void __dma_sync(void *vaddr, size_t size, int direction);
 extern void __dma_sync_page(struct page *page, unsigned long offset,
@@ -37,7 +39,7 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
  * Cache coherent cores.
  */
 
-#define __dma_alloc_coherent(gfp, size, handle)        NULL
+#define __dma_alloc_coherent(dev, gfp, size, handle)   NULL
 #define __dma_free_coherent(size, addr)                ((void)0)
 #define __dma_sync(addr, size, rw)             ((void)0)
 #define __dma_sync_page(pg, off, sz, rw)       ((void)0)
index d60fd18f428cb53b3e4a35c90bdc8590c0283be9..f1f4e23a84e930711c840f71128a5db0724d56d3 100644 (file)
@@ -14,8 +14,6 @@
 #ifndef _ASM_FIXMAP_H
 #define _ASM_FIXMAP_H
 
-extern unsigned long FIXADDR_TOP;
-
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
 #include <asm/page.h>
@@ -24,6 +22,8 @@ extern unsigned long FIXADDR_TOP;
 #include <asm/kmap_types.h>
 #endif
 
+#define FIXADDR_TOP    ((unsigned long)(-PAGE_SIZE))
+
 /*
  * Here we define all the compile-time 'special' virtual
  * addresses. The point is to have a constant address at
index ba45c997830fa05e814d18c1323ad6467ed79bef..c9ff9d75990eb94eaf55944482dff6b5301d3afe 100644 (file)
@@ -10,7 +10,7 @@
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
-extern unsigned long ioremap_bot, ioremap_base;
+extern unsigned long ioremap_bot;
 
 #ifdef CONFIG_44x
 extern int icache_44x_need_flush;
@@ -55,9 +55,31 @@ extern int icache_44x_need_flush;
 #define pgd_ERROR(e) \
        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
 
+/*
+ * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary
+ * value (for now) on others, from where we can start layout kernel
+ * virtual space that goes below PKMAP and FIXMAP
+ */
+#ifdef CONFIG_HIGHMEM
+#define KVIRT_TOP      PKMAP_BASE
+#else
+#define KVIRT_TOP      (0xfe000000UL)  /* for now, could be FIXMAP_BASE ? */
+#endif
+
+/*
+ * ioremap_bot starts at that address. Early ioremaps move down from there,
+ * until mem_init() at which point this becomes the top of the vmalloc
+ * and ioremap space
+ */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define IOREMAP_TOP    ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK)
+#else
+#define IOREMAP_TOP    KVIRT_TOP
+#endif
+
 /*
  * Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 64MB value just means that there will be a 64MB "hole" after the
+ * current 16MB value just means that there will be a 64MB "hole" after the
  * physical memory until the kernel virtual memory starts.  That means that
  * any out-of-bounds memory accesses will hopefully be caught.
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
index 53c7788cba78d2978002e2edc5d03027f459e974..6b02793dc75b5bd3d95bd2d1ff767ec842fa4905 100644 (file)
@@ -32,7 +32,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,
 {
        void *ret;
 #ifdef CONFIG_NOT_COHERENT_CACHE
-       ret = __dma_alloc_coherent(size, dma_handle, flag);
+       ret = __dma_alloc_coherent(dev, size, dma_handle, flag);
        if (ret == NULL)
                return NULL;
        *dma_handle += get_dma_direct_offset(dev);
index 8db35278a4b43643c2cf42b280b79ad9d33be7bc..29b742b90f1f9af47951601d3f58f7db5ea94823 100644 (file)
@@ -18,7 +18,6 @@ obj-$(CONFIG_PPC64)   += copypage_64.o copyuser_64.o \
                           memcpy_64.o usercopy_64.o mem_64.o string.o
 obj-$(CONFIG_XMON)     += sstep.o
 obj-$(CONFIG_KPROBES)  += sstep.o
-obj-$(CONFIG_NOT_COHERENT_CACHE)       += dma-noncoherent.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)      += locks.o
diff --git a/arch/powerpc/lib/dma-noncoherent.c b/arch/powerpc/lib/dma-noncoherent.c
deleted file mode 100644 (file)
index 005a28d..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *  PowerPC version derived from arch/arm/mm/consistent.c
- *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
- *
- *  Copyright (C) 2000 Russell King
- *
- * Consistent memory allocators.  Used for DMA devices that want to
- * share uncached memory with the processor core.  The function return
- * is the virtual address and 'dma_handle' is the physical address.
- * Mostly stolen from the ARM port, with some changes for PowerPC.
- *                                             -- Dan
- *
- * Reorganized to get rid of the arch-specific consistent_* functions
- * and provide non-coherent implementations for the DMA API. -Matt
- *
- * Added in_interrupt() safe dma_alloc_coherent()/dma_free_coherent()
- * implementation. This is pulled straight from ARM and barely
- * modified. -Matt
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/highmem.h>
-#include <linux/dma-mapping.h>
-#include <linux/vmalloc.h>
-
-#include <asm/tlbflush.h>
-
-/*
- * Allocate DMA-coherent memory space and return both the kernel remapped
- * virtual and bus address for that space.
- */
-void *
-__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
-{
-       struct page *page;
-       unsigned long order;
-       int i;
-       unsigned int nr_pages = PAGE_ALIGN(size)>>PAGE_SHIFT;
-       unsigned int array_size = nr_pages * sizeof(struct page *);
-       struct page **pages;
-       struct page *end;
-       u64 mask = 0x00ffffff, limit; /* ISA default */
-       struct vm_struct *area;
-
-       BUG_ON(!mem_init_done);
-       size = PAGE_ALIGN(size);
-       limit = (mask + 1) & ~mask;
-       if (limit && size >= limit) {
-               printk(KERN_WARNING "coherent allocation too big (requested "
-                               "%#x mask %#Lx)\n", size, mask);
-               return NULL;
-       }
-
-       order = get_order(size);
-
-       if (mask != 0xffffffff)
-               gfp |= GFP_DMA;
-
-       page = alloc_pages(gfp, order);
-       if (!page)
-               goto no_page;
-
-       end = page + (1 << order);
-
-       /*
-        * Invalidate any data that might be lurking in the
-        * kernel direct-mapped region for device DMA.
-        */
-       {
-               unsigned long kaddr = (unsigned long)page_address(page);
-               memset(page_address(page), 0, size);
-               flush_dcache_range(kaddr, kaddr + size);
-       }
-
-       split_page(page, order);
-
-       /*
-        * Set the "dma handle"
-        */
-       *handle = page_to_phys(page);
-
-       area = get_vm_area_caller(size, VM_IOREMAP,
-                       __builtin_return_address(1));
-       if (!area)
-               goto out_free_pages;
-
-       if (array_size > PAGE_SIZE) {
-               pages = vmalloc(array_size);
-               area->flags |= VM_VPAGES;
-       } else {
-               pages = kmalloc(array_size, GFP_KERNEL);
-       }
-       if (!pages)
-               goto out_free_area;
-
-       area->pages = pages;
-       area->nr_pages = nr_pages;
-
-       for (i = 0; i < nr_pages; i++)
-               pages[i] = page + i;
-
-       if (map_vm_area(area, pgprot_noncached(PAGE_KERNEL), &pages))
-               goto out_unmap;
-
-       /*
-        * Free the otherwise unused pages.
-        */
-       page += nr_pages;
-       while (page < end) {
-               __free_page(page);
-               page++;
-       }
-
-       return area->addr;
-out_unmap:
-       vunmap(area->addr);
-       if (array_size > PAGE_SIZE)
-               vfree(pages);
-       else
-               kfree(pages);
-       goto out_free_pages;
-out_free_area:
-       free_vm_area(area);
-out_free_pages:
-       if (page)
-               __free_pages(page, order);
-no_page:
-       return NULL;
-}
-EXPORT_SYMBOL(__dma_alloc_coherent);
-
-/*
- * free a page as defined by the above mapping.
- */
-void __dma_free_coherent(size_t size, void *vaddr)
-{
-       vfree(vaddr);
-
-}
-EXPORT_SYMBOL(__dma_free_coherent);
-
-/*
- * make an area consistent.
- */
-void __dma_sync(void *vaddr, size_t size, int direction)
-{
-       unsigned long start = (unsigned long)vaddr;
-       unsigned long end   = start + size;
-
-       switch (direction) {
-       case DMA_NONE:
-               BUG();
-       case DMA_FROM_DEVICE:
-               /*
-                * invalidate only when cache-line aligned otherwise there is
-                * the potential for discarding uncommitted data from the cache
-                */
-               if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
-                       flush_dcache_range(start, end);
-               else
-                       invalidate_dcache_range(start, end);
-               break;
-       case DMA_TO_DEVICE:             /* writeback only */
-               clean_dcache_range(start, end);
-               break;
-       case DMA_BIDIRECTIONAL: /* writeback and invalidate */
-               flush_dcache_range(start, end);
-               break;
-       }
-}
-EXPORT_SYMBOL(__dma_sync);
-
-#ifdef CONFIG_HIGHMEM
-/*
- * __dma_sync_page() implementation for systems using highmem.
- * In this case, each page of a buffer must be kmapped/kunmapped
- * in order to have a virtual address for __dma_sync(). This must
- * not sleep so kmap_atomic()/kunmap_atomic() are used.
- *
- * Note: yes, it is possible and correct to have a buffer extend
- * beyond the first page.
- */
-static inline void __dma_sync_page_highmem(struct page *page,
-               unsigned long offset, size_t size, int direction)
-{
-       size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
-       size_t cur_size = seg_size;
-       unsigned long flags, start, seg_offset = offset;
-       int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
-       int seg_nr = 0;
-
-       local_irq_save(flags);
-
-       do {
-               start = (unsigned long)kmap_atomic(page + seg_nr,
-                               KM_PPC_SYNC_PAGE) + seg_offset;
-
-               /* Sync this buffer segment */
-               __dma_sync((void *)start, seg_size, direction);
-               kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE);
-               seg_nr++;
-
-               /* Calculate next buffer segment size */
-               seg_size = min((size_t)PAGE_SIZE, size - cur_size);
-
-               /* Add the segment size to our running total */
-               cur_size += seg_size;
-               seg_offset = 0;
-       } while (seg_nr < nr_segs);
-
-       local_irq_restore(flags);
-}
-#endif /* CONFIG_HIGHMEM */
-
-/*
- * __dma_sync_page makes memory consistent. identical to __dma_sync, but
- * takes a struct page instead of a virtual address
- */
-void __dma_sync_page(struct page *page, unsigned long offset,
-       size_t size, int direction)
-{
-#ifdef CONFIG_HIGHMEM
-       __dma_sync_page_highmem(page, offset, size, direction);
-#else
-       unsigned long start = (unsigned long)page_address(page) + offset;
-       __dma_sync((void *)start, size, direction);
-#endif
-}
-EXPORT_SYMBOL(__dma_sync_page);
index 17290bcedc5e6b0850cc961d0e99d4ca615adf4e..b746f4ca4209aaa7c385272b098804bbbd7dcb0d 100644 (file)
@@ -26,3 +26,4 @@ obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
 obj-$(CONFIG_PPC_MM_SLICES)    += slice.o
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
 obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
+obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c
new file mode 100644 (file)
index 0000000..36692f5
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ *  PowerPC version derived from arch/arm/mm/consistent.c
+ *    Copyright (C) 2001 Dan Malek (dmalek@jlc.net)
+ *
+ *  Copyright (C) 2000 Russell King
+ *
+ * Consistent memory allocators.  Used for DMA devices that want to
+ * share uncached memory with the processor core.  The function return
+ * is the virtual address and 'dma_handle' is the physical address.
+ * Mostly stolen from the ARM port, with some changes for PowerPC.
+ *                                             -- Dan
+ *
+ * Reorganized to get rid of the arch-specific consistent_* functions
+ * and provide non-coherent implementations for the DMA API. -Matt
+ *
+ * Added in_interrupt() safe dma_alloc_coherent()/dma_free_coherent()
+ * implementation. This is pulled straight from ARM and barely
+ * modified. -Matt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/highmem.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/tlbflush.h>
+
+#include "mmu_decl.h"
+
+/*
+ * This address range defaults to a value that is safe for all
+ * platforms which currently set CONFIG_NOT_COHERENT_CACHE. It
+ * can be further configured for specific applications under
+ * the "Advanced Setup" menu. -Matt
+ */
+#define CONSISTENT_BASE                (IOREMAP_TOP)
+#define CONSISTENT_END                 (CONSISTENT_BASE + CONFIG_CONSISTENT_SIZE)
+#define CONSISTENT_OFFSET(x)   (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
+
+/*
+ * This is the page table (2MB) covering uncached, DMA consistent allocations
+ */
+static DEFINE_SPINLOCK(consistent_lock);
+
+/*
+ * VM region handling support.
+ *
+ * This should become something generic, handling VM region allocations for
+ * vmalloc and similar (ioremap, module space, etc).
+ *
+ * I envisage vmalloc()'s supporting vm_struct becoming:
+ *
+ *  struct vm_struct {
+ *    struct vm_region region;
+ *    unsigned long    flags;
+ *    struct page      **pages;
+ *    unsigned int     nr_pages;
+ *    unsigned long    phys_addr;
+ *  };
+ *
+ * get_vm_area() would then call vm_region_alloc with an appropriate
+ * struct vm_region head (eg):
+ *
+ *  struct vm_region vmalloc_head = {
+ *     .vm_list        = LIST_HEAD_INIT(vmalloc_head.vm_list),
+ *     .vm_start       = VMALLOC_START,
+ *     .vm_end         = VMALLOC_END,
+ *  };
+ *
+ * However, vmalloc_head.vm_start is variable (typically, it is dependent on
+ * the amount of RAM found at boot time.)  I would imagine that get_vm_area()
+ * would have to initialise this each time prior to calling vm_region_alloc().
+ */
+struct ppc_vm_region {
+       struct list_head        vm_list;
+       unsigned long           vm_start;
+       unsigned long           vm_end;
+};
+
+static struct ppc_vm_region consistent_head = {
+       .vm_list        = LIST_HEAD_INIT(consistent_head.vm_list),
+       .vm_start       = CONSISTENT_BASE,
+       .vm_end         = CONSISTENT_END,
+};
+
+static struct ppc_vm_region *
+ppc_vm_region_alloc(struct ppc_vm_region *head, size_t size, gfp_t gfp)
+{
+       unsigned long addr = head->vm_start, end = head->vm_end - size;
+       unsigned long flags;
+       struct ppc_vm_region *c, *new;
+
+       new = kmalloc(sizeof(struct ppc_vm_region), gfp);
+       if (!new)
+               goto out;
+
+       spin_lock_irqsave(&consistent_lock, flags);
+
+       list_for_each_entry(c, &head->vm_list, vm_list) {
+               if ((addr + size) < addr)
+                       goto nospc;
+               if ((addr + size) <= c->vm_start)
+                       goto found;
+               addr = c->vm_end;
+               if (addr > end)
+                       goto nospc;
+       }
+
+ found:
+       /*
+        * Insert this entry _before_ the one we found.
+        */
+       list_add_tail(&new->vm_list, &c->vm_list);
+       new->vm_start = addr;
+       new->vm_end = addr + size;
+
+       spin_unlock_irqrestore(&consistent_lock, flags);
+       return new;
+
+ nospc:
+       spin_unlock_irqrestore(&consistent_lock, flags);
+       kfree(new);
+ out:
+       return NULL;
+}
+
+static struct ppc_vm_region *ppc_vm_region_find(struct ppc_vm_region *head, unsigned long addr)
+{
+       struct ppc_vm_region *c;
+
+       list_for_each_entry(c, &head->vm_list, vm_list) {
+               if (c->vm_start == addr)
+                       goto out;
+       }
+       c = NULL;
+ out:
+       return c;
+}
+
+/*
+ * Allocate DMA-coherent memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *
+__dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+       struct page *page;
+       struct ppc_vm_region *c;
+       unsigned long order;
+       u64 mask = ISA_DMA_THRESHOLD, limit;
+
+       if (dev) {
+               mask = dev->coherent_dma_mask;
+
+               /*
+                * Sanity check the DMA mask - it must be non-zero, and
+                * must be able to be satisfied by a DMA allocation.
+                */
+               if (mask == 0) {
+                       dev_warn(dev, "coherent DMA mask is unset\n");
+                       goto no_page;
+               }
+
+               if ((~mask) & ISA_DMA_THRESHOLD) {
+                       dev_warn(dev, "coherent DMA mask %#llx is smaller "
+                                "than system GFP_DMA mask %#llx\n",
+                                mask, (unsigned long long)ISA_DMA_THRESHOLD);
+                       goto no_page;
+               }
+       }
+
+
+       size = PAGE_ALIGN(size);
+       limit = (mask + 1) & ~mask;
+       if ((limit && size >= limit) ||
+           size >= (CONSISTENT_END - CONSISTENT_BASE)) {
+               printk(KERN_WARNING "coherent allocation too big (requested %#x mask %#Lx)\n",
+                      size, mask);
+               return NULL;
+       }
+
+       order = get_order(size);
+
+       /* Might be useful if we ever have a real legacy DMA zone... */
+       if (mask != 0xffffffff)
+               gfp |= GFP_DMA;
+
+       page = alloc_pages(gfp, order);
+       if (!page)
+               goto no_page;
+
+       /*
+        * Invalidate any data that might be lurking in the
+        * kernel direct-mapped region for device DMA.
+        */
+       {
+               unsigned long kaddr = (unsigned long)page_address(page);
+               memset(page_address(page), 0, size);
+               flush_dcache_range(kaddr, kaddr + size);
+       }
+
+       /*
+        * Allocate a virtual address in the consistent mapping region.
+        */
+       c = ppc_vm_region_alloc(&consistent_head, size,
+                           gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
+       if (c) {
+               unsigned long vaddr = c->vm_start;
+               struct page *end = page + (1 << order);
+
+               split_page(page, order);
+
+               /*
+                * Set the "dma handle"
+                */
+               *handle = page_to_phys(page);
+
+               do {
+                       SetPageReserved(page);
+                       map_page(vaddr, page_to_phys(page),
+                                pgprot_noncached(PAGE_KERNEL));
+                       page++;
+                       vaddr += PAGE_SIZE;
+               } while (size -= PAGE_SIZE);
+
+               /*
+                * Free the otherwise unused pages.
+                */
+               while (page < end) {
+                       __free_page(page);
+                       page++;
+               }
+
+               return (void *)c->vm_start;
+       }
+
+       if (page)
+               __free_pages(page, order);
+ no_page:
+       return NULL;
+}
+EXPORT_SYMBOL(__dma_alloc_coherent);
+
+/*
+ * free a page as defined by the above mapping.
+ */
+void __dma_free_coherent(size_t size, void *vaddr)
+{
+       struct ppc_vm_region *c;
+       unsigned long flags, addr;
+       
+       size = PAGE_ALIGN(size);
+
+       spin_lock_irqsave(&consistent_lock, flags);
+
+       c = ppc_vm_region_find(&consistent_head, (unsigned long)vaddr);
+       if (!c)
+               goto no_area;
+
+       if ((c->vm_end - c->vm_start) != size) {
+               printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
+                      __func__, c->vm_end - c->vm_start, size);
+               dump_stack();
+               size = c->vm_end - c->vm_start;
+       }
+
+       addr = c->vm_start;
+       do {
+               pte_t *ptep;
+               unsigned long pfn;
+
+               ptep = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(addr),
+                                                              addr),
+                                                   addr),
+                                        addr);
+               if (!pte_none(*ptep) && pte_present(*ptep)) {
+                       pfn = pte_pfn(*ptep);
+                       pte_clear(&init_mm, addr, ptep);
+                       if (pfn_valid(pfn)) {
+                               struct page *page = pfn_to_page(pfn);
+
+                               ClearPageReserved(page);
+                               __free_page(page);
+                       }
+               }
+               addr += PAGE_SIZE;
+       } while (size -= PAGE_SIZE);
+
+       flush_tlb_kernel_range(c->vm_start, c->vm_end);
+
+       list_del(&c->vm_list);
+
+       spin_unlock_irqrestore(&consistent_lock, flags);
+
+       kfree(c);
+       return;
+
+ no_area:
+       spin_unlock_irqrestore(&consistent_lock, flags);
+       printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
+              __func__, vaddr);
+       dump_stack();
+}
+EXPORT_SYMBOL(__dma_free_coherent);
+
+/*
+ * make an area consistent.
+ */
+void __dma_sync(void *vaddr, size_t size, int direction)
+{
+       unsigned long start = (unsigned long)vaddr;
+       unsigned long end   = start + size;
+
+       switch (direction) {
+       case DMA_NONE:
+               BUG();
+       case DMA_FROM_DEVICE:
+               /*
+                * invalidate only when cache-line aligned otherwise there is
+                * the potential for discarding uncommitted data from the cache
+                */
+               if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1)))
+                       flush_dcache_range(start, end);
+               else
+                       invalidate_dcache_range(start, end);
+               break;
+       case DMA_TO_DEVICE:             /* writeback only */
+               clean_dcache_range(start, end);
+               break;
+       case DMA_BIDIRECTIONAL: /* writeback and invalidate */
+               flush_dcache_range(start, end);
+               break;
+       }
+}
+EXPORT_SYMBOL(__dma_sync);
+
+#ifdef CONFIG_HIGHMEM
+/*
+ * __dma_sync_page() implementation for systems using highmem.
+ * In this case, each page of a buffer must be kmapped/kunmapped
+ * in order to have a virtual address for __dma_sync(). This must
+ * not sleep so kmap_atomic()/kunmap_atomic() are used.
+ *
+ * Note: yes, it is possible and correct to have a buffer extend
+ * beyond the first page.
+ */
+static inline void __dma_sync_page_highmem(struct page *page,
+               unsigned long offset, size_t size, int direction)
+{
+       size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
+       size_t cur_size = seg_size;
+       unsigned long flags, start, seg_offset = offset;
+       int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
+       int seg_nr = 0;
+
+       local_irq_save(flags);
+
+       do {
+               start = (unsigned long)kmap_atomic(page + seg_nr,
+                               KM_PPC_SYNC_PAGE) + seg_offset;
+
+               /* Sync this buffer segment */
+               __dma_sync((void *)start, seg_size, direction);
+               kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE);
+               seg_nr++;
+
+               /* Calculate next buffer segment size */
+               seg_size = min((size_t)PAGE_SIZE, size - cur_size);
+
+               /* Add the segment size to our running total */
+               cur_size += seg_size;
+               seg_offset = 0;
+       } while (seg_nr < nr_segs);
+
+       local_irq_restore(flags);
+}
+#endif /* CONFIG_HIGHMEM */
+
+/*
+ * __dma_sync_page makes memory consistent. identical to __dma_sync, but
+ * takes a struct page instead of a virtual address
+ */
+void __dma_sync_page(struct page *page, unsigned long offset,
+       size_t size, int direction)
+{
+#ifdef CONFIG_HIGHMEM
+       __dma_sync_page_highmem(page, offset, size, direction);
+#else
+       unsigned long start = (unsigned long)page_address(page) + offset;
+       __dma_sync((void *)start, size, direction);
+#endif
+}
+EXPORT_SYMBOL(__dma_sync_page);
index 666a5e8a5be1d582685d20b23ce5ec045f83cd4d..3de6a0d9382472dc7a81f60b569eb02de298c724 100644 (file)
@@ -168,12 +168,8 @@ void __init MMU_init(void)
                ppc_md.progress("MMU:mapin", 0x301);
        mapin_ram();
 
-#ifdef CONFIG_HIGHMEM
-       ioremap_base = PKMAP_BASE;
-#else
-       ioremap_base = 0xfe000000UL;    /* for now, could be 0xfffff000 */
-#endif /* CONFIG_HIGHMEM */
-       ioremap_bot = ioremap_base;
+       /* Initialize early top-down ioremap allocator */
+       ioremap_bot = IOREMAP_TOP;
 
        /* Map in I/O resources */
        if (ppc_md.progress)
index d0602a76bf7ff4c876a8a0ec9675ab3287b70985..579382c163a9cd40ca9381d3a0eaf345659ed664 100644 (file)
@@ -380,6 +380,23 @@ void __init mem_init(void)
                bsssize >> 10,
                initsize >> 10);
 
+#ifdef CONFIG_PPC32
+       pr_info("Kernel virtual memory layout:\n");
+       pr_info("  * 0x%08lx..0x%08lx  : fixmap\n", FIXADDR_START, FIXADDR_TOP);
+#ifdef CONFIG_HIGHMEM
+       pr_info("  * 0x%08lx..0x%08lx  : highmem PTEs\n",
+               PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP));
+#endif /* CONFIG_HIGHMEM */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+       pr_info("  * 0x%08lx..0x%08lx  : consistent mem\n",
+               IOREMAP_TOP, IOREMAP_TOP + CONFIG_CONSISTENT_SIZE);
+#endif /* CONFIG_NOT_COHERENT_CACHE */
+       pr_info("  * 0x%08lx..0x%08lx  : early ioremap\n",
+               ioremap_bot, IOREMAP_TOP);
+       pr_info("  * 0x%08lx..0x%08lx  : vmalloc & ioremap\n",
+               VMALLOC_START, VMALLOC_END);
+#endif /* CONFIG_PPC32 */
+
        mem_init_done = 1;
 }
 
index a70e311bd457d83991895b2a519411f9ead6499d..030d0005b4d2c0682ca1adfd988b52000e73b7f2 100644 (file)
@@ -127,12 +127,12 @@ static unsigned int steal_context_up(unsigned int id)
 
        pr_debug("[%d] steal context %d from mm @%p\n", cpu, id, mm);
 
-       /* Mark this mm has having no context anymore */
-       mm->context.id = MMU_NO_CONTEXT;
-
        /* Flush the TLB for that context */
        local_flush_tlb_mm(mm);
 
+       /* Mark this mm has having no context anymore */
+       mm->context.id = MMU_NO_CONTEXT;
+
        /* XXX This clear should ultimately be part of local_flush_tlb_mm */
        __clear_bit(id, stale_map[cpu]);
 
index 430d0908fa506341b3133ca6e7eca467f77ce7ef..5422169626ba8f7baa5b0f1a4930ee57a91e246f 100644 (file)
@@ -399,8 +399,6 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
 static int fixmaps;
-unsigned long FIXADDR_TOP = (-PAGE_SIZE);
-EXPORT_SYMBOL(FIXADDR_TOP);
 
 void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
 {
index d3b2b4f109e36ec68a61c7244ef7d4d48e9c335f..5d84df5e27f658972bf9b3acc3c9dd2267bf0176 100644 (file)
@@ -12,7 +12,6 @@
 #ifndef __ASM_SH_FLAT_H
 #define __ASM_SH_FLAT_H
 
-#define        flat_stack_align(sp)                    /* nothing needed */
 #define        flat_argvp_envp_on_stack()              0
 #define        flat_old_ram_flag(flags)                (flags)
 #define        flat_reloc_valid(reloc, size)           ((reloc) <= (size))
index 857e492c571e05ac7714d4b54144acc9560110e1..bbeb0c3fbd90e7ba875c583ab3e2e57cca216714 100644 (file)
@@ -504,8 +504,11 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
                        if (sym->st_shndx == SHN_ABS) {
                                continue;
                        }
-                       if (r_type == R_386_PC32) {
-                               /* PC relative relocations don't need to be adjusted */
+                       if (r_type == R_386_NONE || r_type == R_386_PC32) {
+                               /*
+                                * NONE can be ignored and and PC relative
+                                * relocations don't need to be adjusted.
+                                */
                        }
                        else if (r_type == R_386_32) {
                                /* Visit relocations that need to be adjusted */
index 5054c2ddd1a03471b4423e7c9eb1719dca667901..74b3d2ba84e90a39bb29f166278ce47bcf56437c 100644 (file)
 
 #define SMAP   0x534d4150      /* ASCII "SMAP" */
 
-struct e820_ext_entry {
-       struct e820entry std;
-       u32 ext_flags;
-} __attribute__((packed));
-
 static int detect_memory_e820(void)
 {
        int count = 0;
@@ -29,13 +24,21 @@ static int detect_memory_e820(void)
        u32 size, id, edi;
        u8 err;
        struct e820entry *desc = boot_params.e820_map;
-       static struct e820_ext_entry buf; /* static so it is zeroed */
+       static struct e820entry buf; /* static so it is zeroed */
 
        /*
-        * Set this here so that if the BIOS doesn't change this field
-        * but still doesn't change %ecx, we're still okay...
+        * Note: at least one BIOS is known which assumes that the
+        * buffer pointed to by one e820 call is the same one as
+        * the previous call, and only changes modified fields.  Therefore,
+        * we use a temporary buffer and copy the results entry by entry.
+        *
+        * This routine deliberately does not try to account for
+        * ACPI 3+ extended attributes.  This is because there are
+        * BIOSes in the field which report zero for the valid bit for
+        * all ranges, and we don't currently make any use of the
+        * other attribute bits.  Revisit this if we see the extended
+        * attribute bits deployed in a meaningful way in the future.
         */
-       buf.ext_flags = 1;
 
        do {
                size = sizeof buf;
@@ -66,13 +69,7 @@ static int detect_memory_e820(void)
                        break;
                }
 
-               /* ACPI 3.0 added the extended flags support.  If bit 0
-                  in the extended flags is zero, we're supposed to simply
-                  ignore the entry -- a backwards incompatible change! */
-               if (size > 20 && !(buf.ext_flags & 1))
-                       continue;
-
-               *desc++ = buf.std;
+               *desc++ = buf;
                count++;
        } while (next && count < ARRAY_SIZE(boot_params.e820_map));
 
index c1caefc82e62512245f52b17251af69d2b2d2c2b..77848d9fca6833fa88488adb6e22cae027a7d6c1 100644 (file)
@@ -114,6 +114,13 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 } };
 EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
 
+static int __init x86_xsave_setup(char *s)
+{
+       setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+       return 1;
+}
+__setup("noxsave", x86_xsave_setup);
+
 #ifdef CONFIG_X86_32
 static int cachesize_override __cpuinitdata = -1;
 static int disable_x86_serial_nr __cpuinitdata = 1;
index 208ecf6643df42a80233e3ec10979cba52297241..54b6de2cd9478907d383424e38539935274c6516 100644 (file)
@@ -693,8 +693,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
            policy->cpuinfo.transition_latency > 20 * 1000) {
                policy->cpuinfo.transition_latency = 20 * 1000;
-                       printk_once(KERN_INFO "Capping off P-state tranision"
-                                   " latency at 20 uS\n");
+               printk_once(KERN_INFO
+                           "P-state transition latency capped at 20 uS\n");
        }
 
        /* table init */
index 6ac55bd341ae8802abf29c6180533d08ab68930c..869615193720c1b126dc5069d37cc9620f1049b3 100644 (file)
@@ -168,6 +168,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
                case 0x0E: /* Core */
                case 0x0F: /* Core Duo */
                case 0x16: /* Celeron Core */
+               case 0x1C: /* Atom */
                        p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
                        return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
                case 0x0D: /* Pentium M (Dothan) */
index 3c28ccd49742f26022a49ab3bb6a81cfc1713c4a..a8363e5be4ef5b6b9ce78497b7d2a4aebf3a7f13 100644 (file)
@@ -168,10 +168,12 @@ static int check_powernow(void)
        return 1;
 }
 
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
 static void invalidate_entry(unsigned int entry)
 {
        powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
 }
+#endif
 
 static int get_ranges(unsigned char *pst)
 {
index 4709ead2db526bfc59b803ea06791a0717d539c8..f6b32d11235733a1c2cf7153effc4fa42e68e251 100644 (file)
@@ -649,6 +649,20 @@ static void print_basics(struct powernow_k8_data *data)
                                data->batps);
 }
 
+static u32 freq_from_fid_did(u32 fid, u32 did)
+{
+       u32 mhz = 0;
+
+       if (boot_cpu_data.x86 == 0x10)
+               mhz = (100 * (fid + 0x10)) >> did;
+       else if (boot_cpu_data.x86 == 0x11)
+               mhz = (100 * (fid + 8)) >> did;
+       else
+               BUG();
+
+       return mhz * 1000;
+}
+
 static int fill_powernow_table(struct powernow_k8_data *data,
                struct pst_s *pst, u8 maxvid)
 {
@@ -923,8 +937,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
 
                powernow_table[i].index = index;
 
-               powernow_table[i].frequency =
-                       data->acpi_data.states[i].core_frequency * 1000;
+               /* Frequency may be rounded for these */
+               if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
+                       powernow_table[i].frequency =
+                               freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
+               } else
+                       powernow_table[i].frequency =
+                               data->acpi_data.states[i].core_frequency * 1000;
        }
        return 0;
 }
@@ -1215,13 +1234,16 @@ static int powernowk8_verify(struct cpufreq_policy *pol)
        return cpufreq_frequency_table_verify(pol, data->powernow_table);
 }
 
+static const char ACPI_PSS_BIOS_BUG_MSG[] =
+       KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
+       KERN_ERR FW_BUG PFX "Try again with latest BIOS.\n";
+
 /* per CPU init entry point to the driver */
 static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
 {
        struct powernow_k8_data *data;
        cpumask_t oldmask;
        int rc;
-       static int print_once;
 
        if (!cpu_online(pol->cpu))
                return -ENODEV;
@@ -1244,19 +1266,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
                 * an UP version, and is deprecated by AMD.
                 */
                if (num_online_cpus() != 1) {
-                       /*
-                        * Replace this one with print_once as soon as such a
-                        * thing gets introduced
-                        */
-                       if (!print_once) {
-                               WARN_ONCE(1, KERN_ERR FW_BUG PFX "Your BIOS "
-                                       "does not provide ACPI _PSS objects "
-                                       "in a way that Linux understands. "
-                                       "Please report this to the Linux ACPI"
-                                       " maintainers and complain to your "
-                                       "BIOS vendor.\n");
-                               print_once++;
-                       }
+                       printk_once(ACPI_PSS_BIOS_BUG_MSG);
                        goto err_out;
                }
                if (pol->cpu != 0) {
index 1340dad417f43d8a9fa2666a9e22135daead60c0..667188e0b5a0bfac320d69a0f734dda03b5bee88 100644 (file)
@@ -232,6 +232,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"),
                },
        },
+       {       /* Handle problems with rebooting on Sony VGN-Z540N */
+               .callback = set_bios_reboot,
+               .ident = "Sony VGN-Z540N",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
+               },
+       },
        { }
 };
 
index 3a97a4cf187245462f3890f08313544762642f28..8f0e13be36b31d1a80c94dec2692504d2a9a86db 100644 (file)
@@ -160,8 +160,10 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
        /*
         * If large page isn't supported, there's no benefit in doing
         * this.  Also, on non-NUMA, embedding is better.
+        *
+        * NOTE: disabled for now.
         */
-       if (!cpu_has_pse || !pcpu_need_numa())
+       if (true || !cpu_has_pse || !pcpu_need_numa())
                return -EINVAL;
 
        /*
index b6caf1329b1b12e003dff8f8d761f67e39810f2f..32cf11e5728a2c1c444c407dfc287b8adf1c3c40 100644 (file)
@@ -2897,8 +2897,7 @@ static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu,
 
 static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu)
 {
-       kvm_x86_ops->tlb_flush(vcpu);
-       set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
+       kvm_set_cr3(vcpu, vcpu->arch.cr3);
        return 1;
 }
 
index 49079a46687b740f2e91d2bbfbc31c1c5094c22a..3944e917e794fad77dc54d2afaedda47d6dcdca7 100644 (file)
@@ -338,6 +338,9 @@ EXPORT_SYMBOL_GPL(kvm_lmsw);
 
 void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
+       unsigned long old_cr4 = vcpu->arch.cr4;
+       unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
+
        if (cr4 & CR4_RESERVED_BITS) {
                printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
                kvm_inject_gp(vcpu, 0);
@@ -351,7 +354,8 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
-       } else if (is_paging(vcpu) && !is_pae(vcpu) && (cr4 & X86_CR4_PAE)
+       } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
+                  && ((cr4 ^ old_cr4) & pdptr_bits)
                   && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
                printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
                kvm_inject_gp(vcpu, 0);
index 8f307d914c2ec860c3b9093796362e9c4719ab41..f46c340727b8be21fb8270618ff9d03962667409 100644 (file)
@@ -26,12 +26,16 @@ static unsigned long page_table_shareable(struct vm_area_struct *svma,
        unsigned long sbase = saddr & PUD_MASK;
        unsigned long s_end = sbase + PUD_SIZE;
 
+       /* Allow segments to share if only one is marked locked */
+       unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED;
+       unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED;
+
        /*
         * match the virtual addresses, permission and the alignment of the
         * page table page.
         */
        if (pmd_index(addr) != pmd_index(saddr) ||
-           vma->vm_flags != svma->vm_flags ||
+           vm_flags != svm_flags ||
            sbase < svma->vm_start || svma->vm_end < s_end)
                return 0;
 
index 797f9f107cb6871a3797680c7dbed9430cb0f354..e17efed088c54a7b546b7b76c073ab55231d425e 100644 (file)
@@ -153,7 +153,7 @@ static void __cpa_flush_all(void *arg)
         */
        __flush_tlb_all();
 
-       if (cache && boot_cpu_data.x86_model >= 4)
+       if (cache && boot_cpu_data.x86 >= 4)
                wbinvd();
 }
 
@@ -208,20 +208,15 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
                            int in_flags, struct page **pages)
 {
        unsigned int i, level;
+       unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 
        BUG_ON(irqs_disabled());
 
-       on_each_cpu(__cpa_flush_range, NULL, 1);
+       on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 
-       if (!cache)
+       if (!cache || do_wbinvd)
                return;
 
-       /* 4M threshold */
-       if (numpages >= 1024) {
-               if (boot_cpu_data.x86_model >= 4)
-                       wbinvd();
-               return;
-       }
        /*
         * We only need to flush on one CPU,
         * clflush is a MESI-coherent instruction that
index 95650f83ce2e35f709f951ca51c9422b821d37d5..bc46de3d967f62904962e06bf9beef26095a9a78 100644 (file)
@@ -116,9 +116,6 @@ int acpi_pci_bind(struct acpi_device *device)
        struct acpi_pci_data *pdata;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        acpi_handle handle;
-       struct pci_dev *dev;
-       struct pci_bus *bus;
-
 
        if (!device || !device->parent)
                return -EINVAL;
@@ -176,20 +173,9 @@ int acpi_pci_bind(struct acpi_device *device)
         * Locate matching device in PCI namespace.  If it doesn't exist
         * this typically means that the device isn't currently inserted
         * (e.g. docking station, port replicator, etc.).
-        * We cannot simply search the global pci device list, since
-        * PCI devices are added to the global pci list when the root
-        * bridge start ops are run, which may not have happened yet.
         */
-       bus = pci_find_bus(data->id.segment, data->id.bus);
-       if (bus) {
-               list_for_each_entry(dev, &bus->devices, bus_list) {
-                       if (dev->devfn == PCI_DEVFN(data->id.device,
-                                                   data->id.function)) {
-                               data->dev = dev;
-                               break;
-                       }
-               }
-       }
+       data->dev = pci_get_slot(pdata->bus,
+                               PCI_DEVFN(data->id.device, data->id.function));
        if (!data->dev) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Device %04x:%02x:%02x.%d not present in PCI namespace\n",
@@ -259,9 +245,10 @@ int acpi_pci_bind(struct acpi_device *device)
 
       end:
        kfree(buffer.pointer);
-       if (result)
+       if (result) {
+               pci_dev_put(data->dev);
                kfree(data);
-
+       }
        return result;
 }
 
@@ -303,6 +290,7 @@ static int acpi_pci_unbind(struct acpi_device *device)
        if (data->dev->subordinate) {
                acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
        }
+       pci_dev_put(data->dev);
        kfree(data);
 
       end:
index 72069ba5f1edc666d765f0131d509290e74244ab..10a2d913635a99d76502309efb55895d7a92c5e4 100644 (file)
@@ -148,6 +148,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
        if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
                return;
 
+       if (boot_cpu_has(X86_FEATURE_AMDC1E))
+               type = ACPI_STATE_C1;
+
        /*
         * Check, if one of the previous states already marked the lapic
         * unstable
@@ -611,6 +614,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
                switch (cx->type) {
                case ACPI_STATE_C1:
                        cx->valid = 1;
+                       acpi_timer_check_state(i, pr, cx);
                        break;
 
                case ACPI_STATE_C2:
@@ -830,11 +834,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 
        /* Do not access any ACPI IO ports in suspend path */
        if (acpi_idle_suspend) {
-               acpi_safe_halt();
                local_irq_enable();
+               cpu_relax();
                return 0;
        }
 
+       acpi_state_timer_broadcast(pr, cx, 1);
        kt1 = ktime_get_real();
        acpi_idle_do_entry(cx);
        kt2 = ktime_get_real();
@@ -842,6 +847,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 
        local_irq_enable();
        cx->usage++;
+       acpi_state_timer_broadcast(pr, cx, 0);
 
        return idle_time;
 }
index cafb41000f6bd6b36eaaa4b4348faef59e5c0e49..60e543d3234ea8528b2e55537511690ee3be0d96 100644 (file)
@@ -309,9 +309,15 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
                                  (u32) px->bus_master_latency,
                                  (u32) px->control, (u32) px->status));
 
-               if (!px->core_frequency) {
-                       printk(KERN_ERR PREFIX
-                                   "Invalid _PSS data: freq is zero\n");
+               /*
+                * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
+                */
+               if (!px->core_frequency ||
+                   ((u32)(px->core_frequency * 1000) !=
+                    (px->core_frequency * 1000))) {
+                       printk(KERN_ERR FW_BUG PREFIX
+                              "Invalid BIOS _PSS frequency: 0x%llx MHz\n",
+                              px->core_frequency);
                        result = -EFAULT;
                        kfree(pr->performance->states);
                        goto end;
index 7f16f5f8e7d395616a0d82ae8dbbd8fca8a336fb..227543789ba91db984862f52040fc18d1a7758e9 100644 (file)
@@ -840,7 +840,7 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
                state = acpi_get_throttling_state(pr, value);
                if (state == -1) {
                        ACPI_WARNING((AE_INFO,
-                               "Invalid throttling state, reset\n"));
+                               "Invalid throttling state, reset"));
                        state = 0;
                        ret = acpi_processor_set_throttling(pr, state);
                        if (ret)
index 810cca90ca7f0e390c2ad3a4dee33353848a0d43..1bdfb37377e32d58bcd1f3e35e858c1cc681aa5c 100644 (file)
@@ -570,6 +570,22 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
                DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
                },
        },
+       {
+        .callback = video_set_bqc_offset,
+        .ident = "eMachines E510",
+        .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"),
+               },
+       },
+       {
+        .callback = video_set_bqc_offset,
+        .ident = "Acer Aspire 5315",
+        .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
+               },
+       },
        {}
 };
 
@@ -2334,7 +2350,7 @@ static int __init acpi_video_init(void)
        return acpi_video_register();
 }
 
-void __exit acpi_video_exit(void)
+void acpi_video_exit(void)
 {
 
        acpi_bus_unregister_driver(&acpi_video_bus);
index dc030f1f00f19706a4c5e5d0a077a085b0885187..c6599618523e7fc265daf265880c9c1e7c0fe056 100644 (file)
@@ -700,8 +700,10 @@ int bus_add_driver(struct device_driver *drv)
        }
 
        kobject_uevent(&priv->kobj, KOBJ_ADD);
-       return error;
+       return 0;
 out_unregister:
+       kfree(drv->p);
+       drv->p = NULL;
        kobject_put(&priv->kobj);
 out_put_bus:
        bus_put(bus);
index 4aa527b8a91381289eb175b33f46e3e418d10374..1977d4beb89e0012290a567c850f6a59dd3da1b0 100644 (file)
@@ -879,7 +879,7 @@ int device_add(struct device *dev)
        }
 
        if (!dev_name(dev))
-               goto done;
+               goto name_error;
 
        pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
 
@@ -978,6 +978,9 @@ done:
        cleanup_device_parent(dev);
        if (parent)
                put_device(parent);
+name_error:
+       kfree(dev->p);
+       dev->p = NULL;
        goto done;
 }
 
index c51f11bb29ae2bdd0a13077147e6db357da8be27..8ae0f63602e0730a71647cb571cbf933d76ceec8 100644 (file)
@@ -257,6 +257,10 @@ EXPORT_SYMBOL_GPL(driver_register);
  */
 void driver_unregister(struct device_driver *drv)
 {
+       if (!drv || !drv->p) {
+               WARN(1, "Unexpected driver unregister!\n");
+               return;
+       }
        driver_remove_groups(drv, drv->groups);
        bus_remove_driver(drv);
 }
index 69b4ddb7de3b8c00d59a34fd16af5dc789e7b109..3e4bc699bc0f30349be3ed75b9ecc28cdb77ddf1 100644 (file)
@@ -357,6 +357,7 @@ static void dpm_power_up(pm_message_t state)
 {
        struct device *dev;
 
+       mutex_lock(&dpm_list_mtx);
        list_for_each_entry(dev, &dpm_list, power.entry)
                if (dev->power.status > DPM_OFF) {
                        int error;
@@ -366,6 +367,7 @@ static void dpm_power_up(pm_message_t state)
                        if (error)
                                pm_dev_err(dev, state, " early", error);
                }
+       mutex_unlock(&dpm_list_mtx);
 }
 
 /**
@@ -614,6 +616,7 @@ int device_power_down(pm_message_t state)
        int error = 0;
 
        suspend_device_irqs();
+       mutex_lock(&dpm_list_mtx);
        list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
                error = suspend_device_noirq(dev, state);
                if (error) {
@@ -622,6 +625,7 @@ int device_power_down(pm_message_t state)
                }
                dev->power.status = DPM_OFF_IRQ;
        }
+       mutex_unlock(&dpm_list_mtx);
        if (error)
                device_power_up(resume_event(state));
        return error;
index d270e8eb3e67f3fb0af2af1b6d4ea7a36521cf07..47d2ad0ae079c738fa8aa90656595026a56d7a8a 100644 (file)
@@ -1070,11 +1070,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
+       unlock_policy_rwsem_write(cpu);
+
        if (cpufreq_driver->target)
                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
-       unlock_policy_rwsem_write(cpu);
-
        kobject_put(&data->kobj);
 
        /* we need to make sure that the underlying kobj is actually
index 2ecd95e4ab1aca33c6e858698d0c16f1b28a19ba..7a74d175287b2f44fc7a7329ce79bd51b5f9b779 100644 (file)
@@ -91,6 +91,9 @@ static unsigned int dbs_enable;       /* number of CPUs using this policy */
  * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
  * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
  * is recursive for the same process. -Venki
+ * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
+ * would deadlock with cancel_delayed_work_sync(), which is needed for proper
+ * raceless workqueue teardown.
  */
 static DEFINE_MUTEX(dbs_mutex);
 
@@ -542,7 +545,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
 static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
 {
        dbs_info->enable = 0;
-       cancel_delayed_work(&dbs_info->work);
+       cancel_delayed_work_sync(&dbs_info->work);
 }
 
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
index 338f428a15b765ceaef4686225715d5d2f9f93e3..e741c339df768e77e6f155658b16ef2757897afd 100644 (file)
@@ -98,6 +98,9 @@ static unsigned int dbs_enable;       /* number of CPUs using this policy */
  * (like __cpufreq_driver_target()) is being called with dbs_mutex taken, then
  * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
  * is recursive for the same process. -Venki
+ * DEADLOCK ALERT! (2) : do_dbs_timer() must not take the dbs_mutex, because it
+ * would deadlock with cancel_delayed_work_sync(), which is needed for proper
+ * raceless workqueue teardown.
  */
 static DEFINE_MUTEX(dbs_mutex);
 
@@ -562,7 +565,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
 static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
 {
        dbs_info->enable = 0;
-       cancel_delayed_work(&dbs_info->work);
+       cancel_delayed_work_sync(&dbs_info->work);
 }
 
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
index da8a8ed9e411008d68e14820444695176caa9318..f18d1bde04397178dfd4a88f263c77546449c381 100644 (file)
@@ -179,9 +179,14 @@ static void dma_halt(struct fsl_dma_chan *fsl_chan)
 static void set_ld_eol(struct fsl_dma_chan *fsl_chan,
                        struct fsl_desc_sw *desc)
 {
+       u64 snoop_bits;
+
+       snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX)
+               ? FSL_DMA_SNEN : 0;
+
        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);
+               DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL
+                       | snoop_bits, 64);
 }
 
 static void append_ld_queue(struct fsl_dma_chan *fsl_chan,
@@ -313,8 +318,8 @@ static void fsl_chan_toggle_ext_start(struct fsl_dma_chan *fsl_chan, int enable)
 
 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);
+       struct fsl_desc_sw *desc;
        unsigned long flags;
        dma_cookie_t cookie;
 
@@ -322,14 +327,17 @@ static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx)
        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;
+       list_for_each_entry(desc, &tx->tx_list, node) {
+               cookie++;
+               if (cookie < 0)
+                       cookie = 1;
 
-       append_ld_queue(fsl_chan, desc);
-       list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev);
+               desc->async_tx.cookie = cookie;
+       }
+
+       fsl_chan->common.cookie = cookie;
+       append_ld_queue(fsl_chan, tx_to_fsl_desc(tx));
+       list_splice_init(&tx->tx_list, fsl_chan->ld_queue.prev);
 
        spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
 
@@ -454,8 +462,8 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
 {
        struct fsl_dma_chan *fsl_chan;
        struct fsl_desc_sw *first = NULL, *prev = NULL, *new;
+       struct list_head *list;
        size_t copy;
-       LIST_HEAD(link_chain);
 
        if (!chan)
                return NULL;
@@ -472,7 +480,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
                if (!new) {
                        dev_err(fsl_chan->dev,
                                        "No free memory for link descriptor\n");
-                       return NULL;
+                       goto fail;
                }
 #ifdef FSL_DMA_LD_DEBUG
                dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new);
@@ -507,7 +515,19 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy(
        /* Set End-of-link to the last link descriptor of new list*/
        set_ld_eol(fsl_chan, new);
 
-       return first ? &first->async_tx : NULL;
+       return &first->async_tx;
+
+fail:
+       if (!first)
+               return NULL;
+
+       list = &first->async_tx.tx_list;
+       list_for_each_entry_safe_reverse(new, prev, list, node) {
+               list_del(&new->node);
+               dma_pool_free(fsl_chan->desc_pool, new, new->async_tx.phys);
+       }
+
+       return NULL;
 }
 
 /**
@@ -598,15 +618,16 @@ static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
        dma_addr_t next_dest_addr;
        unsigned long flags;
 
+       spin_lock_irqsave(&fsl_chan->desc_lock, flags);
+
        if (!dma_is_idle(fsl_chan))
-               return;
+               goto out_unlock;
 
        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;
@@ -617,19 +638,20 @@ static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
                                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 %p\n",
-                               (void *)next_dest_addr);
+               dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%llx\n",
+                               (unsigned long long)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);
        }
+
+out_unlock:
+       spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
 }
 
 /**
@@ -734,8 +756,9 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
         */
        if (stat & FSL_DMA_SR_EOSI) {
                dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n");
-               dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n",
-                       (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan));
+               dev_dbg(fsl_chan->dev, "event: clndar 0x%llx, nlndar 0x%llx\n",
+                       (unsigned long long)get_cdar(fsl_chan),
+                       (unsigned long long)get_ndar(fsl_chan));
                stat &= ~FSL_DMA_SR_EOSI;
                update_cookie = 1;
        }
@@ -830,7 +853,7 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
                        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) {
+       if (new_fsl_chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) {
                dev_err(fdev->dev, "There is no %d channel!\n",
                                new_fsl_chan->id);
                err = -EINVAL;
@@ -925,8 +948,8 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
        }
 
        dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
-                       "controller at %p...\n",
-                       match->compatible, (void *)fdev->reg.start);
+                       "controller at 0x%llx...\n",
+                       match->compatible, (unsigned long long)fdev->reg.start);
        fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end
                                                - fdev->reg.start + 1);
 
index 1955ee8d6d2019df1e3b9182b6abb54a2823f587..a600fc0f79625a268ef6114fda6d3d3de49d4ded 100644 (file)
@@ -173,7 +173,7 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
        xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
 #ifdef  CONFIG_I7300_IDLE_IOAT_CHANNEL
-       if (i7300_idle_platform_probe(NULL, NULL) == 0) {
+       if (i7300_idle_platform_probe(NULL, NULL, 1) == 0) {
                device->common.chancnt--;
        }
 #endif
index e5f5c5a8ba6c9bf61616a01afde3bbfe22ac25c1..956982f8739b372d05c1f3dec73ad4735884b0e0 100644 (file)
@@ -192,16 +192,20 @@ config EDAC_PPC4XX
 
 config EDAC_AMD8131
        tristate "AMD8131 HyperTransport PCI-X Tunnel"
-       depends on EDAC_MM_EDAC && PCI
+       depends on EDAC_MM_EDAC && PCI && PPC_MAPLE
        help
          Support for error detection and correction on the
          AMD8131 HyperTransport PCI-X Tunnel chip.
+         Note, add more Kconfig dependency if it's adopted
+         on some machine other than Maple.
 
 config EDAC_AMD8111
        tristate "AMD8111 HyperTransport I/O Hub"
-       depends on EDAC_MM_EDAC && PCI
+       depends on EDAC_MM_EDAC && PCI && PPC_MAPLE
        help
          Support for error detection and correction on the
          AMD8111 HyperTransport I/O Hub chip.
+         Note, add more Kconfig dependency if it's adopted
+         on some machine other than Maple.
 
 endif # EDAC
index a5fdcf02f591d586a33c37bd1d9337798d99bd42..59076819135d2bca280f0b60ead4a1160177d549 100644 (file)
@@ -35,3 +35,5 @@ obj-$(CONFIG_EDAC_MPC85XX)            += mpc85xx_edac.o
 obj-$(CONFIG_EDAC_MV64X60)             += mv64x60_edac.o
 obj-$(CONFIG_EDAC_CELL)                        += cell_edac.o
 obj-$(CONFIG_EDAC_PPC4XX)              += ppc4xx_edac.o
+obj-$(CONFIG_EDAC_AMD8111)             += amd8111_edac.o
+obj-$(CONFIG_EDAC_AMD8131)             += amd8131_edac.o
index 614692181120b86a1106e9f5906a961601377bcf..2cb58ef743e03b79cc2e9d35460699f644e69d56 100644 (file)
@@ -389,7 +389,7 @@ static int amd8111_dev_probe(struct pci_dev *dev,
        dev_info->edac_dev->dev = &dev_info->dev->dev;
        dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
        dev_info->edac_dev->ctl_name = dev_info->ctl_name;
-       dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id;
+       dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
 
        if (edac_op_state == EDAC_OPSTATE_POLL)
                dev_info->edac_dev->edac_check = dev_info->check;
@@ -473,7 +473,7 @@ static int amd8111_pci_probe(struct pci_dev *dev,
        pci_info->edac_dev->dev = &pci_info->dev->dev;
        pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
        pci_info->edac_dev->ctl_name = pci_info->ctl_name;
-       pci_info->edac_dev->dev_name = pci_info->dev->dev.bus_id;
+       pci_info->edac_dev->dev_name = dev_name(&pci_info->dev->dev);
 
        if (edac_op_state == EDAC_OPSTATE_POLL)
                pci_info->edac_dev->edac_check = pci_info->check;
index c083b31cac5a40c19a5393b15414267933e863a8..b432d60c622a5bc52f951bde2983d0e325bea2b4 100644 (file)
@@ -287,7 +287,7 @@ static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)
        dev_info->edac_dev->dev = &dev_info->dev->dev;
        dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;
        dev_info->edac_dev->ctl_name = dev_info->ctl_name;
-       dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id;
+       dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);
 
        if (edac_op_state == EDAC_OPSTATE_POLL)
                dev_info->edac_dev->edac_check = amd8131_chipset.check;
index 4cd35d8fd799a1e75de762954bc34af86e79190b..f5d46e7199d48d03c12bfbc7b866540e607cddf1 100644 (file)
@@ -67,12 +67,18 @@ config DRM_I830
          will load the correct one.
 
 config DRM_I915
+       tristate "i915 driver"
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        select FB
        select FRAMEBUFFER_CONSOLE if !EMBEDDED
-       tristate "i915 driver"
+       # i915 depends on ACPI_VIDEO when ACPI is enabled
+       # but for select to work, need to select ACPI_VIDEO's dependencies, ick
+       select VIDEO_OUTPUT_CONTROL if ACPI
+       select BACKLIGHT_CLASS_DEVICE if ACPI
+       select INPUT if ACPI
+       select ACPI_VIDEO if ACPI
        help
          Choose this option if you have a system that has Intel 830M, 845G,
          852GM, 855GM 865G or 915G integrated graphics.  If M is selected, the
@@ -84,12 +90,6 @@ config DRM_I915
 config DRM_I915_KMS
        bool "Enable modesetting on intel by default"
        depends on DRM_I915
-       # i915 KMS depends on ACPI_VIDEO when ACPI is enabled
-       # but for select to work, need to select ACPI_VIDEO's dependencies, ick
-       select VIDEO_OUTPUT_CONTROL if ACPI
-       select BACKLIGHT_CLASS_DEVICE if ACPI
-       select INPUT if ACPI
-       select ACPI_VIDEO if ACPI
        help
          Choose this option if you want kernel modesetting enabled by default,
          and you have a new enough userspace to support this. Running old
index 9b149fe824c37fef0a8618886d4ff90e5f45b159..c431fa54bbb55b4d5d8afc32d9ea1468d05f66e5 100644 (file)
@@ -180,7 +180,8 @@ typedef struct drm_i915_private {
        int backlight_duty_cycle;  /* restore backlight to this value */
        bool panel_wants_dither;
        struct drm_display_mode *panel_fixed_mode;
-       struct drm_display_mode *vbt_mode; /* if any */
+       struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
+       struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
 
        /* Feature bits from the VBIOS */
        unsigned int int_tv_support:1;
index b189b49c7602e338b87070aec7aa42d9e32acdb3..670d12881468297e8e0af0fe40222c3f54f5cb2f 100644 (file)
@@ -349,7 +349,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
        last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
        num_pages = last_data_page - first_data_page + 1;
 
-       user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+       user_pages = drm_calloc_large(num_pages, sizeof(struct page *));
        if (user_pages == NULL)
                return -ENOMEM;
 
@@ -429,7 +429,7 @@ fail_put_user_pages:
                SetPageDirty(user_pages[i]);
                page_cache_release(user_pages[i]);
        }
-       kfree(user_pages);
+       drm_free_large(user_pages);
 
        return ret;
 }
@@ -649,7 +649,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
        num_pages = last_data_page - first_data_page + 1;
 
-       user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+       user_pages = drm_calloc_large(num_pages, sizeof(struct page *));
        if (user_pages == NULL)
                return -ENOMEM;
 
@@ -719,7 +719,7 @@ out_unlock:
 out_unpin_pages:
        for (i = 0; i < pinned_pages; i++)
                page_cache_release(user_pages[i]);
-       kfree(user_pages);
+       drm_free_large(user_pages);
 
        return ret;
 }
@@ -824,7 +824,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
        num_pages = last_data_page - first_data_page + 1;
 
-       user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+       user_pages = drm_calloc_large(num_pages, sizeof(struct page *));
        if (user_pages == NULL)
                return -ENOMEM;
 
@@ -902,7 +902,7 @@ fail_unlock:
 fail_put_user_pages:
        for (i = 0; i < pinned_pages; i++)
                page_cache_release(user_pages[i]);
-       kfree(user_pages);
+       drm_free_large(user_pages);
 
        return ret;
 }
@@ -1145,7 +1145,14 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
                        mutex_unlock(&dev->struct_mutex);
                        return VM_FAULT_SIGBUS;
                }
-               list_add(&obj_priv->list, &dev_priv->mm.inactive_list);
+
+               ret = i915_gem_object_set_to_gtt_domain(obj, write);
+               if (ret) {
+                       mutex_unlock(&dev->struct_mutex);
+                       return VM_FAULT_SIGBUS;
+               }
+
+               list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
        }
 
        /* Need a new fence register? */
@@ -1375,7 +1382,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
                        mutex_unlock(&dev->struct_mutex);
                        return ret;
                }
-               list_add(&obj_priv->list, &dev_priv->mm.inactive_list);
+               list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
        }
 
        drm_gem_object_unreference(obj);
@@ -1408,9 +1415,7 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)
                }
        obj_priv->dirty = 0;
 
-       drm_free(obj_priv->pages,
-                page_count * sizeof(struct page *),
-                DRM_MEM_DRIVER);
+       drm_free_large(obj_priv->pages);
        obj_priv->pages = NULL;
 }
 
@@ -2024,8 +2029,7 @@ i915_gem_object_get_pages(struct drm_gem_object *obj)
         */
        page_count = obj->size / PAGE_SIZE;
        BUG_ON(obj_priv->pages != NULL);
-       obj_priv->pages = drm_calloc(page_count, sizeof(struct page *),
-                                    DRM_MEM_DRIVER);
+       obj_priv->pages = drm_calloc_large(page_count, sizeof(struct page *));
        if (obj_priv->pages == NULL) {
                DRM_ERROR("Faled to allocate page list\n");
                obj_priv->pages_refcount--;
@@ -2131,8 +2135,10 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
                return;
        }
 
-       pitch_val = (obj_priv->stride / 128) - 1;
-       WARN_ON(pitch_val & ~0x0000000f);
+       pitch_val = obj_priv->stride / 128;
+       pitch_val = ffs(pitch_val) - 1;
+       WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
+
        val = obj_priv->gtt_offset;
        if (obj_priv->tiling_mode == I915_TILING_Y)
                val |= 1 << I830_FENCE_TILING_Y_SHIFT;
@@ -2424,6 +2430,16 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
        if (obj_priv->pages == NULL)
                return;
 
+       /* XXX: The 865 in particular appears to be weird in how it handles
+        * cache flushing.  We haven't figured it out, but the
+        * clflush+agp_chipset_flush doesn't appear to successfully get the
+        * data visible to the PGU, while wbinvd + agp_chipset_flush does.
+        */
+       if (IS_I865G(obj->dev)) {
+               wbinvd();
+               return;
+       }
+
        drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE);
 }
 
@@ -3111,7 +3127,7 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list,
                reloc_count += exec_list[i].relocation_count;
        }
 
-       *relocs = drm_calloc(reloc_count, sizeof(**relocs), DRM_MEM_DRIVER);
+       *relocs = drm_calloc_large(reloc_count, sizeof(**relocs));
        if (*relocs == NULL)
                return -ENOMEM;
 
@@ -3125,8 +3141,7 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list,
                                     exec_list[i].relocation_count *
                                     sizeof(**relocs));
                if (ret != 0) {
-                       drm_free(*relocs, reloc_count * sizeof(**relocs),
-                                DRM_MEM_DRIVER);
+                       drm_free_large(*relocs);
                        *relocs = NULL;
                        return -EFAULT;
                }
@@ -3165,7 +3180,7 @@ i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list,
        }
 
 err:
-       drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER);
+       drm_free_large(relocs);
 
        return ret;
 }
@@ -3198,10 +3213,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
                return -EINVAL;
        }
        /* Copy in the exec list from userland */
-       exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
-                              DRM_MEM_DRIVER);
-       object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
-                                DRM_MEM_DRIVER);
+       exec_list = drm_calloc_large(sizeof(*exec_list), args->buffer_count);
+       object_list = drm_calloc_large(sizeof(*object_list), args->buffer_count);
        if (exec_list == NULL || object_list == NULL) {
                DRM_ERROR("Failed to allocate exec or object list "
                          "for %d buffers\n",
@@ -3462,10 +3475,8 @@ err:
        }
 
 pre_mutex_err:
-       drm_free(object_list, sizeof(*object_list) * args->buffer_count,
-                DRM_MEM_DRIVER);
-       drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
-                DRM_MEM_DRIVER);
+       drm_free_large(object_list);
+       drm_free_large(exec_list);
        drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects,
                 DRM_MEM_DRIVER);
 
index 52a059354e83a7397c96dd8401434e6134cceee5..540dd336e6ec682ade96cc0c56f9f7078a2e97ac 100644 (file)
@@ -213,7 +213,8 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
        if (tiling_mode == I915_TILING_NONE)
                return true;
 
-       if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
+       if (!IS_I9XX(dev) ||
+           (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
                tile_width = 128;
        else
                tile_width = 512;
@@ -225,11 +226,18 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
                if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
                        return false;
        } else if (IS_I9XX(dev)) {
-               if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL ||
+               uint32_t pitch_val = ffs(stride / tile_width) - 1;
+
+               /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
+                * instead of 4 (2KB) on 945s.
+                */
+               if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
                    size > (I830_FENCE_MAX_SIZE_VAL << 20))
                        return false;
        } else {
-               if (stride / 128 > I830_FENCE_MAX_PITCH_VAL ||
+               uint32_t pitch_val = ffs(stride / tile_width) - 1;
+
+               if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
                    size > (I830_FENCE_MAX_SIZE_VAL << 19))
                        return false;
        }
index 15da44cf21b13f8270051afed48d860cfa30af7d..375569d01d011fc00be4b94dbae0db06668af6de 100644 (file)
 #define   I830_FENCE_SIZE_BITS(size)   ((ffs((size) >> 19) - 1) << 8)
 #define   I830_FENCE_PITCH_SHIFT       4
 #define   I830_FENCE_REG_VALID         (1<<0)
-#define   I830_FENCE_MAX_PITCH_VAL     0x10
+#define   I915_FENCE_MAX_PITCH_VAL     0x10
+#define   I830_FENCE_MAX_PITCH_VAL     6
 #define   I830_FENCE_MAX_SIZE_VAL      (1<<8)
 
 #define   I915_FENCE_START_MASK                0x0ff00000
 
 /* Cursor A & B regs */
 #define CURACNTR               0x70080
+/* Old style CUR*CNTR flags (desktop 8xx) */
+#define   CURSOR_ENABLE                0x80000000
+#define   CURSOR_GAMMA_ENABLE  0x40000000
+#define   CURSOR_STRIDE_MASK   0x30000000
+#define   CURSOR_FORMAT_SHIFT  24
+#define   CURSOR_FORMAT_MASK   (0x07 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_2C     (0x00 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_3C     (0x01 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_4C     (0x02 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_ARGB   (0x04 << CURSOR_FORMAT_SHIFT)
+#define   CURSOR_FORMAT_XRGB   (0x05 << CURSOR_FORMAT_SHIFT)
+/* New style CUR*CNTR flags */
+#define   CURSOR_MODE          0x27
 #define   CURSOR_MODE_DISABLE   0x00
 #define   CURSOR_MODE_64_32B_AX 0x07
 #define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_PIPE_SELECT  (1 << 28)
+#define   MCURSOR_PIPE_A       0x00
+#define   MCURSOR_PIPE_B       (1 << 28)
 #define   MCURSOR_GAMMA_ENABLE  (1 << 26)
 #define CURABASE               0x70084
 #define CURAPOS                        0x70088
 #define   CURSOR_POS_SIGN       0x8000
 #define   CURSOR_X_SHIFT        0
 #define   CURSOR_Y_SHIFT        16
+#define CURSIZE                        0x700a0
 #define CURBCNTR               0x700c0
 #define CURBBASE               0x700c4
 #define CURBPOS                        0x700c8
index fc28e2bbd5427e6030869724dfb9bd20b5797451..9d78cff33b2478198a72646e183544fafa1aec8d 100644 (file)
@@ -57,9 +57,43 @@ find_section(struct bdb_header *bdb, int section_id)
        return NULL;
 }
 
-/* Try to find panel data */
 static void
-parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
+fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
+                       struct lvds_dvo_timing *dvo_timing)
+{
+       panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
+               dvo_timing->hactive_lo;
+       panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
+               ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
+       panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
+               dvo_timing->hsync_pulse_width;
+       panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
+               ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
+
+       panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
+               dvo_timing->vactive_lo;
+       panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
+               dvo_timing->vsync_off;
+       panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
+               dvo_timing->vsync_pulse_width;
+       panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
+               ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
+       panel_fixed_mode->clock = dvo_timing->clock * 10;
+       panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+
+       /* Some VBTs have bogus h/vtotal values */
+       if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
+               panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
+       if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
+               panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+
+       drm_mode_set_name(panel_fixed_mode);
+}
+
+/* Try to find integrated panel data */
+static void
+parse_lfp_panel_data(struct drm_i915_private *dev_priv,
+                           struct bdb_header *bdb)
 {
        struct bdb_lvds_options *lvds_options;
        struct bdb_lvds_lfp_data *lvds_lfp_data;
@@ -91,38 +125,45 @@ parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
        panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
                                      DRM_MEM_DRIVER);
 
-       panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
-               dvo_timing->hactive_lo;
-       panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
-               ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
-       panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
-               dvo_timing->hsync_pulse_width;
-       panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
-               ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
+       fill_detail_timing_data(panel_fixed_mode, dvo_timing);
 
-       panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
-               dvo_timing->vactive_lo;
-       panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
-               dvo_timing->vsync_off;
-       panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
-               dvo_timing->vsync_pulse_width;
-       panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
-               ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
-       panel_fixed_mode->clock = dvo_timing->clock * 10;
-       panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
+       dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
 
-       /* Some VBTs have bogus h/vtotal values */
-       if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)
-               panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;
-       if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)
-               panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;
+       DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+       drm_mode_debug_printmodeline(panel_fixed_mode);
 
-       drm_mode_set_name(panel_fixed_mode);
+       return;
+}
+
+/* Try to find sdvo panel data */
+static void
+parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
+                     struct bdb_header *bdb)
+{
+       struct bdb_sdvo_lvds_options *sdvo_lvds_options;
+       struct lvds_dvo_timing *dvo_timing;
+       struct drm_display_mode *panel_fixed_mode;
 
-       dev_priv->vbt_mode = panel_fixed_mode;
+       dev_priv->sdvo_lvds_vbt_mode = NULL;
 
-       DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
-       drm_mode_debug_printmodeline(panel_fixed_mode);
+       sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+       if (!sdvo_lvds_options)
+               return;
+
+       dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);
+       if (!dvo_timing)
+               return;
+
+       panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
+                                     DRM_MEM_DRIVER);
+
+       if (!panel_fixed_mode)
+               return;
+
+       fill_detail_timing_data(panel_fixed_mode,
+                       dvo_timing + sdvo_lvds_options->panel_type);
+
+       dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;
 
        return;
 }
@@ -199,7 +240,8 @@ intel_init_bios(struct drm_device *dev)
 
        /* Grab useful general definitions */
        parse_general_features(dev_priv, bdb);
-       parse_panel_data(dev_priv, bdb);
+       parse_lfp_panel_data(dev_priv, bdb);
+       parse_sdvo_panel_data(dev_priv, bdb);
 
        pci_unmap_rom(pdev, bios);
 
index de621aad85b56c9789f1149d6b3806a74c7f8799..8ca2cde15804598374acf140671db2747bdd0010 100644 (file)
@@ -279,6 +279,23 @@ struct vch_bdb_22 {
        struct vch_panel_data panels[16];
 } __attribute__((packed));
 
+struct bdb_sdvo_lvds_options {
+       u8 panel_backlight;
+       u8 h40_set_panel_type;
+       u8 panel_type;
+       u8 ssc_clk_freq;
+       u16 als_low_trip;
+       u16 als_high_trip;
+       u8 sclalarcoeff_tab_row_num;
+       u8 sclalarcoeff_tab_row_size;
+       u8 coefficient[8];
+       u8 panel_misc_bits_1;
+       u8 panel_misc_bits_2;
+       u8 panel_misc_bits_3;
+       u8 panel_misc_bits_4;
+} __attribute__((packed));
+
+
 bool intel_init_bios(struct drm_device *dev);
 
 /*
index 19148c3df63796bde6320dbda053bca73bd469be..640f5158effc742d489942fdc01db5fb024cc52a 100644 (file)
@@ -198,9 +198,142 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
        return intel_ddc_probe(intel_output);
 }
 
+static enum drm_connector_status
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+{
+       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_device *dev = encoder->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       uint32_t pipe = intel_crtc->pipe;
+       uint32_t save_bclrpat;
+       uint32_t save_vtotal;
+       uint32_t vtotal, vactive;
+       uint32_t vsample;
+       uint32_t vblank, vblank_start, vblank_end;
+       uint32_t dsl;
+       uint32_t bclrpat_reg;
+       uint32_t vtotal_reg;
+       uint32_t vblank_reg;
+       uint32_t vsync_reg;
+       uint32_t pipeconf_reg;
+       uint32_t pipe_dsl_reg;
+       uint8_t st00;
+       enum drm_connector_status status;
+
+       if (pipe == 0) {
+               bclrpat_reg = BCLRPAT_A;
+               vtotal_reg = VTOTAL_A;
+               vblank_reg = VBLANK_A;
+               vsync_reg = VSYNC_A;
+               pipeconf_reg = PIPEACONF;
+               pipe_dsl_reg = PIPEADSL;
+       } else {
+               bclrpat_reg = BCLRPAT_B;
+               vtotal_reg = VTOTAL_B;
+               vblank_reg = VBLANK_B;
+               vsync_reg = VSYNC_B;
+               pipeconf_reg = PIPEBCONF;
+               pipe_dsl_reg = PIPEBDSL;
+       }
+
+       save_bclrpat = I915_READ(bclrpat_reg);
+       save_vtotal = I915_READ(vtotal_reg);
+       vblank = I915_READ(vblank_reg);
+
+       vtotal = ((save_vtotal >> 16) & 0xfff) + 1;
+       vactive = (save_vtotal & 0x7ff) + 1;
+
+       vblank_start = (vblank & 0xfff) + 1;
+       vblank_end = ((vblank >> 16) & 0xfff) + 1;
+
+       /* Set the border color to purple. */
+       I915_WRITE(bclrpat_reg, 0x500050);
+
+       if (IS_I9XX(dev)) {
+               uint32_t pipeconf = I915_READ(pipeconf_reg);
+               I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
+               /* Wait for next Vblank to substitue
+                * border color for Color info */
+               intel_wait_for_vblank(dev);
+               st00 = I915_READ8(VGA_MSR_WRITE);
+               status = ((st00 & (1 << 4)) != 0) ?
+                       connector_status_connected :
+                       connector_status_disconnected;
+
+               I915_WRITE(pipeconf_reg, pipeconf);
+       } else {
+               bool restore_vblank = false;
+               int count, detect;
+
+               /*
+               * If there isn't any border, add some.
+               * Yes, this will flicker
+               */
+               if (vblank_start <= vactive && vblank_end >= vtotal) {
+                       uint32_t vsync = I915_READ(vsync_reg);
+                       uint32_t vsync_start = (vsync & 0xffff) + 1;
+
+                       vblank_start = vsync_start;
+                       I915_WRITE(vblank_reg,
+                                  (vblank_start - 1) |
+                                  ((vblank_end - 1) << 16));
+                       restore_vblank = true;
+               }
+               /* sample in the vertical border, selecting the larger one */
+               if (vblank_start - vactive >= vtotal - vblank_end)
+                       vsample = (vblank_start + vactive) >> 1;
+               else
+                       vsample = (vtotal + vblank_end) >> 1;
+
+               /*
+                * Wait for the border to be displayed
+                */
+               while (I915_READ(pipe_dsl_reg) >= vactive)
+                       ;
+               while ((dsl = I915_READ(pipe_dsl_reg)) <= vsample)
+                       ;
+               /*
+                * Watch ST00 for an entire scanline
+                */
+               detect = 0;
+               count = 0;
+               do {
+                       count++;
+                       /* Read the ST00 VGA status register */
+                       st00 = I915_READ8(VGA_MSR_WRITE);
+                       if (st00 & (1 << 4))
+                               detect++;
+               } while ((I915_READ(pipe_dsl_reg) == dsl));
+
+               /* restore vblank if necessary */
+               if (restore_vblank)
+                       I915_WRITE(vblank_reg, vblank);
+               /*
+                * If more than 3/4 of the scanline detected a monitor,
+                * then it is assumed to be present. This works even on i830,
+                * where there isn't any way to force the border color across
+                * the screen
+                */
+               status = detect * 4 > count * 3 ?
+                        connector_status_connected :
+                        connector_status_disconnected;
+       }
+
+       /* Restore previous settings */
+       I915_WRITE(bclrpat_reg, save_bclrpat);
+
+       return status;
+}
+
 static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
+       struct intel_output *intel_output = to_intel_output(connector);
+       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_crtc *crtc;
+       int dpms_mode;
+       enum drm_connector_status status;
 
        if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
                if (intel_crt_detect_hotplug(connector))
@@ -212,8 +345,20 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
        if (intel_crt_detect_ddc(connector))
                return connector_status_connected;
 
-       /* TODO use load detect */
-       return connector_status_unknown;
+       /* for pre-945g platforms use load detect */
+       if (encoder->crtc && encoder->crtc->enabled) {
+               status = intel_crt_load_detect(encoder->crtc, intel_output);
+       } else {
+               crtc = intel_get_load_detect_pipe(intel_output,
+                                                 NULL, &dpms_mode);
+               if (crtc) {
+                       status = intel_crt_load_detect(crtc, intel_output);
+                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+               } else
+                       status = connector_status_unknown;
+       }
+
+       return status;
 }
 
 static void intel_crt_destroy(struct drm_connector *connector)
index 3387cf32f385cb103fe84f4722a1003810118914..c9d6f10ba92eb833620d1c686c234ffc574eb81a 100644 (file)
@@ -1357,7 +1357,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        int pipe = intel_crtc->pipe;
        uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
        uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
-       uint32_t temp;
+       uint32_t temp = I915_READ(control);
        size_t addr;
        int ret;
 
@@ -1366,7 +1366,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        /* if we want to turn off the cursor ignore width and height */
        if (!handle) {
                DRM_DEBUG("cursor off\n");
-               temp = CURSOR_MODE_DISABLE;
+               if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+                       temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
+                       temp |= CURSOR_MODE_DISABLE;
+               } else {
+                       temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
+               }
                addr = 0;
                bo = NULL;
                mutex_lock(&dev->struct_mutex);
@@ -1409,10 +1414,19 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                addr = obj_priv->phys_obj->handle->busaddr;
        }
 
-       temp = 0;
-       /* set the pipe for the cursor */
-       temp |= (pipe << 28);
-       temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+       if (!IS_I9XX(dev))
+               I915_WRITE(CURSIZE, (height << 12) | width);
+
+       /* Hooray for CUR*CNTR differences */
+       if (IS_MOBILE(dev) || IS_I9XX(dev)) {
+               temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+               temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+               temp |= (pipe << 28); /* Connect to correct pipe */
+       } else {
+               temp &= ~(CURSOR_FORMAT_MASK);
+               temp |= CURSOR_ENABLE;
+               temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
+       }
 
  finish:
        I915_WRITE(control, temp);
index 439a86514993b991606f1d13ba14cb3406b617b1..53731f0ffcb52b4d3444cdfe659f38b5fec479a0 100644 (file)
@@ -511,10 +511,10 @@ void intel_lvds_init(struct drm_device *dev)
        }
 
        /* Failed to get EDID, what about VBT? */
-       if (dev_priv->vbt_mode) {
+       if (dev_priv->lfp_lvds_vbt_mode) {
                mutex_lock(&dev->mode_config.mutex);
                dev_priv->panel_fixed_mode =
-                       drm_mode_duplicate(dev, dev_priv->vbt_mode);
+                       drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);
                mutex_unlock(&dev->mode_config.mutex);
                if (dev_priv->panel_fixed_mode) {
                        dev_priv->panel_fixed_mode->type |=
index 9913651c1e1703d78dba7eb34ab3fdd82135a3e3..f3ef6bfd8ffc93fe0cab884238ddc0043cc4bcaf 100644 (file)
@@ -69,6 +69,10 @@ struct intel_sdvo_priv {
         * This is set if we treat the device as HDMI, instead of DVI.
         */
        bool is_hdmi;
+       /**
+        * This is set if we detect output of sdvo device as LVDS.
+        */
+       bool is_lvds;
 
        /**
         * Returned SDTV resolutions allowed for the current format, if the
@@ -1398,10 +1402,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 {
        struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 
        /* set the bus switch and get the modes */
-       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
        intel_ddc_get_modes(intel_output);
 
 #if 0
@@ -1543,6 +1545,37 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
                }
 }
 
+static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
+{
+       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct drm_i915_private *dev_priv = connector->dev->dev_private;
+
+       /*
+        * Attempt to get the mode list from DDC.
+        * Assume that the preferred modes are
+        * arranged in priority order.
+        */
+       /* set the bus switch and get the modes */
+       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+       intel_ddc_get_modes(intel_output);
+       if (list_empty(&connector->probed_modes) == false)
+               return;
+
+       /* Fetch modes from VBT */
+       if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
+               struct drm_display_mode *newmode;
+               newmode = drm_mode_duplicate(connector->dev,
+                                            dev_priv->sdvo_lvds_vbt_mode);
+               if (newmode != NULL) {
+                       /* Guarantee the mode is preferred */
+                       newmode->type = (DRM_MODE_TYPE_PREFERRED |
+                                        DRM_MODE_TYPE_DRIVER);
+                       drm_mode_probed_add(connector, newmode);
+               }
+       }
+}
+
 static int intel_sdvo_get_modes(struct drm_connector *connector)
 {
        struct intel_output *output = to_intel_output(connector);
@@ -1550,6 +1583,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
 
        if (sdvo_priv->is_tv)
                intel_sdvo_get_tv_modes(connector);
+       else if (sdvo_priv->is_lvds == true)
+               intel_sdvo_get_lvds_modes(connector);
        else
                intel_sdvo_get_ddc_modes(connector);
 
@@ -1564,6 +1599,9 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
 
        if (intel_output->i2c_bus)
                intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_output->ddc_bus)
+               intel_i2c_destroy(intel_output->ddc_bus);
+
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
        kfree(intel_output);
@@ -1660,12 +1698,56 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
        return true;
 }
 
+static struct intel_output *
+intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+{
+       struct drm_device *dev = chan->drm_dev;
+       struct drm_connector *connector;
+       struct intel_output *intel_output = NULL;
+
+       list_for_each_entry(connector,
+                       &dev->mode_config.connector_list, head) {
+               if (to_intel_output(connector)->ddc_bus == chan) {
+                       intel_output = to_intel_output(connector);
+                       break;
+               }
+       }
+       return intel_output;
+}
+
+static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
+                                 struct i2c_msg msgs[], int num)
+{
+       struct intel_output *intel_output;
+       struct intel_sdvo_priv *sdvo_priv;
+       struct i2c_algo_bit_data *algo_data;
+       struct i2c_algorithm *algo;
+
+       algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
+       intel_output =
+               intel_sdvo_chan_to_intel_output(
+                               (struct intel_i2c_chan *)(algo_data->data));
+       if (intel_output == NULL)
+               return -EINVAL;
+
+       sdvo_priv = intel_output->dev_priv;
+       algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo;
+
+       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+       return algo->master_xfer(i2c_adap, msgs, num);
+}
+
+static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
+       .master_xfer    = intel_sdvo_master_xfer,
+};
+
 bool intel_sdvo_init(struct drm_device *dev, int output_device)
 {
        struct drm_connector *connector;
        struct intel_output *intel_output;
        struct intel_sdvo_priv *sdvo_priv;
        struct intel_i2c_chan *i2cbus = NULL;
+       struct intel_i2c_chan *ddcbus = NULL;
        int connector_type;
        u8 ch[0x40];
        int i;
@@ -1676,17 +1758,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
                return false;
        }
 
-       connector = &intel_output->base;
-
-       drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
-                          DRM_MODE_CONNECTOR_Unknown);
-       drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
        sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
        intel_output->type = INTEL_OUTPUT_SDVO;
 
-       connector->interlace_allowed = 0;
-       connector->doublescan_allowed = 0;
-
        /* setup the DDC bus. */
        if (output_device == SDVOB)
                i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
@@ -1694,7 +1768,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
                i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
        if (!i2cbus)
-               goto err_connector;
+               goto err_inteloutput;
 
        sdvo_priv->i2c_bus = i2cbus;
 
@@ -1710,7 +1784,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        intel_output->i2c_bus = i2cbus;
        intel_output->dev_priv = sdvo_priv;
 
-
        /* Read the regs to test if we can talk to the device */
        for (i = 0; i < 0x40; i++) {
                if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
@@ -1720,6 +1793,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
                }
        }
 
+       /* setup the DDC bus. */
+       if (output_device == SDVOB)
+               ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+       else
+               ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+
+       if (ddcbus == NULL)
+               goto err_i2c;
+
+       intel_sdvo_i2c_bit_algo.functionality =
+               intel_output->i2c_bus->adapter.algo->functionality;
+       ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo;
+       intel_output->ddc_bus = ddcbus;
+
+       /* In defaut case sdvo lvds is false */
+       sdvo_priv->is_lvds = false;
        intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
 
        if (sdvo_priv->caps.output_flags &
@@ -1729,7 +1818,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
                else
                        sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
 
-               connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                encoder_type = DRM_MODE_ENCODER_TMDS;
                connector_type = DRM_MODE_CONNECTOR_DVID;
 
@@ -1747,7 +1835,6 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
        {
                sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
-               connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
@@ -1756,30 +1843,28 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
        {
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
-               connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                encoder_type = DRM_MODE_ENCODER_DAC;
                connector_type = DRM_MODE_CONNECTOR_VGA;
        }
        else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
        {
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
-               connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                encoder_type = DRM_MODE_ENCODER_DAC;
                connector_type = DRM_MODE_CONNECTOR_VGA;
        }
        else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
        {
                sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
-               connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                encoder_type = DRM_MODE_ENCODER_LVDS;
                connector_type = DRM_MODE_CONNECTOR_LVDS;
+               sdvo_priv->is_lvds = true;
        }
        else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
        {
                sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
-               connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                encoder_type = DRM_MODE_ENCODER_LVDS;
                connector_type = DRM_MODE_CONNECTOR_LVDS;
+               sdvo_priv->is_lvds = true;
        }
        else
        {
@@ -1795,9 +1880,16 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
                goto err_i2c;
        }
 
+       connector = &intel_output->base;
+       drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
+                          connector_type);
+       drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
+       connector->interlace_allowed = 0;
+       connector->doublescan_allowed = 0;
+       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+
        drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
        drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
-       connector->connector_type = connector_type;
 
        drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
        drm_sysfs_connector_add(connector);
@@ -1829,14 +1921,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
                  sdvo_priv->caps.output_flags &
                        (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
 
-       intel_output->ddc_bus = i2cbus;
-
        return true;
 
 err_i2c:
+       if (ddcbus != NULL)
+               intel_i2c_destroy(intel_output->ddc_bus);
        intel_i2c_destroy(intel_output->i2c_bus);
-err_connector:
-       drm_connector_cleanup(connector);
+err_inteloutput:
        kfree(intel_output);
 
        return false;
index bf740394d70431f1cb0f37732f6ca68fd7aaa4ed..949c97ff57e35bec6917c4aab4aca2ebaa165c32 100644 (file)
@@ -41,6 +41,10 @@ static int debug;
 module_param_named(debug, debug, uint, 0644);
 MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
 
+static int forceload;
+module_param_named(forceload, forceload, uint, 0644);
+MODULE_PARM_DESC(debug, "Enable driver testing on unvalidated i5000");
+
 #define dprintk(fmt, arg...) \
        do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0)
 
@@ -552,7 +556,7 @@ static int __init i7300_idle_init(void)
        cpus_clear(idle_cpumask);
        total_us = 0;
 
-       if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev))
+       if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload))
                return -ENODEV;
 
        if (i7300_idle_thrt_save())
index e54e002665b0c7d697ae9dc5cc0750747bde9069..5d445f48789b899528c1f30d1f1115f324d553a5 100644 (file)
@@ -42,6 +42,7 @@ static unsigned int input_abs_bypass_init_data[] __initdata = {
        ABS_MT_POSITION_Y,
        ABS_MT_TOOL_TYPE,
        ABS_MT_BLOB_ID,
+       ABS_MT_TRACKING_ID,
        0
 };
 static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
index 67248c31e19a06ab17ba7980bfd3c04fb54d7a52..be5bbbb8ae4ee5105439fc074af9a779654920eb 100644 (file)
@@ -210,7 +210,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
        timeout = wait_event_timeout(ps2dev->wait,
                                     !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
 
-       if (ps2dev->cmdcnt && timeout > 0) {
+       if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
 
                timeout = ps2_adjust_timeout(ps2dev, command, timeout);
                wait_event_timeout(ps2dev->wait,
index f100c7f4c1dbf2ea72ad771f0775e39d666dd3ed..6954f55001080d29b337a37c9398b6c8f867ec1a 100644 (file)
@@ -419,7 +419,7 @@ static int ucb1400_ts_remove(struct platform_device *dev)
 #ifdef CONFIG_PM
 static int ucb1400_ts_resume(struct platform_device *dev)
 {
-       struct ucb1400_ts *ucb = platform_get_drvdata(dev);
+       struct ucb1400_ts *ucb = dev->dev.platform_data;
 
        if (ucb->ts_task) {
                /*
index b171e75cb52e51f920125abc984648f22415e961..29808c4fb1cb658ddc9c91f9187ef4cadb39afa4 100644 (file)
@@ -175,7 +175,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
                return -EINVAL;
        }
        src = iwb->read;
-       if (unlikely(limit > BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
+       if (unlikely(limit >= BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
                     (read < src && limit >= src))) {
                pr_err("isoc write buffer frame reservation violated\n");
                return -EFAULT;
index 1a83910f674f031cded0dd302d485ad9e6804365..eaf722fe309a2919de7cd3488b452b7604d94546 100644 (file)
@@ -358,6 +358,16 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
                        if (emulate_insn(cpu))
                                return;
                }
+               /* If KVM is active, the vmcall instruction triggers a
+                * General Protection Fault.  Normally it triggers an
+                * invalid opcode fault (6): */
+       case 6:
+               /* We need to check if ring == GUEST_PL and
+                * faulting instruction == vmcall. */
+               if (is_hypercall(cpu)) {
+                       rewrite_hypercall(cpu);
+                       return;
+               }
                break;
        case 14: /* We've intercepted a Page Fault. */
                /* The Guest accessed a virtual address that wasn't mapped.
@@ -403,15 +413,6 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
                 * up the pointer now to indicate a hypercall is pending. */
                cpu->hcall = (struct hcall_args *)cpu->regs;
                return;
-       case 6:
-               /* kvm hypercalls trigger an invalid opcode fault (6).
-                * We need to check if ring == GUEST_PL and
-                * faulting instruction == vmcall. */
-               if (is_hypercall(cpu)) {
-                       rewrite_hypercall(cpu);
-                       return;
-               }
-               break;
        }
 
        /* We didn't handle the trap, so it needs to go to the Guest. */
index 47c68bc75a1780be7e1b6679e64d8ee8b6e860e9..56df1cee8fb3435a43e33b07ba1a3dadaf528680 100644 (file)
@@ -1097,14 +1097,12 @@ void bitmap_daemon_work(struct bitmap *bitmap)
        }
        bitmap->allclean = 1;
 
+       spin_lock_irqsave(&bitmap->lock, flags);
        for (j = 0; j < bitmap->chunks; j++) {
                bitmap_counter_t *bmc;
-               spin_lock_irqsave(&bitmap->lock, flags);
-               if (!bitmap->filemap) {
+               if (!bitmap->filemap)
                        /* error or shutdown */
-                       spin_unlock_irqrestore(&bitmap->lock, flags);
                        break;
-               }
 
                page = filemap_get_page(bitmap, j);
 
@@ -1121,6 +1119,8 @@ void bitmap_daemon_work(struct bitmap *bitmap)
                                        write_page(bitmap, page, 0);
                                        bitmap->allclean = 0;
                                }
+                               spin_lock_irqsave(&bitmap->lock, flags);
+                               j |= (PAGE_BITS - 1);
                                continue;
                        }
 
@@ -1181,9 +1181,10 @@ void bitmap_daemon_work(struct bitmap *bitmap)
                                        ext2_clear_bit(file_page_offset(j), paddr);
                                kunmap_atomic(paddr, KM_USER0);
                        }
-               }
-               spin_unlock_irqrestore(&bitmap->lock, flags);
+               } else
+                       j |= PAGE_COUNTER_MASK;
        }
+       spin_unlock_irqrestore(&bitmap->lock, flags);
 
        /* now sync the final page */
        if (lastpage != NULL) {
index fccc8343a2501dbb8db452ea9e5469df11ef53e1..641b211fe3feb33e15cb1159e3a76ca26b90c124 100644 (file)
@@ -1375,6 +1375,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
 
        sb->raid_disks = cpu_to_le32(mddev->raid_disks);
        sb->size = cpu_to_le64(mddev->dev_sectors);
+       sb->chunksize = cpu_to_le32(mddev->chunk_size >> 9);
+       sb->level = cpu_to_le32(mddev->level);
+       sb->layout = cpu_to_le32(mddev->layout);
 
        if (mddev->bitmap && mddev->bitmap_file == NULL) {
                sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
@@ -3303,7 +3306,9 @@ static ssize_t
 action_show(mddev_t *mddev, char *page)
 {
        char *type = "idle";
-       if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+       if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+               type = "frozen";
+       else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
            (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
                if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
                        type = "reshape";
@@ -3326,7 +3331,12 @@ action_store(mddev_t *mddev, const char *page, size_t len)
        if (!mddev->pers || !mddev->pers->sync_request)
                return -EINVAL;
 
-       if (cmd_match(page, "idle")) {
+       if (cmd_match(page, "frozen"))
+               set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+       else
+               clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+
+       if (cmd_match(page, "idle") || cmd_match(page, "frozen")) {
                if (mddev->sync_thread) {
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
                        md_unregister_thread(mddev->sync_thread);
@@ -3680,7 +3690,7 @@ array_size_store(mddev_t *mddev, const char *buf, size_t len)
                if (strict_blocks_to_sectors(buf, &sectors) < 0)
                        return -EINVAL;
                if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
-                       return -EINVAL;
+                       return -E2BIG;
 
                mddev->external_size = 1;
        }
@@ -5557,7 +5567,7 @@ static struct block_device_operations md_fops =
        .owner          = THIS_MODULE,
        .open           = md_open,
        .release        = md_release,
-       .locked_ioctl   = md_ioctl,
+       .ioctl          = md_ioctl,
        .getgeo         = md_getgeo,
        .media_changed  = md_media_changed,
        .revalidate_disk= md_revalidate,
@@ -6352,12 +6362,13 @@ void md_do_sync(mddev_t *mddev)
 
                skipped = 0;
 
-               if ((mddev->curr_resync > mddev->curr_resync_completed &&
-                    (mddev->curr_resync - mddev->curr_resync_completed)
-                   > (max_sectors >> 4)) ||
-                   (j - mddev->curr_resync_completed)*2
-                   >= mddev->resync_max - mddev->curr_resync_completed
-                       ) {
+               if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+                   ((mddev->curr_resync > mddev->curr_resync_completed &&
+                     (mddev->curr_resync - mddev->curr_resync_completed)
+                     > (max_sectors >> 4)) ||
+                    (j - mddev->curr_resync_completed)*2
+                    >= mddev->resync_max - mddev->curr_resync_completed
+                           )) {
                        /* time to update curr_resync_completed */
                        blk_unplug(mddev->queue);
                        wait_event(mddev->recovery_wait,
index 4616bc3a6e713065e689943db4cdde421076d318..5d400aef8d9b40f9ec0a58749037bcbbf61977df 100644 (file)
@@ -3811,13 +3811,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
        safepos = conf->reshape_safe;
        sector_div(safepos, data_disks);
        if (mddev->delta_disks < 0) {
-               writepos -= reshape_sectors;
+               writepos -= min_t(sector_t, reshape_sectors, writepos);
                readpos += reshape_sectors;
                safepos += reshape_sectors;
        } else {
                writepos += reshape_sectors;
-               readpos -= reshape_sectors;
-               safepos -= reshape_sectors;
+               readpos -= min_t(sector_t, reshape_sectors, readpos);
+               safepos -= min_t(sector_t, reshape_sectors, safepos);
        }
 
        /* 'writepos' is the most advanced device address we might write.
index f3548d0480142cb5fa8c5e599ff3b8add7b91e97..40c26080ecdaab563e8cacfd63e716d7f34f172f 100644 (file)
@@ -831,6 +831,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
                break;
 
        case NAND_CMD_READID:
+               host->col_addr = 0;
                send_read_id(host);
                break;
 
@@ -867,6 +868,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        mtd->priv = this;
        mtd->owner = THIS_MODULE;
        mtd->dev.parent = &pdev->dev;
+       mtd->name = "mxc_nand";
 
        /* 50 us command delay time */
        this->chip_delay = 5;
@@ -882,8 +884,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        this->verify_buf = mxc_nand_verify_buf;
 
        host->clk = clk_get(&pdev->dev, "nfc");
-       if (IS_ERR(host->clk))
+       if (IS_ERR(host->clk)) {
+               err = PTR_ERR(host->clk);
                goto eclk;
+       }
 
        clk_enable(host->clk);
        host->clk_act = 1;
@@ -896,7 +900,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
 
        host->regs = ioremap(res->start, res->end - res->start + 1);
        if (!host->regs) {
-               err = -EIO;
+               err = -ENOMEM;
                goto eres;
        }
 
@@ -1011,30 +1015,35 @@ static int __devexit mxcnd_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM
 static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       struct mtd_info *info = platform_get_drvdata(pdev);
+       struct mtd_info *mtd = platform_get_drvdata(pdev);
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
        int ret = 0;
 
        DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n");
-       if (info)
-               ret = info->suspend(info);
-
-       /* Disable the NFC clock */
-       clk_disable(nfc_clk);   /* FIXME */
+       if (mtd) {
+               ret = mtd->suspend(mtd);
+               /* Disable the NFC clock */
+               clk_disable(host->clk);
+       }
 
        return ret;
 }
 
 static int mxcnd_resume(struct platform_device *pdev)
 {
-       struct mtd_info *info = platform_get_drvdata(pdev);
+       struct mtd_info *mtd = platform_get_drvdata(pdev);
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
        int ret = 0;
 
        DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
-       /* Enable the NFC clock */
-       clk_enable(nfc_clk);    /* FIXME */
 
-       if (info)
-               info->resume(info);
+       if (mtd) {
+               /* Enable the NFC clock */
+               clk_enable(host->clk);
+               mtd->resume(mtd);
+       }
 
        return ret;
 }
@@ -1055,13 +1064,7 @@ static struct platform_driver mxcnd_driver = {
 
 static int __init mxc_nd_init(void)
 {
-       /* Register the device driver structure. */
-       pr_info("MXC MTD nand Driver\n");
-       if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) {
-               printk(KERN_ERR "Driver register failed for mxcnd_driver\n");
-               return -ENODEV;
-       }
-       return 0;
+       return platform_driver_probe(&mxcnd_driver, mxcnd_probe);
 }
 
 static void __exit mxc_nd_cleanup(void)
index 1fc4602a6ff2c29912f64759207f0d38a8e17895..a1c25cb4669fb8b9a95b7a1410355423d46b5599 100644 (file)
@@ -102,7 +102,7 @@ obj-$(CONFIG_HAMACHI) += hamachi.o
 obj-$(CONFIG_NET) += Space.o loopback.o
 obj-$(CONFIG_SEEQ8005) += seeq8005.o
 obj-$(CONFIG_NET_SB1000) += sb1000.o
-obj-$(CONFIG_MAC8390) += mac8390.o 8390.o
+obj-$(CONFIG_MAC8390) += mac8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
 obj-$(CONFIG_HP100) += hp100.o
index b2c49679bba78407fe51d58b57cc62344feb7b0d..a0519184e54ee7d7a30aed189a7ce13e5ab122f1 100644 (file)
@@ -1885,8 +1885,17 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 
                        if (unlikely(!newskb))
                                newskb = skb;
-                       else if (skb)
+                       else if (skb) {
+                               /*
+                                * We need to reset ->data to what it
+                                * was before gfar_new_skb() re-aligned
+                                * it to an RXBUF_ALIGNMENT boundary
+                                * before we put the skb back on the
+                                * recycle list.
+                                */
+                               skb->data = skb->head + NET_SKB_PAD;
                                __skb_queue_head(&priv->rx_recycle, skb);
+                       }
                } else {
                        /* Increment the number of packets */
                        dev->stats.rx_packets++;
index 8e884869a05bfd40995af322554e6601c6d129c5..f26667d5eaaec9a4c8837528259665cff1513a6f 100644 (file)
@@ -304,7 +304,7 @@ struct net_device * __init mac8390_probe(int unit)
        if (!MACH_IS_MAC)
                return ERR_PTR(-ENODEV);
 
-       dev = alloc_ei_netdev();
+       dev = ____alloc_ei_netdev(0);
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
@@ -481,10 +481,10 @@ void cleanup_module(void)
 static const struct net_device_ops mac8390_netdev_ops = {
        .ndo_open               = mac8390_open,
        .ndo_stop               = mac8390_close,
-       .ndo_start_xmit         = ei_start_xmit,
-       .ndo_tx_timeout         = ei_tx_timeout,
-       .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_start_xmit         = __ei_start_xmit,
+       .ndo_tx_timeout         = __ei_tx_timeout,
+       .ndo_get_stats          = __ei_get_stats,
+       .ndo_set_multicast_list = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
index 0b6e8c89683581efdfc35925adaa018998468db5..8247a945a1d9b0df7f11aebc858eccb7552a02cd 100644 (file)
@@ -3554,54 +3554,64 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
        int handled = 0;
        int status;
 
+       /* loop handling interrupts until we have no new ones or
+        * we hit a invalid/hotplug case.
+        */
        status = RTL_R16(IntrStatus);
+       while (status && status != 0xffff) {
+               handled = 1;
 
-       /* hotplug/major error/no more work/shared irq */
-       if ((status == 0xffff) || !status)
-               goto out;
-
-       handled = 1;
+               /* Handle all of the error cases first. These will reset
+                * the chip, so just exit the loop.
+                */
+               if (unlikely(!netif_running(dev))) {
+                       rtl8169_asic_down(ioaddr);
+                       break;
+               }
 
-       if (unlikely(!netif_running(dev))) {
-               rtl8169_asic_down(ioaddr);
-               goto out;
-       }
+               /* Work around for rx fifo overflow */
+               if (unlikely(status & RxFIFOOver) &&
+               (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+                       netif_stop_queue(dev);
+                       rtl8169_tx_timeout(dev);
+                       break;
+               }
 
-       status &= tp->intr_mask;
-       RTL_W16(IntrStatus,
-               (status & RxFIFOOver) ? (status | RxOverflow) : status);
+               if (unlikely(status & SYSErr)) {
+                       rtl8169_pcierr_interrupt(dev);
+                       break;
+               }
 
-       if (!(status & tp->intr_event))
-               goto out;
+               if (status & LinkChg)
+                       rtl8169_check_link_status(dev, tp, ioaddr);
 
-       /* Work around for rx fifo overflow */
-       if (unlikely(status & RxFIFOOver) &&
-           (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
-               netif_stop_queue(dev);
-               rtl8169_tx_timeout(dev);
-               goto out;
-       }
+               /* We need to see the lastest version of tp->intr_mask to
+                * avoid ignoring an MSI interrupt and having to wait for
+                * another event which may never come.
+                */
+               smp_rmb();
+               if (status & tp->intr_mask & tp->napi_event) {
+                       RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+                       tp->intr_mask = ~tp->napi_event;
+
+                       if (likely(napi_schedule_prep(&tp->napi)))
+                               __napi_schedule(&tp->napi);
+                       else if (netif_msg_intr(tp)) {
+                               printk(KERN_INFO "%s: interrupt %04x in poll\n",
+                               dev->name, status);
+                       }
+               }
 
-       if (unlikely(status & SYSErr)) {
-               rtl8169_pcierr_interrupt(dev);
-               goto out;
+               /* We only get a new MSI interrupt when all active irq
+                * sources on the chip have been acknowledged. So, ack
+                * everything we've seen and check if new sources have become
+                * active to avoid blocking all interrupts from the chip.
+                */
+               RTL_W16(IntrStatus,
+                       (status & RxFIFOOver) ? (status | RxOverflow) : status);
+               status = RTL_R16(IntrStatus);
        }
 
-       if (status & LinkChg)
-               rtl8169_check_link_status(dev, tp, ioaddr);
-
-       if (status & tp->napi_event) {
-               RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
-               tp->intr_mask = ~tp->napi_event;
-
-               if (likely(napi_schedule_prep(&tp->napi)))
-                       __napi_schedule(&tp->napi);
-               else if (netif_msg_intr(tp)) {
-                       printk(KERN_INFO "%s: interrupt %04x in poll\n",
-                              dev->name, status);
-               }
-       }
-out:
        return IRQ_RETVAL(handled);
 }
 
@@ -3617,13 +3627,15 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
 
        if (work_done < budget) {
                napi_complete(napi);
-               tp->intr_mask = 0xffff;
-               /*
-                * 20040426: the barrier is not strictly required but the
-                * behavior of the irq handler could be less predictable
-                * without it. Btw, the lack of flush for the posted pci
-                * write is safe - FR
+
+               /* We need for force the visibility of tp->intr_mask
+                * for other CPUs, as we can loose an MSI interrupt
+                * and potentially wait for a retransmit timeout if we don't.
+                * The posted write to IntrMask is safe, as it will
+                * eventually make it to the chip and we won't loose anything
+                * until it does.
                 */
+               tp->intr_mask = 0xffff;
                smp_wmb();
                RTL_W16(IntrMask, tp->intr_event);
        }
index ca4151a9e2229a20b88149577db093e98a942aae..17851321b7fd0ea7bd1e7815577ba5654de149ce 100644 (file)
@@ -505,27 +505,52 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg)
 #ifdef CONFIG_PM
        struct usb_device *usb_dev = i2400mu->usb_dev;
 #endif
+       unsigned is_autosuspend = 0;
        struct i2400m *i2400m = &i2400mu->i2400m;
 
+#ifdef CONFIG_PM
+       if (usb_dev->auto_pm > 0)
+               is_autosuspend = 1;
+#endif
+
        d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event);
        if (i2400m->updown == 0)
                goto no_firmware;
-       d_printf(1, dev, "fw up, requesting standby\n");
+       if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) {
+               /* ugh -- the device is connected and this suspend
+                * request is an autosuspend one (not a system standby
+                * / hibernate).
+                *
+                * The only way the device can go to standby is if the
+                * link with the base station is in IDLE mode; that
+                * were the case, we'd be in status
+                * I2400M_SS_CONNECTED_IDLE. But we are not.
+                *
+                * If we *tell* him to go power save now, it'll reset
+                * as a precautionary measure, so if this is an
+                * autosuspend thing, say no and it'll come back
+                * later, when the link is IDLE
+                */
+               result = -EBADF;
+               d_printf(1, dev, "fw up, link up, not-idle, autosuspend: "
+                        "not entering powersave\n");
+               goto error_not_now;
+       }
+       d_printf(1, dev, "fw up: entering powersave\n");
        atomic_dec(&i2400mu->do_autopm);
        result = i2400m_cmd_enter_powersave(i2400m);
        atomic_inc(&i2400mu->do_autopm);
-#ifdef CONFIG_PM
-       if (result < 0 && usb_dev->auto_pm == 0) {
+       if (result < 0 && !is_autosuspend) {
                /* System suspend, can't fail */
                dev_err(dev, "failed to suspend, will reset on resume\n");
                result = 0;
        }
-#endif
        if (result < 0)
                goto error_enter_powersave;
        i2400mu_notification_release(i2400mu);
-       d_printf(1, dev, "fw up, got standby\n");
+       d_printf(1, dev, "powersave requested\n");
 error_enter_powersave:
+error_not_now:
 no_firmware:
        d_fnend(3, dev, "(iface %p pm_msg %u) = %d\n",
                iface, pm_msg.event, result);
index d734757391270be2b549a89376df0ccb38bb66bf..9eabf4d1f2e7cd021f5041576776aeb1a658a905 100644 (file)
@@ -6467,6 +6467,7 @@ static int airo_get_encode(struct net_device *dev,
 {
        struct airo_info *local = dev->ml_priv;
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+       int wep_key_len;
        u8 buf[16];
 
        if (!local->wep_capable)
@@ -6500,11 +6501,13 @@ static int airo_get_encode(struct net_device *dev,
        dwrq->flags |= index + 1;
 
        /* Copy the key to the user buffer */
-       dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf));
-       if (dwrq->length != -1)
-               memcpy(extra, buf, dwrq->length);
-       else
+       wep_key_len = get_wep_key(local, index, &buf[0], sizeof(buf));
+       if (wep_key_len < 0) {
                dwrq->length = 0;
+       } else {
+               dwrq->length = wep_key_len;
+               memcpy(extra, buf, dwrq->length);
+       }
 
        return 0;
 }
@@ -6617,7 +6620,7 @@ static int airo_get_encodeext(struct net_device *dev,
        struct airo_info *local = dev->ml_priv;
        struct iw_point *encoding = &wrqu->encoding;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-       int idx, max_key_len;
+       int idx, max_key_len, wep_key_len;
        u8 buf[16];
 
        if (!local->wep_capable)
@@ -6661,11 +6664,13 @@ static int airo_get_encodeext(struct net_device *dev,
        memset(extra, 0, 16);
        
        /* Copy the key to the user buffer */
-       ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
-       if (ext->key_len != -1)
-               memcpy(extra, buf, ext->key_len);
-       else
+       wep_key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
+       if (wep_key_len < 0) {
                ext->key_len = 0;
+       } else {
+               ext->key_len = wep_key_len;
+               memcpy(extra, buf, ext->key_len);
+       }
 
        return 0;
 }
index 9e2faae5ae942c81d5a857d2b9c528138370cbfa..b48b29dca3d2a6b70ad1e08479d12dea51f5a69d 100644 (file)
@@ -1487,28 +1487,35 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
 {
        s8 tmp;
        s16 min_pwrL, min_pwrR;
-       s16 pwr_i = pwrL[0];
-
-       do {
-               pwr_i--;
-               tmp = (s8) ath5k_get_interpolated_value(pwr_i,
-                                               pwrL[0], pwrL[1],
-                                               stepL[0], stepL[1]);
-
-       } while (tmp > 1);
-
-       min_pwrL = pwr_i;
-
-       pwr_i = pwrR[0];
-       do {
-               pwr_i--;
-               tmp = (s8) ath5k_get_interpolated_value(pwr_i,
-                                               pwrR[0], pwrR[1],
-                                               stepR[0], stepR[1]);
-
-       } while (tmp > 1);
+       s16 pwr_i;
+
+       if (pwrL[0] == pwrL[1])
+               min_pwrL = pwrL[0];
+       else {
+               pwr_i = pwrL[0];
+               do {
+                       pwr_i--;
+                       tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+                                                       pwrL[0], pwrL[1],
+                                                       stepL[0], stepL[1]);
+               } while (tmp > 1);
+
+               min_pwrL = pwr_i;
+       }
 
-       min_pwrR = pwr_i;
+       if (pwrR[0] == pwrR[1])
+               min_pwrR = pwrR[0];
+       else {
+               pwr_i = pwrR[0];
+               do {
+                       pwr_i--;
+                       tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+                                                       pwrR[0], pwrR[1],
+                                                       stepR[0], stepR[1]);
+               } while (tmp > 1);
+
+               min_pwrR = pwr_i;
+       }
 
        /* Keep the right boundary so that it works for both curves */
        return max(min_pwrL, min_pwrR);
index 7a17d31b2fd9f762a2bd8870639e7e0ed8b3723c..5f72c111c2e8fbec500ef4e50fce7acff2ef685e 100644 (file)
@@ -26,7 +26,7 @@
 \*****************************/
 
 #include <linux/pci.h>                 /* To determine if a card is pci-e */
-#include <linux/bitops.h>      /* For get_bitmask_order */
+#include <linux/log2.h>
 #include "ath5k.h"
 #include "reg.h"
 #include "base.h"
@@ -69,10 +69,10 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
 
        /* Get exponent
         * ALGO: coef_exp = 14 - highest set bit position */
-       coef_exp = get_bitmask_order(coef_scaled);
+       coef_exp = ilog2(coef_scaled);
 
        /* Doesn't make sense if it's zero*/
-       if (!coef_exp)
+       if (!coef_scaled || !coef_exp)
                return -EINVAL;
 
        /* Note: we've shifted coef_scaled by 24 */
@@ -359,7 +359,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
                        mode |= AR5K_PHY_MODE_FREQ_5GHZ;
 
                        if (ah->ah_radio == AR5K_RF5413)
-                               clock |= AR5K_PHY_PLL_40MHZ_5413;
+                               clock = AR5K_PHY_PLL_40MHZ_5413;
                        else
                                clock |= AR5K_PHY_PLL_40MHZ;
 
index e5ca2511a81a2b5949a1373ff87b329f77c161e2..9452461ce8645be87d9c3779e6388bb910d8ea63 100644 (file)
@@ -46,7 +46,7 @@
 #include "iwl-6000-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL5000_UCODE_API_MAX 1
+#define IWL5000_UCODE_API_MAX 2
 #define IWL5150_UCODE_API_MAX 2
 
 /* Lowest firmware API version supported */
index 3bb28db4a40fd5aa71dfc08ac4605a84dda17e86..f46ba24757768226a842ef1f51bc0b61f53275cd 100644 (file)
@@ -669,13 +669,6 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
        if (!iwl_is_ready_rf(priv))
                return -EAGAIN;
 
-       cancel_delayed_work(&priv->scan_check);
-       if (iwl_scan_cancel_timeout(priv, 100)) {
-               IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
-               IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
-               return -EAGAIN;
-       }
-
        iwl_commit_rxon(priv);
 
        return 0;
index e7c65c4f741bfb0be178586d4e8c908de347c653..6330b91e37ceab65eb776e4c336a91bf827b5607 100644 (file)
@@ -227,9 +227,6 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
        /* The HW is no longer scanning */
        clear_bit(STATUS_SCAN_HW, &priv->status);
 
-       /* The scan completion notification came in, so kill that timer... */
-       cancel_delayed_work(&priv->scan_check);
-
        IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n",
                       (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
                                                "2.4" : "5.2",
@@ -712,6 +709,8 @@ static void iwl_bg_request_scan(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
+       cancel_delayed_work(&priv->scan_check);
+
        if (!iwl_is_ready(priv)) {
                IWL_WARN(priv, "request scan called when driver not ready.\n");
                goto done;
@@ -925,6 +924,8 @@ void iwl_bg_scan_completed(struct work_struct *work)
 
        IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
 
+       cancel_delayed_work(&priv->scan_check);
+
        ieee80211_scan_completed(priv->hw, false);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
index 4cce66133500a04087084ab8eec0979160b7262f..ff4d0e41d7c492237d5740b423be5918b526bc3f 100644 (file)
@@ -782,13 +782,6 @@ static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
        if (!iwl_is_ready_rf(priv))
                return -EAGAIN;
 
-       cancel_delayed_work(&priv->scan_check);
-       if (iwl_scan_cancel_timeout(priv, 100)) {
-               IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
-               IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
-               return -EAGAIN;
-       }
-
        iwl3945_commit_rxon(priv);
 
        return 0;
@@ -3298,6 +3291,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
+       cancel_delayed_work(&priv->scan_check);
+
        if (!iwl_is_ready(priv)) {
                IWL_WARN(priv, "request scan called when driver not ready.\n");
                goto done;
index 07d378ef0b46297995d016b039af2452e2646bea..7b3ee8c2eaef91bac4c9d959f69785d197c1ff35 100644 (file)
@@ -138,7 +138,7 @@ void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
 
        if (cipher == CIPHER_TKIP_NO_MIC)
                cipher = CIPHER_TKIP;
-       if (cipher == CIPHER_NONE || cipher > CIPHER_MAX)
+       if (cipher == CIPHER_NONE || cipher >= CIPHER_MAX)
                return;
 
        /* Remove CIPHER_NONE index */
index f0e99d4c066b9acfeada76a623258d5fda744b5d..242257b19441fb31bc95b0ba10324ffc2ec8df35 100644 (file)
@@ -78,16 +78,20 @@ void free_cpu_buffers(void)
        op_ring_buffer_write = NULL;
 }
 
+#define RB_EVENT_HDR_SIZE 4
+
 int alloc_cpu_buffers(void)
 {
        int i;
 
        unsigned long buffer_size = oprofile_cpu_buffer_size;
+       unsigned long byte_size = buffer_size * (sizeof(struct op_sample) +
+                                                RB_EVENT_HDR_SIZE);
 
-       op_ring_buffer_read = ring_buffer_alloc(buffer_size, OP_BUFFER_FLAGS);
+       op_ring_buffer_read = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
        if (!op_ring_buffer_read)
                goto fail;
-       op_ring_buffer_write = ring_buffer_alloc(buffer_size, OP_BUFFER_FLAGS);
+       op_ring_buffer_write = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
        if (!op_ring_buffer_write)
                goto fail;
 
index e6a7e847ee805cbdd24384c08bc532560097c398..ea31a452b153e55e8ce378000e02ee952a5e8991 100644 (file)
@@ -352,8 +352,8 @@ static int __devinit parport_init_chip(struct parisc_device *dev)
        unsigned long port;
 
        if (!dev->irq) {
-               printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n",
-                       dev->hpa.start);
+               printk(KERN_WARNING "IRQ not found for parallel device at 0x%llx\n",
+                       (unsigned long long)dev->hpa.start);
                return -ENODEV;
        }
 
index 4fc168b70095bcd0b76646411429a8dcf4920a1c..e68d5f20ffb3fb8198560dfb414fe126ecbeda6d 100644 (file)
@@ -129,7 +129,6 @@ struct acpiphp_func {
        struct acpiphp_bridge *bridge;  /* Ejectable PCI-to-PCI bridge */
 
        struct list_head sibling;
-       struct pci_dev *pci_dev;
        struct notifier_block nb;
        acpi_handle     handle;
 
index a33794d9e0dce60d3ae57948122e1e53efa57aa5..3a6064bce5614a84ba16e1411a50bcfc7afddce3 100644 (file)
@@ -32,9 +32,6 @@
 
 /*
  * Lifetime rules for pci_dev:
- *  - The one in acpiphp_func has its refcount elevated by pci_get_slot()
- *    when the driver is loaded or when an insertion event occurs.  It loses
- *    a refcount when its ejected or the driver unloads.
  *  - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
  *    when the bridge is scanned and it loses a refcount when the bridge
  *    is removed.
@@ -130,6 +127,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        unsigned long long adr, sun;
        int device, function, retval;
        struct pci_bus *pbus = bridge->pci_bus;
+       struct pci_dev *pdev;
 
        if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
                return AE_OK;
@@ -213,10 +211,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
        newfunc->slot = slot;
        list_add_tail(&newfunc->sibling, &slot->funcs);
 
-       /* associate corresponding pci_dev */
-       newfunc->pci_dev = pci_get_slot(pbus, PCI_DEVFN(device, function));
-       if (newfunc->pci_dev) {
+       pdev = pci_get_slot(pbus, PCI_DEVFN(device, function));
+       if (pdev) {
                slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
+               pci_dev_put(pdev);
        }
 
        if (is_dock_device(handle)) {
@@ -617,7 +615,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
                                if (ACPI_FAILURE(status))
                                        err("failed to remove notify handler\n");
                        }
-                       pci_dev_put(func->pci_dev);
                        list_del(list);
                        kfree(func);
                }
@@ -1101,22 +1098,24 @@ static int __ref enable_device(struct acpiphp_slot *slot)
        pci_enable_bridges(bus);
        pci_bus_add_devices(bus);
 
-       /* associate pci_dev to our representation */
        list_for_each (l, &slot->funcs) {
                func = list_entry(l, struct acpiphp_func, sibling);
-               func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
-                                                       func->function));
-               if (!func->pci_dev)
+               dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
+                                                 func->function));
+               if (!dev)
                        continue;
 
-               if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
-                   func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
+               if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
+                   dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) {
+                       pci_dev_put(dev);
                        continue;
+               }
 
                status = find_p2p_bridge(func->handle, (u32)1, bus, NULL);
                if (ACPI_FAILURE(status))
                        warn("find_p2p_bridge failed (error code = 0x%x)\n",
                                status);
+               pci_dev_put(dev);
        }
 
        slot->flags |= SLOT_ENABLED;
@@ -1142,17 +1141,14 @@ static void disable_bridges(struct pci_bus *bus)
  */
 static int disable_device(struct acpiphp_slot *slot)
 {
-   &nbs