Merge branch 'for_rmk' of git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4-base into devel
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 2f10ce6..004ee16 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -150,6 +150,11 @@
Unit: revolution/min (RPM)
RW
+fan[1-*]_max Fan maximum value
+ Unit: revolution/min (RPM)
+ Only rarely supported by the hardware.
+ RW
+
fan[1-*]_input Fan input value.
Unit: revolution/min (RPM)
RO
@@ -390,6 +395,7 @@
in[0-*]_min_alarm
in[0-*]_max_alarm
fan[1-*]_min_alarm
+fan[1-*]_max_alarm
temp[1-*]_min_alarm
temp[1-*]_max_alarm
temp[1-*]_crit_alarm
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt
index 9f09557..a12ea3b 100644
--- a/Documentation/input/multi-touch-protocol.txt
+++ b/Documentation/input/multi-touch-protocol.txt
@@ -18,8 +18,12 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e87bdbf..fd5cac0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1535,6 +1535,10 @@
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.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 8eec05b..322869f 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -334,6 +334,7 @@
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)
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
index bba2dbb..cfac20c 100644
--- a/Documentation/sound/alsa/Procfile.txt
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -104,6 +104,11 @@
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.
diff --git a/MAINTAINERS b/MAINTAINERS
index ee86be0..581fedc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -434,7 +434,7 @@
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 @@
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 @@
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: 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 @@
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 @@
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 @@
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 @@
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
@@ -1540,6 +1542,13 @@
S: Maintained
F: drivers/net/wan/cosa*
+CPMAC ETHERNET DRIVER
+P: Florian Fainelli
+M: florian@openwrt.org
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/cpmac.c
+
CPU FREQUENCY DRIVERS
P: Dave Jones
M: davej@redhat.com
@@ -1971,8 +1980,8 @@
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 +2258,7 @@
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.*
diff --git a/Makefile b/Makefile
index 739fd34..610d1c3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 30
-EXTRAVERSION = -rc7
+EXTRAVERSION = -rc8
NAME = Man-Eating Seals of Antiquity
# *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f42cf3a..8381bd7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -394,6 +394,7 @@
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
@@ -415,6 +416,7 @@
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
@@ -428,6 +430,7 @@
select CPU_FEROCEON
select PCI
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select PLAT_ORION
diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c
index 5589444..f37afd9 100644
--- a/arch/arm/common/clkdev.c
+++ b/arch/arm/common/clkdev.c
@@ -135,6 +135,24 @@
}
EXPORT_SYMBOL(clkdev_alloc);
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
+ struct device *dev)
+{
+ struct clk *r = clk_get(dev, id);
+ struct clk_lookup *l;
+
+ if (IS_ERR(r))
+ return PTR_ERR(r);
+
+ l = clkdev_alloc(r, alias, alias_dev_name);
+ clk_put(r);
+ if (!l)
+ return -ENODEV;
+ clkdev_add(l);
+ return 0;
+}
+EXPORT_SYMBOL(clk_add_alias);
+
/*
* clkdev_drop - remove a clock dynamically allocated
*/
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index dcf8153..0a1abb9 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -182,6 +182,7 @@
CONFIG_MACH_DB88F6281_BP=y
CONFIG_MACH_RD88F6192_NAS=y
CONFIG_MACH_RD88F6281=y
+CONFIG_MACH_MV88F6281GTW_GE=y
CONFIG_MACH_SHEEVAPLUG=y
CONFIG_MACH_TS219=y
CONFIG_PLAT_ORION=y
@@ -270,7 +271,9 @@
#
# CPU Power Management
#
-# CONFIG_CPU_IDLE is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
#
# Floating point emulation
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 5b98f76..9e23852 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -903,7 +903,8 @@
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_TIMERIOMEM=m
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 6116e48..15f8a09 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -114,3 +114,16 @@
.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
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index ee99723..16b52f3 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -44,11 +44,29 @@
: "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 @@
: "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 @@
: "r" (&v->counter), "Ir" (i)
: "cc");
+ smp_mb();
+
return result;
}
@@ -84,6 +124,8 @@
{
unsigned long oldval, res;
+ smp_mb();
+
do {
__asm__ __volatile__("@ atomic_cmpxchg\n"
"ldrex %1, [%2]\n"
@@ -95,6 +137,8 @@
: "cc");
} while (res);
+ smp_mb();
+
return oldval;
}
@@ -135,6 +179,7 @@
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 @@
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 @@
}
#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 @@
#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
diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
index 1d77e51..59426a4 100644
--- a/arch/arm/include/asm/flat.h
+++ b/arch/arm/include/asm/flat.h
@@ -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))
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
index ada93a8..4fc1565 100644
--- a/arch/arm/include/asm/sizes.h
+++ b/arch/arm/include/asm/sizes.h
@@ -29,6 +29,7 @@
#define SZ_512 0x00000200
#define SZ_1K 0x00000400
+#define SZ_2K 0x00000800
#define SZ_4K 0x00001000
#define SZ_8K 0x00002000
#define SZ_16K 0x00004000
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index bd4dc8e..d65b2f5 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -248,6 +248,8 @@
unsigned int tmp;
#endif
+ smp_mb();
+
switch (size) {
#if __LINUX_ARM_ARCH__ >= 6
case 1:
@@ -307,6 +309,7 @@
__bad_xchg(ptr, size), ret = 0;
break;
}
+ smp_mb();
return ret;
}
@@ -316,6 +319,12 @@
#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 @@
#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)
diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c
index d4a0da1..950391f 100644
--- a/arch/arm/kernel/elf.c
+++ b/arch/arm/kernel/elf.c
@@ -78,6 +78,15 @@
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);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index d662a2f..83b1da6 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -815,10 +815,7 @@
*/
__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
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index 2e787d4..c7f2627 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -18,12 +18,14 @@
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
diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h
index de67526..213a4fc 100644
--- a/arch/arm/mach-gemini/include/mach/hardware.h
+++ b/arch/arm/mach-gemini/include/mach/hardware.h
@@ -15,10 +15,9 @@
/*
* 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
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index b5421cc..25100f7 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -20,6 +20,12 @@
Say 'Y' here if you want your kernel to support the
Marvell RD-88F6281 Reference Board.
+config MACH_MV88F6281GTW_GE
+ bool "Marvell 88F6281 GTW GE Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell 88F6281 GTW GE Board.
+
config MACH_SHEEVAPLUG
bool "Marvell SheevaPlug Reference Board"
help
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 8f03c9b..9dd680e 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -3,5 +3,8 @@
obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o
+obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
obj-$(CONFIG_MACH_TS219) += ts219-setup.o
+
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 5db4f0b..1da5d1c 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -20,6 +20,7 @@
*/
#define TARGET_DDR 0
#define TARGET_DEV_BUS 1
+#define TARGET_SRAM 3
#define TARGET_PCIE 4
#define ATTR_DEV_SPI_ROM 0x1e
#define ATTR_DEV_BOOT 0x1d
@@ -30,6 +31,7 @@
#define ATTR_DEV_CS0 0x3e
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
+#define ATTR_SRAM 0x01
/*
* Helpers to get DDR bank info
@@ -48,7 +50,6 @@
struct mbus_dram_target_info kirkwood_mbus_dram_info;
-static int __initdata win_alloc_count;
static int __init cpu_win_can_remap(int win)
{
@@ -112,7 +113,11 @@
setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
- win_alloc_count = 3;
+ /*
+ * Setup window for SRAM.
+ */
+ setup_cpu_win(3, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
+ TARGET_SRAM, ATTR_SRAM, -1);
/*
* Setup MBUS dram target info.
@@ -140,8 +145,3 @@
}
kirkwood_mbus_dram_info.num_cs = cs;
}
-
-void __init kirkwood_setup_sram_win(u32 base, u32 size)
-{
- setup_cpu_win(win_alloc_count++, base, size, 0x03, 0x00, -1);
-}
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index eeb0024..0f69198 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -16,6 +16,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
+#include <linux/mtd/nand.h>
#include <linux/spi/orion_spi.h>
#include <net/dsa.h>
#include <asm/page.h>
@@ -29,6 +30,7 @@
#include <plat/mvsdio.h>
#include <plat/mv_xor.h>
#include <plat/orion_nand.h>
+#include <plat/orion_wdt.h>
#include <plat/time.h>
#include "common.h"
@@ -54,6 +56,13 @@
iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
}
+/*
+ * Default clock control bits. Any bit _not_ set in this variable
+ * will be cleared from the hardware after platform devices have been
+ * registered. Some reserved bits must be set to 1.
+ */
+unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
+
/*****************************************************************************
* EHCI
@@ -95,6 +104,7 @@
void __init kirkwood_ehci_init(void)
{
+ kirkwood_clk_ctrl |= CGC_USB0;
platform_device_register(&kirkwood_ehci);
}
@@ -144,10 +154,14 @@
.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)
{
+ kirkwood_clk_ctrl |= CGC_GE0;
eth_data->shared = &kirkwood_ge00_shared;
kirkwood_ge00.dev.platform_data = eth_data;
@@ -202,10 +216,14 @@
.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)
{
+ kirkwood_clk_ctrl |= CGC_GE1;
eth_data->shared = &kirkwood_ge01_shared;
kirkwood_ge01.dev.platform_data = eth_data;
@@ -252,6 +270,43 @@
/*****************************************************************************
+ * NAND flash
+ ****************************************************************************/
+static struct resource kirkwood_nand_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
+ .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
+ KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data kirkwood_nand_data = {
+ .cle = 0,
+ .ale = 1,
+ .width = 8,
+};
+
+static struct platform_device kirkwood_nand_flash = {
+ .name = "orion_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &kirkwood_nand_data,
+ },
+ .resource = &kirkwood_nand_resource,
+ .num_resources = 1,
+};
+
+void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
+ int chip_delay)
+{
+ kirkwood_clk_ctrl |= CGC_RUNIT;
+ kirkwood_nand_data.parts = parts;
+ kirkwood_nand_data.nr_parts = nr_parts;
+ kirkwood_nand_data.chip_delay = chip_delay;
+ platform_device_register(&kirkwood_nand_flash);
+}
+
+
+/*****************************************************************************
* SoC RTC
****************************************************************************/
static struct resource kirkwood_rtc_resource = {
@@ -295,6 +350,9 @@
void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
{
+ kirkwood_clk_ctrl |= CGC_SATA0;
+ if (sata_data->n_ports > 1)
+ kirkwood_clk_ctrl |= CGC_SATA1;
sata_data->dram = &kirkwood_mbus_dram_info;
kirkwood_sata.dev.platform_data = sata_data;
platform_device_register(&kirkwood_sata);
@@ -340,6 +398,7 @@
else
mvsdio_data->clock = 200000000;
mvsdio_data->dram = &kirkwood_mbus_dram_info;
+ kirkwood_clk_ctrl |= CGC_SDIO;
kirkwood_sdio.dev.platform_data = mvsdio_data;
platform_device_register(&kirkwood_sdio);
}
@@ -371,6 +430,7 @@
void __init kirkwood_spi_init()
{
+ kirkwood_clk_ctrl |= CGC_RUNIT;
platform_device_register(&kirkwood_spi);
}
@@ -386,12 +446,10 @@
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,
@@ -503,6 +561,43 @@
/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+
+static struct resource kirkwood_crypto_res[] = {
+ {
+ .name = "regs",
+ .start = CRYPTO_PHYS_BASE,
+ .end = CRYPTO_PHYS_BASE + 0xffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "sram",
+ .start = KIRKWOOD_SRAM_PHYS_BASE,
+ .end = KIRKWOOD_SRAM_PHYS_BASE + KIRKWOOD_SRAM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "crypto interrupt",
+ .start = IRQ_KIRKWOOD_CRYPTO,
+ .end = IRQ_KIRKWOOD_CRYPTO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kirkwood_crypto_device = {
+ .name = "mv_crypto",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(kirkwood_crypto_res),
+ .resource = kirkwood_crypto_res,
+};
+
+void __init kirkwood_crypto_init(void)
+{
+ kirkwood_clk_ctrl |= CGC_CRYPTO;
+ platform_device_register(&kirkwood_crypto_device);
+}
+
+
+/*****************************************************************************
* XOR
****************************************************************************/
static struct mv_xor_platform_shared_data kirkwood_xor_shared_data = {
@@ -593,6 +688,7 @@
static void __init kirkwood_xor0_init(void)
{
+ kirkwood_clk_ctrl |= CGC_XOR0;
platform_device_register(&kirkwood_xor0_shared);
/*
@@ -691,6 +787,7 @@
static void __init kirkwood_xor1_init(void)
{
+ kirkwood_clk_ctrl |= CGC_XOR1;
platform_device_register(&kirkwood_xor1_shared);
/*
@@ -709,6 +806,29 @@
/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct orion_wdt_platform_data kirkwood_wdt_data = {
+ .tclk = 0,
+};
+
+static struct platform_device kirkwood_wdt_device = {
+ .name = "orion_wdt",
+ .id = -1,
+ .dev = {
+ .platform_data = &kirkwood_wdt_data,
+ },
+ .num_resources = 0,
+};
+
+static void __init kirkwood_wdt_init(void)
+{
+ kirkwood_wdt_data.tclk = kirkwood_tclk;
+ platform_device_register(&kirkwood_wdt_device);
+}
+
+
+/*****************************************************************************
* Time handling
****************************************************************************/
int kirkwood_tclk;
@@ -800,6 +920,49 @@
/* internal devices that every board has */
kirkwood_rtc_init();
+ kirkwood_wdt_init();
kirkwood_xor0_init();
kirkwood_xor1_init();
+ kirkwood_crypto_init();
}
+
+static int __init kirkwood_clock_gate(void)
+{
+ unsigned int curr = readl(CLOCK_GATING_CTRL);
+
+ printk(KERN_DEBUG "Gating clock of unused units\n");
+ printk(KERN_DEBUG "before: 0x%08x\n", curr);
+
+ /* Make sure those units are accessible */
+ writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0, CLOCK_GATING_CTRL);
+
+ /* For SATA: first shutdown the phy */
+ if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
+ /* Disable PLL and IVREF */
+ writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
+ /* Disable PHY */
+ writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
+ }
+ if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
+ /* Disable PLL and IVREF */
+ writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
+ /* Disable PHY */
+ writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
+ }
+
+ /* For PCIe: first shutdown the phy */
+ if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
+ writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
+ while (1)
+ if (readl(PCIE_STATUS) & 0x1)
+ break;
+ writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
+ }
+
+ /* Now gate clock the required units */
+ writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
+ printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
+
+ return 0;
+}
+late_initcall(kirkwood_clock_gate);
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 6ee8840..d7de434 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -15,6 +15,7 @@
struct mv643xx_eth_platform_data;
struct mv_sata_platform_data;
struct mvsdio_platform_data;
+struct mtd_partition;
/*
* Basic Kirkwood init functions used early by machine-setup.
@@ -25,7 +26,6 @@
extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
void kirkwood_setup_cpu_mbus(void);
-void kirkwood_setup_sram_win(u32 base, u32 size);
void kirkwood_pcie_id(u32 *dev, u32 *rev);
@@ -40,9 +40,11 @@
void kirkwood_i2c_init(void);
void kirkwood_uart0_init(void);
void kirkwood_uart1_init(void);
+void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay);
extern int kirkwood_tclk;
extern struct sys_timer kirkwood_timer;
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
#endif
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c
new file mode 100644
index 0000000..f68d33f
--- /dev/null
+++ b/arch/arm/mach-kirkwood/cpuidle.c
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-kirkwood/cpuidle.c
+ *
+ * CPU idle Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The cpu idle uses wait-for-interrupt and DDR self refresh in order
+ * to implement two idle states -
+ * #1 wait-for-interrupt
+ * #2 wait-for-interrupt and DDR self refresh
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <mach/kirkwood.h>
+
+#define KIRKWOOD_MAX_STATES 2
+
+static struct cpuidle_driver kirkwood_idle_driver = {
+ .name = "kirkwood_idle",
+ .owner = THIS_MODULE,
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
+
+/* Actual code that puts the SoC in different idle states */
+static int kirkwood_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+ if (state == &dev->states[0])
+ /* Wait for interrupt state */
+ cpu_do_idle();
+ else if (state == &dev->states[1]) {
+ /*
+ * Following write will put DDR in self refresh.
+ * Note that we have 256 cycles before DDR puts it
+ * self in self-refresh, so the wait-for-interrupt
+ * call afterwards won't get the DDR from self refresh
+ * mode.
+ */
+ writel(0x7, DDR_OPERATION_BASE);
+ cpu_do_idle();
+ }
+ do_gettimeofday(&after);
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+ return idle_time;
+}
+
+/* Initialize CPU idle by registering the idle states */
+static int kirkwood_init_cpuidle(void)
+{
+ struct cpuidle_device *device;
+
+ cpuidle_register_driver(&kirkwood_idle_driver);
+
+ device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
+ device->state_count = KIRKWOOD_MAX_STATES;
+
+ /* Wait for interrupt state */
+ device->states[0].enter = kirkwood_enter_idle;
+ device->states[0].exit_latency = 1;
+ device->states[0].target_residency = 10000;
+ device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[0].name, "WFI");
+ strcpy(device->states[0].desc, "Wait for interrupt");
+
+ /* Wait for interrupt and DDR self refresh state */
+ device->states[1].enter = kirkwood_enter_idle;
+ device->states[1].exit_latency = 10;
+ device->states[1].target_residency = 10000;
+ device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[1].name, "DDR SR");
+ strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+
+ if (cpuidle_register_device(device)) {
+ printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+device_initcall(kirkwood_init_cpuidle);
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index 5505d58..39bdf4b 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -11,14 +11,12 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
-#include <plat/orion_nand.h>
#include <plat/mvsdio.h>
#include "common.h"
#include "mpp.h"
@@ -39,32 +37,6 @@
},
};
-static struct resource db88f6281_nand_resource = {
- .flags = IORESOURCE_MEM,
- .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
- .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
- KIRKWOOD_NAND_MEM_SIZE - 1,
-};
-
-static struct orion_nand_data db88f6281_nand_data = {
- .parts = db88f6281_nand_parts,
- .nr_parts = ARRAY_SIZE(db88f6281_nand_parts),
- .cle = 0,
- .ale = 1,
- .width = 8,
- .chip_delay = 25,
-};
-
-static struct platform_device db88f6281_nand_flash = {
- .name = "orion_nand",
- .id = -1,
- .dev = {
- .platform_data = &db88f6281_nand_data,
- },
- .resource = &db88f6281_nand_resource,
- .num_resources = 1,
-};
-
static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
@@ -92,13 +64,12 @@
kirkwood_init();
kirkwood_mpp_conf(db88f6281_mpp_config);
+ kirkwood_nand_init(ARRAY_AND_SIZE(db88f6281_nand_parts), 25);
kirkwood_ehci_init();
kirkwood_ge00_init(&db88f6281_ge00_data);
kirkwood_sata_init(&db88f6281_sata_data);
kirkwood_uart0_init();
kirkwood_sdio_init(&db88f6281_mvsdio_data);
-
- platform_device_register(&db88f6281_nand_flash);
}
static int __init db88f6281_pci_init(void)
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 4f7029f..9e80d92 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -17,12 +17,15 @@
#define CPU_RESET 0x00000002
#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define WDT_RESET_OUT_EN 0x00000002
#define SOFT_RESET_OUT_EN 0x00000004
#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
#define SOFT_RESET 0x00000001
#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110)
+#define WDT_INT_REQ 0x0008
+
#define BRIDGE_MASK (BRIDGE_VIRT_BASE | 0x0114)
#define BRIDGE_INT_TIMER0 0x0002
#define BRIDGE_INT_TIMER1 0x0004
@@ -39,4 +42,22 @@
#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128)
#define L2_WRITETHROUGH 0x00000010
+#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c)
+#define CGC_GE0 (1 << 0)
+#define CGC_PEX0 (1 << 2)
+#define CGC_USB0 (1 << 3)
+#define CGC_SDIO (1 << 4)
+#define CGC_TSU (1 << 5)
+#define CGC_DUNIT (1 << 6)
+#define CGC_RUNIT (1 << 7)
+#define CGC_XOR0 (1 << 8)
+#define CGC_AUDIO (1 << 9)
+#define CGC_SATA0 (1 << 14)
+#define CGC_SATA1 (1 << 15)
+#define CGC_XOR1 (1 << 16)
+#define CGC_CRYPTO (1 << 17)
+#define CGC_GE1 (1 << 19)
+#define CGC_TDM (1 << 20)
+#define CGC_RESERVED ((1 << 18) | (0x6 << 21))
+
#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h
index be07be0..a643a84 100644
--- a/arch/arm/mach-kirkwood/include/mach/io.h
+++ b/arch/arm/mach-kirkwood/include/mach/io.h
@@ -19,6 +19,31 @@
+ KIRKWOOD_PCIE_IO_VIRT_BASE);
}
+static inline void __iomem *
+__arch_ioremap(unsigned long paddr, size_t size, unsigned int mtype)
+{
+ void __iomem *retval;
+ unsigned long offs = paddr - KIRKWOOD_REGS_PHYS_BASE;
+ if (mtype == MT_DEVICE && size && offs < KIRKWOOD_REGS_SIZE &&
+ size <= KIRKWOOD_REGS_SIZE && offs + size <= KIRKWOOD_REGS_SIZE) {
+ retval = (void __iomem *)KIRKWOOD_REGS_VIRT_BASE + offs;
+ } else {
+ retval = __arm_ioremap(paddr, size, mtype);
+ }
+
+ return retval;
+}
+
+static inline void
+__arch_iounmap(void __iomem *addr)
+{
+ if (addr < (void __iomem *)KIRKWOOD_REGS_VIRT_BASE ||
+ addr >= (void __iomem *)(KIRKWOOD_REGS_VIRT_BASE + KIRKWOOD_REGS_SIZE))
+ __iounmap(addr);
+}
+
+#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m)
+#define __arch_iounmap(a) __arch_iounmap(a)
#define __io(a) __io(a)
#define __mem_pci(a) (a)
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index b3e1395..07af858 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -20,16 +20,18 @@
* f1000000 on-chip peripheral registers
* f2000000 PCIe I/O space
* f3000000 NAND controller address window
+ * f4000000 Security Accelerator SRAM
*
* virt phys size
* fee00000 f1000000 1M on-chip peripheral registers
* fef00000 f2000000 1M PCIe I/O space
*/
+#define KIRKWOOD_SRAM_PHYS_BASE 0xf4000000
+#define KIRKWOOD_SRAM_SIZE SZ_2K
+
#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf3000000
-#define KIRKWOOD_NAND_MEM_SIZE SZ_64K /* 1K is sufficient, but 64K
- * is the minimal window size
- */
+#define KIRKWOOD_NAND_MEM_SIZE SZ_1K
#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfef00000
@@ -48,6 +50,7 @@
*/
#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x00000)
#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE | 0x1500)
+#define DDR_OPERATION_BASE (DDR_VIRT_BASE | 0x1418)
#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x10000)
#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x10000)
@@ -63,7 +66,11 @@
#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000)
+#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000)
+
#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
+#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
+#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
@@ -80,6 +87,11 @@
#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x74000)
#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x80000)
+#define SATA_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x80000)
+#define SATA0_IF_CTRL (SATA_VIRT_BASE | 0x2050)
+#define SATA0_PHY_MODE_2 (SATA_VIRT_BASE | 0x2330)
+#define SATA1_IF_CTRL (SATA_VIRT_BASE | 0x4050)
+#define SATA1_PHY_MODE_2 (SATA_VIRT_BASE | 0x4330)
#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x90000)
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
index 63c4493..a5900f6 100644
--- a/arch/arm/mach-kirkwood/mpp.c
+++ b/arch/arm/mach-kirkwood/mpp.c
@@ -48,6 +48,9 @@
if (!variant_mask)
return;
+ /* Initialize gpiolib. */
+ orion_gpio_init();
+
printk(KERN_DEBUG "initial MPP regs:");
for (i = 0; i < MPP_NR_REGS; i++) {
mpp_ctrl[i] = readl(MPP_CTRL(i));
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
new file mode 100644
index 0000000..0358f45
--- /dev/null
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+ *
+ * Marvell 88F6281 GTW GE Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/timer.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data mv88f6281gtw_ge_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data mv88f6281gtw_ge_switch_chip_data = {
+ .port_names[0] = "lan1",
+ .port_names[1] = "lan2",
+ .port_names[2] = "lan3",
+ .port_names[3] = "lan4",
+ .port_names[4] = "wan",
+ .port_names[5] = "cpu",
+};
+
+static struct dsa_platform_data mv88f6281gtw_ge_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &mv88f6281gtw_ge_switch_chip_data,
+};
+
+static const struct flash_platform_data mv88f6281gtw_ge_spi_slave_data = {
+ .type = "mx25l12805d",
+};
+
+static struct spi_board_info __initdata mv88f6281gtw_ge_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &mv88f6281gtw_ge_spi_slave_data,
+ .irq = -1,
+ .max_speed_hz = 50000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static struct gpio_keys_button mv88f6281gtw_ge_button_pins[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = 47,
+ .desc = "SWR Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_F1,
+ .gpio = 46,
+ .desc = "WPS Button(F1)",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mv88f6281gtw_ge_button_data = {
+ .buttons = mv88f6281gtw_ge_button_pins,
+ .nbuttons = ARRAY_SIZE(mv88f6281gtw_ge_button_pins),
+};
+
+static struct platform_device mv88f6281gtw_ge_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &mv88f6281gtw_ge_button_data,
+ },
+};
+
+static struct gpio_led mv88f6281gtw_ge_led_pins[] = {
+ {
+ .name = "gtw:green:Status",
+ .gpio = 20,
+ .active_low = 0,
+ }, {
+ .name = "gtw:red:Status",
+ .gpio = 21,
+ .active_low = 0,
+ }, {
+ .name = "gtw:green:USB",
+ .gpio = 12,
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data mv88f6281gtw_ge_led_data = {
+ .leds = mv88f6281gtw_ge_led_pins,
+ .num_leds = ARRAY_SIZE(mv88f6281gtw_ge_led_pins),
+};
+
+static struct platform_device mv88f6281gtw_ge_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mv88f6281gtw_ge_led_data,
+ },
+};
+
+static unsigned int mv88f6281gtw_ge_mpp_config[] __initdata = {
+ MPP12_GPO, /* Status#_USB pin */
+ MPP20_GPIO, /* Status#_GLED pin */
+ MPP21_GPIO, /* Status#_RLED pin */
+ MPP46_GPIO, /* WPS_Switch pin */
+ MPP47_GPIO, /* SW_Init pin */
+ 0
+};
+
+static void __init mv88f6281gtw_ge_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(mv88f6281gtw_ge_mpp_config);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&mv88f6281gtw_ge_ge00_data);
+ kirkwood_ge00_switch_init(&mv88f6281gtw_ge_switch_plat_data, NO_IRQ);
+ spi_register_board_info(mv88f6281gtw_ge_spi_slave_info,
+ ARRAY_SIZE(mv88f6281gtw_ge_spi_slave_info));
+ kirkwood_spi_init();
+ kirkwood_uart0_init();
+ platform_device_register(&mv88f6281gtw_ge_leds);
+ platform_device_register(&mv88f6281gtw_ge_buttons);
+}
+
+static int __init mv88f6281gtw_ge_pci_init(void)
+{
+ if (machine_is_mv88f6281gtw_ge())
+ kirkwood_pcie_init();
+
+ return 0;
+}
+subsys_initcall(mv88f6281gtw_ge_pci_init);
+
+MACHINE_START(MV88F6281GTW_GE, "Marvell 88F6281 GTW GE Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = mv88f6281gtw_ge_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index 73fccac..d90b9aa 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -14,6 +14,7 @@
#include <asm/irq.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
+#include <mach/bridge-regs.h>
#include "common.h"
@@ -95,6 +96,7 @@
static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
{
struct resource *res;
+ extern unsigned int kirkwood_clk_ctrl;
/*
* Generic PCIe unit setup.
@@ -133,6 +135,8 @@
sys->resource[2] = NULL;
sys->io_offset = 0;
+ kirkwood_clk_ctrl |= CGC_PEX0;
+
return 1;
}
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index 2f0e4ef..8bf4153 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -11,8 +11,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/spi/flash.h>
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 31e996d..31708dd 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
-#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
@@ -22,7 +21,6 @@
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include <plat/mvsdio.h>
-#include <plat/orion_nand.h>
#include "common.h"
#include "mpp.h"
@@ -42,32 +40,6 @@
},
};
-static struct resource rd88f6281_nand_resource = {
- .flags = IORESOURCE_MEM,
- .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
- .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
- KIRKWOOD_NAND_MEM_SIZE - 1,
-};
-
-static struct orion_nand_data rd88f6281_nand_data = {
- .parts = rd88f6281_nand_parts,
- .nr_parts = ARRAY_SIZE(rd88f6281_nand_parts),
- .cle = 0,
- .ale = 1,
- .width = 8,
- .chip_delay = 25,
-};
-
-static struct platform_device rd88f6281_nand_flash = {
- .name = "orion_nand",
- .id = -1,
- .dev = {
- .platform_data = &rd88f6281_nand_data,
- },
- .resource = &rd88f6281_nand_resource,
- .num_resources = 1,
-};
-
static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_NONE,
.speed = SPEED_1000,
@@ -114,6 +86,7 @@
kirkwood_init();
kirkwood_mpp_conf(rd88f6281_mpp_config);
+ kirkwood_nand_init(ARRAY_AND_SIZE(rd88f6281_nand_parts), 25);
kirkwood_ehci_init();
kirkwood_ge00_init(&rd88f6281_ge00_data);
@@ -129,8 +102,6 @@
kirkwood_sata_init(&rd88f6281_sata_data);
kirkwood_sdio_init(&rd88f6281_mvsdio_data);
kirkwood_uart0_init();
-
- platform_device_register(&rd88f6281_nand_flash);
}
static int __init rd88f6281_pci_init(void)
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
index 831e4a5..c7319ee 100644
--- a/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
@@ -20,7 +19,6 @@
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
#include <plat/mvsdio.h>
-#include <plat/orion_nand.h>
#include "common.h"
#include "mpp.h"
@@ -40,38 +38,12 @@
},
};
-static struct resource sheevaplug_nand_resource = {
- .flags = IORESOURCE_MEM,
- .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
- .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
- KIRKWOOD_NAND_MEM_SIZE - 1,
-};
-
-static struct orion_nand_data sheevaplug_nand_data = {
- .parts = sheevaplug_nand_parts,
- .nr_parts = ARRAY_SIZE(sheevaplug_nand_parts),
- .cle = 0,
- .ale = 1,
- .width = 8,
- .chip_delay = 25,
-};
-
-static struct platform_device sheevaplug_nand_flash = {
- .name = "orion_nand",
- .id = -1,
- .dev = {
- .platform_data = &sheevaplug_nand_data,
- },
- .resource = &sheevaplug_nand_resource,
- .num_resources = 1,
-};
-
static struct mv643xx_eth_platform_data sheevaplug_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
static struct mvsdio_platform_data sheevaplug_mvsdio_data = {
- // unfortunately the CD signal has not been connected */
+ /* unfortunately the CD signal has not been connected */
};
static struct gpio_led sheevaplug_led_pins[] = {
@@ -111,6 +83,7 @@
kirkwood_mpp_conf(sheevaplug_mpp_config);
kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(sheevaplug_nand_parts), 25);
if (gpio_request(29, "USB Power Enable") != 0 ||
gpio_direction_output(29, 1) != 0)
@@ -120,7 +93,6 @@
kirkwood_ge00_init(&sheevaplug_ge00_data);
kirkwood_sdio_init(&sheevaplug_mvsdio_data);
- platform_device_register(&sheevaplug_nand_flash);
platform_device_register(&sheevaplug_leds);
}
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index dda5743..01aa213 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -142,6 +142,8 @@
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 @@
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
};
diff --git a/arch/arm/mach-loki/common.c b/arch/arm/mach-loki/common.c
index c0d2d9d..818f19d 100644
--- a/arch/arm/mach-loki/common.c
+++ b/arch/arm/mach-loki/common.c
@@ -82,6 +82,9 @@
.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 @@
.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)
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
index d0bdb6e..2e91464 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -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)
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
index 48a1cbc..d97de36 100644
--- a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
@@ -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)
diff --git a/arch/arm/mach-mmp/include/mach/mfp.h b/arch/arm/mach-mmp/include/mach/mfp.h
index 277ea4c..62e510e 100644
--- a/arch/arm/mach-mmp/include/mach/mfp.h
+++ b/arch/arm/mach-mmp/include/mach/mfp.h
@@ -12,16 +12,13 @@
* 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
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index b03a6ed..a8400bb 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -136,7 +136,7 @@
.set_mode = timer_set_mode,
};
-static cycle_t clksrc_read(void)
+static cycle_t clksrc_read(struct clocksource *cs)
{
return timer_read();
}
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index 9ba5950..1b22e4a 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -321,6 +321,9 @@
.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 @@
.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 @@
.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 @@
.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 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 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,
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index f289b0e..22b4ff8 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -28,6 +28,9 @@
{
int i;
+ /* Initialize gpiolib. */
+ orion_gpio_init();
+
orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF));
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig
index 6155044..c77da58 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-mx2/Kconfig
@@ -59,4 +59,12 @@
help
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
+
+config MACH_MX27LITE
+ bool "LogicPD MX27 LITEKIT platform"
+ depends on MACH_MX27
+ help
+ Include support for MX27 LITEKIT platform. This includes specific
+ configurations for the board and its peripherals.
+
endif
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile
index d140e2d..b9b1cca 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-mx2/Makefile
@@ -16,3 +16,5 @@
obj-$(CONFIG_MACH_PCM038) += pcm038.o
obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o
+obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o
+
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c
index 999d013..fa2b292 100644
--- a/arch/arm/mach-mx2/clock_imx21.c
+++ b/arch/arm/mach-mx2/clock_imx21.c
@@ -48,6 +48,25 @@
__raw_writel(reg, clk->enable_reg);
}
+static unsigned long _clk_generic_round_rate(struct clk *clk,
+ unsigned long rate,
+ u32 max_divisor)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > max_divisor)
+ div = max_divisor;
+
+ return parent_rate / div;
+}
+
static int _clk_spll_enable(struct clk *clk)
{
u32 reg;
@@ -78,19 +97,7 @@
static unsigned long _clk_perclkx_round_rate(struct clk *clk,
unsigned long rate)
{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > 64)
- div = 64;
-
- return parent_rate / div;
+ return _clk_generic_round_rate(clk, rate, 64);
}
static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
@@ -130,6 +137,32 @@
return parent_rate / (usb_pdf + 1U);
}
+static unsigned long _clk_usb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ return _clk_generic_round_rate(clk, rate, 8);
+}
+
+static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg = CSCR() & ~CCM_CSCR_USB_MASK;
+ reg |= div << CCM_CSCR_USB_OFFSET;
+ __raw_writel(reg, CCM_CSCR);
+
+ return 0;
+}
+
static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
{
unsigned long parent_rate;
@@ -595,11 +628,14 @@
static struct clk usb_clk[] = {
{
.parent = &spll_clk,
+ .secondary = &usb_clk[1],
.get_rate = _clk_usb_recalc,
.enable = _clk_enable,
.enable_reg = CCM_PCCR_USBOTG_REG,
.enable_shift = CCM_PCCR_USBOTG_OFFSET,
.disable = _clk_disable,
+ .round_rate = _clk_usb_round_rate,
+ .set_rate = _clk_usb_set_rate,
}, {
.parent = &hclk_clk,
.enable = _clk_enable,
@@ -768,18 +804,7 @@
static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > 8)
- div = 8;
-
- return parent_rate / div;
+ return _clk_generic_round_rate(clk, rate, 8);
}
static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
@@ -921,7 +946,7 @@
_REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
- _REGISTER_CLOCK(NULL, "usb", usb_clk[0])
+ _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
_REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
_REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
diff --git a/arch/arm/mach-mx2/mx27lite.c b/arch/arm/mach-mx2/mx27lite.c
new file mode 100644
index 0000000..3ae11cb
--- /dev/null
+++ b/arch/arm/mach-mx2/mx27lite.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux.h>
+#include <mach/board-mx27lite.h>
+
+#include "devices.h"
+
+static unsigned int mx27lite_pins[] = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mxc_fec_device,
+};
+
+static void __init mx27lite_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
+ "imx27lite");
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx27lite_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27lite_timer = {
+ .init = mx27lite_timer_init,
+};
+
+MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
+ .phys_io = AIPI_BASE_ADDR,
+ .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mx27lite_init,
+ .timer = &mx27lite_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27pdk.c b/arch/arm/mach-mx2/mx27pdk.c
index 90b1fa5..1d9238c 100644
--- a/arch/arm/mach-mx2/mx27pdk.c
+++ b/arch/arm/mach-mx2/mx27pdk.c
@@ -88,7 +88,7 @@
.phys_io = AIPI_BASE_ADDR,
.io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
- .map_io = mxc_map_io,
+ .map_io = mx27_map_io,
.init_irq = mxc_init_irq,
.init_machine = mx27pdk_init,
.timer = &mx27pdk_timer,
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 229fb3e..17a21a2 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -57,6 +57,13 @@
Include support for mx31moboard platform. This includes specific
configurations for the board and its peripherals.
+config MACH_MX31LILLY
+ bool "Support MX31 LILLY-1131 platforms (INCO startec)"
+ select ARCH_MX31
+ help
+ Include support for mx31 based LILLY1131 modules. This includes
+ specific configurations for the board and its peripherals.
+
config MACH_QONG
bool "Support Dave/DENX QongEVB-LITE platform"
select ARCH_MX31
@@ -71,4 +78,18 @@
Include support for Phytec pcm043 platform. This includes
specific configurations for the board and its peripherals.
+config MACH_ARMADILLO5X0
+ bool "Support Atmark Armadillo-500 Development Base Board"
+ select ARCH_MX31
+ help
+ Include support for Atmark Armadillo-500 platform. This includes
+ specific configurations for the board and its peripherals.
+
+config MACH_MX35_3DS
+ bool "Support MX35PDK platform"
+ select ARCH_MX35
+ default n
+ help
+ Include support for MX35PDK platform. This includes specific
+ configurations for the board and its peripherals.
endif
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index cd6547b..0322696 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -8,6 +8,7 @@
obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o
obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
+obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o
obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o
obj-$(CONFIG_MACH_PCM037) += pcm037.o
obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o
@@ -15,3 +16,5 @@
mx31moboard-marxbot.o
obj-$(CONFIG_MACH_QONG) += qong.o
obj-$(CONFIG_MACH_PCM043) += pcm043.o
+obj-$(CONFIG_MACH_ARMADILLO5X0) += armadillo5x0.o
+obj-$(CONFIG_MACH_MX35_3DS) += mx35pdk.o
diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c
new file mode 100644
index 0000000..54118109
--- /dev/null
+++ b/arch/arm/mach-mx3/armadillo5x0.c
@@ -0,0 +1,295 @@
+/*
+ * armadillo5x0.c
+ *
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * updates in http://alberdroid.blogspot.com/
+ *
+ * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
+ * Based on mx31ads.c and pcm037.c Great Work!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-armadillo5x0.h>
+#include <mach/mmc.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+
+#include "devices.h"
+
+static int armadillo5x0_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ /* UART2 */
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ /* LAN9118_IRQ */
+ IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ /* Framebuffer */
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
+
+};
+
+/*
+ * FB support
+ */
+static const struct fb_videomode fb_modedb[] = {
+ { /* 640x480 @ 60 Hz */
+ .name = "CRT-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 35,
+ .right_margin = 115,
+ .upper_margin = 43,
+ .lower_margin = 1,
+ .hsync_len = 10,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {/* 800x600 @ 56 Hz */
+ .name = "CRT-SVGA",
+ .refresh = 56,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000,
+ .left_margin = 30,
+ .right_margin = 108,
+ .upper_margin = 13,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .name = "CRT-VGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+/*
+ * SDHC 1
+ * MMC support
+ */
+static int armadillo5x0_sdhc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static int armadillo5x0_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+ int gpio_det, gpio_wp;
+
+ gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
+ gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
+
+ ret = gpio_request(gpio_det, "sdhc-card-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(gpio_det);
+
+ ret = gpio_request(gpio_wp, "sdhc-write-protect");
+ if (ret)
+ goto err_gpio_free;
+
+ gpio_direction_input(gpio_wp);
+
+ /* When supported the trigger type have to be BOTH */
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "sdhc-detect", data);
+
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(gpio_wp);
+
+err_gpio_free:
+ gpio_free(gpio_det);
+
+ return ret;
+
+}
+
+static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+ .get_ro = armadillo5x0_sdhc1_get_ro,
+ .init = armadillo5x0_sdhc1_init,
+ .exit = armadillo5x0_sdhc1_exit,
+};
+
+/*
+ * SMSC 9118
+ * Network support
+ */
+static struct resource armadillo5x0_smc911x_resources[] = {
+ {
+ .start = CS3_BASE_ADDR,
+ .end = CS3_BASE_ADDR + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device armadillo5x0_smc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(armadillo5x0_smc911x_resources),
+ .resource = armadillo5x0_smc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+/* UART device data */
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &armadillo5x0_smc911x_device,
+};
+
+/*
+ * Perform board specific initializations
+ */
+static void __init armadillo5x0_init(void)
+{
+ mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
+ ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ /* Register UART */
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ mxc_register_device(&mxc_uart_device1, &uart_pdata);
+
+ /* SMSC9118 IRQ pin */
+ gpio_direction_input(MX31_PIN_GPIO1_0);
+
+ /* Register SDHC */
+ mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
+
+ /* Register FB */
+ mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+ mxc_register_device(&mx3_fb, &mx3fb_pdata);
+}
+
+static void __init armadillo5x0_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer armadillo5x0_timer = {
+ .init = armadillo5x0_timer_init,
+};
+
+MACHINE_START(ARMADILLO5X0, "Armadillo-500")
+ /* Maintainer: Alberto Panizzo */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x00000100,
+ .map_io = mx31_map_io,
+ .init_irq = mxc_init_irq,
+ .timer = &armadillo5x0_timer,
+ .init_machine = armadillo5x0_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index 28bd11d..217d114 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -483,7 +483,7 @@
DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &ahb_clk);
+DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
@@ -571,6 +571,13 @@
for (i = 0; i < ARRAY_SIZE(lookups); i++)
clkdev_add(&lookups[i]);
+ /* change the csi_clk parent if necessary */
+ reg = __raw_readl(MXC_CCM_CCMR);
+ if (!(reg & MXC_CCM_CCMR_CSCS))
+ if (clk_set_parent(&csi_clk, &usb_pll_clk))
+ pr_err("%s: error changing csi_clk parent\n", __func__);
+
+
/* Turn off all possible clocks */
__raw_writel((3 << 4), MXC_CCM_CGR0);
__raw_writel(0, MXC_CCM_CGR1);
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 475410a..ffd494d 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -16,3 +16,5 @@
extern struct platform_device mxcsdhc_device0;
extern struct platform_device mxcsdhc_device1;
extern struct platform_device mxc_otg_udc_device;
+extern struct platform_device mxc_rnga_device;
+
diff --git a/arch/arm/mach-mx3/mx31lilly-db.c b/arch/arm/mach-mx3/mx31lilly-db.c
new file mode 100644
index 0000000..3b3a78f
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31lilly-db.c
@@ -0,0 +1,216 @@
+/*
+ * LILLY-1131 development board support
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * based on code for other MX31 boards,
+ *
+ * Copyright 2005-2007 Freescale Semiconductor
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+#include <mach/mmc.h>
+#include <mach/mx3fb.h>
+#include <mach/ipu.h>
+
+#include "devices.h"
+
+/*
+ * This file contains board-specific initialization routines for the
+ * LILLY-1131 development board. If you design an own baseboard for the
+ * module, use this file as base for support code.
+ */
+
+static unsigned int lilly_db_board_pins[] __initdata = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ MX31_PIN_CSPI3_MOSI__RXD3,
+ MX31_PIN_CSPI3_MISO__TXD3,
+ MX31_PIN_CSPI3_SCLK__RTS3,
+ MX31_PIN_CSPI3_SPI_RDY__CTS3,
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ MX31_PIN_CONTRAST__CONTRAST,
+};
+
+/* UART */
+static struct imxuart_platform_data uart_pdata __initdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* MMC support */
+
+static int mxc_mmc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+}
+
+static int gpio_det, gpio_wp;
+
+static int mxc_mmc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1);
+ gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0);
+
+ ret = gpio_request(gpio_det, "MMC detect");
+ if (ret)
+ return ret;
+
+ ret = gpio_request(gpio_wp, "MMC w/p");
+ if (ret)
+ goto exit_free_det;
+
+ gpio_direction_input(gpio_det);
+ gpio_direction_input(gpio_wp);
+
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "MMC detect", data);
+ if (ret)
+ goto exit_free_wp;
+
+ return 0;
+
+exit_free_wp:
+ gpio_free(gpio_wp);
+
+exit_free_det:
+ gpio_free(gpio_det);
+
+ return ret;
+}
+
+static void mxc_mmc1_exit(struct device *dev, void *data)
+{
+ gpio_free(gpio_det);
+ gpio_free(gpio_wp);
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
+}
+
+static struct imxmmc_platform_data mmc_pdata = {
+ .get_ro = mxc_mmc1_get_ro,
+ .init = mxc_mmc1_init,
+ .exit = mxc_mmc1_exit,
+};
+
+/* Framebuffer support */
+static struct ipu_platform_data ipu_data __initdata = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static const struct fb_videomode fb_modedb = {
+ /* 640x480 TFT panel (IPS-056T) */
+ .name = "CRT-VGA",
+ .refresh = 64,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 30000,
+ .left_margin = 200,
+ .right_margin = 2,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct mx3fb_platform_data fb_pdata __initdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .name = "CRT-VGA",
+ .mode = &fb_modedb,
+ .num_modes = 1,
+};
+
+#define LCD_VCC_EN_GPIO (7)
+
+static void __init mx31lilly_init_fb(void)
+{
+ if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) {
+ printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n");
+ return;
+ }
+
+ mxc_register_device(&mx3_ipu, &ipu_data);
+ mxc_register_device(&mx3_fb, &fb_pdata);
+ gpio_direction_output(LCD_VCC_EN_GPIO, 1);
+}
+
+void __init mx31lilly_db_init(void)
+{
+ mxc_iomux_setup_multiple_pins(lilly_db_board_pins,
+ ARRAY_SIZE(lilly_db_board_pins),
+ "development board pins");
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ mxc_register_device(&mxc_uart_device1, &uart_pdata);
+ mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
+ mx31lilly_init_fb();
+}
+
diff --git a/arch/arm/mach-mx3/mx31lilly.c b/arch/arm/mach-mx3/mx31lilly.c
new file mode 100644
index 0000000..6ab2f16
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31lilly.c
@@ -0,0 +1,155 @@
+/*
+ * LILLY-1131 module support
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * based on code for other MX31 boards,
+ *
+ * Copyright 2005-2007 Freescale Semiconductor
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+
+#include "devices.h"
+
+/*
+ * This file contains module-specific initialization routines for LILLY-1131.
+ * Initialization of peripherals found on the baseboard is implemented in the
+ * appropriate baseboard support code.
+ */
+
+/* SMSC ethernet support */
+
+static struct resource smsc91x_resources[] = {
+ {
+ .start = CS4_BASE_ADDR,
+ .end = CS4_BASE_ADDR + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT |
+ SMSC911X_SAVE_MAC_ADDRESS |
+ SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc91x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc91x_resources),
+ .resource = smsc91x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ }
+};
+
+/* NOR flash */
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource nor_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .resource = &nor_flash_resource,
+ .num_resources = 1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &smsc91x_device,
+ &physmap_flash_device,
+ &mxc_i2c_device1,
+};
+
+static int mx31lilly_baseboard;
+core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
+
+static void __init mx31lilly_board_init(void)
+{
+ switch (mx31lilly_baseboard) {
+ case MX31LILLY_NOBOARD:
+ break;
+ case MX31LILLY_DB:
+ mx31lilly_db_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n",
+ mx31lilly_baseboard);
+ }
+
+ mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__SCL, "I2C SCL");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__SDA, "I2C SDA");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mx31lilly_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31lilly_timer = {
+ .init = mx31lilly_timer_init,
+};
+
+MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mx31lilly_board_init,
+ .timer = &mx31lilly_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c
index 32599e5..c19838d 100644
--- a/arch/arm/mach-mx3/mx31pdk.c
+++ b/arch/arm/mach-mx3/mx31pdk.c
@@ -21,6 +21,8 @@
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -56,6 +58,39 @@
};
/*
+ * Support for the SMSC9217 on the Debug board.
+ */
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource smsc911x_resources[] = {
+ {
+ .start = LAN9217_BASE_ADDR,
+ .end = LAN9217_BASE_ADDR + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = EXPIO_INT_ENET,
+ .end = EXPIO_INT_ENET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+/*
* Routines for the CPLD on the debug board. It contains a CPLD handling
* LEDs, switches, interrupts for Ethernet.
*/
@@ -207,7 +242,8 @@
mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mx31pdk_init_expio();
+ if (!mx31pdk_init_expio())
+ platform_device_register(&smsc911x_device);
}
static void __init mx31pdk_timer_init(void)
diff --git a/arch/arm/mach-mx3/mx35pdk.c b/arch/arm/mach-mx3/mx35pdk.c
new file mode 100644
index 0000000..6d15374
--- /dev/null
+++ b/arch/arm/mach-mx3/mx35pdk.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx35.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mxc_fec_device,
+};
+
+static struct pad_desc mx35pdk_pads[] = {
+ /* UART1 */
+ MX35_PAD_CTS1__UART1_CTS,
+ MX35_PAD_RTS1__UART1_RTS,
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* FEC */
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX35_PAD_FEC_COL__FEC_COL,
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX35_PAD_FEC_MDC__FEC_MDC,
+ MX35_PAD_FEC_MDIO__FEC_MDIO,
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+ MX35_PAD_FEC_CRS__FEC_CRS,
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+}
+
+static void __init mx35pdk_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer mx35pdk_timer = {
+ .init = mx35pdk_timer_init,
+};
+
+MACHINE_START(MX35_3DS, "Freescale MX35PDK")
+ /* Maintainer: Freescale Semiconductor, Inc */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = mx35_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mx35pdk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index c14d121..6f3f77d 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/mbus.h>
#include <linux/io.h>
+#include <linux/errno.h>
#include <mach/hardware.h>
#include "common.h"
@@ -44,6 +45,7 @@
#define TARGET_DEV_BUS 1
#define TARGET_PCI 3
#define TARGET_PCIE 4
+#define TARGET_SRAM 9
#define ATTR_PCIE_MEM 0x59
#define ATTR_PCIE_IO 0x51
#define ATTR_PCIE_WA 0x79
@@ -53,6 +55,7 @@
#define ATTR_DEV_CS1 0x1d
#define ATTR_DEV_CS2 0x1b
#define ATTR_DEV_BOOT 0xf
+#define ATTR_SRAM 0x0
/*
* Helpers to get DDR bank info
@@ -87,13 +90,13 @@
return 0;
}
-static void __init setup_cpu_win(int win, u32 base, u32 size,
+static int __init setup_cpu_win(int win, u32 base, u32 size,
u8 target, u8 attr, int remap)
{
if (win >= 8) {
printk(KERN_ERR "setup_cpu_win: trying to allocate "
"window %d\n", win);
- return;
+ return -ENOSPC;
}
writel(base & 0xffff0000, CPU_WIN_BASE(win));
@@ -107,6 +110,7 @@
writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
writel(0, CPU_WIN_REMAP_HI(win));
}
+ return 0;
}
void __init orion5x_setup_cpu_mbus_bridge(void)
@@ -193,3 +197,9 @@
setup_cpu_win(win_alloc_count++, base, size,
TARGET_PCIE, ATTR_PCIE_WA, -1);
}
+
+int __init orion5x_setup_sram_win(void)
+{
+ return setup_cpu_win(win_alloc_count, ORION5X_SRAM_PHYS_BASE,
+ ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1);
+}
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 6af99dd..eafcc49 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -31,7 +31,7 @@
#include <plat/ehci-orion.h>
#include <plat/mv_xor.h>
#include <plat/orion_nand.h>
-#include <plat/orion5x_wdt.h>
+#include <plat/orion_wdt.h>
#include <plat/time.h>
#include "common.h"
@@ -188,6 +188,9 @@
.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 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,
@@ -535,16 +536,52 @@
platform_device_register(&orion5x_xor1_channel);
}
+static struct resource orion5x_crypto_res[] = {
+ {
+ .name = "regs",
+ .start = ORION5X_CRYPTO_PHYS_BASE,
+ .end = ORION5X_CRYPTO_PHYS_BASE + 0xffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "sram",
+ .start = ORION5X_SRAM_PHYS_BASE,
+ .end = ORION5X_SRAM_PHYS_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "crypto interrupt",
+ .start = IRQ_ORION5X_CESA,
+ .end = IRQ_ORION5X_CESA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion5x_crypto_device = {
+ .name = "mv_crypto",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(orion5x_crypto_res),
+ .resource = orion5x_crypto_res,
+};
+
+int __init orion5x_crypto_init(void)
+{
+ int ret;
+
+ ret = orion5x_setup_sram_win();
+ if (ret)
+ return ret;
+
+ return platform_device_register(&orion5x_crypto_device);
+}
/*****************************************************************************
* Watchdog
****************************************************************************/
-static struct orion5x_wdt_platform_data orion5x_wdt_data = {
+static struct orion_wdt_platform_data orion5x_wdt_data = {
.tclk = 0,
};
static struct platform_device orion5x_wdt_device = {
- .name = "orion5x_wdt",
+ .name = "orion_wdt",
.id = -1,
.dev = {
.platform_data = &orion5x_wdt_data,
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index 798b9a5..de483e8 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -26,6 +26,7 @@
void orion5x_setup_dev1_win(u32 base, u32 size);
void orion5x_setup_dev2_win(u32 base, u32 size);
void orion5x_setup_pcie_wa_win(u32 base, u32 size);
+int orion5x_setup_sram_win(void);
void orion5x_ehci0_init(void);
void orion5x_ehci1_init(void);
@@ -37,6 +38,7 @@
void orion5x_uart0_init(void);
void orion5x_uart1_init(void);
void orion5x_xor_init(void);
+int orion5x_crypto_init(void);
/*
* PCIe/PCI functions.
diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
index be896e5..5c9744c 100644
--- a/arch/arm/mach-orion5x/include/mach/bridge-regs.h
+++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
@@ -17,8 +17,8 @@
#define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE | 0x104)
-#define CPU_RESET_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x108)
-#define WDT_RESET 0x0002
+#define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x108)
+#define WDT_RESET_OUT_EN 0x0002
#define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE | 0x10c)
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
index 377a773..2d87665 100644
--- a/arch/arm/mach-orion5x/include/mach/orion5x.h
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -24,6 +24,7 @@
* f1000000 on-chip peripheral registers
* f2000000 PCIe I/O space
* f2100000 PCI I/O space
+ * f2200000 SRAM dedicated for the crypto unit
* f4000000 device bus mappings (boot)
* fa000000 device bus mappings (cs0)
* fa800000 device bus mappings (cs2)
@@ -49,6 +50,9 @@
#define ORION5X_PCI_IO_BUS_BASE 0x00100000
#define ORION5X_PCI_IO_SIZE SZ_1M
+#define ORION5X_SRAM_PHYS_BASE (0xf2200000)
+#define ORION5X_SRAM_SIZE SZ_8K
+
/* Relevant only for Orion-1/Orion-NAS */
#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
#define ORION5X_PCIE_WA_VIRT_BASE 0xfe000000
@@ -94,6 +98,8 @@
#define ORION5X_SATA_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x80000)
#define ORION5X_SATA_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x80000)
+#define ORION5X_CRYPTO_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x90000)
+
#define ORION5X_USB1_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0xa0000)
#define ORION5X_USB1_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0xa0000)
diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h
index e912490..60e734c 100644
--- a/arch/arm/mach-orion5x/include/mach/system.h
+++ b/arch/arm/mach-orion5x/include/mach/system.h
@@ -23,7 +23,7 @@
/*
* Enable and issue soft reset
*/
- orion5x_setbits(CPU_RESET_MASK, (1 << 2));
+ orion5x_setbits(RSTOUTn_MASK, (1 << 2));
orion5x_setbits(CPU_SOFT_RESET, 1);
}
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
index e23a3f9..bc4c3b9 100644
--- a/arch/arm/mach-orion5x/mpp.c
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -124,6 +124,9 @@
u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL);
u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL);
+ /* Initialize gpiolib. */
+ orion_gpio_init();
+
while (mode->mpp >= 0) {
u32 *reg;
int num_type;
diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c
index 41e6d50..61c086b 100644
--- a/arch/arm/mach-orion5x/mss2-setup.c
+++ b/arch/arm/mach-orion5x/mss2-setup.c
@@ -181,9 +181,9 @@
/*
* Enable and issue soft reset
*/
- reg = readl(CPU_RESET_MASK);
+ reg = readl(RSTOUTn_MASK);
reg |= 1 << 2;
- writel(reg, CPU_RESET_MASK);
+ writel(reg, RSTOUTn_MASK);
reg = readl(CPU_SOFT_RESET);
reg |= 1;
diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h
index 0f9cdf4..37b3d48 100644
--- a/arch/arm/mach-orion5x/ts78xx-fpga.h
+++ b/arch/arm/mach-orion5x/ts78xx-fpga.h
@@ -25,6 +25,7 @@
/* Technologic Systems */
struct fpga_device ts_rtc;
struct fpga_device ts_nand;
+ struct fpga_device ts_rng;
};
struct ts78xx_fpga_data {
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
index 9a6b397..5041d1b 100644
--- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -17,6 +17,7 @@
#include <linux/m48t86.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/timeriomem-rng.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -270,12 +271,57 @@
}
/*****************************************************************************
+ * HW RNG
+ ****************************************************************************/
+#define TS_RNG_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x044)
+
+static struct resource ts78xx_ts_rng_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = TS_RNG_DATA,
+ .end = TS_RNG_DATA + 4 - 1,
+};
+
+static struct timeriomem_rng_data ts78xx_ts_rng_data = {
+ .period = 1000000, /* one second */
+};
+
+static struct platform_device ts78xx_ts_rng_device = {
+ .name = "timeriomem_rng",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_ts_rng_data,
+ },
+ .resource = &ts78xx_ts_rng_resource,
+ .num_resources = 1,
+};
+
+static int ts78xx_ts_rng_load(void)
+{
+ int rc;
+
+ if (ts78xx_fpga.supports.ts_rng.init == 0) {
+ rc = platform_device_register(&ts78xx_ts_rng_device);
+ if (!rc)
+ ts78xx_fpga.supports.ts_rng.init = 1;
+ } else
+ rc = platform_device_add(&ts78xx_ts_rng_device);
+
+ return rc;
+};
+
+static void ts78xx_ts_rng_unload(void)
+{
+ platform_device_del(&ts78xx_ts_rng_device);
+}
+
+/*****************************************************************************
* FPGA 'hotplug' support code
****************************************************************************/
static void ts78xx_fpga_devices_zero_init(void)
{
ts78xx_fpga.supports.ts_rtc.init = 0;
ts78xx_fpga.supports.ts_nand.init = 0;
+ ts78xx_fpga.supports.ts_rng.init = 0;
}
static void ts78xx_fpga_supports(void)
@@ -289,10 +335,12 @@
case TS7800_REV_5:
ts78xx_fpga.supports.ts_rtc.present = 1;
ts78xx_fpga.supports.ts_nand.present = 1;
+ ts78xx_fpga.supports.ts_rng.present = 1;
break;
default:
ts78xx_fpga.supports.ts_rtc.present = 0;
ts78xx_fpga.supports.ts_nand.present = 0;
+ ts78xx_fpga.supports.ts_rng.present = 0;
}
}
@@ -316,6 +364,14 @@
}
ret |= tmp;
}
+ if (ts78xx_fpga.supports.ts_rng.present == 1) {
+ tmp = ts78xx_ts_rng_load();
+ if (tmp) {
+ printk(KERN_INFO "TS-78xx: RNG not registered\n");
+ ts78xx_fpga.supports.ts_rng.present = 0;
+ }
+ ret |= tmp;
+ }
return ret;
}
@@ -328,6 +384,8 @@
ts78xx_ts_rtc_unload();
if (ts78xx_fpga.supports.ts_nand.present == 1)
ts78xx_ts_nand_unload();
+ if (ts78xx_fpga.supports.ts_rng.present == 1)
+ ts78xx_ts_rng_unload();
return ret;
}
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
index 7ddc22c..6920821 100644
--- a/arch/arm/mach-orion5x/wnr854t-setup.c
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -15,6 +15,7 @@
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
+#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
@@ -97,6 +98,20 @@
.duplex = DUPLEX_FULL,
};
+static struct dsa_chip_data wnr854t_switch_chip_data = {
+ .port_names[0] = "lan3",
+ .port_names[1] = "lan4",
+ .port_names[2] = "wan",
+ .port_names[3] = "cpu",
+ .port_names[5] = "lan1",
+ .port_names[7] = "lan2",
+};
+
+static struct dsa_platform_data wnr854t_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &wnr854t_switch_chip_data,
+};
+
static void __init wnr854t_init(void)
{
/*
@@ -110,6 +125,7 @@
* Configure peripherals.
*/
orion5x_eth_init(&wnr854t_eth_data);
+ orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE,
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index db52d2c..49ae382 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -86,20 +86,3 @@
for (i = 0; i < num; i++)
clkdev_add(&clks[i]);
}
-
-int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
- struct device *dev)
-{
- struct clk *r = clk_get(dev, id);
- struct clk_lookup *l;
-
- if (!r)
- return -ENODEV;
-
- l = clkdev_alloc(r, alias, alias_dev_name);
- clk_put(r);
- if (!l)
- return -ENODEV;
- clkdev_add(l);
- return 0;
-}
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 92ba16e..7db966d 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -111,9 +111,9 @@
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 @@
#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 @@
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 */
diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h
index 31e6a7b..b6c1055 100644
--- a/arch/arm/mach-pxa/include/mach/reset.h
+++ b/arch/arm/mach-pxa/include/mach/reset.h
@@ -13,8 +13,9 @@
/**
* 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 */
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 7ffb91d..cf6b720 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -322,6 +322,7 @@
#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 @@
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 @@
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 @@
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);
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index 24a967e..2e65f05 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -62,6 +62,8 @@
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ GPIO95_AC97_nRESET,
/* IrDA */
GPIO108_GPIO, /* ir disable */
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 3066236..05bf979 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -64,6 +64,7 @@
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
GPIO95_AC97_nRESET,
/* IrDA */
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index e2d44b1..e99a893 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -65,6 +65,7 @@
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
GPIO95_AC97_nRESET,
/* IrDA */
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
index df29d45..01e9d64 100644
--- a/arch/arm/mach-pxa/reset.c
+++ b/arch/arm/mach-pxa/reset.c
@@ -20,7 +20,7 @@
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 @@
}
if (output)
- rc = gpio_direction_output(gpio, 0);
+ rc = gpio_direction_output(gpio, level);
else
rc = gpio_direction_input(gpio);
if (rc) {
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index c18e34a..5a45fe3 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -531,9 +531,15 @@
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 __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;
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index afac5b6..a0bd46e 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -897,7 +897,7 @@
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;
diff --git a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
new file mode 100644
index 0000000..8769e91
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>.
+ * All Rights Reserved.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
+#define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
+
+#include <mach/hardware.h>
+
+/* mandatory for CONFIG_DEBUG_LL */
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27lite.h b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
new file mode 100644
index 0000000..a870f8e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__
+#define __ASM_ARCH_MXC_BOARD_MX27LITE_H__
+
+/* mandatory for CONFIG_DEBUG_LL */
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
new file mode 100644
index 0000000..78cf31e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on code for mobots boards,
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
+#define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
+
+/* mandatory for CONFIG_LL_DEBUG */
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000)
+
+#ifndef __ASSEMBLY__
+
+enum mx31lilly_boards {
+ MX31LILLY_NOBOARD = 0,
+ MX31LILLY_DB = 1,
+};
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ */
+
+extern void mx31lilly_db_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
new file mode 100644
index 0000000..1111037
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__
+#define __ASM_ARCH_MXC_BOARD_MX35PDK_H__
+
+/* mandatory for CONFIG_DEBUG_LL */
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index e6b841b..bbc5f67 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -43,6 +43,15 @@
#ifdef CONFIG_MACH_MX27_3DS
#include <mach/board-mx27pdk.h>
#endif
+#ifdef CONFIG_MACH_ARMADILLO5X0
+#include <mach/board-armadillo5x0.h>
+#endif
+#ifdef CONFIG_MACH_MX35_3DS
+#include <mach/board-mx35pdk.h>
+#endif
+#ifdef CONFIG_MACH_MX27LITE
+#include <mach/board-mx27lite.h>
+#endif
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 32eb9e3..e814803 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -15,10 +15,9 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/io.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
static DEFINE_SPINLOCK(gpio_lock);
-static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
@@ -46,82 +45,54 @@
writel(u, GPIO_OUT(pin));
}
+static inline void __set_blinking(unsigned pin, int blink)
+{
+ u32 u;
+
+ u = readl(GPIO_BLINK_EN(pin));
+ if (blink)
+ u |= 1 << (pin & 31);
+ else
+ u &= ~(1 << (pin & 31));
+ writel(u, GPIO_BLINK_EN(pin));
+}
+
+static inline int orion_gpio_is_valid(unsigned pin, int mode)
+{
+ if (pin < GPIO_MAX) {
+ if ((mode & GPIO_INPUT_OK) && !test_bit(pin, gpio_valid_input))
+ goto err_out;
+ if ((mode & GPIO_OUTPUT_OK) && !test_bit(pin, gpio_valid_output))
+ goto err_out;
+ return true;
+ }
+
+err_out:
+ pr_debug("%s: invalid GPIO %d\n", __func__, pin);
+ return false;
+}
/*
* GENERIC_GPIO primitives.
*/
-int gpio_direction_input(unsigned pin)
+static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
{
unsigned long flags;
- if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
- pr_debug("%s: invalid GPIO %d\n", __func__, pin);
+ if (!orion_gpio_is_valid(pin, GPIO_INPUT_OK))
return -EINVAL;
- }
spin_lock_irqsave(&gpio_lock, flags);
- /*
- * Some callers might not have used gpio_request(),
- * so flag this pin as requested now.
- */
- if (gpio_label[pin] == NULL)
- gpio_label[pin] = "?";
-
- /*
- * Configure GPIO direction.
- */
+ /* Configure GPIO direction. */
__set_direction(pin, 1);
spin_unlock_irqrestore(&gpio_lock, flags);
return 0;
}
-EXPORT_SYMBOL(gpio_direction_input);
-int gpio_direction_output(unsigned pin, int value)
-{
- unsigned long flags;
- u32 u;
-
- if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) {
- pr_debug("%s: invalid GPIO %d\n", __func__, pin);
- return -EINVAL;
- }
-
- spin_lock_irqsave(&gpio_lock, flags);
-
- /*
- * Some callers might not have used gpio_request(),
- * so flag this pin as requested now.
- */
- if (gpio_label[pin] == NULL)
- gpio_label[pin] = "?";
-
- /*
- * Disable blinking.
- */
- u = readl(GPIO_BLINK_EN(pin));
- u &= ~(1 << (pin & 31));
- writel(u, GPIO_BLINK_EN(pin));
-
- /*
- * Configure GPIO output value.
- */
- __set_level(pin, value);
-
- /*
- * Configure GPIO direction.
- */
- __set_direction(pin, 0);
-
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-int gpio_get_value(unsigned pin)
+static int orion_gpio_get_value(struct gpio_chip *chip, unsigned pin)
{
int val;
@@ -132,83 +103,75 @@
return (val >> (pin & 31)) & 1;
}
-EXPORT_SYMBOL(gpio_get_value);
-void gpio_set_value(unsigned pin, int value)
+static int orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
+ int value)
{
unsigned long flags;
- u32 u;
+
+ if (!orion_gpio_is_valid(pin, GPIO_OUTPUT_OK))
+ return -EINVAL;
spin_lock_irqsave(&gpio_lock, flags);
- /*
- * Disable blinking.
- */
- u = readl(GPIO_BLINK_EN(pin));
- u &= ~(1 << (pin & 31));
- writel(u, GPIO_BLINK_EN(pin));
+ /* Disable blinking. */
+ __set_blinking(pin, 0);
- /*
- * Configure GPIO output value.
- */
+ /* Configure GPIO output value. */
+ __set_level(pin, value);
+
+ /* Configure GPIO direction. */
+ __set_direction(pin, 0);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+
+ return 0;
+}
+
+static void orion_gpio_set_value(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ /* Configure GPIO output value. */
__set_level(pin, value);
spin_unlock_irqrestore(&gpio_lock, flags);
}
-EXPORT_SYMBOL(gpio_set_value);
-int gpio_request(unsigned pin, const char *label)
+static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
{
- unsigned long flags;
- int ret;
-
- if (pin >= GPIO_MAX ||
- !(test_bit(pin, gpio_valid_input) ||
- test_bit(pin, gpio_valid_output))) {
- pr_debug("%s: invalid GPIO %d\n", __func__, pin);
- return -EINVAL;
- }
-
- spin_lock_irqsave(&gpio_lock, flags);
- if (gpio_label[pin] == NULL) {
- gpio_label[pin] = label ? label : "?";
- ret = 0;
- } else {
- pr_debug("%s: GPIO %d already used as %s\n",
- __func__, pin, gpio_label[pin]);
- ret = -EBUSY;
- }
- spin_unlock_irqrestore(&gpio_lock, flags);
-
- return ret;
+ if (orion_gpio_is_valid(pin, GPIO_INPUT_OK) ||
+ orion_gpio_is_valid(pin, GPIO_OUTPUT_OK))
+ return 0;
+ return -EINVAL;
}
-EXPORT_SYMBOL(gpio_request);
-void gpio_free(unsigned pin)
+static struct gpio_chip orion_gpiochip = {
+ .label = "orion_gpio",
+ .direction_input = orion_gpio_direction_input,
+ .get = orion_gpio_get_value,
+ .direction_output = orion_gpio_direction_output,
+ .set = orion_gpio_set_value,
+ .request = orion_gpio_request,
+ .base = 0,
+ .ngpio = GPIO_MAX,
+ .can_sleep = 0,
+};
+
+void __init orion_gpio_init(void)
{
- if (pin >= GPIO_MAX ||
- !(test_bit(pin, gpio_valid_input) ||
- test_bit(pin, gpio_valid_output))) {
- pr_debug("%s: invalid GPIO %d\n", __func__, pin);
- return;
- }
-
- if (gpio_label[pin] == NULL)
- pr_warning("%s: GPIO %d already freed\n", __func__, pin);
- else
- gpio_label[pin] = NULL;
+ gpiochip_add(&orion_gpiochip);
}
-EXPORT_SYMBOL(gpio_free);
-
/*
* Orion-specific GPIO API extensions.
*/
void __init orion_gpio_set_unused(unsigned pin)
{
- /*
- * Configure as output, drive low.
- */
+ /* Configure as output, drive low. */
__set_level(pin, 0);
__set_direction(pin, 0);
}
@@ -230,21 +193,14 @@
void orion_gpio_set_blink(unsigned pin, int blink)
{
unsigned long flags;
- u32 u;
spin_lock_irqsave(&gpio_lock, flags);
- /*
- * Set output value to zero.
- */
+ /* Set output value to zero. */
__set_level(pin, 0);
- u = readl(GPIO_BLINK_EN(pin));
- if (blink)
- u |= 1 << (pin & 31);
- else
- u &= ~(1 << (pin & 31));
- writel(u, GPIO_BLINK_EN(pin));
+ /* Set blinking. */
+ __set_blinking(pin, blink);
spin_unlock_irqrestore(&gpio_lock, flags);
}
@@ -368,7 +324,7 @@
}
struct irq_chip orion_gpio_irq_chip = {
- .name = "orion_gpio",
+ .name = "orion_gpio_irq",
.ack = gpio_irq_ack,
.mask = gpio_irq_mask,
.unmask = gpio_irq_unmask,
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h
index 33f6c6a..9646a94 100644
--- a/arch/arm/plat-orion/include/plat/gpio.h
+++ b/arch/arm/plat-orion/include/plat/gpio.h
@@ -14,12 +14,9 @@
/*
* GENERIC_GPIO primitives.
*/
-int gpio_request(unsigned pin, const char *label);
-void gpio_free(unsigned pin);
-int gpio_direction_input(unsigned pin);
-int gpio_direction_output(unsigned pin, int value);
-int gpio_get_value(unsigned pin);
-void gpio_set_value(unsigned pin, int value);
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
/*
* Orion-specific GPIO API extensions.
@@ -27,11 +24,13 @@
void orion_gpio_set_unused(unsigned pin);
void orion_gpio_set_blink(unsigned pin, int blink);
-#define GPIO_BIDI_OK (1 << 0)
-#define GPIO_INPUT_OK (1 << 1)
-#define GPIO_OUTPUT_OK (1 << 2)
+#define GPIO_INPUT_OK (1 << 0)
+#define GPIO_OUTPUT_OK (1 << 1)
void orion_gpio_set_valid(unsigned pin, int mode);
+/* Initialize gpiolib. */
+void __init orion_gpio_init(void);
+
/*
* GPIO interrupt handling.
*/
diff --git a/arch/arm/plat-orion/include/plat/orion5x_wdt.h b/arch/arm/plat-orion/include/plat/orion_wdt.h
similarity index 64%
rename from arch/arm/plat-orion/include/plat/orion5x_wdt.h
rename to arch/arm/plat-orion/include/plat/orion_wdt.h
index 3c9cf6a3..665c362 100644
--- a/arch/arm/plat-orion/include/plat/orion5x_wdt.h
+++ b/arch/arm/plat-orion/include/plat/orion_wdt.h
@@ -1,15 +1,15 @@
/*
- * arch/arm/plat-orion/include/plat/orion5x_wdt.h
+ * arch/arm/plat-orion/include/plat/orion_wdt.h
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
-#ifndef __PLAT_ORION5X_WDT_H
-#define __PLAT_ORION5X_WDT_H
+#ifndef __PLAT_ORION_WDT_H
+#define __PLAT_ORION_WDT_H
-struct orion5x_wdt_platform_data {
+struct orion_wdt_platform_data {
u32 tclk; /* no <linux/clk.h> support yet */
};
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
index de8a001..715a301 100644
--- a/arch/arm/plat-orion/time.c
+++ b/arch/arm/plat-orion/time.c
@@ -12,11 +12,15 @@
*/
#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cnt32_to_63.h>
+#include <linux/timer.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/mach/time.h>
#include <mach/bridge-regs.h>
+#include <mach/hardware.h>
/*
* Number of timer ticks per jiffy.
@@ -39,6 +43,56 @@
/*
+ * Orion's sched_clock implementation. It has a resolution of
+ * at least 7.5ns (133MHz TCLK) and a maximum value of 834 days.
+ *
+ * Because the hardware timer period is quite short (21 secs if
+ * 200MHz TCLK) and because cnt32_to_63() needs to be called at
+ * least once per half period to work properly, a kernel timer is
+ * set up to ensure this requirement is always met.
+ */
+#define TCLK2NS_SCALE_FACTOR 8
+
+static unsigned long tclk2ns_scale;
+
+unsigned long long sched_clock(void)
+{
+ unsigned long long v = cnt32_to_63(0xffffffff - readl(TIMER0_VAL));
+ return (v * tclk2ns_scale) >> TCLK2NS_SCALE_FACTOR;
+}
+
+static struct timer_list cnt32_to_63_keepwarm_timer;
+
+static void cnt32_to_63_keepwarm(unsigned long data)
+{
+ mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
+ (void) sched_clock();
+}
+
+static void __init setup_sched_clock(unsigned long tclk)
+{
+ unsigned long long v;
+ unsigned long data;
+
+ v = NSEC_PER_SEC;
+ v <<= TCLK2NS_SCALE_FACTOR;
+ v += tclk/2;
+ do_div(v, tclk);
+ /*
+ * We want an even value to automatically clear the top bit
+ * returned by cnt32_to_63() without an additional run time
+ * instruction. So if the LSB is 1 then round it up.
+ */
+ if (v & 1)
+ v++;
+ tclk2ns_scale = v;
+
+ data = (0xffffffffUL / tclk / 2 - 2) * HZ;
+ setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
+ mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
+}
+
+/*
* Clocksource handling.
*/
static cycle_t orion_clksrc_read(struct clocksource *cs)
@@ -176,6 +230,10 @@
ticks_per_jiffy = (tclk + HZ/2) / HZ;
+ /*
+ * Set scale and timer for sched_clock
+ */
+ setup_sched_clock(tclk);
/*
* Setup free-running clocksource timer (interrupts
@@ -190,7 +248,6 @@
orion_clksrc.mult = clocksource_hz2mult(tclk, orion_clksrc.shift);
clocksource_register(&orion_clksrc);
-
/*
* Setup clockevent timer (interrupt-driven.)
*/
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 945e0d2..fec6467 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
index 7858564..0000000
--- a/arch/blackfin/include/asm/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-+mach
diff --git a/arch/blackfin/include/asm/flat.h b/arch/blackfin/include/asm/flat.h
index e70074e..733a178 100644
--- a/arch/blackfin/include/asm/flat.h
+++ b/arch/blackfin/include/asm/flat.h
@@ -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)
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 1e57b63..cf5066d 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -378,8 +378,10 @@
#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
index 0000000..c5f676c
--- /dev/null
+++ b/arch/blackfin/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c
index 2aaae78..46518b1 100644
--- a/arch/blackfin/lib/strncmp.c
+++ b/arch/blackfin/lib/strncmp.c
@@ -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)
{
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 21e65a3..a063a43 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1581,6 +1581,8 @@
.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
diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h
index 2a87350..bd12b31 100644
--- a/arch/h8300/include/asm/flat.h
+++ b/arch/h8300/include/asm/flat.h
@@ -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))
diff --git a/arch/m32r/include/asm/flat.h b/arch/m32r/include/asm/flat.h
index d851cf0..5d711c4 100644
--- a/arch/m32r/include/asm/flat.h
+++ b/arch/m32r/include/asm/flat.h
@@ -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
diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
index 814b517..a0e2907 100644
--- a/arch/m68k/include/asm/flat.h
+++ b/arch/m68k/include/asm/flat.h
@@ -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))
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a0d1146..cdc9a6f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -868,6 +868,18 @@
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
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 5339bb4..ea8870a 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc3
-# Tue Nov 11 19:36:51 2008
+# Linux kernel version: 2.6.30-rc7
+# Mon May 25 14:53:25 2009
#
# CONFIG_PPC64 is not set
@@ -14,6 +14,7 @@
# CONFIG_40x is not set
# CONFIG_44x is not set
# CONFIG_E200 is not set
+CONFIG_PPC_BOOK3S=y
CONFIG_PPC_FPU=y
CONFIG_ALTIVEC=y
CONFIG_PPC_STD_MMU=y
@@ -43,7 +44,7 @@
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_NVRAM=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
CONFIG_OF=y
@@ -52,12 +53,14 @@
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_DTC=y
# CONFIG_DEFAULT_UIMAGE is not set
CONFIG_HIBERNATE_32=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -72,14 +75,24 @@
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -88,23 +101,27 @@
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-# CONFIG_COMPAT_BRK is not set
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -114,10 +131,12 @@
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
@@ -127,10 +146,10 @@
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -138,11 +157,8 @@
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -158,14 +174,11 @@
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
CONFIG_FREEZER=y
#
# Platform support
#
-CONFIG_PPC_MULTIPLATFORM=y
-CONFIG_CLASSIC32=y
# CONFIG_PPC_CHRP is not set
# CONFIG_MPC5121_ADS is not set
# CONFIG_MPC5121_GENERIC is not set
@@ -178,7 +191,9 @@
# CONFIG_PPC_83xx is not set
# CONFIG_PPC_86xx is not set
# CONFIG_EMBEDDED6xx is not set
+# CONFIG_AMIGAONE is not set
CONFIG_PPC_NATIVE=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
# CONFIG_IPIC is not set
CONFIG_MPIC=y
# CONFIG_MPIC_WEIRD is not set
@@ -212,11 +227,12 @@
CONFIG_PPC601_SYNC_FIX=y
# CONFIG_TAU is not set
# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
#
# Kernel options
#
-# CONFIG_HIGHMEM is not set
+CONFIG_HIGHMEM=y
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -239,6 +255,7 @@
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
@@ -250,12 +267,17 @@
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_MIGRATION is not set
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
@@ -288,6 +310,8 @@
# CONFIG_PCI_MSI is not set
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
@@ -397,6 +421,8 @@
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -405,6 +431,7 @@
CONFIG_NETFILTER_XT_TARGET_TRACE=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
@@ -415,6 +442,7 @@
CONFIG_NETFILTER_XT_MATCH_ESP=m
# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
@@ -478,17 +506,15 @@
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_IP_DCCP=m
CONFIG_INET_DCCP_DIAG=m
-CONFIG_IP_DCCP_ACKVEC=y
#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
-CONFIG_IP_DCCP_CCID2=m
# CONFIG_IP_DCCP_CCID2_DEBUG is not set
-CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_CCID3=y
# CONFIG_IP_DCCP_CCID3_DEBUG is not set
CONFIG_IP_DCCP_CCID3_RTO=100
-CONFIG_IP_DCCP_TFRC_LIB=m
+CONFIG_IP_DCCP_TFRC_LIB=y
#
# DCCP Kernel Hacking
@@ -508,13 +534,16 @@
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
CONFIG_IRDA=m
@@ -577,8 +606,6 @@
#
# Bluetooth device drivers
#
-CONFIG_BT_HCIUSB=m
-# CONFIG_BT_HCIUSB_SCO is not set
# CONFIG_BT_HCIBTUSB is not set
# CONFIG_BT_HCIUART is not set
CONFIG_BT_HCIBCM203X=m
@@ -590,31 +617,27 @@
# CONFIG_BT_HCIBTUART is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
CONFIG_CFG80211=m
-CONFIG_NL80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
CONFIG_MAC80211=m
#
# Rate control algorithm selection
#
-CONFIG_MAC80211_RC_PID=y
-# CONFIG_MAC80211_RC_MINSTREL is not set
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
-CONFIG_MAC80211_RC_DEFAULT="pid"
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
# CONFIG_MAC80211_MESH is not set
CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -662,17 +685,27 @@
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_TIMINGS=y
CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
@@ -684,7 +717,6 @@
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDESCSI=y
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_PROC_FS=y
@@ -714,6 +746,7 @@
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
# CONFIG_BLK_DEV_IT8213 is not set
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
@@ -728,7 +761,6 @@
# CONFIG_BLK_DEV_TC86C001 is not set
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
CONFIG_BLK_DEV_IDEDMA=y
#
@@ -772,6 +804,7 @@
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -791,8 +824,12 @@
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -822,6 +859,7 @@
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
@@ -881,6 +919,7 @@
# CONFIG_ANSLCD is not set
CONFIG_PMAC_RACKMETER=m
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -898,6 +937,8 @@
CONFIG_SUNGEM=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -913,7 +954,6 @@
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
@@ -923,6 +963,7 @@
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
@@ -935,6 +976,7 @@
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -945,18 +987,20 @@
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
-# CONFIG_MV643XX_ETH is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
@@ -966,6 +1010,7 @@
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -974,20 +1019,11 @@
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
# CONFIG_LIBERTAS is not set
# CONFIG_LIBERTAS_THINFIRM is not set
# CONFIG_AIRO is not set
-CONFIG_HERMES=m
-CONFIG_APPLE_AIRPORT=m
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_NORTEL_HERMES is not set
-CONFIG_PCI_HERMES=m
-CONFIG_PCMCIA_HERMES=m
-# CONFIG_PCMCIA_SPECTRUM is not set
# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
# CONFIG_AIRO_CS is not set
# CONFIG_PCMCIA_WL3501 is not set
CONFIG_PRISM54=m
@@ -997,15 +1033,17 @@
# CONFIG_RTL8187 is not set
# CONFIG_ADM8211 is not set
# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
CONFIG_P54_COMMON=m
# CONFIG_P54_USB is not set
# CONFIG_P54_PCI is not set
+CONFIG_P54_LEDS=y
# CONFIG_ATH5K is not set
# CONFIG_ATH9K is not set
-# CONFIG_IWLCORE is not set
-# CONFIG_IWLWIFI_LEDS is not set
-# CONFIG_IWLAGN is not set
-# CONFIG_IWL3945 is not set
+# CONFIG_AR9170_USB is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
# CONFIG_HOSTAP is not set
CONFIG_B43=m
CONFIG_B43_PCI_AUTOSELECT=y
@@ -1025,6 +1063,19 @@
# CONFIG_B43LEGACY_PIO_MODE is not set
# CONFIG_ZD1211RW is not set
# CONFIG_RT2X00 is not set
+CONFIG_HERMES=m
+CONFIG_HERMES_CACHE_FW_ON_INIT=y
+CONFIG_APPLE_AIRPORT=m
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_NORTEL_HERMES is not set
+CONFIG_PCI_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_PCMCIA_SPECTRUM is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -1036,6 +1087,7 @@
CONFIG_USB_USBNET=m
CONFIG_USB_NET_AX8817X=m
CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_CDC_EEM is not set
# CONFIG_USB_NET_DM9601 is not set
# CONFIG_USB_NET_SMSC95XX is not set
# CONFIG_USB_NET_GL620A is not set
@@ -1099,7 +1151,7 @@
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
+CONFIG_MOUSE_APPLETOUCH=y
# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
@@ -1150,10 +1202,13 @@
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
CONFIG_NVRAM=y
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
@@ -1232,12 +1287,9 @@
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -1259,11 +1311,11 @@
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=m
CONFIG_SSB_SPROM=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
@@ -1281,18 +1333,13 @@
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
-
-#
-# Voltage and Current regulators
-#
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
#
# Multimedia devices
@@ -1390,6 +1437,7 @@
# CONFIG_FB_KYRO is not set
CONFIG_FB_3DFX=y
# CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_3DFX_I2C=y
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
@@ -1399,12 +1447,14 @@
# CONFIG_FB_IBM_GXT4500 is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=m
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
#
# Display device support
@@ -1444,11 +1494,13 @@
CONFIG_SND_PCM_OSS=m
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_HRTIMER is not set
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
CONFIG_SND_DRIVERS=y
CONFIG_SND_DUMMY=m
# CONFIG_SND_VIRMIDI is not set
@@ -1486,6 +1538,8 @@
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1551,28 +1605,31 @@
#
# Special HID drivers
#
-CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
+# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
+CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_TOPSEED=y
# CONFIG_THRUSTMASTER_FF is not set
# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
@@ -1603,6 +1660,7 @@
CONFIG_USB_EHCI_ROOT_HUB_TT=y
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1625,24 +1683,23 @@
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_ALAUDA is not set
-CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_ONETOUCH=m
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -1665,7 +1722,7 @@
# CONFIG_USB_SERIAL_CH341 is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CP210X is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -1701,15 +1758,19 @@
# CONFIG_USB_SERIAL_NAVMAN is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
# CONFIG_USB_SERIAL_SPCP8X5 is not set
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1726,7 +1787,6 @@
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
CONFIG_USB_APPLEDISPLAY=m
@@ -1738,6 +1798,11 @@
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1748,7 +1813,9 @@
# LED drivers
#
# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
#
# LED Triggers
@@ -1759,11 +1826,16 @@
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1774,6 +1846,7 @@
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
@@ -1783,7 +1856,9 @@
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
@@ -1792,6 +1867,7 @@
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1801,6 +1877,11 @@
CONFIG_FUSE_FS=m
#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
@@ -1831,10 +1912,7 @@
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
CONFIG_HFS_FS=m
@@ -1843,6 +1921,7 @@
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1851,6 +1930,7 @@
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1868,7 +1948,6 @@
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1940,11 +2019,13 @@
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
#
# Library routines
#
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
@@ -1954,15 +2035,18 @@
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
#
# Kernel hacking
@@ -1973,13 +2057,16 @@
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
@@ -1994,6 +2081,7 @@
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
@@ -2001,6 +2089,7 @@
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -2009,7 +2098,14 @@
# CONFIG_FAULT_INJECTION is not set
CONFIG_LATENCYTOP=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
#
# Tracers
@@ -2017,12 +2113,19 @@
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_CODE_PATCHING_SELFTEST is not set
@@ -2033,6 +2136,7 @@
CONFIG_XMON_DISASSEMBLY=y
CONFIG_DEBUGGER=y
CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
# CONFIG_BDI_SWITCH is not set
CONFIG_BOOTX_TEXT=y
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -2051,13 +2155,20 @@
#
# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -2127,6 +2238,7 @@
# Compression
#
CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index c69f2b5..cb448d68 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -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 @@
* 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)
diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h
index d60fd18..f1f4e23 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -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 @@
#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
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index ba45c99..c9ff9d7 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -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;
@@ -56,8 +56,30 @@
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
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 53c7788..6b02793 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -32,7 +32,7 @@
{
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);
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 8db3527..29b742b 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -18,7 +18,6 @@
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
index 005a28d..0000000
--- a/arch/powerpc/lib/dma-noncoherent.c
+++ /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);
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 17290bc..b746f4c 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -26,3 +26,4 @@
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
index 0000000..36692f5
--- /dev/null
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -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);
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 666a5e8..3de6a0d9 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -168,12 +168,8 @@
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)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index d0602a7..579382c 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -380,6 +380,23 @@
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;
}
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index a70e311..030d000 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -127,12 +127,12 @@
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]);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 430d090..5422169 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -399,8 +399,6 @@
#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)
{
diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
index d3b2b4f..5d84df5 100644
--- a/arch/sh/include/asm/flat.h
+++ b/arch/sh/include/asm/flat.h
@@ -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))
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index 425c2f9..d42e393 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -208,8 +208,9 @@
else \
clear_thread_flag(TIF_ABI_PENDING); \
/* flush_thread will update pgd cache */ \
- if (current->personality != PER_LINUX32) \
- set_personality(PER_LINUX); \
+ if (personality(current->personality) != PER_LINUX32) \
+ set_personality(PER_LINUX | \
+ (current->personality & (~PER_MASK))); \
} while (0)
#endif /* !(__ASM_SPARC64_ELF_H) */
diff --git a/arch/sparc/lib/csum_copy_from_user.S b/arch/sparc/lib/csum_copy_from_user.S
index a22eddb..e0304e6 100644
--- a/arch/sparc/lib/csum_copy_from_user.S
+++ b/arch/sparc/lib/csum_copy_from_user.S
@@ -5,7 +5,7 @@
#define EX_LD(x) \
98: x; \
- .section .fixup; \
+ .section .fixup, "ax"; \
.align 4; \
99: retl; \
mov -1, %o0; \
diff --git a/arch/sparc/lib/csum_copy_to_user.S b/arch/sparc/lib/csum_copy_to_user.S
index d5b12f4..afd01ac 100644
--- a/arch/sparc/lib/csum_copy_to_user.S
+++ b/arch/sparc/lib/csum_copy_to_user.S
@@ -5,7 +5,7 @@
#define EX_ST(x) \
98: x; \
- .section .fixup; \
+ .section .fixup,"ax"; \
.align 4; \
99: retl; \
mov -1, %o0; \
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
index 857e492..bbeb0c3 100644
--- a/arch/x86/boot/compressed/relocs.c
+++ b/arch/x86/boot/compressed/relocs.c
@@ -504,8 +504,11 @@
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 */
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index 5054c2d..74b3d2b 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -17,11 +17,6 @@
#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 @@
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 @@
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));
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c1caefc..77848d9 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -114,6 +114,13 @@
} };
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;
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 208ecf6..54b6de2 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -693,8 +693,8 @@
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 */
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 6ac55bd..8696151 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -168,6 +168,7 @@
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) */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index 3c28ccd..a8363e5 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -168,10 +168,12 @@
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)
{
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 4709ead..f6b32d1 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -649,6 +649,20 @@
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 @@
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 @@
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 @@
* 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) {
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 1340dad..667188e 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -232,6 +232,14 @@
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"),
+ },
+ },
{ }
};
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 3a97a4c..8f0e13b 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -160,8 +160,10 @@
/*
* 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;
/*
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index b6caf13..32cf11e 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2897,8 +2897,7 @@
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;
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 49079a4..3944e91 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -338,6 +338,9 @@
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 @@
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);
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index 8f307d9..f46c340 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -26,12 +26,16 @@
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;
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 797f9f1..e17efed 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -153,7 +153,7 @@
*/
__flush_tlb_all();
- if (cache && boot_cpu_data.x86_model >= 4)
+ if (cache && boot_cpu_data.x86 >= 4)
wbinvd();
}
@@ -208,20 +208,15 @@
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
diff --git a/crypto/ahash.c b/crypto/ahash.c
index b2d1ee3..f347637 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -82,10 +82,11 @@
if (err)
return err;
- walk->offset = 0;
-
- if (nbytes)
+ if (nbytes) {
+ walk->offset = 0;
+ walk->pg++;
return hash_walk_next(walk);
+ }
if (!walk->total)
return 0;
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 95650f8..bc46de3 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -116,9 +116,6 @@
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 @@
* 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 @@
end:
kfree(buffer.pointer);
- if (result)
+ if (result) {
+ pci_dev_put(data->dev);
kfree(data);
-
+ }
return result;
}
@@ -303,6 +290,7 @@
if (data->dev->subordinate) {
acpi_pci_irq_del_prt(data->id.segment, data->bus->number);
}
+ pci_dev_put(data->dev);
kfree(data);
end:
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 72069ba..10a2d91 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -148,6 +148,9 @@
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 @@
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 @@
/* 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 @@
local_irq_enable();
cx->usage++;
+ acpi_state_timer_broadcast(pr, cx, 0);
return idle_time;
}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index cafb410..60e543d 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -309,9 +309,15 @@
(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;
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 7f16f5f..2275437 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -840,7 +840,7 @@
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)
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 810cca9..1bdfb37 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -570,6 +570,22 @@
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 @@
return acpi_video_register();
}
-void __exit acpi_video_exit(void)
+void acpi_video_exit(void)
{
acpi_bus_unregister_driver(&acpi_video_bus);
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index bdb2369..9a69809 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -20,13 +20,24 @@
/* No PIO or DMA methods needed for this device */
+static unsigned int netcell_read_id(struct ata_device *adev,
+ struct ata_taskfile *tf, u16 *id)
+{
+ unsigned int err_mask = ata_do_dev_read_id(adev, tf, id);
+ /* Firmware forgets to mark words 85-87 valid */
+ if (err_mask == 0)
+ id[ATA_ID_CSF_DEFAULT] |= 0x0400;
+ return err_mask;
+}
+
static struct scsi_host_template netcell_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations netcell_ops = {
.inherits = &ata_bmdma_port_ops,
- .cable_detect = ata_cable_80wire,
+ .cable_detect = ata_cable_80wire,
+ .read_id = netcell_read_id,
};
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index dc030f1..c659961 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -700,8 +700,10 @@
}
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);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4aa527b..1977d4b 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -879,7 +879,7 @@
}
if (!dev_name(dev))
- goto done;
+ goto name_error;
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -978,6 +978,9 @@
cleanup_device_parent(dev);
if (parent)
put_device(parent);
+name_error:
+ kfree(dev->p);
+ dev->p = NULL;
goto done;
}
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index c51f11b..8ae0f63 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -257,6 +257,10 @@
*/
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);
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 69b4ddb..3e4bc69 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -357,6 +357,7 @@
{
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 @@
if (error)
pm_dev_err(dev, state, " early", error);
}
+ mutex_unlock(&dpm_list_mtx);
}
/**
@@ -614,6 +616,7 @@
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 @@
}
dev->power.status = DPM_OFF_IRQ;
}
+ mutex_unlock(&dpm_list_mtx);
if (error)
device_power_up(resume_event(state));
return error;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index d270e8e..47d2ad0 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1070,11 +1070,11 @@
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
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 2ecd95e..7a74d17 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -91,6 +91,9 @@
* (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_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,
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 338f428..e741c33 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -98,6 +98,9 @@
* (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_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,
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index da8a8ed..f18d1bd 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -179,9 +179,14 @@
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 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 @@
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 @@
{
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 @@
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 @@
/* 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 @@
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 @@
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 @@
*/
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 @@
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 @@
}
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);
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 1955ee8..a600fc0 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -173,7 +173,7 @@
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
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index e5f5c5a..956982f 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -192,16 +192,20 @@
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
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index a5fdcf0..5907681 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -35,3 +35,5 @@
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
diff --git a/drivers/edac/amd8111_edac.c b/drivers/edac/amd8111_edac.c
index 6146921..2cb58ef 100644
--- a/drivers/edac/amd8111_edac.c
+++ b/drivers/edac/amd8111_edac.c
@@ -389,7 +389,7 @@
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 @@
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;
diff --git a/drivers/edac/amd8131_edac.c b/drivers/edac/amd8131_edac.c
index c083b31..b432d60 100644
--- a/drivers/edac/amd8131_edac.c
+++ b/drivers/edac/amd8131_edac.c
@@ -287,7 +287,7 @@
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;
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 4cd35d8..f5d46e7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -67,12 +67,18 @@
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_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
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9b149fe..c431fa5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -180,7 +180,8 @@
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;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b189b49..670d128 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -349,7 +349,7 @@
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 @@
SetPageDirty(user_pages[i]);
page_cache_release(user_pages[i]);
}
- kfree(user_pages);
+ drm_free_large(user_pages);
return ret;
}
@@ -649,7 +649,7 @@
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_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 @@
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_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 @@
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 @@
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 @@
}
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 @@
*/
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 @@
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 @@
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 @@
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 @@
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 @@
}
err:
- drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER);
+ drm_free_large(relocs);
return ret;
}
@@ -3198,10 +3213,8 @@
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 @@
}
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);
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 52a0593..540dd33 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -213,7 +213,8 @@
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 @@
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;
}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 15da44c..375569d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -190,7 +190,8 @@
#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
@@ -1410,9 +1411,25 @@
/* 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
@@ -1420,6 +1437,7 @@
#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
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index fc28e2b..9d78cff 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -57,9 +57,43 @@
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,35 +125,9 @@
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;
-
- /* 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);
-
- dev_priv->vbt_mode = panel_fixed_mode;
+ dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
drm_mode_debug_printmodeline(panel_fixed_mode);
@@ -127,6 +135,39 @@
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->sdvo_lvds_vbt_mode = NULL;
+
+ 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;
+}
+
static void
parse_general_features(struct drm_i915_private *dev_priv,
struct bdb_header *bdb)
@@ -199,7 +240,8 @@
/* 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);
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index de621aa..8ca2cde 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -279,6 +279,23 @@
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);
/*
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 19148c3..640f515 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -198,9 +198,142 @@
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 @@
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)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3387cf3..c9d6f10 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1357,7 +1357,7 @@
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 @@
/* 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 @@
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);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 439a865..53731f0 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -511,10 +511,10 @@
}
/* 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 |=
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 9913651..f3ef6bf 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -69,6 +69,10 @@
* 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 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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
+ /* 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 @@
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 @@
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 @@
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 @@
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 @@
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;
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index b5e3b28..a1787fd 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -182,7 +182,7 @@
.name = "lm78",
},
.probe = lm78_isa_probe,
- .remove = lm78_isa_remove,
+ .remove = __devexit_p(lm78_isa_remove),
};
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index 61111fd..39d4e01 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -33,6 +33,16 @@
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
+static void netcell_quirkproc(ide_drive_t *drive)
+{
+ /* mark words 85-87 as valid */
+ drive->id[ATA_ID_CSF_DEFAULT] |= 0x4000;
+}
+
+static const struct ide_port_ops netcell_port_ops = {
+ .quirkproc = netcell_quirkproc,
+};
+
#define DECLARE_GENERIC_PCI_DEV(extra_flags) \
{ \
.name = DRV_NAME, \
@@ -74,6 +84,7 @@
{ /* 6: Revolution */
.name = DRV_NAME,
+ .port_ops = &netcell_port_ops,
.host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD,
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index bf74039..949c97f 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -41,6 +41,10 @@
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 @@
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())
diff --git a/drivers/input/input.c b/drivers/input/input.c
index e54e002..5d445f4 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -42,6 +42,7 @@
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)];
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 67248c3..be5bbbb 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -210,7 +210,7 @@
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,
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index f100c7f..6954f55 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -419,7 +419,7 @@
#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) {
/*
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index b171e75..29808c4 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -175,7 +175,7 @@
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;
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 1a83910..eaf722f 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -358,6 +358,16 @@
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 @@
* 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. */
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 47c68bc..56df1ce 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1097,14 +1097,12 @@
}
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 @@
write_page(bitmap, page, 0);
bitmap->allclean = 0;
}
+ spin_lock_irqsave(&bitmap->lock, flags);
+ j |= (PAGE_BITS - 1);
continue;
}
@@ -1181,9 +1181,10 @@
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) {
diff --git a/drivers/md/md.c b/drivers/md/md.c
index fccc834..641b211 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1375,6 +1375,9 @@
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 @@
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 @@
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 @@
if (strict_blocks_to_sectors(buf, §ors) < 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 @@
.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 @@
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,
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 4616bc3..5d400ae 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3811,13 +3811,13 @@
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.
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index f3548d0..40c2608 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -831,6 +831,7 @@
break;
case NAND_CMD_READID:
+ host->col_addr = 0;
send_read_id(host);
break;
@@ -867,6 +868,7 @@
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 @@
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 @@
host->regs = ioremap(res->start, res->end - res->start + 1);
if (!host->regs) {
- err = -EIO;
+ err = -ENOMEM;
goto eres;
}
@@ -1011,30 +1015,35 @@
#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 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)
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index fbb3719..682aad8 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -480,9 +480,13 @@
#ifdef CONFIG_EISA
static struct eisa_device_id el3_eisa_ids[] = {
+ { "TCM5090" },
+ { "TCM5091" },
{ "TCM5092" },
{ "TCM5093" },
+ { "TCM5094" },
{ "TCM5095" },
+ { "TCM5098" },
{ "" }
};
MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1fc4602..a1c25cb 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -102,7 +102,7 @@
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
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index fb57b75..1342418 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -37,6 +37,7 @@
*/
static struct pci_device_id atl1e_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
/* required last entry */
{ 0 }
};
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 0ab2254..4e81712 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -82,6 +82,12 @@
#include "atl1.h"
+#define ATLX_DRIVER_VERSION "2.1.3"
+MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
+ Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATLX_DRIVER_VERSION);
+
/* Temporary hack for merging atl1 and atl2 */
#include "atlx.c"
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h
index 297a03d..14054b7 100644
--- a/drivers/net/atlx/atlx.h
+++ b/drivers/net/atlx/atlx.h
@@ -29,12 +29,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#define ATLX_DRIVER_VERSION "2.1.3"
-MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
- Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATLX_DRIVER_VERSION);
-
#define ATLX_ERR_PHY 2
#define ATLX_ERR_PHY_SPEED 7
#define ATLX_ERR_PHY_RES 8
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 9f971ed..b4da182 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -979,22 +979,7 @@
return 0;
}
-static const struct net_device_ops bfin_mac_netdev_ops = {
- .ndo_open = bfin_mac_open,
- .ndo_stop = bfin_mac_close,
- .ndo_start_xmit = bfin_mac_hard_start_xmit,
- .ndo_set_mac_address = bfin_mac_set_mac_address,
- .ndo_tx_timeout = bfin_mac_timeout,
- .ndo_set_multicast_list = bfin_mac_set_multicast_list,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = bfin_mac_poll,
-#endif
-};
-
/*
- *
* this makes the board clean up everything that it can
* and not talk to the outside world. Caused by
* an 'ifconfig ethX down'
@@ -1019,6 +1004,20 @@
return 0;
}
+static const struct net_device_ops bfin_mac_netdev_ops = {
+ .ndo_open = bfin_mac_open,
+ .ndo_stop = bfin_mac_close,
+ .ndo_start_xmit = bfin_mac_hard_start_xmit,
+ .ndo_set_mac_address = bfin_mac_set_mac_address,
+ .ndo_tx_timeout = bfin_mac_timeout,
+ .ndo_set_multicast_list = bfin_mac_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = bfin_mac_poll,
+#endif
+};
+
static int __devinit bfin_mac_probe(struct platform_device *pdev)
{
struct net_device *ndev;
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 714df2b..c888e97 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -85,8 +85,8 @@
struct page *page;
void *va;
unsigned int offset;
- u64 *p_cnt;
- DECLARE_PCI_UNMAP_ADDR(mapping);
+ unsigned long *p_cnt;
+ dma_addr_t mapping;
};
struct rx_desc;
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 7ea4841..17858b9 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -2496,14 +2496,16 @@
for_each_port(adapter, i) {
struct net_device *dev = adapter->port[i];
struct port_info *p = netdev_priv(dev);
+ int link_fault;
spin_lock_irq(&adapter->work_lock);
- if (p->link_fault) {
+ link_fault = p->link_fault;
+ spin_unlock_irq(&adapter->work_lock);
+
+ if (link_fault) {
t3_link_fault(adapter, i);
- spin_unlock_irq(&adapter->work_lock);
continue;
}
- spin_unlock_irq(&adapter->work_lock);
if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) {
t3_xgm_intr_disable(adapter, i);
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 26d3587..b3ee2bc 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -355,7 +355,7 @@
(*d->pg_chunk.p_cnt)--;
if (!*d->pg_chunk.p_cnt)
pci_unmap_page(pdev,
- pci_unmap_addr(&d->pg_chunk, mapping),
+ d->pg_chunk.mapping,
q->alloc_size, PCI_DMA_FROMDEVICE);
put_page(d->pg_chunk.page);
@@ -454,7 +454,7 @@
q->pg_chunk.offset = 0;
mapping = pci_map_page(adapter->pdev, q->pg_chunk.page,
0, q->alloc_size, PCI_DMA_FROMDEVICE);
- pci_unmap_addr_set(&q->pg_chunk, mapping, mapping);
+ q->pg_chunk.mapping = mapping;
}
sd->pg_chunk = q->pg_chunk;
@@ -511,8 +511,7 @@
nomem: q->alloc_failed++;
break;
}
- mapping = pci_unmap_addr(&sd->pg_chunk, mapping) +
- sd->pg_chunk.offset;
+ mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset;
pci_unmap_addr_set(sd, dma_addr, mapping);
add_one_rx_chunk(mapping, d, q->gen);
@@ -881,7 +880,7 @@
(*sd->pg_chunk.p_cnt)--;
if (!*sd->pg_chunk.p_cnt)
pci_unmap_page(adap->pdev,
- pci_unmap_addr(&sd->pg_chunk, mapping),
+ sd->pg_chunk.mapping,
fl->alloc_size,
PCI_DMA_FROMDEVICE);
if (!skb) {
@@ -2096,7 +2095,7 @@
(*sd->pg_chunk.p_cnt)--;
if (!*sd->pg_chunk.p_cnt)
pci_unmap_page(adap->pdev,
- pci_unmap_addr(&sd->pg_chunk, mapping),
+ sd->pg_chunk.mapping,
fl->alloc_size,
PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 4f68aeb..4950d5d 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1274,6 +1274,11 @@
A_XGM_INT_STATUS + mac->offset);
link_fault &= F_LINKFAULTCHANGE;
+ link_ok = lc->link_ok;
+ speed = lc->speed;
+ duplex = lc->duplex;
+ fc = lc->fc;
+
phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
if (link_fault) {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index b1419e2..fffb006 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4027,8 +4027,9 @@
PCI_DMA_FROMDEVICE);
length = le16_to_cpu(rx_desc->length);
-
- if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
+ /* !EOP means multiple descriptors were used to store a single
+ * packet, also make sure the frame isn't just CRC only */
+ if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) {
/* All receives must fit into a single buffer */
E1000_DBG("%s: Receive packet consumed multiple"
" buffers\n", netdev->name);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index f9a846b..9f6a68f 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -897,6 +897,12 @@
};
static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED;
+/*
+ * Power down phy when interface is down (persists through reboot;
+ * older Linux and other OSes may not power it up again)
+ */
+static int phy_power_down = 0;
+
static inline struct fe_priv *get_nvpriv(struct net_device *dev)
{
return netdev_priv(dev);
@@ -1485,7 +1491,10 @@
/* restart auto negotiation, power down phy */
mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
- mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE | BMCR_PDOWN);
+ mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
+ if (phy_power_down) {
+ mii_control |= BMCR_PDOWN;
+ }
if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
return PHY_ERROR;
}
@@ -5513,7 +5522,7 @@
nv_drain_rxtx(dev);
- if (np->wolenabled) {
+ if (np->wolenabled || !phy_power_down) {
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
nv_start_rx(dev);
} else {
@@ -6367,6 +6376,8 @@
MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0.");
module_param(phy_cross, int, 0);
MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0.");
+module_param(phy_power_down, int, 0);
+MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0).");
MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b2c4967..a051918 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1885,8 +1885,17 @@
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++;
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 0642d52..cf35296 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -259,7 +259,7 @@
(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
| IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
- | IEVENT_MAG)
+ | IEVENT_MAG | IEVENT_BABR)
#define IMASK_INIT_CLEAR 0x00000000
#define IMASK_BABR 0x80000000
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index 8e88486..22e74a0 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -304,7 +304,7 @@
if (!MACH_IS_MAC)
return ERR_PTR(-ENODEV);
- dev = alloc_ei_netdev();
+ dev = ____alloc_ei_netdev(0);
if (!dev)
return ERR_PTR(-ENOMEM);
@@ -481,15 +481,15 @@
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,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ei_poll,
+ .ndo_poll_controller = __ei_poll,
#endif
};
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index ac6fc49..e5c98a9 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -426,7 +426,7 @@
INC_PERF_COUNTER(priv->pstats.tx_poll);
- if (!spin_trylock(&ring->comp_lock)) {
+ if (!spin_trylock_irq(&ring->comp_lock)) {
mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
return;
}
@@ -439,7 +439,7 @@
if (inflight && priv->port_up)
mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
- spin_unlock(&ring->comp_lock);
+ spin_unlock_irq(&ring->comp_lock);
}
static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
@@ -482,9 +482,9 @@
/* Poll the CQ every mlx4_en_TX_MODER_POLL packets */
if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0)
- if (spin_trylock(&ring->comp_lock)) {
+ if (spin_trylock_irq(&ring->comp_lock)) {
mlx4_en_process_tx_cq(priv->dev, cq);
- spin_unlock(&ring->comp_lock);
+ spin_unlock_irq(&ring->comp_lock);
}
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0b6e8c8..8247a94 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3554,54 +3554,64 @@
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;
-
- if (unlikely(!netif_running(dev))) {
- rtl8169_asic_down(ioaddr);
- goto out;
- }
-
- status &= tp->intr_mask;
- RTL_W16(IntrStatus,
- (status & RxFIFOOver) ? (status | RxOverflow) : status);
-
- if (!(status & tp->intr_event))
- 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);
- goto out;
- }
-
- if (unlikely(status & SYSErr)) {
- rtl8169_pcierr_interrupt(dev);
- goto out;
- }
-
- 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);
+ /* 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;
}
+
+ /* 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;
+ }
+
+ if (unlikely(status & SYSErr)) {
+ rtl8169_pcierr_interrupt(dev);
+ break;
+ }
+
+ if (status & LinkChg)
+ rtl8169_check_link_status(dev, tp, ioaddr);
+
+ /* 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);
+ }
+ }
+
+ /* 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);
}
-out:
+
return IRQ_RETVAL(handled);
}
@@ -3617,13 +3627,15 @@
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);
}
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index ca4151a..1785132 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -505,27 +505,52 @@
#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);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 8a08235..3d94e7d 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -430,6 +430,7 @@
ASUS P5B Deluxe
Toshiba Satellite Pro series of laptops
Asus Wireless Link
+ Linksys WUSB54GC-EU
Thanks to Realtek for their support!
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index d734757..9eabf4d 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -6467,6 +6467,7 @@
{
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 @@
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 @@
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 @@
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;
}
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 744f4f4..8d93ca4 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1873,18 +1873,18 @@
if (ret != CMD_STATUS_COMPLETE) {
queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
SCAN_POLL_INTERVAL);
- goto exit;
+ mutex_unlock(&priv->mtx);
+ return;
}
- ieee80211_scan_completed(priv->hw, false);
-
if (is_valid_ether_addr(priv->bssid))
at76_join(priv);
- ieee80211_wake_queues(priv->hw);
-
-exit:
mutex_unlock(&priv->mtx);
+
+ ieee80211_scan_completed(priv->hw, false);
+
+ ieee80211_wake_queues(priv->hw);
}
static int at76_hw_scan(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 9e2faae..b48b29d 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -1487,28 +1487,35 @@
{
s8 tmp;
s16 min_pwrL, min_pwrR;
- s16 pwr_i = pwrL[0];
+ s16 pwr_i;
- do {
- pwr_i--;
- tmp = (s8) ath5k_get_interpolated_value(pwr_i,
- pwrL[0], pwrL[1],
- stepL[0], stepL[1]);
+ 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);
- } while (tmp > 1);
+ min_pwrL = pwr_i;
+ }
- min_pwrL = 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);
- 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;
+ min_pwrR = pwr_i;
+ }
/* Keep the right boundary so that it works for both curves */
return max(min_pwrL, min_pwrR);
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index 7a17d31..5f72c11 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -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 @@
/* 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 @@
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;
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index e5ca251..9452461 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -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 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3bb28db..f46ba24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -669,13 +669,6 @@
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;
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e7c65c4..6330b91 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -227,9 +227,6 @@
/* 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 @@
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 @@
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))
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4cce661..ff4d0e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -782,13 +782,6 @@
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 @@
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;
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 07d378e..7b3ee8c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -138,7 +138,7 @@
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 */
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index bac6cfb..d51ba0a 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -71,6 +71,8 @@
{USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
/* AirLive */
{USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
+ /* Linksys */
+ {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B},
{}
};
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index f0e99d4..242257b 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -78,16 +78,20 @@
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;
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
index e6a7e84..ea31a45 100644
--- a/drivers/parport/parport_gsc.c
+++ b/drivers/parport/parport_gsc.c
@@ -352,8 +352,8 @@
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;
}
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index 0ebca45..dffa5d4 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -614,7 +614,10 @@
* pardevice fields. -arca
*/
port->ops->init_state(tmp, tmp->state);
- parport_device_proc_register(tmp);
+ if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) {
+ port->proc_device = tmp;
+ parport_device_proc_register(tmp);
+ }
return tmp;
out_free_all:
@@ -646,10 +649,14 @@
}
#endif
- parport_device_proc_unregister(dev);
-
port = dev->port->physport;
+ if (port->proc_device == dev) {
+ port->proc_device = NULL;
+ clear_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags);
+ parport_device_proc_unregister(dev);
+ }
+
if (port->cad == dev) {
printk(KERN_DEBUG "%s: %s forgot to release port\n",
port->name, dev->name);
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 4fc168b..e68d5f2 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -129,7 +129,6 @@
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;
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a33794d..3a6064bc 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -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 @@
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 @@
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 @@
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 @@
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 int disable_device(struct acpiphp_slot *slot)
{
- int retval = 0;
struct acpiphp_func *func;
- struct list_head *l;
+ struct pci_dev *pdev;
/* is this slot already disabled? */
if (!(slot->flags & SLOT_ENABLED))
goto err_exit;
- list_for_each (l, &slot->funcs) {
- func = list_entry(l, struct acpiphp_func, sibling);
-
+ list_for_each_entry(func, &slot->funcs, sibling) {
if (func->bridge) {
/* cleanup p2p bridges under this P2P bridge */
cleanup_p2p_bridge(func->bridge->handle,
@@ -1160,35 +1156,28 @@
func->bridge = NULL;
}
- if (func->pci_dev) {
- pci_stop_bus_device(func->pci_dev);
- if (func->pci_dev->subordinate) {
- disable_bridges(func->pci_dev->subordinate);
- pci_disable_device(func->pci_dev);
+ pdev = pci_get_slot(slot->bridge->pci_bus,
+ PCI_DEVFN(slot->device, func->function));
+ if (pdev) {
+ pci_stop_bus_device(pdev);
+ if (pdev->subordinate) {
+ disable_bridges(pdev->subordinate);
+ pci_disable_device(pdev);
}
+ pci_remove_bus_device(pdev);
+ pci_dev_put(pdev);
}
}
- list_for_each (l, &slot->funcs) {
- func = list_entry(l, struct acpiphp_func, sibling);
-
+ list_for_each_entry(func, &slot->funcs, sibling) {
acpiphp_unconfigure_ioapics(func->handle);
acpiphp_bus_trim(func->handle);
- /* try to remove anyway.
- * acpiphp_bus_add might have been failed */
-
- if (!func->pci_dev)
- continue;
-
- pci_remove_bus_device(func->pci_dev);
- pci_dev_put(func->pci_dev);
- func->pci_dev = NULL;
}
slot->flags &= (~SLOT_ENABLED);
- err_exit:
- return retval;
+err_exit:
+ return 0;
}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index b4b3981..a0127e9 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -137,6 +137,7 @@
unsigned char mcr;
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
+ unsigned char cur_iotype; /* Running I/O type */
/*
* Some bits in registers are cleared on a read, so they must
@@ -471,6 +472,7 @@
static void set_io_from_upio(struct uart_port *p)
{
+ struct uart_8250_port *up = (struct uart_8250_port *)p;
switch (p->iotype) {
case UPIO_HUB6:
p->serial_in = hub6_serial_in;
@@ -509,6 +511,8 @@
p->serial_out = io_serial_out;
break;
}
+ /* Remember loaded iotype */
+ up->cur_iotype = p->iotype;
}
static void
@@ -1937,6 +1941,9 @@
up->capabilities = uart_config[up->port.type].flags;
up->mcr = 0;
+ if (up->port.iotype != up->cur_iotype)
+ set_io_from_upio(port);
+
if (up->port.type == PORT_16C950) {
/* Wake up and initialize UART */
up->acr = 0;
@@ -2563,6 +2570,9 @@
if (ret < 0)
probeflags &= ~PROBE_RSA;
+ if (up->port.iotype != up->cur_iotype)
+ set_io_from_upio(port);
+
if (flags & UART_CONFIG_TYPE)
autoconfig(up, probeflags);
if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
@@ -2671,6 +2681,11 @@
{
int i;
+ for (i = 0; i < nr_uarts; i++) {
+ struct uart_8250_port *up = &serial8250_ports[i];
+ up->cur_iotype = 0xFF;
+ }
+
serial8250_isa_init_ports();
for (i = 0; i < nr_uarts; i++) {
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 418b4fe..33149d9 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -39,9 +39,9 @@
*/
if (parisc_parent(dev)->id.hw_type != HPHW_IOA)
printk(KERN_INFO
- "Serial: device 0x%lx not configured.\n"
+ "Serial: device 0x%llx not configured.\n"
"Enable support for Wax, Lasi, Asp or Dino.\n",
- dev->hpa.start);
+ (unsigned long long)dev->hpa.start);
return -ENODEV;
}
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 4cfa1eb..8c5bda2 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -70,6 +70,23 @@
struct clk *clk;
unsigned int im; /* interrupt mask */
unsigned int old_status;
+ unsigned int ifls; /* vendor-specific */
+};
+
+/* There is by now at least one vendor with differing details, so handle it */
+struct vendor_data {
+ unsigned int ifls;
+ unsigned int fifosize;
+};
+
+static struct vendor_data vendor_arm = {
+ .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
+ .fifosize = 16,
+};
+
+static struct vendor_data vendor_st = {
+ .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF,
+ .fifosize = 64,
};
static void pl011_stop_tx(struct uart_port *port)
@@ -360,8 +377,7 @@
if (retval)
goto clk_dis;
- writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
- uap->port.membase + UART011_IFLS);
+ writew(uap->ifls, uap->port.membase + UART011_IFLS);
/*
* Provoke TX FIFO interrupt into asserting.
@@ -732,6 +748,7 @@
static int pl011_probe(struct amba_device *dev, struct amba_id *id)
{
struct uart_amba_port *uap;
+ struct vendor_data *vendor = id->data;
void __iomem *base;
int i, ret;
@@ -762,12 +779,13 @@
goto unmap;
}
+ uap->ifls = vendor->ifls;
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
uap->port.iotype = UPIO_MEM;
uap->port.irq = dev->irq[0];
- uap->port.fifosize = 16;
+ uap->port.fifosize = vendor->fifosize;
uap->port.ops = &amba_pl011_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = i;
@@ -812,6 +830,12 @@
{
.id = 0x00041011,
.mask = 0x000fffff,
+ .data = &vendor_arm,
+ },
+ {
+ .id = 0x00380802,
+ .mask = 0x00ffffff,
+ .data = &vendor_st,
},
{ 0, 0 },
};
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 3f5d5a2..738c8a5 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -1024,6 +1024,8 @@
if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports))
co->index = 0;
sport = imx_ports[co->index];
+ if(sport == NULL)
+ return -ENODEV;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 7f72f8c..b3feb61 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -988,7 +988,7 @@
pr_debug("mpc52xx_console_setup co=%p, co->index=%i, options=%s\n",
co, co->index, options);
- if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) {
+ if ((co->index < 0) || (co->index >= MPC52xx_PSC_MAXNUM)) {
pr_debug("PSC%x out of range\n", co->index);
return -EINVAL;
}
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 0716cdb..0a3dc5e 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -11,7 +11,6 @@
obj-$(CONFIG_PCI) += host/
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_ISP116X_HCD) += host/
-obj-$(CONFIG_USB_ISP1760_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
obj-$(CONFIG_USB_UHCI_HCD) += host/
obj-$(CONFIG_USB_FHCI_HCD) += host/
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 0a69c09..7a1164d 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1375,6 +1375,9 @@
{ USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
},
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 563d572..05c913c 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -794,7 +794,8 @@
if (ep->desc) {
list_add_tail(&req->queue, &ep->queue);
- if (ep->is_in || (ep_is_control(ep)
+ if ((!ep_is_control(ep) && ep->is_in) ||
+ (ep_is_control(ep)
&& (ep->state == DATA_STAGE_IN
|| ep->state == STATUS_STAGE_IN)))
usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY);
@@ -1940,7 +1941,7 @@
usba_writel(udc, CTRL, USBA_DISABLE_MASK);
clk_disable(pclk);
- usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep,
+ usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep,
GFP_KERNEL);
if (!usba_ep)
goto err_alloc_ep;
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index cd07ea3..1543846 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -1658,6 +1658,7 @@
u32 reg_base, or_reg, skip_reg;
unsigned long flags;
struct ptd ptd;
+ packet_enqueue *pe;
switch (usb_pipetype(urb->pipe)) {
case PIPE_ISOCHRONOUS:
@@ -1669,6 +1670,7 @@
reg_base = INT_REGS_OFFSET;
or_reg = HC_INT_IRQ_MASK_OR_REG;
skip_reg = HC_INT_PTD_SKIPMAP_REG;
+ pe = enqueue_an_INT_packet;
break;
default:
@@ -1676,6 +1678,7 @@
reg_base = ATL_REGS_OFFSET;
or_reg = HC_ATL_IRQ_MASK_OR_REG;
skip_reg = HC_ATL_PTD_SKIPMAP_REG;
+ pe = enqueue_an_ATL_packet;
break;
}
@@ -1687,6 +1690,7 @@
u32 skip_map;
u32 or_map;
struct isp1760_qtd *qtd;
+ struct isp1760_qh *qh = ints->qh;
skip_map = isp1760_readl(hcd->regs + skip_reg);
skip_map |= 1 << i;
@@ -1699,8 +1703,7 @@
priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base
+ i * sizeof(ptd), sizeof(ptd));
qtd = ints->qtd;
-
- clean_up_qtdlist(qtd);
+ qtd = clean_up_qtdlist(qtd);
free_mem(priv, ints->payload);
@@ -1711,7 +1714,24 @@
ints->payload = 0;
isp1760_urb_done(priv, urb, status);
+ if (qtd)
+ pe(hcd, qh, qtd);
break;
+
+ } else if (ints->qtd) {
+ struct isp1760_qtd *qtd, *prev_qtd = ints->qtd;
+
+ for (qtd = ints->qtd->hw_next; qtd; qtd = qtd->hw_next) {
+ if (qtd->urb == urb) {
+ prev_qtd->hw_next = clean_up_qtdlist(qtd);
+ isp1760_urb_done(priv, urb, status);
+ break;
+ }
+ prev_qtd = qtd;
+ }
+ /* we found the urb before the end of the list */
+ if (qtd)
+ break;
}
ints++;
}
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0a566ee..f331e2b 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -974,6 +974,7 @@
if (retval > 0) {
/* quietly accept this device, but don't bind to a
serial port as it's about to disappear */
+ serial->num_ports = 0;
goto exit;
}
}
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 9a577a8..2fb63f6 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -29,14 +29,8 @@
/* configurable parameters */
#define ATMEL_LCDC_CVAL_DEFAULT 0xc8
-#define ATMEL_LCDC_DMA_BURST_LEN 8
-
-#if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) || \
- defined(CONFIG_ARCH_AT91SAM9RL)
-#define ATMEL_LCDC_FIFO_SIZE 2048
-#else
-#define ATMEL_LCDC_FIFO_SIZE 512
-#endif
+#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */
+#define ATMEL_LCDC_FIFO_SIZE 512 /* words */
#if defined(CONFIG_ARCH_AT91)
#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 5e9c630..d3a568e 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -947,7 +947,8 @@
int win;
for (win = 0; win <= S3C_FB_MAX_WIN; win++)
- s3c_fb_release_win(sfb, sfb->windows[win]);
+ if (sfb->windows[win])
+ s3c_fb_release_win(sfb, sfb->windows[win]);
iounmap(sfb->regs);
@@ -985,11 +986,20 @@
static int s3c_fb_resume(struct platform_device *pdev)
{
struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb_platdata *pd = sfb->pdata;
struct s3c_fb_win *win;
int win_no;
clk_enable(sfb->bus_clk);
+ /* setup registers */
+ writel(pd->vidcon1, sfb->regs + VIDCON1);
+
+ /* zero all windows before we do anything */
+ for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++)
+ s3c_fb_clear_win(sfb, win_no);
+
+ /* restore framebuffers */
for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
win = sfb->windows[win_no];
if (!win)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5eb8f21..5744cac 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -231,14 +231,14 @@
NOTE: once enabled, this timer cannot be disabled.
Say N if you are unsure.
-config ORION5X_WATCHDOG
- tristate "Orion5x watchdog"
- depends on ARCH_ORION5X
+config ORION_WATCHDOG
+ tristate "Orion watchdog"
+ depends on ARCH_ORION5X || ARCH_KIRKWOOD
help
Say Y here if to include support for the watchdog timer
- in the Orion5x ARM SoCs.
+ in the Marvell Orion5x and Kirkwood ARM SoCs.
To compile this driver as a module, choose M here: the
- module will be called orion5x_wdt.
+ module will be called orion_wdt.
# AVR32 Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 7f8c56b..c3afa14 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -40,7 +40,7 @@
obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
-obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o
+obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion_wdt.c
similarity index 64%
rename from drivers/watchdog/orion5x_wdt.c
rename to drivers/watchdog/orion_wdt.c
index 2cde568..2d9fb96 100644
--- a/drivers/watchdog/orion5x_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -1,7 +1,7 @@
/*
- * drivers/watchdog/orion5x_wdt.c
+ * drivers/watchdog/orion_wdt.c
*
- * Watchdog driver for Orion5x processors
+ * Watchdog driver for Orion/Kirkwood processors
*
* Author: Sylver Bruneau <sylver.bruneau@googlemail.com>
*
@@ -23,7 +23,7 @@
#include <linux/io.h>
#include <linux/spinlock.h>
#include <mach/bridge-regs.h>
-#include <plat/orion5x_wdt.h>
+#include <plat/orion_wdt.h>
/*
* Watchdog timer block registers.
@@ -43,7 +43,7 @@
static unsigned long wdt_status;
static spinlock_t wdt_lock;
-static void orion5x_wdt_ping(void)
+static void orion_wdt_ping(void)
{
spin_lock(&wdt_lock);
@@ -53,7 +53,7 @@
spin_unlock(&wdt_lock);
}
-static void orion5x_wdt_enable(void)
+static void orion_wdt_enable(void)
{
u32 reg;
@@ -73,23 +73,23 @@
writel(reg, TIMER_CTRL);
/* Enable reset on watchdog */
- reg = readl(CPU_RESET_MASK);
- reg |= WDT_RESET;
- writel(reg, CPU_RESET_MASK);
+ reg = readl(RSTOUTn_MASK);
+ reg |= WDT_RESET_OUT_EN;
+ writel(reg, RSTOUTn_MASK);
spin_unlock(&wdt_lock);
}
-static void orion5x_wdt_disable(void)
+static void orion_wdt_disable(void)
{
u32 reg;
spin_lock(&wdt_lock);
/* Disable reset on watchdog */
- reg = readl(CPU_RESET_MASK);
- reg &= ~WDT_RESET;
- writel(reg, CPU_RESET_MASK);
+ reg = readl(RSTOUTn_MASK);
+ reg &= ~WDT_RESET_OUT_EN;
+ writel(reg, RSTOUTn_MASK);
/* Disable watchdog timer */
reg = readl(TIMER_CTRL);
@@ -99,7 +99,7 @@
spin_unlock(&wdt_lock);
}
-static int orion5x_wdt_get_timeleft(int *time_left)
+static int orion_wdt_get_timeleft(int *time_left)
{
spin_lock(&wdt_lock);
*time_left = readl(WDT_VAL) / wdt_tclk;
@@ -107,16 +107,16 @@
return 0;
}
-static int orion5x_wdt_open(struct inode *inode, struct file *file)
+static int orion_wdt_open(struct inode *inode, struct file *file)
{
if (test_and_set_bit(WDT_IN_USE, &wdt_status))
return -EBUSY;
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
- orion5x_wdt_enable();
+ orion_wdt_enable();
return nonseekable_open(inode, file);
}
-static ssize_t orion5x_wdt_write(struct file *file, const char *data,
+static ssize_t orion_wdt_write(struct file *file, const char *data,
size_t len, loff_t *ppos)
{
if (len) {
@@ -133,18 +133,18 @@
set_bit(WDT_OK_TO_CLOSE, &wdt_status);
}
}
- orion5x_wdt_ping();
+ orion_wdt_ping();
}
return len;
}
-static int orion5x_wdt_settimeout(int new_time)
+static int orion_wdt_settimeout(int new_time)
{
if ((new_time <= 0) || (new_time > wdt_max_duration))
return -EINVAL;
/* Set new watchdog time to be used when
- * orion5x_wdt_enable() or orion5x_wdt_ping() is called. */
+ * orion_wdt_enable() or orion_wdt_ping() is called. */
heartbeat = new_time;
return 0;
}
@@ -152,10 +152,10 @@
static const struct watchdog_info ident = {
.options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING,
- .identity = "Orion5x Watchdog",
+ .identity = "Orion Watchdog",
};
-static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd,
+static long orion_wdt_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
int ret = -ENOTTY;
@@ -173,7 +173,7 @@
break;
case WDIOC_KEEPALIVE:
- orion5x_wdt_ping();
+ orion_wdt_ping();
ret = 0;
break;
@@ -182,11 +182,11 @@
if (ret)
break;
- if (orion5x_wdt_settimeout(time)) {
+ if (orion_wdt_settimeout(time)) {
ret = -EINVAL;
break;
}
- orion5x_wdt_ping();
+ orion_wdt_ping();
/* Fall through */
case WDIOC_GETTIMEOUT:
@@ -194,7 +194,7 @@
break;
case WDIOC_GETTIMELEFT:
- if (orion5x_wdt_get_timeleft(&time)) {
+ if (orion_wdt_get_timeleft(&time)) {
ret = -EINVAL;
break;
}
@@ -204,10 +204,10 @@
return ret;
}
-static int orion5x_wdt_release(struct inode *inode, struct file *file)
+static int orion_wdt_release(struct inode *inode, struct file *file)
{
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
- orion5x_wdt_disable();
+ orion_wdt_disable();
else
printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
"timer will not stop\n");
@@ -218,98 +218,98 @@
}
-static const struct file_operations orion5x_wdt_fops = {
+static const struct file_operations orion_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
- .write = orion5x_wdt_write,
- .unlocked_ioctl = orion5x_wdt_ioctl,
- .open = orion5x_wdt_open,
- .release = orion5x_wdt_release,
+ .write = orion_wdt_write,
+ .unlocked_ioctl = orion_wdt_ioctl,
+ .open = orion_wdt_open,
+ .release = orion_wdt_release,
};
-static struct miscdevice orion5x_wdt_miscdev = {
+static struct miscdevice orion_wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
- .fops = &orion5x_wdt_fops,
+ .fops = &orion_wdt_fops,
};
-static int __devinit orion5x_wdt_probe(struct platform_device *pdev)
+static int __devinit orion_wdt_probe(struct platform_device *pdev)
{
- struct orion5x_wdt_platform_data *pdata = pdev->dev.platform_data;
+ struct orion_wdt_platform_data *pdata = pdev->dev.platform_data;
int ret;
if (pdata) {
wdt_tclk = pdata->tclk;
} else {
- printk(KERN_ERR "Orion5x Watchdog misses platform data\n");
+ printk(KERN_ERR "Orion Watchdog misses platform data\n");
return -ENODEV;
}
- if (orion5x_wdt_miscdev.parent)
+ if (orion_wdt_miscdev.parent)
return -EBUSY;
- orion5x_wdt_miscdev.parent = &pdev->dev;
+ orion_wdt_miscdev.parent = &pdev->dev;
wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk;
- if (orion5x_wdt_settimeout(heartbeat))
+ if (orion_wdt_settimeout(heartbeat))
heartbeat = wdt_max_duration;
- ret = misc_register(&orion5x_wdt_miscdev);
+ ret = misc_register(&orion_wdt_miscdev);
if (ret)
return ret;
- printk(KERN_INFO "Orion5x Watchdog Timer: Initial timeout %d sec%s\n",
+ printk(KERN_INFO "Orion Watchdog Timer: Initial timeout %d sec%s\n",
heartbeat, nowayout ? ", nowayout" : "");
return 0;
}
-static int __devexit orion5x_wdt_remove(struct platform_device *pdev)
+static int __devexit orion_wdt_remove(struct platform_device *pdev)
{
int ret;
if (test_bit(WDT_IN_USE, &wdt_status)) {
- orion5x_wdt_disable();
+ orion_wdt_disable();
clear_bit(WDT_IN_USE, &wdt_status);
}
- ret = misc_deregister(&orion5x_wdt_miscdev);
+ ret = misc_deregister(&orion_wdt_miscdev);
if (!ret)
- orion5x_wdt_miscdev.parent = NULL;
+ orion_wdt_miscdev.parent = NULL;
return ret;
}
-static void orion5x_wdt_shutdown(struct platform_device *pdev)
+static void orion_wdt_shutdown(struct platform_device *pdev)
{
if (test_bit(WDT_IN_USE, &wdt_status))
- orion5x_wdt_disable();
+ orion_wdt_disable();
}
-static struct platform_driver orion5x_wdt_driver = {
- .probe = orion5x_wdt_probe,
- .remove = __devexit_p(orion5x_wdt_remove),
- .shutdown = orion5x_wdt_shutdown,
+static struct platform_driver orion_wdt_driver = {
+ .probe = orion_wdt_probe,
+ .remove = __devexit_p(orion_wdt_remove),
+ .shutdown = orion_wdt_shutdown,
.driver = {
.owner = THIS_MODULE,
- .name = "orion5x_wdt",
+ .name = "orion_wdt",
},
};
-static int __init orion5x_wdt_init(void)
+static int __init orion_wdt_init(void)
{
spin_lock_init(&wdt_lock);
- return platform_driver_register(&orion5x_wdt_driver);
+ return platform_driver_register(&orion_wdt_driver);
}
-static void __exit orion5x_wdt_exit(void)
+static void __exit orion_wdt_exit(void)
{
- platform_driver_unregister(&orion5x_wdt_driver);
+ platform_driver_unregister(&orion_wdt_driver);
}
-module_init(orion5x_wdt_init);
-module_exit(orion5x_wdt_exit);
+module_init(orion_wdt_init);
+module_exit(orion_wdt_exit);
MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
-MODULE_DESCRIPTION("Orion5x Processor Watchdog");
+MODULE_DESCRIPTION("Orion Processor Watchdog");
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
diff --git a/firmware/cis/.gitignore b/firmware/cis/.gitignore
new file mode 100644
index 0000000..1de3984
--- /dev/null
+++ b/firmware/cis/.gitignore
@@ -0,0 +1 @@
+*.cis
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 5cebf0b..697f6b5 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -41,6 +41,7 @@
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <asm/cacheflush.h>
+#include <asm/page.h>
/****************************************************************************/
@@ -54,6 +55,18 @@
#define DBG_FLT(a...)
#endif
+/*
+ * User data (stack, data section and bss) needs to be aligned
+ * for the same reasons as SLAB memory is, and to the same amount.
+ * Avoid duplicating architecture specific code by using the same
+ * macro as with SLAB allocation:
+ */
+#ifdef ARCH_SLAB_MINALIGN
+#define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN)
+#else
+#define FLAT_DATA_ALIGN (sizeof(void *))
+#endif
+
#define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */
#define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */
@@ -114,20 +127,18 @@
int envc = bprm->envc;
char uninitialized_var(dummy);
- sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p);
+ sp = (unsigned long *)p;
+ sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
+ sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN);
+ argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0);
+ envp = argv + (argc + 1);
- sp -= envc+1;
- envp = sp;
- sp -= argc+1;
- argv = sp;
-
- flat_stack_align(sp);
if (flat_argvp_envp_on_stack()) {
- --sp; put_user((unsigned long) envp, sp);
- --sp; put_user((unsigned long) argv, sp);
+ put_user((unsigned long) envp, sp + 2);
+ put_user((unsigned long) argv, sp + 1);
}
- put_user(argc,--sp);
+ put_user(argc, sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
put_user((unsigned long) p, argv++);
@@ -558,7 +569,9 @@
ret = realdatastart;
goto err;
}
- datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
+ datapos = ALIGN(realdatastart +
+ MAX_SHARED_LIBS * sizeof(unsigned long),
+ FLAT_DATA_ALIGN);
DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",
(int)(data_len + bss_len + stack_len), (int)datapos);
@@ -604,9 +617,12 @@
}
realdatastart = textpos + ntohl(hdr->data_start);
- datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
- reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
- MAX_SHARED_LIBS * sizeof(unsigned long));
+ datapos = ALIGN(realdatastart +
+ MAX_SHARED_LIBS * sizeof(unsigned long),
+ FLAT_DATA_ALIGN);
+
+ reloc = (unsigned long *)
+ (datapos + (ntohl(hdr->reloc_start) - text_len));
memp = textpos;
memp_size = len;
#ifdef CONFIG_BINFMT_ZFLAT
@@ -854,7 +870,7 @@
stack_len = TOP_OF_ARGS - bprm->p; /* the strings */
stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */
stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */
-
+ stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */
res = load_flat_file(bprm, &libinfo, 0, &stack_len);
if (res > (unsigned long)-4096)
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 19218e1..f7c255f 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -122,13 +122,13 @@
}
/*
- * cf-bind.c
+ * bind.c
*/
extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
/*
- * cf-daemon.c
+ * daemon.c
*/
extern const struct file_operations cachefiles_daemon_fops;
@@ -136,17 +136,17 @@
unsigned fnr, unsigned bnr);
/*
- * cf-interface.c
+ * interface.c
*/
extern const struct fscache_cache_ops cachefiles_cache_ops;
/*
- * cf-key.c
+ * key.c
*/
extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
/*
- * cf-namei.c
+ * namei.c
*/
extern int cachefiles_delete_object(struct cachefiles_cache *cache,
struct cachefiles_object *object);
@@ -165,7 +165,7 @@
struct dentry *dir, char *filename);
/*
- * cf-proc.c
+ * proc.c
*/
#ifdef CONFIG_CACHEFILES_HISTOGRAM
extern atomic_t cachefiles_lookup_histogram[HZ];
@@ -190,7 +190,7 @@
#endif
/*
- * cf-rdwr.c
+ * rdwr.c
*/
extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
struct page *, gfp_t);
@@ -205,7 +205,7 @@
extern void cachefiles_uncache_page(struct fscache_object *, struct page *);
/*
- * cf-security.c
+ * security.c
*/
extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
@@ -225,7 +225,7 @@
}
/*
- * cf-xattr.c
+ * xattr.c
*/
extern int cachefiles_check_object_type(struct cachefiles_object *object);
extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index e0cbd16..1c34130 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -28,7 +28,7 @@
#define FSCACHE_MAX_THREADS 32
/*
- * fsc-cache.c
+ * cache.c
*/
extern struct list_head fscache_cache_list;
extern struct rw_semaphore fscache_addremove_sem;
@@ -37,7 +37,7 @@
struct fscache_cookie *);
/*
- * fsc-cookie.c
+ * cookie.c
*/
extern struct kmem_cache *fscache_cookie_jar;
@@ -45,13 +45,13 @@
extern void __fscache_cookie_put(struct fscache_cookie *);
/*
- * fsc-fsdef.c
+ * fsdef.c
*/
extern struct fscache_cookie fscache_fsdef_index;
extern struct fscache_cookie_def fscache_fsdef_netfs_def;
/*
- * fsc-histogram.c
+ * histogram.c
*/
#ifdef CONFIG_FSCACHE_HISTOGRAM
extern atomic_t fscache_obj_instantiate_histogram[HZ];
@@ -75,7 +75,7 @@
#endif
/*
- * fsc-main.c
+ * main.c
*/
extern unsigned fscache_defer_lookup;
extern unsigned fscache_defer_create;
@@ -86,14 +86,14 @@
extern int fscache_wait_bit_interruptible(void *);
/*
- * fsc-object.c
+ * object.c
*/
extern void fscache_withdrawing_object(struct fscache_cache *,
struct fscache_object *);
extern void fscache_enqueue_object(struct fscache_object *);
/*
- * fsc-operation.c
+ * operation.c
*/
extern int fscache_submit_exclusive_op(struct fscache_object *,
struct fscache_operation *);
@@ -104,7 +104,7 @@
extern void fscache_operation_gc(struct work_struct *);
/*
- * fsc-proc.c
+ * proc.c
*/
#ifdef CONFIG_PROC_FS
extern int __init fscache_proc_init(void);
@@ -115,7 +115,7 @@
#endif
/*
- * fsc-stats.c
+ * stats.c
*/
#ifdef CONFIG_FSCACHE_STATS
extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS];
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index c32b4a1..a024474 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -480,13 +480,6 @@
return;
filebad:
- mutex_lock(&c->erase_free_sem);
- spin_lock(&c->erase_completion_lock);
- /* Stick it on a list (any list) so erase_failed can take it
- right off again. Silly, but shouldn't happen often. */
- list_move(&jeb->list, &c->erasing_list);
- spin_unlock(&c->erase_completion_lock);
- mutex_unlock(&c->erase_free_sem);
jffs2_erase_failed(c, jeb, bad_offset);
return;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a4d2426..4674f80 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2594,12 +2594,9 @@
unsigned long timestamp = (unsigned long)data;
if (task->tk_status < 0) {
- switch (task->tk_status) {
- case -NFS4ERR_STALE_CLIENTID:
- case -NFS4ERR_EXPIRED:
- case -NFS4ERR_CB_PATH_DOWN:
- nfs4_schedule_state_recovery(clp);
- }
+ /* Unless we're shutting down, schedule state recovery! */
+ if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0)
+ nfs4_schedule_state_recovery(clp);
return;
}
spin_lock(&clp->cl_lock);
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index d9ef602..e3ed590 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -129,7 +129,7 @@
Opt_err
};
-static match_table_t __initconst tokens = {
+static const match_table_t tokens __initconst = {
{Opt_port, "port=%u"},
{Opt_rsize, "rsize=%u"},
{Opt_wsize, "wsize=%u"},
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 6c68ffd..b660435 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1015,6 +1015,7 @@
host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
set_fs(oldfs);
if (host_err >= 0) {
+ *cnt = host_err;
nfsdstats.io_write += host_err;
fsnotify_modify(file->f_path.dentry);
}
@@ -1060,10 +1061,9 @@
}
dprintk("nfsd: write complete host_err=%d\n", host_err);
- if (host_err >= 0) {
+ if (host_err >= 0)
err = 0;
- *cnt = host_err;
- } else
+ else
err = nfserrno(host_err);
out:
return err;
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index e90b60d..300f1cd 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -311,7 +311,7 @@
ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
if (ret < 0) {
if (ret != -ENOENT)
- goto out_sem;
+ goto out_header;
/* skip hole */
ret = 0;
continue;
@@ -344,7 +344,7 @@
continue;
printk(KERN_ERR "%s: cannot delete block\n",
__func__);
- goto out_sem;
+ goto out_header;
}
}
@@ -361,6 +361,8 @@
nilfs_mdt_mark_dirty(cpfile);
kunmap_atomic(kaddr, KM_USER0);
}
+
+ out_header:
brelse(header_bh);
out_sem:
diff --git a/fs/proc/base.c b/fs/proc/base.c
index fb45615..3326bbf 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1956,7 +1956,7 @@
const struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
- struct dentry *error = ERR_PTR(-EINVAL);
+ struct dentry *error = ERR_PTR(-ENOENT);
inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index b1606e0..561a9c0 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -723,7 +723,7 @@
mutex_unlock(&sysfs_workq_mutex);
if (sysfs_workqueue == NULL) {
- sysfs_workqueue = create_workqueue("sysfsd");
+ sysfs_workqueue = create_singlethread_workqueue("sysfsd");
if (sysfs_workqueue == NULL) {
module_put(owner);
return -ENOMEM;
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index af6843c..179cbd6 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -103,7 +103,7 @@
static inline int
kmem_shake_allow(gfp_t gfp_mask)
{
- return (gfp_mask & __GFP_WAIT) != 0;
+ return ((gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS));
}
#endif /* __XFS_SUPPORT_KMEM_H__ */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index e6d839b..7465f9e 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -347,13 +347,15 @@
error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
-out_unlock:
- xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
out:
kmem_free(tempifp);
return error;
+out_unlock:
+ xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ goto out;
+
out_trans_cancel:
xfs_trans_cancel(tp, 0);
goto out_unlock;
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 8379e3b..cbd451b 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -160,7 +160,7 @@
nagcount = new + (nb_mod != 0);
if (nb_mod && nb_mod < XFS_MIN_AG_BLOCKS) {
nagcount--;
- nb = nagcount * mp->m_sb.sb_agblocks;
+ nb = (xfs_rfsblock_t)nagcount * mp->m_sb.sb_agblocks;
if (nb < mp->m_sb.sb_dblocks)
return XFS_ERROR(EINVAL);
}
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index c8c4221..b84d8ae 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1519,6 +1519,30 @@
{
return kcalloc(nmemb, size, GFP_KERNEL);
}
+
+static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
+{
+ u8 *addr;
+
+ if (size <= PAGE_SIZE)
+ return kcalloc(nmemb, size, GFP_KERNEL);
+
+ addr = vmalloc(nmemb * size);
+ if (!addr)
+ return NULL;
+
+ memset(addr, 0, nmemb * size);
+
+ return addr;
+}
+
+static __inline void drm_free_large(void *ptr)
+{
+ if (!is_vmalloc_addr(ptr))
+ return kfree(ptr);
+
+ vfree(ptr);
+}
#else
extern void *drm_alloc(size_t size, int area);
extern void drm_free(void *pt, size_t size, int area);
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h
index 48ee32a..42949e2 100644
--- a/include/linux/amba/serial.h
+++ b/include/linux/amba/serial.h
@@ -114,6 +114,9 @@
#define UART011_IFLS_TX4_8 (2 << 0)
#define UART011_IFLS_TX6_8 (3 << 0)
#define UART011_IFLS_TX7_8 (4 << 0)
+/* special values for ST vendor with deeper fifo */
+#define UART011_IFLS_RX_HALF (5 << 3)
+#define UART011_IFLS_TX_HALF (5 << 0)
#define UART011_OEIM (1 << 10) /* overrun error interrupt mask */
#define UART011_BEIM (1 << 9) /* break error interrupt mask */
diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h
index 6326585..7b09c83 100644
--- a/include/linux/auto_fs.h
+++ b/include/linux/auto_fs.h
@@ -14,13 +14,12 @@
#ifndef _LINUX_AUTO_FS_H
#define _LINUX_AUTO_FS_H
+#include <linux/types.h>
#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/limits.h>
-#include <linux/types.h>
#include <linux/ioctl.h>
#else
-#include <asm/types.h>
#include <sys/ioctl.h>
#endif /* __KERNEL__ */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1db9bbf..1d37f42 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -142,4 +142,17 @@
*/
struct clk *clk_get_sys(const char *dev_id, const char *con_id);
+/**
+ * clk_add_alias - add a new clock alias
+ * @alias: name for clock alias
+ * @alias_dev_name: device name
+ * @id: platform specific clock name
+ * @dev: device
+ *
+ * Allows using generic clock names for drivers by adding a new alias.
+ * Assumes clkdev, see clkdev.h for more info.
+ */
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
+ struct device *dev);
+
#endif
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 3282ee4..4fa9996 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -13,6 +13,7 @@
#define _LINUX_CRED_H
#include <linux/capability.h>
+#include <linux/init.h>
#include <linux/key.h>
#include <asm/atomic.h>
diff --git a/include/linux/i7300_idle.h b/include/linux/i7300_idle.h
index 05a80c4..1587b7d 100644
--- a/include/linux/i7300_idle.h
+++ b/include/linux/i7300_idle.h
@@ -16,35 +16,33 @@
struct fbd_ioat {
unsigned int vendor;
unsigned int ioat_dev;
+ unsigned int enabled;
};
/*
* The i5000 chip-set has the same hooks as the i7300
- * but support is disabled by default because this driver
- * has not been validated on that platform.
+ * but it is not enabled by default and must be manually
+ * manually enabled with "forceload=1" because it is
+ * only lightly validated.
*/
-#define SUPPORT_I5000 0
static const struct fbd_ioat fbd_ioat_list[] = {
- {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
-#if SUPPORT_I5000
- {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
-#endif
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB, 1},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT, 0},
{0, 0}
};
/* table of devices that work with this driver */
static const struct pci_device_id pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
-#if SUPPORT_I5000
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
-#endif
{ } /* Terminating entry */
};
/* Check for known platforms with I/O-AT */
static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev,
- struct pci_dev **ioat_dev)
+ struct pci_dev **ioat_dev,
+ int enable_all)
{
int i;
struct pci_dev *memdev, *dmadev;
@@ -69,6 +67,8 @@
for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
if (dmadev->vendor == fbd_ioat_list[i].vendor &&
dmadev->device == fbd_ioat_list[i].ioat_dev) {
+ if (!(fbd_ioat_list[i].enabled || enable_all))
+ continue;
if (fbd_dev)
*fbd_dev = memdev;
if (ioat_dev)
diff --git a/include/linux/input.h b/include/linux/input.h
index 0e6ff5d..6fed4f6 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -656,6 +656,7 @@
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
#define ABS_MAX 0x3f
#define ABS_CNT (ABS_MAX+1)
diff --git a/include/linux/net_dropmon.h b/include/linux/net_dropmon.h
index 0217fb8..0e2e100 100644
--- a/include/linux/net_dropmon.h
+++ b/include/linux/net_dropmon.h
@@ -1,6 +1,7 @@
#ifndef __NET_DROPMON_H
#define __NET_DROPMON_H
+#include <linux/types.h>
#include <linux/netlink.h>
struct net_dm_drop_point {
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
index 3066789..b2f384d 100644
--- a/include/linux/netfilter/nf_conntrack_tcp.h
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -35,6 +35,9 @@
/* Has unacknowledged data */
#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10
+/* The field td_maxack has been set */
+#define IP_CT_TCP_FLAG_MAXACK_SET 0x20
+
struct nf_ct_tcp_flags {
__u8 flags;
__u8 mask;
@@ -46,6 +49,7 @@
u_int32_t td_end; /* max of seq + len */
u_int32_t td_maxend; /* max of ack + max(win, 1) */
u_int32_t td_maxwin; /* max(win) */
+ u_int32_t td_maxack; /* max of ack */
u_int8_t td_scale; /* window scale factor */
u_int8_t flags; /* per direction options */
};
diff --git a/include/linux/parport.h b/include/linux/parport.h
index e1f83c5..38a423e 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -324,6 +324,10 @@
int spintime;
atomic_t ref_count;
+ unsigned long devflags;
+#define PARPORT_DEVPROC_REGISTERED 0
+ struct pardevice *proc_device; /* Currently register proc device */
+
struct list_head full_list;
struct parport *slaves[3];
};
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 62d8143..d476aad 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -437,6 +437,11 @@
return 0;
}
+static inline void
+mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
+{
+}
+
#endif /* CONFIG_SWAP */
#endif /* __KERNEL__*/
#endif /* _LINUX_SWAP_H */
diff --git a/init/main.c b/init/main.c
index 3bbf93b..d721dad 100644
--- a/init/main.c
+++ b/init/main.c
@@ -566,8 +566,7 @@
tick_init();
boot_cpu_init();
page_address_init();
- printk(KERN_NOTICE);
- printk(linux_banner);
+ printk(KERN_NOTICE "%s", linux_banner);
setup_arch(&command_line);
mm_init_owner(&init_mm, &init_task);
setup_command_line(command_line);
diff --git a/kernel/async.c b/kernel/async.c
index 968ef94..5054030 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -92,19 +92,23 @@
static async_cookie_t __lowest_in_progress(struct list_head *running)
{
struct async_entry *entry;
+ async_cookie_t ret = next_cookie; /* begin with "infinity" value */
+
if (!list_empty(running)) {
entry = list_first_entry(running,
struct async_entry, list);
- return entry->cookie;
- } else if (!list_empty(&async_pending)) {
- entry = list_first_entry(&async_pending,
- struct async_entry, list);
- return entry->cookie;
- } else {
- /* nothing in progress... next_cookie is "infinity" */
- return next_cookie;
+ ret = entry->cookie;
}
+ if (!list_empty(&async_pending)) {
+ list_for_each_entry(entry, &async_pending, list)
+ if (entry->running == running) {
+ ret = entry->cookie;
+ break;
+ }
+ }
+
+ return ret;
}
static async_cookie_t lowest_in_progress(struct list_head *running)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 5a758c6..e498377 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1451,7 +1451,6 @@
error = device_suspend(PMSG_FREEZE);
if (error)
goto Resume_console;
- device_pm_lock();
/* At this point, device_suspend() has been called,
* but *not* device_power_down(). We *must*
* device_power_down() now. Otherwise, drivers for
@@ -1489,7 +1488,6 @@
enable_nonboot_cpus();
device_power_up(PMSG_RESTORE);
Resume_devices:
- device_pm_unlock();
device_resume(PMSG_RESTORE);
Resume_console:
resume_console();
diff --git a/kernel/kmod.c b/kernel/kmod.c
index b750675..7e95bed 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -370,8 +370,10 @@
sub_info->argv = argv;
sub_info->envp = envp;
sub_info->cred = prepare_usermodehelper_creds();
- if (!sub_info->cred)
+ if (!sub_info->cred) {
+ kfree(sub_info);
return NULL;
+ }
out:
return sub_info;
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index b0dc9e7..5cb080e 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -215,8 +215,6 @@
if (error)
return error;
- device_pm_lock();
-
/* At this point, device_suspend() has been called, but *not*
* device_power_down(). We *must* call device_power_down() now.
* Otherwise, drivers for some devices (e.g. interrupt controllers)
@@ -227,7 +225,7 @@
if (error) {
printk(KERN_ERR "PM: Some devices failed to power down, "
"aborting hibernation\n");
- goto Unlock;
+ return error;
}
error = platform_pre_snapshot(platform_mode);
@@ -280,9 +278,6 @@
device_power_up(in_suspend ?
(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
- Unlock:
- device_pm_unlock();
-
return error;
}
@@ -344,13 +339,11 @@
{
int error;
- device_pm_lock();
-
error = device_power_down(PMSG_QUIESCE);
if (error) {
printk(KERN_ERR "PM: Some devices failed to power down, "
"aborting resume\n");
- goto Unlock;
+ return error;
}
error = platform_pre_restore(platform_mode);
@@ -403,9 +396,6 @@
device_power_up(PMSG_RECOVER);
- Unlock:
- device_pm_unlock();
-
return error;
}
@@ -464,11 +454,9 @@
goto Resume_devices;
}
- device_pm_lock();
-
error = device_power_down(PMSG_HIBERNATE);
if (error)
- goto Unlock;
+ goto Resume_devices;
error = hibernation_ops->prepare();
if (error)
@@ -493,9 +481,6 @@
device_power_up(PMSG_RESTORE);
- Unlock:
- device_pm_unlock();
-
Resume_devices:
entering_platform_hibernation = false;
device_resume(PMSG_RESTORE);
diff --git a/kernel/power/main.c b/kernel/power/main.c
index f99ed6a..8680282 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -289,12 +289,10 @@
{
int error;
- device_pm_lock();
-
if (suspend_ops->prepare) {
error = suspend_ops->prepare();
if (error)
- goto Done;
+ return error;
}
error = device_power_down(PMSG_SUSPEND);
@@ -343,9 +341,6 @@
if (suspend_ops->finish)
suspend_ops->finish();
- Done:
- device_pm_unlock();
-
return error;
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 379ff0b..1b60f30 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -121,7 +121,6 @@
mapping->nrpages--;
__dec_zone_page_state(page, NR_FILE_PAGES);
BUG_ON(page_mapped(page));
- mem_cgroup_uncharge_cache_page(page);
/*
* Some filesystems seem to re-dirty the page even after
@@ -145,6 +144,7 @@
spin_lock_irq(&mapping->tree_lock);
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
+ mem_cgroup_uncharge_cache_page(page);
}
static int sync_page(void *word)
@@ -476,13 +476,13 @@
if (likely(!error)) {
mapping->nrpages++;
__inc_zone_page_state(page, NR_FILE_PAGES);
+ spin_unlock_irq(&mapping->tree_lock);
} else {
page->mapping = NULL;
+ spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);
page_cache_release(page);
}
-
- spin_unlock_irq(&mapping->tree_lock);
radix_tree_preload_end();
} else
mem_cgroup_uncharge_cache_page(page);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 28c655b..e83ad2c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -316,7 +316,7 @@
static struct resv_map *vma_resv_map(struct vm_area_struct *vma)
{
VM_BUG_ON(!is_vm_hugetlb_page(vma));
- if (!(vma->vm_flags & VM_SHARED))
+ if (!(vma->vm_flags & VM_MAYSHARE))
return (struct resv_map *)(get_vma_private_data(vma) &
~HPAGE_RESV_MASK);
return NULL;
@@ -325,7 +325,7 @@
static void set_vma_resv_map(struct vm_area_struct *vma, struct resv_map *map)
{
VM_BUG_ON(!is_vm_hugetlb_page(vma));
- VM_BUG_ON(vma->vm_flags & VM_SHARED);
+ VM_BUG_ON(vma->vm_flags & VM_MAYSHARE);
set_vma_private_data(vma, (get_vma_private_data(vma) &
HPAGE_RESV_MASK) | (unsigned long)map);
@@ -334,7 +334,7 @@
static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags)
{
VM_BUG_ON(!is_vm_hugetlb_page(vma));
- VM_BUG_ON(vma->vm_flags & VM_SHARED);
+ VM_BUG_ON(vma->vm_flags & VM_MAYSHARE);
set_vma_private_data(vma, get_vma_private_data(vma) | flags);
}
@@ -353,7 +353,7 @@
if (vma->vm_flags & VM_NORESERVE)
return;
- if (vma->vm_flags & VM_SHARED) {
+ if (vma->vm_flags & VM_MAYSHARE) {
/* Shared mappings always use reserves */
h->resv_huge_pages--;
} else if (is_vma_resv_set(vma, HPAGE_RESV_OWNER)) {
@@ -369,14 +369,14 @@
void reset_vma_resv_huge_pages(struct vm_area_struct *vma)
{
VM_BUG_ON(!is_vm_hugetlb_page(vma));
- if (!(vma->vm_flags & VM_SHARED))
+ if (!(vma->vm_flags & VM_MAYSHARE))
vma->vm_private_data = (void *)0;
}
/* Returns true if the VMA has associated reserve pages */
static int vma_has_reserves(struct vm_area_struct *vma)
{
- if (vma->vm_flags & VM_SHARED)
+ if (vma->vm_flags & VM_MAYSHARE)
return 1;
if (is_vma_resv_set(vma, HPAGE_RESV_OWNER))
return 1;
@@ -924,7 +924,7 @@
struct address_space *mapping = vma->vm_file->f_mapping;
struct inode *inode = mapping->host;
- if (vma->vm_flags & VM_SHARED) {
+ if (vma->vm_flags & VM_MAYSHARE) {
pgoff_t idx = vma_hugecache_offset(h, vma, addr);
return region_chg(&inode->i_mapping->private_list,
idx, idx + 1);
@@ -949,7 +949,7 @@
struct address_space *mapping = vma->vm_file->f_mapping;
struct inode *inode = mapping->host;
- if (vma->vm_flags & VM_SHARED) {
+ if (vma->vm_flags & VM_MAYSHARE) {
pgoff_t idx = vma_hugecache_offset(h, vma, addr);
region_add(&inode->i_mapping->private_list, idx, idx + 1);
@@ -1893,7 +1893,7 @@
* at the time of fork() could consume its reserves on COW instead
* of the full address range.
*/
- if (!(vma->vm_flags & VM_SHARED) &&
+ if (!(vma->vm_flags & VM_MAYSHARE) &&
is_vma_resv_set(vma, HPAGE_RESV_OWNER) &&
old_page != pagecache_page)
outside_reserve = 1;
@@ -2000,7 +2000,7 @@
clear_huge_page(page, address, huge_page_size(h));
__SetPageUptodate(page);
- if (vma->vm_flags & VM_SHARED) {
+ if (vma->vm_flags & VM_MAYSHARE) {
int err;
struct inode *inode = mapping->host;
@@ -2104,7 +2104,7 @@
goto out_mutex;
}
- if (!(vma->vm_flags & VM_SHARED))
+ if (!(vma->vm_flags & VM_MAYSHARE))
pagecache_page = hugetlbfs_pagecache_page(h,
vma, address);
}
@@ -2289,7 +2289,7 @@
* to reserve the full area even if read-only as mprotect() may be
* called to make the mapping read-write. Assume !vma is a shm mapping
*/
- if (!vma || vma->vm_flags & VM_SHARED)
+ if (!vma || vma->vm_flags & VM_MAYSHARE)
chg = region_chg(&inode->i_mapping->private_list, from, to);
else {
struct resv_map *resv_map = resv_map_alloc();
@@ -2330,7 +2330,7 @@
* consumed reservations are stored in the map. Hence, nothing
* else has to be done for private mappings here
*/
- if (!vma || vma->vm_flags & VM_SHARED)
+ if (!vma || vma->vm_flags & VM_MAYSHARE)
region_add(&inode->i_mapping->private_list, from, to);
return 0;
}
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 01c2d8f..78eb855 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -314,14 +314,6 @@
return mem;
}
-static bool mem_cgroup_is_obsolete(struct mem_cgroup *mem)
-{
- if (!mem)
- return true;
- return css_is_removed(&mem->css);
-}
-
-
/*
* Call callback function against all cgroup under hierarchy tree.
*/
@@ -932,7 +924,7 @@
if (unlikely(!mem))
return 0;
- VM_BUG_ON(!mem || mem_cgroup_is_obsolete(mem));
+ VM_BUG_ON(css_is_removed(&mem->css));
while (1) {
int ret;
@@ -1488,8 +1480,9 @@
__mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE);
}
+#ifdef CONFIG_SWAP
/*
- * called from __delete_from_swap_cache() and drop "page" account.
+ * called after __delete_from_swap_cache() and drop "page" account.
* memcg information is recorded to swap_cgroup of "ent"
*/
void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
@@ -1506,6 +1499,7 @@
if (memcg)
css_put(&memcg->css);
}
+#endif
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
/*
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 92bcf1d..a7b2460 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -284,22 +284,28 @@
printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj "
"name\n");
do_each_thread(g, p) {
- /*
- * total_vm and rss sizes do not exist for tasks with a
- * detached mm so there's no need to report them.
- */
- if (!p->mm)
- continue;
+ struct mm_struct *mm;
+
if (mem && !task_in_mem_cgroup(p, mem))
continue;
if (!thread_group_leader(p))
continue;
task_lock(p);
+ mm = p->mm;
+ if (!mm) {
+ /*
+ * total_vm and rss sizes do not exist for tasks with no
+ * mm so there's no need to report them; they can't be
+ * oom killed anyway.
+ */
+ task_unlock(p);
+ continue;
+ }
printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n",
- p->pid, __task_cred(p)->uid, p->tgid,
- p->mm->total_vm, get_mm_rss(p->mm), (int)task_cpu(p),
- p->oomkilladj, p->comm);
+ p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm,
+ get_mm_rss(mm), (int)task_cpu(p), p->oomkilladj,
+ p->comm);
task_unlock(p);
} while_each_thread(g, p);
}
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 3ecea98..1416e7e 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -109,8 +109,6 @@
*/
void __delete_from_swap_cache(struct page *page)
{
- swp_entry_t ent = {.val = page_private(page)};
-
VM_BUG_ON(!PageLocked(page));
VM_BUG_ON(!PageSwapCache(page));
VM_BUG_ON(PageWriteback(page));
@@ -121,7 +119,6 @@
total_swapcache_pages--;
__dec_zone_page_state(page, NR_FILE_PAGES);
INC_CACHE_INFO(del_total);
- mem_cgroup_uncharge_swapcache(page, ent);
}
/**
@@ -191,6 +188,7 @@
__delete_from_swap_cache(page);
spin_unlock_irq(&swapper_space.tree_lock);
+ mem_cgroup_uncharge_swapcache(page, entry);
swap_free(entry);
page_cache_release(page);
}
diff --git a/mm/truncate.c b/mm/truncate.c
index 55206fa..12e1579 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -359,6 +359,7 @@
BUG_ON(page_has_private(page));
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
+ mem_cgroup_uncharge_cache_page(page);
page_cache_release(page); /* pagecache ref */
return 1;
failed:
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5fa3eda..d254306 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -470,10 +470,12 @@
swp_entry_t swap = { .val = page_private(page) };
__delete_from_swap_cache(page);
spin_unlock_irq(&mapping->tree_lock);
+ mem_cgroup_uncharge_swapcache(page, swap);
swap_free(swap);
} else {
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
+ mem_cgroup_uncharge_cache_page(page);
}
return 1;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 4cc3624..95f7a7a 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -90,9 +90,6 @@
struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
struct hci_dev *hdev = conn->hdev;
- /* ensure previous del is complete */
- flush_work(&conn->work_del);
-
dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
if (device_add(&conn->dev) < 0) {
@@ -118,9 +115,6 @@
struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
struct hci_dev *hdev = conn->hdev;
- /* ensure previous add is complete */
- flush_work(&conn->work_add);
-
if (!device_is_registered(&conn->dev))
return;
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 3779c14..0666a82 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2447,7 +2447,7 @@
if (pkt_dev->cflows) {
/* let go of the SAs if we have them */
int i = 0;
- for (; i < pkt_dev->nflows; i++){
+ for (; i < pkt_dev->cflows; i++) {
struct xfrm_state *x = pkt_dev->flows[i].x;
if (x) {
xfrm_state_put(x);
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index ec0ae49..33c7c85 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -986,9 +986,12 @@
static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
{
int wasfull;
- t_key cindex, key = tn->key;
+ t_key cindex, key;
struct tnode *tp;
+ preempt_disable();
+ key = tn->key;
+
while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) {
cindex = tkey_extract_bits(key, tp->pos, tp->bits);
wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
@@ -1007,6 +1010,7 @@
if (IS_TNODE(tn))
tn = (struct tnode *)resize(t, (struct tnode *)tn);
+ preempt_enable();
return (struct node *)tn;
}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index c4c60e9..28205e5 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -784,8 +784,8 @@
{
static unsigned int rover;
unsigned int i = rover, goal;
- struct rtable *rth, **rthp;
- unsigned long length = 0, samples = 0;
+ struct rtable *rth, *aux, **rthp;
+ unsigned long samples = 0;
unsigned long sum = 0, sum2 = 0;
u64 mult;
@@ -795,9 +795,9 @@
goal = (unsigned int)mult;
if (goal > rt_hash_mask)
goal = rt_hash_mask + 1;
- length = 0;
for (; goal > 0; goal--) {
unsigned long tmo = ip_rt_gc_timeout;
+ unsigned long length;
i = (i + 1) & rt_hash_mask;
rthp = &rt_hash_table[i].chain;
@@ -809,8 +809,10 @@
if (*rthp == NULL)
continue;
+ length = 0;
spin_lock_bh(rt_hash_lock_addr(i));
while ((rth = *rthp) != NULL) {
+ prefetch(rth->u.dst.rt_next);
if (rt_is_expired(rth)) {
*rthp = rth->u.dst.rt_next;
rt_free(rth);
@@ -819,33 +821,30 @@
if (rth->u.dst.expires) {
/* Entry is expired even if it is in use */
if (time_before_eq(jiffies, rth->u.dst.expires)) {
+nofree:
tmo >>= 1;
rthp = &rth->u.dst.rt_next;
/*
- * Only bump our length if the hash
- * inputs on entries n and n+1 are not
- * the same, we only count entries on
+ * We only count entries on
* a chain with equal hash inputs once
* so that entries for different QOS
* levels, and other non-hash input
* attributes don't unfairly skew
* the length computation
*/
- if ((*rthp == NULL) ||
- !compare_hash_inputs(&(*rthp)->fl,
- &rth->fl))
- length += ONE;
+ for (aux = rt_hash_table[i].chain;;) {
+ if (aux == rth) {
+ length += ONE;
+ break;
+ }
+ if (compare_hash_inputs(&aux->fl, &rth->fl))
+ break;
+ aux = aux->u.dst.rt_next;
+ }
continue;
}
- } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) {
- tmo >>= 1;
- rthp = &rth->u.dst.rt_next;
- if ((*rthp == NULL) ||
- !compare_hash_inputs(&(*rthp)->fl,
- &rth->fl))
- length += ONE;
- continue;
- }
+ } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
+ goto nofree;
/* Cleanup aged off entries. */
*rthp = rth->u.dst.rt_next;
@@ -1068,7 +1067,6 @@
static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
{
struct rtable *rth, **rthp;
- struct rtable *rthi;
unsigned long now;
struct rtable *cand, **candp;
u32 min_score;
@@ -1088,7 +1086,6 @@
}
rthp = &rt_hash_table[hash].chain;
- rthi = NULL;
spin_lock_bh(rt_hash_lock_addr(hash));
while ((rth = *rthp) != NULL) {
@@ -1134,17 +1131,6 @@
chain_length++;
rthp = &rth->u.dst.rt_next;
-
- /*
- * check to see if the next entry in the chain
- * contains the same hash input values as rt. If it does
- * This is where we will insert into the list, instead of
- * at the head. This groups entries that differ by aspects not
- * relvant to the hash function together, which we use to adjust
- * our chain length
- */
- if (*rthp && compare_hash_inputs(&(*rthp)->fl, &rt->fl))
- rthi = rth;
}
if (cand) {
@@ -1205,10 +1191,7 @@
}
}
- if (rthi)
- rt->u.dst.rt_next = rthi->u.dst.rt_next;
- else
- rt->u.dst.rt_next = rt_hash_table[hash].chain;
+ rt->u.dst.rt_next = rt_hash_table[hash].chain;
#if RT_CACHE_DEBUG >= 2
if (rt->u.dst.rt_next) {
@@ -1224,10 +1207,7 @@
* previous writes to rt are comitted to memory
* before making rt visible to other CPUS.
*/
- if (rthi)
- rcu_assign_pointer(rthi->u.dst.rt_next, rt);
- else
- rcu_assign_pointer(rt_hash_table[hash].chain, rt);
+ rcu_assign_pointer(rt_hash_table[hash].chain, rt);
spin_unlock_bh(rt_hash_lock_addr(hash));
*rp = rt;
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index a453aac..c6743ee 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -158,6 +158,11 @@
}
EXPORT_SYMBOL_GPL(tcp_vegas_cwnd_event);
+static inline u32 tcp_vegas_ssthresh(struct tcp_sock *tp)
+{
+ return min(tp->snd_ssthresh, tp->snd_cwnd-1);
+}
+
static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
{
struct tcp_sock *tp = tcp_sk(sk);
@@ -221,11 +226,10 @@
*/
diff = tp->snd_cwnd * (rtt-vegas->baseRTT) / vegas->baseRTT;
- if (diff > gamma && tp->snd_ssthresh > 2 ) {
+ if (diff > gamma && tp->snd_cwnd <= tp->snd_ssthresh) {
/* Going too fast. Time to slow down
* and switch to congestion avoidance.
*/
- tp->snd_ssthresh = 2;
/* Set cwnd to match the actual rate
* exactly:
@@ -235,6 +239,7 @@
* utilization.
*/
tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1);
+ tp->snd_ssthresh = tcp_vegas_ssthresh(tp);
} else if (tp->snd_cwnd <= tp->snd_ssthresh) {
/* Slow start. */
@@ -250,6 +255,8 @@
* we slow down.
*/
tp->snd_cwnd--;
+ tp->snd_ssthresh
+ = tcp_vegas_ssthresh(tp);
} else if (diff < alpha) {
/* We don't have enough extra packets
* in the network, so speed up.
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1394ddb..032a5ec 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -137,6 +137,7 @@
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
+ .rt6i_protocol = RTPROT_KERNEL,
.rt6i_metric = ~(u32) 0,
.rt6i_ref = ATOMIC_INIT(1),
};
@@ -159,6 +160,7 @@
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
+ .rt6i_protocol = RTPROT_KERNEL,
.rt6i_metric = ~(u32) 0,
.rt6i_ref = ATOMIC_INIT(1),
};
@@ -176,6 +178,7 @@
}
},
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
+ .rt6i_protocol = RTPROT_KERNEL,
.rt6i_metric = ~(u32) 0,
.rt6i_ref = ATOMIC_INIT(1),
};
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 8e757dd..aee0d6b 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -22,6 +22,7 @@
#include <linux/netfilter/nfnetlink_conntrack.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_log.h>
static DEFINE_RWLOCK(dccp_lock);
@@ -553,6 +554,9 @@
ct->proto.dccp.state = new_state;
write_unlock_bh(&dccp_lock);
+ if (new_state != old_state)
+ nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
+
dn = dccp_pernet(net);
nf_ct_refresh_acct(ct, ctinfo, skb, dn->dccp_timeout[new_state]);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index b5ccf2b..97a6e93 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -634,6 +634,14 @@
sender->td_end = end;
sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
}
+ if (tcph->ack) {
+ if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) {
+ sender->td_maxack = ack;
+ sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET;
+ } else if (after(ack, sender->td_maxack))
+ sender->td_maxack = ack;
+ }
+
/*
* Update receiver data.
*/
@@ -919,6 +927,16 @@
return -NF_ACCEPT;
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
+ && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
+ && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
+ /* Invalid RST */
+ write_unlock_bh(&tcp_lock);
+ if (LOG_INVALID(net, IPPROTO_TCP))
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ "nf_ct_tcp: invalid RST ");
+ return -NF_ACCEPT;
+ }
+ if (index == TCP_RST_SET
&& ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
&& ct->proto.tcp.last_index == TCP_SYN_SET)
|| (!test_bit(IPS_ASSURED_BIT, &ct->status)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index fd326ac..66a6dd5 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -581,6 +581,12 @@
+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
+ nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
+ if (in && skb_mac_header_was_set(skb)) {
+ size += nla_total_size(skb->dev->hard_header_len)
+ + nla_total_size(sizeof(u_int16_t)) /* hwtype */
+ + nla_total_size(sizeof(u_int16_t)); /* hwlen */
+ }
+
spin_lock_bh(&inst->lock);
if (inst->flags & NFULNL_CFG_F_SEQ)
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index a5b5369..219dcdb 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -926,7 +926,7 @@
if (!hlist_empty(&htable->hash[*bucket])) {
hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node)
if (dl_seq_real_show(ent, htable->family, s))
- return 1;
+ return -1;
}
return 0;
}
diff --git a/net/rxrpc/ar-connection.c b/net/rxrpc/ar-connection.c
index 0f1218b..67e38a0 100644
--- a/net/rxrpc/ar-connection.c
+++ b/net/rxrpc/ar-connection.c
@@ -343,9 +343,9 @@
/* not yet present - create a candidate for a new connection
* and then redo the check */
conn = rxrpc_alloc_connection(gfp);
- if (IS_ERR(conn)) {
- _leave(" = %ld", PTR_ERR(conn));
- return PTR_ERR(conn);
+ if (!conn) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
}
conn->trans = trans;
@@ -508,9 +508,9 @@
/* not yet present - create a candidate for a new connection and then
* redo the check */
candidate = rxrpc_alloc_connection(gfp);
- if (IS_ERR(candidate)) {
- _leave(" = %ld", PTR_ERR(candidate));
- return PTR_ERR(candidate);
+ if (!candidate) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
}
candidate->trans = trans;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 0759f32..09cdcdf 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -135,6 +135,7 @@
unsigned long cl;
unsigned long fh;
int err;
+ int tp_created = 0;
if (net != &init_net)
return -EINVAL;
@@ -266,10 +267,7 @@
goto errout;
}
- spin_lock_bh(root_lock);
- tp->next = *back;
- *back = tp;
- spin_unlock_bh(root_lock);
+ tp_created = 1;
} else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
goto errout;
@@ -296,8 +294,11 @@
switch (n->nlmsg_type) {
case RTM_NEWTFILTER:
err = -EEXIST;
- if (n->nlmsg_flags & NLM_F_EXCL)
+ if (n->nlmsg_flags & NLM_F_EXCL) {
+ if (tp_created)
+ tcf_destroy(tp);
goto errout;
+ }
break;
case RTM_DELTFILTER:
err = tp->ops->delete(tp, fh);
@@ -314,8 +315,18 @@
}
err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh);
- if (err == 0)
+ if (err == 0) {
+ if (tp_created) {
+ spin_lock_bh(root_lock);
+ tp->next = *back;
+ *back = tp;
+ spin_unlock_bh(root_lock);
+ }
tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER);
+ } else {
+ if (tp_created)
+ tcf_destroy(tp);
+ }
errout:
if (cl)
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 91a3db4..cc29b44 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -104,8 +104,7 @@
struct tcf_result *res)
{
struct cls_cgroup_head *head = tp->root;
- struct cgroup_cls_state *cs;
- int ret = 0;
+ u32 classid;
/*
* Due to the nature of the classifier it is required to ignore all
@@ -121,17 +120,18 @@
return -1;
rcu_read_lock();
- cs = task_cls_state(current);
- if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) {
- res->classid = cs->classid;
- res->class = 0;
- ret = tcf_exts_exec(skb, &head->exts, res);
- } else
- ret = -1;
-
+ classid = task_cls_state(current)->classid;
rcu_read_unlock();
- return ret;
+ if (!classid)
+ return -1;
+
+ if (!tcf_em_tree_match(skb, &head->ematches, NULL))
+ return -1;
+
+ res->classid = classid;
+ res->class = 0;
+ return tcf_exts_exec(skb, &head->exts, res);
}
static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index af31988..9d50423 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -345,6 +345,7 @@
lock_sock(sock->sk);
sock->sk->sk_sndbuf = snd * 2;
sock->sk->sk_rcvbuf = rcv * 2;
+ sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;
release_sock(sock->sk);
#endif
}
@@ -796,6 +797,23 @@
test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags),
test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags));
+ if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags))
+ /* sndbuf needs to have room for one request
+ * per thread, otherwise we can stall even when the
+ * network isn't a bottleneck.
+ *
+ * We count all threads rather than threads in a
+ * particular pool, which provides an upper bound
+ * on the number of threads which will access the socket.
+ *
+ * rcvbuf just needs to be able to hold a few requests.
+ * Normally they will be removed from the queue
+ * as soon a a complete request arrives.
+ */
+ svc_sock_setbufsize(svsk->sk_sock,
+ (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+ 3 * serv->sv_max_mesg);
+
clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
/* Receive data. If we haven't got the record length yet, get
@@ -1043,6 +1061,15 @@
tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
+ /* initialise setting must have enough space to
+ * receive and respond to one request.
+ * svc_tcp_recvfrom will re-adjust if necessary
+ */
+ svc_sock_setbufsize(svsk->sk_sock,
+ 3 * svsk->sk_xprt.xpt_server->sv_max_mesg,
+ 3 * svsk->sk_xprt.xpt_server->sv_max_mesg);
+
+ set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
if (sk->sk_state != TCP_ESTABLISHED)
set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
@@ -1112,14 +1139,8 @@
/* Initialize the socket */
if (sock->type == SOCK_DGRAM)
svc_udp_init(svsk, serv);
- else {
- /* initialise setting must have enough space to
- * receive and respond to one request.
- */
- svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg,
- 4 * serv->sv_max_mesg);
+ else
svc_tcp_init(svsk, serv);
- }
dprintk("svc: svc_setup_socket created %p (inet %p)\n",
svsk, svsk->sk_sk);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 8b510c5..f11be72 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -128,7 +128,8 @@
page_bytes -= sge_bytes;
frmr->page_list->page_list[page_no] =
- ib_dma_map_page(xprt->sc_cm_id->device, page, 0,
+ ib_dma_map_single(xprt->sc_cm_id->device,
+ page_address(page),
PAGE_SIZE, DMA_TO_DEVICE);
if (ib_dma_mapping_error(xprt->sc_cm_id->device,
frmr->page_list->page_list[page_no]))
@@ -532,18 +533,17 @@
clear_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
/* Prepare the SGE for the RPCRDMA Header */
+ ctxt->sge[0].lkey = rdma->sc_dma_lkey;
+ ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp);
ctxt->sge[0].addr =
- ib_dma_map_page(rdma->sc_cm_id->device,
- page, 0, PAGE_SIZE, DMA_TO_DEVICE);
+ ib_dma_map_single(rdma->sc_cm_id->device, page_address(page),
+ ctxt->sge[0].length, DMA_TO_DEVICE);
if (ib_dma_mapping_error(rdma->sc_cm_id->device, ctxt->sge[0].addr))
goto err;
atomic_inc(&rdma->sc_dma_used);
ctxt->direction = DMA_TO_DEVICE;
- ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp);
- ctxt->sge[0].lkey = rdma->sc_dma_lkey;
-
/* Determine how many of our SGE are to be transmitted */
for (sge_no = 1; byte_count && sge_no < vec->count; sge_no++) {
sge_bytes = min_t(size_t, vec->sge[sge_no].iov_len, byte_count);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 4b0c2fa..5151f9f 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -500,8 +500,8 @@
BUG_ON(sge_no >= xprt->sc_max_sge);
page = svc_rdma_get_page();
ctxt->pages[sge_no] = page;
- pa = ib_dma_map_page(xprt->sc_cm_id->device,
- page, 0, PAGE_SIZE,
+ pa = ib_dma_map_single(xprt->sc_cm_id->device,
+ page_address(page), PAGE_SIZE,
DMA_FROM_DEVICE);
if (ib_dma_mapping_error(xprt->sc_cm_id->device, pa))
goto err_put_ctxt;
@@ -1315,8 +1315,8 @@
length = svc_rdma_xdr_encode_error(xprt, rmsgp, err, va);
/* Prepare SGE for local address */
- sge.addr = ib_dma_map_page(xprt->sc_cm_id->device,
- p, 0, PAGE_SIZE, DMA_FROM_DEVICE);
+ sge.addr = ib_dma_map_single(xprt->sc_cm_id->device,
+ page_address(p), PAGE_SIZE, DMA_FROM_DEVICE);
if (ib_dma_mapping_error(xprt->sc_cm_id->device, sge.addr)) {
put_page(p);
return;
@@ -1343,7 +1343,7 @@
if (ret) {
dprintk("svcrdma: Error %d posting send for protocol error\n",
ret);
- ib_dma_unmap_page(xprt->sc_cm_id->device,
+ ib_dma_unmap_single(xprt->sc_cm_id->device,
sge.addr, PAGE_SIZE,
DMA_FROM_DEVICE);
svc_rdma_put_context(ctxt, 1);
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 3b21e0c..465aafc 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -1495,7 +1495,8 @@
frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT;
frmr_wr.wr.fast_reg.access_flags = (writing ?
- IB_ACCESS_REMOTE_WRITE : IB_ACCESS_REMOTE_READ);
+ IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :
+ IB_ACCESS_REMOTE_READ);
frmr_wr.wr.fast_reg.rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
DECR_CQCOUNT(&r_xprt->rx_ep);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 08265ca..487cb62 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1551,6 +1551,13 @@
queue_regulatory_request(request);
+ /*
+ * This ensures last_request is populated once modules
+ * come swinging in and calling regulatory hints and
+ * wiphy_apply_custom_regulatory().
+ */
+ flush_scheduled_work();
+
return 0;
}
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index cb6a5bb..0e59f9a 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -786,6 +786,13 @@
err = -EFAULT;
goto out;
}
+
+ if (cmd == SIOCSIWENCODEEXT) {
+ struct iw_encode_ext *ee = (void *) extra;
+
+ if (iwp->length < sizeof(*ee) + ee->key_len)
+ return -EFAULT;
+ }
}
err = handler(dev, info, (union iwreq_data *) iwp, extra);
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 5b48191..e42be5c 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -27,6 +27,12 @@
static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
{
+ int rc;
+
+ rc = cap_bprm_set_creds(bprm);
+ if (rc)
+ return rc;
+
/*
* Do only if this function is called for the first time of an execve
* operation.
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a2a792c..d659995 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -249,6 +249,11 @@
new_hw_ptr = hw_base + pos;
}
}
+
+ /* Do jiffies check only in xrun_debug mode */
+ if (!xrun_debug(substream))
+ goto no_jiffies_check;
+
/* Skip the jiffies check for hardwares with BATCH flag.
* Such hardware usually just increases the position at each IRQ,
* thus it can't give any strange position.
@@ -336,7 +341,9 @@
hw_base = 0;
new_hw_ptr = hw_base + pos;
}
- if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
+ /* Do jiffies check only in xrun_debug mode */
+ if (xrun_debug(substream) &&
+ ((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
hw_ptr_error(substream,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
@@ -1478,7 +1485,6 @@
runtime->status->hw_ptr %= runtime->buffer_size;
else
runtime->status->hw_ptr = 0;
- runtime->hw_ptr_jiffies = jiffies;
snd_pcm_stream_unlock_irqrestore(substream, flags);
return 0;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index fc6f98e..b5da656 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -848,6 +848,7 @@
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream);
+ runtime->hw_ptr_jiffies = jiffies;
runtime->status->state = state;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0)
@@ -961,6 +962,11 @@
{
if (substream->runtime->trigger_master != substream)
return 0;
+ /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
+ * a delta betwen the current jiffies, this gives a large enough
+ * delta, effectively to skip the check once.
+ */
+ substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
return substream->ops->trigger(substream,
push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 21e99cf..3128e1a 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2141,6 +2141,7 @@
/* including bogus ALC268 in slot#2 that conflicts with ALC888 */
SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
/* forced codec slots */
+ SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
{}
};
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 56ce19e..4fcbe21 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1848,6 +1848,7 @@
static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
+ SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
CXT5051_LAPTOP),
SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index bcbb736..0fd258e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -776,6 +776,12 @@
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
if (pincap & AC_PINCAP_VREF_80)
val = PIN_VREF80;
+ else if (pincap & AC_PINCAP_VREF_50)
+ val = PIN_VREF50;
+ else if (pincap & AC_PINCAP_VREF_100)
+ val = PIN_VREF100;
+ else if (pincap & AC_PINCAP_VREF_GRD)
+ val = PIN_VREFGRD;
}
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 03b3646..d2fd8ef 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -150,6 +150,7 @@
STAC_D965_REF,
STAC_D965_3ST,
STAC_D965_5ST,
+ STAC_D965_5ST_NO_FP,
STAC_DELL_3ST,
STAC_DELL_BIOS,
STAC_927X_MODELS
@@ -2154,6 +2155,13 @@
0x40000100, 0x40000100
};
+static unsigned int d965_5st_no_fp_pin_configs[14] = {
+ 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
+ 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
+ 0x40000100, 0x40000100, 0x40000100, 0x01442070,
+ 0x40000100, 0x40000100
+};
+
static unsigned int dell_3st_pin_configs[14] = {
0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
0x01111212, 0x01116211, 0x01813050, 0x01112214,
@@ -2166,6 +2174,7 @@
[STAC_D965_REF] = ref927x_pin_configs,
[STAC_D965_3ST] = d965_3st_pin_configs,
[STAC_D965_5ST] = d965_5st_pin_configs,
+ [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
[STAC_DELL_3ST] = dell_3st_pin_configs,
[STAC_DELL_BIOS] = NULL,
};
@@ -2176,6 +2185,7 @@
[STAC_D965_REF] = "ref",
[STAC_D965_3ST] = "3stack",
[STAC_D965_5ST] = "5stack",
+ [STAC_D965_5ST_NO_FP] = "5stack-no-fp",
[STAC_DELL_3ST] = "dell-3stack",
[STAC_DELL_BIOS] = "dell-bios",
};
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 823296d..a6b8848 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3347,7 +3347,7 @@
[QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface,
[QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface,
[QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface,
- [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
+ [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface,
[QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
[QUIRK_MIDI_CME] = snd_usb_create_midi_interface,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 36e4f7a..8e7f789 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -153,7 +153,7 @@
QUIRK_MIDI_YAMAHA,
QUIRK_MIDI_MIDIMAN,
QUIRK_MIDI_NOVATION,
- QUIRK_MIDI_RAW,
+ QUIRK_MIDI_FASTLANE,
QUIRK_MIDI_EMAGIC,
QUIRK_MIDI_CME,
QUIRK_MIDI_US122L,
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 26bad37..2fb35cc 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -1778,8 +1778,18 @@
umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
- case QUIRK_MIDI_RAW:
+ case QUIRK_MIDI_FASTLANE:
umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
+ /*
+ * Interface 1 contains isochronous endpoints, but with the same
+ * numbers as in interface 0. Since it is interface 1 that the
+ * USB core has most recently seen, these descriptors are now
+ * associated with the endpoint numbers. This will foul up our
+ * attempts to submit bulk/interrupt URBs to the endpoints in
+ * interface 0, so we have to make sure that the USB core looks
+ * again at interface 0 by calling usb_set_interface() on it.
+ */
+ usb_set_interface(umidi->chip->dev, 0, 0);
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
case QUIRK_MIDI_EMAGIC:
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 647ef50..5d955aa 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1868,7 +1868,7 @@
.data = & (const struct snd_usb_audio_quirk[]) {
{
.ifnum = 0,
- .type = QUIRK_MIDI_RAW
+ .type = QUIRK_MIDI_FASTLANE
},
{
.ifnum = 1,