diff --git a/[refs] b/[refs]
index b29c6bb2989c..209339d517d8 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: de47a4176c532ef5961b8a46a2d541a3517412d3
+refs/heads/master: 84f8bf38b9368add916e7c335b6b94a7ae927cb1
diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl
index 2f7fd4360848..9c27e5125dd2 100644
--- a/trunk/Documentation/DocBook/device-drivers.tmpl
+++ b/trunk/Documentation/DocBook/device-drivers.tmpl
@@ -102,9 +102,12 @@ X!Iinclude/linux/kobject.h
!Iinclude/linux/device.h
Device Drivers Base
+!Idrivers/base/init.c
!Edrivers/base/driver.c
!Edrivers/base/core.c
+!Edrivers/base/syscore.c
!Edrivers/base/class.c
+!Idrivers/base/node.c
!Edrivers/base/firmware_class.c
!Edrivers/base/transport_class.c
-!Edrivers/base/sys.c
+!Edrivers/base/dd.c
!Iinclude/linux/platform_device.h
!Edrivers/base/platform.c
!Edrivers/base/bus.c
+
+ Device Drivers DMA Management
+!Edrivers/base/dma-buf.c
+!Edrivers/base/dma-coherent.c
+!Edrivers/base/dma-mapping.c
Device Drivers Power Management
!Edrivers/base/power/main.c
@@ -219,7 +227,7 @@ X!Isound/sound_firmware.c
16x50 UART Driver
!Edrivers/tty/serial/serial_core.c
-!Edrivers/tty/serial/8250.c
+!Edrivers/tty/serial/8250/8250.c
diff --git a/trunk/Documentation/driver-model/devres.txt b/trunk/Documentation/driver-model/devres.txt
index 10c64c8a13d4..41c0c5d1ba14 100644
--- a/trunk/Documentation/driver-model/devres.txt
+++ b/trunk/Documentation/driver-model/devres.txt
@@ -233,6 +233,10 @@ certainly invest a bit more effort into libata core layer).
6. List of managed interfaces
-----------------------------
+MEM
+ devm_kzalloc()
+ devm_kfree()
+
IO region
devm_request_region()
devm_request_mem_region()
diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt
index 1bea46a54b1c..a0ffac029a0d 100644
--- a/trunk/Documentation/feature-removal-schedule.txt
+++ b/trunk/Documentation/feature-removal-schedule.txt
@@ -510,3 +510,17 @@ Why: The pci_scan_bus_parented() interface creates a new root bus. The
convert to using pci_scan_root_bus() so they can supply a list of
bus resources when the bus is created.
Who: Bjorn Helgaas
+
+----------------------------
+
+What: The CAP9 SoC family will be removed
+When: 3.4
+Files: arch/arm/mach-at91/at91cap9.c
+ arch/arm/mach-at91/at91cap9_devices.c
+ arch/arm/mach-at91/include/mach/at91cap9.h
+ arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+ arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+ arch/arm/mach-at91/board-cap9adk.c
+Why: The code is not actively maintained and platforms are now hard to find.
+Who: Nicolas Ferre
+ Jean-Christophe PLAGNIOL-VILLARD
diff --git a/trunk/Documentation/input/event-codes.txt b/trunk/Documentation/input/event-codes.txt
index 23fcb05175be..53305bd08182 100644
--- a/trunk/Documentation/input/event-codes.txt
+++ b/trunk/Documentation/input/event-codes.txt
@@ -17,11 +17,11 @@ reports supported by a device are also provided by sysfs in
class/input/event*/device/capabilities/, and the properties of a device are
provided in class/input/event*/device/properties.
-Types:
-==========
-Types are groupings of codes under a logical input construct. Each type has a
-set of applicable codes to be used in generating events. See the Codes section
-for details on valid codes for each type.
+Event types:
+===========
+Event types are groupings of codes under a logical input construct. Each
+type has a set of applicable codes to be used in generating events. See the
+Codes section for details on valid codes for each type.
* EV_SYN:
- Used as markers to separate events. Events may be separated in time or in
@@ -63,9 +63,9 @@ for details on valid codes for each type.
* EV_FF_STATUS:
- Used to receive force feedback device status.
-Codes:
-==========
-Codes define the precise type of event.
+Event codes:
+===========
+Event codes define the precise type of event.
EV_SYN:
----------
@@ -220,6 +220,56 @@ EV_PWR:
EV_PWR events are a special type of event used specifically for power
mangement. Its usage is not well defined. To be addressed later.
+Device properties:
+=================
+Normally, userspace sets up an input device based on the data it emits,
+i.e., the event types. In the case of two devices emitting the same event
+types, additional information can be provided in the form of device
+properties.
+
+INPUT_PROP_DIRECT + INPUT_PROP_POINTER:
+--------------------------------------
+The INPUT_PROP_DIRECT property indicates that device coordinates should be
+directly mapped to screen coordinates (not taking into account trivial
+transformations, such as scaling, flipping and rotating). Non-direct input
+devices require non-trivial transformation, such as absolute to relative
+transformation for touchpads. Typical direct input devices: touchscreens,
+drawing tablets; non-direct devices: touchpads, mice.
+
+The INPUT_PROP_POINTER property indicates that the device is not transposed
+on the screen and thus requires use of an on-screen pointer to trace user's
+movements. Typical pointer devices: touchpads, tablets, mice; non-pointer
+device: touchscreen.
+
+If neither INPUT_PROP_DIRECT or INPUT_PROP_POINTER are set, the property is
+considered undefined and the device type should be deduced in the
+traditional way, using emitted event types.
+
+INPUT_PROP_BUTTONPAD:
+--------------------
+For touchpads where the button is placed beneath the surface, such that
+pressing down on the pad causes a button click, this property should be
+set. Common in clickpad notebooks and macbooks from 2009 and onwards.
+
+Originally, the buttonpad property was coded into the bcm5974 driver
+version field under the name integrated button. For backwards
+compatibility, both methods need to be checked in userspace.
+
+INPUT_PROP_SEMI_MT:
+------------------
+Some touchpads, most common between 2008 and 2011, can detect the presence
+of multiple contacts without resolving the individual positions; only the
+number of contacts and a rectangular shape is known. For such
+touchpads, the semi-mt property should be set.
+
+Depending on the device, the rectangle may enclose all touches, like a
+bounding box, or just some of them, for instance the two most recent
+touches. The diversity makes the rectangle of limited use, but some
+gestures can normally be extracted from it.
+
+If INPUT_PROP_SEMI_MT is not set, the device is assumed to be a true MT
+device.
+
Guidelines:
==========
The guidelines below ensure proper single-touch and multi-finger functionality.
@@ -240,6 +290,8 @@ used to report when a touch is active on the screen.
BTN_{MOUSE,LEFT,MIDDLE,RIGHT} must not be reported as the result of touch
contact. BTN_TOOL_ events should be reported where possible.
+For new hardware, INPUT_PROP_DIRECT should be set.
+
Trackpads:
----------
Legacy trackpads that only provide relative position information must report
@@ -250,6 +302,8 @@ location of the touch. BTN_TOUCH should be used to report when a touch is active
on the trackpad. Where multi-finger support is available, BTN_TOOL_ should
be used to report the number of touches active on the trackpad.
+For new hardware, INPUT_PROP_POINTER should be set.
+
Tablets:
----------
BTN_TOOL_ events must be reported when a stylus or other tool is active on
@@ -260,3 +314,5 @@ button may be used for buttons on the tablet except BTN_{MOUSE,LEFT}.
BTN_{0,1,2,etc} are good generic codes for unlabeled buttons. Do not use
meaningful buttons, like BTN_FORWARD, unless the button is labeled for that
purpose on the device.
+
+For new hardware, both INPUT_PROP_DIRECT and INPUT_PROP_POINTER should be set.
diff --git a/trunk/Documentation/pinctrl.txt b/trunk/Documentation/pinctrl.txt
index 6727b92bc2fb..150fd3833d0b 100644
--- a/trunk/Documentation/pinctrl.txt
+++ b/trunk/Documentation/pinctrl.txt
@@ -857,42 +857,41 @@ case), we define a mapping like this:
...
{
- .name "2bit"
+ .name = "2bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
- .name "4bit"
+ .name = "4bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
- .name "4bit"
+ .name = "4bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
- .name "8bit"
+ .name = "8bit"
.ctrl_dev_name = "pinctrl-foo",
- .function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
- .name "8bit"
+ .name = "8bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
- .name "8bit"
+ .name = "8bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_3_grp",
@@ -995,7 +994,7 @@ This is enabled by simply setting the .hog_on_boot field in the map to true,
like this:
{
- .name "POWERMAP"
+ .name = "POWERMAP"
.ctrl_dev_name = "pinctrl-foo",
.function = "power_func",
.hog_on_boot = true,
@@ -1025,7 +1024,7 @@ it, disables and releases it, and muxes it in on the pins defined by group B:
foo_switch()
{
- struct pinmux pmx;
+ struct pinmux *pmx;
/* Enable on position A */
pmx = pinmux_get(&device, "spi0-pos-A");
diff --git a/trunk/Documentation/stable_kernel_rules.txt b/trunk/Documentation/stable_kernel_rules.txt
index 21fd05c28e73..f0ab5cf28fca 100644
--- a/trunk/Documentation/stable_kernel_rules.txt
+++ b/trunk/Documentation/stable_kernel_rules.txt
@@ -25,7 +25,8 @@ Procedure for submitting patches to the -stable tree:
- Send the patch, after verifying that it follows the above rules, to
stable@vger.kernel.org. You must note the upstream commit ID in the
- changelog of your submission.
+ changelog of your submission, as well as the kernel version you wish
+ it to be applied to.
- To have the patch automatically included in the stable tree, add the tag
Cc: stable@vger.kernel.org
in the sign-off area. Once the patch is merged it will be applied to
diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt
index 8c20fbd8b42d..6d78841fd416 100644
--- a/trunk/Documentation/sysctl/kernel.txt
+++ b/trunk/Documentation/sysctl/kernel.txt
@@ -601,6 +601,8 @@ can be ORed together:
instead of using the one provided by the hardware.
512 - A kernel warning has occurred.
1024 - A module from drivers/staging was loaded.
+2048 - The system is working around a severe firmware bug.
+4096 - An out-of-tree module has been loaded.
==============================================================
diff --git a/trunk/Documentation/thermal/sysfs-api.txt b/trunk/Documentation/thermal/sysfs-api.txt
index b61e46f449aa..1733ab947a95 100644
--- a/trunk/Documentation/thermal/sysfs-api.txt
+++ b/trunk/Documentation/thermal/sysfs-api.txt
@@ -284,7 +284,7 @@ method, the sys I/F structure will be built like this:
The framework includes a simple notification mechanism, in the form of a
netlink event. Netlink socket initialization is done during the _init_
of the framework. Drivers which intend to use the notification mechanism
-just need to call generate_netlink_event() with two arguments viz
+just need to call thermal_generate_netlink_event() with two arguments viz
(originator, event). Typically the originator will be an integer assigned
to a thermal_zone_device when it registers itself with the framework. The
event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
diff --git a/trunk/Documentation/virtual/00-INDEX b/trunk/Documentation/virtual/00-INDEX
index 8e601991d91c..924bd462675e 100644
--- a/trunk/Documentation/virtual/00-INDEX
+++ b/trunk/Documentation/virtual/00-INDEX
@@ -4,8 +4,6 @@ Virtualization support in the Linux kernel.
- this file.
kvm/
- Kernel Virtual Machine. See also http://linux-kvm.org
-lguest/
- - Extremely simple hypervisor for experimental/educational use.
uml/
- User Mode Linux, builds/runs Linux kernel as a userspace program.
virtio.txt
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 93c68d5f1cf4..55ca0bea142c 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -159,7 +159,7 @@ S: Maintained
F: drivers/net/ethernet/realtek/r8169.c
8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-serial@vger.kernel.org
W: http://serial.sourceforge.net
S: Maintained
@@ -789,12 +789,6 @@ F: arch/arm/mach-mx*/
F: arch/arm/mach-imx/
F: arch/arm/plat-mxc/
-ARM/FREESCALE IMX51
-M: Amit Kucheria
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/mach-mx5/
-
ARM/FREESCALE IMX6
M: Shawn Guo
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1783,9 +1777,9 @@ X: net/wireless/wext*
CHAR and MISC DRIVERS
M: Arnd Bergmann
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
-S: Maintained
+S: Supported
F: drivers/char/*
F: drivers/misc/*
@@ -2287,7 +2281,7 @@ F: drivers/acpi/dock.c
DOCUMENTATION
M: Randy Dunlap
L: linux-doc@vger.kernel.org
-T: quilt http://userweb.kernel.org/~rdunlap/kernel-doc-patches/current/
+T: quilt http://xenotime.net/kernel-doc-patches/current/
S: Maintained
F: Documentation/
@@ -2320,7 +2314,7 @@ F: lib/lru_cache.c
F: Documentation/blockdev/drbd/
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
S: Supported
F: Documentation/kobject.txt
@@ -2350,6 +2344,9 @@ F: include/drm/i915*
DRM DRIVERS FOR EXYNOS
M: Inki Dae
+M: Joonyoung Shim
+M: Seung-Woo Kim
+M: Kyungmin Park
L: dri-devel@lists.freedesktop.org
S: Supported
F: drivers/gpu/drm/exynos
@@ -2402,7 +2399,7 @@ F: net/bridge/netfilter/ebt*.c
ECRYPT FILE SYSTEM
M: Tyler Hicks
-M: Dustin Kirkland
+M: Dustin Kirkland
L: ecryptfs@vger.kernel.org
W: https://launchpad.net/ecryptfs
S: Supported
@@ -3989,11 +3986,11 @@ M: Rusty Russell
L: lguest@lists.ozlabs.org
W: http://lguest.ozlabs.org/
S: Odd Fixes
-F: Documentation/virtual/lguest/
+F: arch/x86/include/asm/lguest*.h
F: arch/x86/lguest/
F: drivers/lguest/
F: include/linux/lguest*.h
-F: arch/x86/include/asm/lguest*.h
+F: tools/lguest/
LINUX FOR IBM pSERIES (RS/6000)
M: Paul Mackerras
@@ -4133,10 +4130,11 @@ L: linux-ntfs-dev@lists.sourceforge.net
W: http://www.linux-ntfs.org/content/view/19/37/
S: Maintained
F: Documentation/ldm.txt
-F: fs/partitions/ldm.*
+F: block/partitions/ldm.*
LogFS
M: Joern Engel
+M: Prasad Joshi
L: logfs@logfs.org
W: logfs.org
S: Maintained
@@ -4278,13 +4276,6 @@ S: Orphan
F: drivers/video/matrox/matroxfb_*
F: include/linux/matroxfb.h
-MAX1668 TEMPERATURE SENSOR DRIVER
-M: "David George"
-L: lm-sensors@lm-sensors.org
-S: Maintained
-F: Documentation/hwmon/max1668
-F: drivers/hwmon/max1668.c
-
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
M: "Hans J. Koch"
L: lm-sensors@lm-sensors.org
@@ -5636,7 +5627,7 @@ W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: arch/s390/
F: drivers/s390/
-F: fs/partitions/ibm.c
+F: block/partitions/ibm.c
F: Documentation/s390/
F: Documentation/DocBook/s390*
@@ -6279,15 +6270,15 @@ S: Maintained
F: arch/alpha/kernel/srm_env.c
STABLE BRANCH
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: stable@vger.kernel.org
-S: Maintained
+S: Supported
STAGING SUBSYSTEM
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
L: devel@driverdev.osuosl.org
-S: Maintained
+S: Supported
F: drivers/staging/
STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS
@@ -6399,11 +6390,6 @@ M: Omar Ramirez Luna
S: Odd Fixes
F: drivers/staging/tidspbridge/
-STAGING - TRIDENT TVMASTER TMxxxx USB VIDEO CAPTURE DRIVERS
-L: linux-media@vger.kernel.org
-S: Odd Fixes
-F: drivers/staging/tm6000/
-
STAGING - USB ENE SM/MS CARD READER DRIVER
M: Al Cho
S: Odd Fixes
@@ -6672,10 +6658,10 @@ S: Maintained
K: ^Subject:.*(?i)trivial
TTY LAYER
-M: Greg Kroah-Hartman
-S: Maintained
+M: Greg Kroah-Hartman
+S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
-F: drivers/tty/*
+F: drivers/tty/
F: drivers/tty/serial/serial_core.c
F: include/linux/serial_core.h
F: include/linux/serial.h
@@ -6961,7 +6947,7 @@ S: Maintained
F: drivers/usb/serial/digi_acceleport.c
USB SERIAL DRIVER
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-usb@vger.kernel.org
S: Supported
F: Documentation/usb/usb-serial.txt
@@ -6976,9 +6962,8 @@ S: Maintained
F: drivers/usb/serial/empeg.c
USB SERIAL KEYSPAN DRIVER
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-usb@vger.kernel.org
-W: http://www.kroah.com/linux/
S: Maintained
F: drivers/usb/serial/*keyspan*
@@ -7006,7 +6991,7 @@ F: Documentation/video4linux/sn9c102.txt
F: drivers/media/video/sn9c102/
USB SUBSYSTEM
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
@@ -7093,7 +7078,7 @@ F: fs/hppfs/
USERSPACE I/O (UIO)
M: "Hans J. Koch"
-M: Greg Kroah-Hartman
+M: Greg Kroah-Hartman
S: Maintained
F: Documentation/DocBook/uio-howto.tmpl
F: drivers/uio/
@@ -7368,6 +7353,7 @@ S: Supported
F: Documentation/hwmon/wm83??
F: arch/arm/mach-s3c64xx/mach-crag6410*
F: drivers/leds/leds-wm83*.c
+F: drivers/hwmon/wm83??-hwmon.c
F: drivers/input/misc/wm831x-on.c
F: drivers/input/touchscreen/wm831x-ts.c
F: drivers/input/touchscreen/wm97*.c
diff --git a/trunk/Makefile b/trunk/Makefile
index 71e6ed21dd15..e3b23e864a53 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 3
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig
index 24626b0419ee..a48aecc17eac 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -754,7 +754,7 @@ config ARCH_SA1100
select ARCH_HAS_CPUFREQ
select CPU_FREQ
select GENERIC_CLOCKEVENTS
- select CLKDEV_LOOKUP
+ select HAVE_CLK
select HAVE_SCHED_CLOCK
select TICK_ONESHOT
select ARCH_REQUIRE_GPIOLIB
@@ -825,7 +825,6 @@ config ARCH_S5PC100
select HAVE_CLK
select CLKDEV_LOOKUP
select CPU_V7
- select ARM_L1_CACHE_SHIFT_6
select ARCH_USES_GETTIMEOFFSET
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C_RTC if RTC_CLASS
@@ -842,7 +841,6 @@ config ARCH_S5PV210
select HAVE_CLK
select CLKDEV_LOOKUP
select CLKSRC_MMIO
- select ARM_L1_CACHE_SHIFT_6
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_SCHED_CLOCK
diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c
index b2dc2dd7f1df..c47d6199b784 100644
--- a/trunk/arch/arm/common/gic.c
+++ b/trunk/arch/arm/common/gic.c
@@ -41,6 +41,7 @@
#include
#include
+#include
#include
#include
@@ -352,11 +353,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
unsigned int gic_irqs = gic->gic_irqs;
struct irq_domain *domain = &gic->domain;
void __iomem *base = gic_data_dist_base(gic);
- u32 cpu = 0;
-
-#ifdef CONFIG_SMP
- cpu = cpu_logical_map(smp_processor_id());
-#endif
+ u32 cpu = cpu_logical_map(smp_processor_id());
cpumask = 1 << cpu;
cpumask |= cpumask << 8;
diff --git a/trunk/arch/arm/include/asm/assembler.h b/trunk/arch/arm/include/asm/assembler.h
index b6e65dedfd71..62f8095d46de 100644
--- a/trunk/arch/arm/include/asm/assembler.h
+++ b/trunk/arch/arm/include/asm/assembler.h
@@ -237,7 +237,7 @@
*/
#ifdef CONFIG_THUMB2_KERNEL
- .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()
+ .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER()
9999:
.if \inc == 1
\instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
@@ -277,7 +277,7 @@
#else /* !CONFIG_THUMB2_KERNEL */
- .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()
+ .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER()
.rept \rept
9999:
.if \inc == 1
diff --git a/trunk/arch/arm/include/asm/domain.h b/trunk/arch/arm/include/asm/domain.h
index af18ceaacf5d..b5dc173d336f 100644
--- a/trunk/arch/arm/include/asm/domain.h
+++ b/trunk/arch/arm/include/asm/domain.h
@@ -83,9 +83,9 @@
* instructions (inline assembly)
*/
#ifdef CONFIG_CPU_USE_DOMAINS
-#define T(instr) #instr "t"
+#define TUSER(instr) #instr "t"
#else
-#define T(instr) #instr
+#define TUSER(instr) #instr
#endif
#else /* __ASSEMBLY__ */
@@ -95,9 +95,9 @@
* instructions
*/
#ifdef CONFIG_CPU_USE_DOMAINS
-#define T(instr) instr ## t
+#define TUSER(instr) instr ## t
#else
-#define T(instr) instr
+#define TUSER(instr) instr
#endif
#endif /* __ASSEMBLY__ */
diff --git a/trunk/arch/arm/include/asm/futex.h b/trunk/arch/arm/include/asm/futex.h
index 253cc86318bf..7be54690aeec 100644
--- a/trunk/arch/arm/include/asm/futex.h
+++ b/trunk/arch/arm/include/asm/futex.h
@@ -75,9 +75,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
__asm__ __volatile__( \
- "1: " T(ldr) " %1, [%3]\n" \
+ "1: " TUSER(ldr) " %1, [%3]\n" \
" " insn "\n" \
- "2: " T(str) " %0, [%3]\n" \
+ "2: " TUSER(str) " %0, [%3]\n" \
" mov %0, #0\n" \
__futex_atomic_ex_table("%5") \
: "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
@@ -95,10 +95,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
return -EFAULT;
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
- "1: " T(ldr) " %1, [%4]\n"
+ "1: " TUSER(ldr) " %1, [%4]\n"
" teq %1, %2\n"
" it eq @ explicit IT needed for the 2b label\n"
- "2: " T(streq) " %3, [%4]\n"
+ "2: " TUSER(streq) " %3, [%4]\n"
__futex_atomic_ex_table("%5")
: "+r" (ret), "=&r" (val)
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
diff --git a/trunk/arch/arm/include/asm/smp.h b/trunk/arch/arm/include/asm/smp.h
index 1e5717afc4ac..ae29293270a3 100644
--- a/trunk/arch/arm/include/asm/smp.h
+++ b/trunk/arch/arm/include/asm/smp.h
@@ -70,12 +70,6 @@ extern void platform_secondary_init(unsigned int cpu);
*/
extern void platform_smp_prepare_cpus(unsigned int);
-/*
- * Logical CPU mapping.
- */
-extern int __cpu_logical_map[NR_CPUS];
-#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
-
/*
* Initial data for bringing up a secondary CPU.
*/
diff --git a/trunk/arch/arm/include/asm/smp_plat.h b/trunk/arch/arm/include/asm/smp_plat.h
index f24c1b9e211d..558d6c80aca9 100644
--- a/trunk/arch/arm/include/asm/smp_plat.h
+++ b/trunk/arch/arm/include/asm/smp_plat.h
@@ -43,4 +43,10 @@ static inline int cache_ops_need_broadcast(void)
}
#endif
+/*
+ * Logical CPU mapping.
+ */
+extern int __cpu_logical_map[];
+#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+
#endif
diff --git a/trunk/arch/arm/include/asm/tlb.h b/trunk/arch/arm/include/asm/tlb.h
index 5d3ed7e38561..314d4664eae7 100644
--- a/trunk/arch/arm/include/asm/tlb.h
+++ b/trunk/arch/arm/include/asm/tlb.h
@@ -198,7 +198,15 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long addr)
{
pgtable_page_dtor(pte);
- tlb_add_flush(tlb, addr);
+
+ /*
+ * With the classic ARM MMU, a pte page has two corresponding pmd
+ * entries, each covering 1MB.
+ */
+ addr &= PMD_MASK;
+ tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
+ tlb_add_flush(tlb, addr + SZ_1M);
+
tlb_remove_page(tlb, pte);
}
diff --git a/trunk/arch/arm/include/asm/uaccess.h b/trunk/arch/arm/include/asm/uaccess.h
index b293616a1a1a..2958976d867b 100644
--- a/trunk/arch/arm/include/asm/uaccess.h
+++ b/trunk/arch/arm/include/asm/uaccess.h
@@ -227,7 +227,7 @@ do { \
#define __get_user_asm_byte(x,addr,err) \
__asm__ __volatile__( \
- "1: " T(ldrb) " %1,[%2],#0\n" \
+ "1: " TUSER(ldrb) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -263,7 +263,7 @@ do { \
#define __get_user_asm_word(x,addr,err) \
__asm__ __volatile__( \
- "1: " T(ldr) " %1,[%2],#0\n" \
+ "1: " TUSER(ldr) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -308,7 +308,7 @@ do { \
#define __put_user_asm_byte(x,__pu_addr,err) \
__asm__ __volatile__( \
- "1: " T(strb) " %1,[%2],#0\n" \
+ "1: " TUSER(strb) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -341,7 +341,7 @@ do { \
#define __put_user_asm_word(x,__pu_addr,err) \
__asm__ __volatile__( \
- "1: " T(str) " %1,[%2],#0\n" \
+ "1: " TUSER(str) " %1,[%2],#0\n" \
"2:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
@@ -366,10 +366,10 @@ do { \
#define __put_user_asm_dword(x,__pu_addr,err) \
__asm__ __volatile__( \
- ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \
- ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \
- THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \
- THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \
+ ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \
+ ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \
+ THUMB( "1: " TUSER(str) " " __reg_oper1 ", [%1]\n" ) \
+ THUMB( "2: " TUSER(str) " " __reg_oper0 ", [%1, #4]\n" ) \
"3:\n" \
" .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \
diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S
index 3a456c6c7005..be16a48007b4 100644
--- a/trunk/arch/arm/kernel/entry-armv.S
+++ b/trunk/arch/arm/kernel/entry-armv.S
@@ -790,7 +790,7 @@ __kuser_cmpxchg64: @ 0xffff0f60
smp_dmb arm
rsbs r0, r3, #0 @ set returned val and C flag
ldmfd sp!, {r4, r5, r6, r7}
- bx lr
+ usr_ret lr
#elif !defined(CONFIG_SMP)
diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S
index 520889cf1b5b..9fd0ba90c1d2 100644
--- a/trunk/arch/arm/kernel/entry-common.S
+++ b/trunk/arch/arm/kernel/entry-common.S
@@ -149,6 +149,11 @@ ENDPROC(ret_from_fork)
#endif
#endif
+.macro mcount_adjust_addr rd, rn
+ bic \rd, \rn, #1 @ clear the Thumb bit if present
+ sub \rd, \rd, #MCOUNT_INSN_SIZE
+.endm
+
.macro __mcount suffix
mcount_enter
ldr r0, =ftrace_trace_function
@@ -173,8 +178,7 @@ ENDPROC(ret_from_fork)
mcount_exit
1: mcount_get_lr r1 @ lr of instrumented func
- mov r0, lr @ instrumented function
- sub r0, r0, #MCOUNT_INSN_SIZE
+ mcount_adjust_addr r0, lr @ instrumented function
adr lr, BSYM(2f)
mov pc, r2
2: mcount_exit
@@ -184,8 +188,7 @@ ENDPROC(ret_from_fork)
mcount_enter
mcount_get_lr r1 @ lr of instrumented func
- mov r0, lr @ instrumented function
- sub r0, r0, #MCOUNT_INSN_SIZE
+ mcount_adjust_addr r0, lr @ instrumented function
.globl ftrace_call\suffix
ftrace_call\suffix:
@@ -205,11 +208,11 @@ ftrace_graph_call\suffix:
#ifdef CONFIG_DYNAMIC_FTRACE
@ called from __ftrace_caller, saved in mcount_enter
ldr r1, [sp, #16] @ instrumented routine (func)
+ mcount_adjust_addr r1, r1
#else
@ called from __mcount, untouched in lr
- mov r1, lr @ instrumented routine (func)
+ mcount_adjust_addr r1, lr @ instrumented routine (func)
#endif
- sub r1, r1, #MCOUNT_INSN_SIZE
mov r2, fp @ frame pointer
bl prepare_ftrace_return
mcount_exit
diff --git a/trunk/arch/arm/kernel/perf_event_v7.c b/trunk/arch/arm/kernel/perf_event_v7.c
index 460bbbb6b885..6933244c68f9 100644
--- a/trunk/arch/arm/kernel/perf_event_v7.c
+++ b/trunk/arch/arm/kernel/perf_event_v7.c
@@ -469,6 +469,20 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
+ [C(NODE)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
};
/*
@@ -579,6 +593,20 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
},
},
+ [C(NODE)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
};
/*
diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c
index e1d5e1929fbd..e33870ff0ac0 100644
--- a/trunk/arch/arm/kernel/ptrace.c
+++ b/trunk/arch/arm/kernel/ptrace.c
@@ -699,10 +699,13 @@ static int vfp_set(struct task_struct *target,
{
int ret;
struct thread_info *thread = task_thread_info(target);
- struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
+ struct vfp_hard_struct new_vfp;
const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+ vfp_sync_hwstate(thread);
+ new_vfp = thread->vfpstate.hard;
+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
&new_vfp.fpregs,
user_fpregs_offset,
@@ -723,9 +726,8 @@ static int vfp_set(struct task_struct *target,
if (ret)
return ret;
- vfp_sync_hwstate(thread);
- thread->vfpstate.hard = new_vfp;
vfp_flush_hwstate(thread);
+ thread->vfpstate.hard = new_vfp;
return 0;
}
diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c
index 129fbd55bde8..a255c39612ca 100644
--- a/trunk/arch/arm/kernel/setup.c
+++ b/trunk/arch/arm/kernel/setup.c
@@ -21,7 +21,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -160,7 +159,7 @@ static struct resource mem_res[] = {
.flags = IORESOURCE_MEM
},
{
- .name = "Kernel text",
+ .name = "Kernel code",
.start = 0,
.end = 0,
.flags = IORESOURCE_MEM
@@ -427,6 +426,20 @@ void cpu_init(void)
: "r14");
}
+int __cpu_logical_map[NR_CPUS];
+
+void __init smp_setup_processor_id(void)
+{
+ int i;
+ u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
+
+ cpu_logical_map(0) = cpu;
+ for (i = 1; i < NR_CPUS; ++i)
+ cpu_logical_map(i) = i == cpu ? 0 : i;
+
+ printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
+}
+
static void __init setup_processor(void)
{
struct proc_info_list *list;
diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c
index 0340224cf73c..9e617bd4a146 100644
--- a/trunk/arch/arm/kernel/signal.c
+++ b/trunk/arch/arm/kernel/signal.c
@@ -227,6 +227,8 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
return -EINVAL;
+ vfp_flush_hwstate(thread);
+
/*
* Copy the floating point registers. There can be unused
* registers see asm/hwcap.h for details.
@@ -251,9 +253,6 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
- if (!err)
- vfp_flush_hwstate(thread);
-
return err ? -EFAULT : 0;
}
diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c
index 57db122a4f62..cdeb727527d3 100644
--- a/trunk/arch/arm/kernel/smp.c
+++ b/trunk/arch/arm/kernel/smp.c
@@ -233,20 +233,6 @@ void __ref cpu_die(void)
}
#endif /* CONFIG_HOTPLUG_CPU */
-int __cpu_logical_map[NR_CPUS];
-
-void __init smp_setup_processor_id(void)
-{
- int i;
- u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
-
- cpu_logical_map(0) = cpu;
- for (i = 1; i < NR_CPUS; ++i)
- cpu_logical_map(i) = i == cpu ? 0 : i;
-
- printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
-}
-
/*
* Called by both boot and secondaries to move global data into
* per-processor storage.
@@ -443,9 +429,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
static void ipi_timer(void)
{
struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
- irq_enter();
evt->event_handler(evt);
- irq_exit();
}
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
@@ -548,7 +532,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
switch (ipinr) {
case IPI_TIMER:
+ irq_enter();
ipi_timer();
+ irq_exit();
break;
case IPI_RESCHEDULE:
@@ -556,15 +542,21 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
break;
case IPI_CALL_FUNC:
+ irq_enter();
generic_smp_call_function_interrupt();
+ irq_exit();
break;
case IPI_CALL_FUNC_SINGLE:
+ irq_enter();
generic_smp_call_function_single_interrupt();
+ irq_exit();
break;
case IPI_CPU_STOP:
+ irq_enter();
ipi_cpu_stop(cpu);
+ irq_exit();
break;
default:
diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c
index c8e938553d47..4285daa077b0 100644
--- a/trunk/arch/arm/kernel/smp_twd.c
+++ b/trunk/arch/arm/kernel/smp_twd.c
@@ -252,6 +252,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
else
twd_calibrate_rate();
+ __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+
clk->name = "local_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_C3STOP;
diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S
index f76e75548670..1e19691e0406 100644
--- a/trunk/arch/arm/kernel/vmlinux.lds.S
+++ b/trunk/arch/arm/kernel/vmlinux.lds.S
@@ -4,6 +4,7 @@
*/
#include
+#include
#include
#include
#include
@@ -181,7 +182,7 @@ SECTIONS
}
#endif
- PERCPU_SECTION(32)
+ PERCPU_SECTION(L1_CACHE_BYTES)
#ifdef CONFIG_XIP_KERNEL
__data_loc = ALIGN(4); /* location in binary */
@@ -212,13 +213,13 @@ SECTIONS
#endif
NOSAVE_DATA
- CACHELINE_ALIGNED_DATA(32)
- READ_MOSTLY_DATA(32)
+ CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
+ READ_MOSTLY_DATA(L1_CACHE_BYTES)
/*
* The exception fixup table (might need resorting at runtime)
*/
- . = ALIGN(32);
+ . = ALIGN(4);
__start___ex_table = .;
#ifdef CONFIG_MMU
*(__ex_table)
diff --git a/trunk/arch/arm/lib/getuser.S b/trunk/arch/arm/lib/getuser.S
index 1b049cd7a49a..11093a7c3e32 100644
--- a/trunk/arch/arm/lib/getuser.S
+++ b/trunk/arch/arm/lib/getuser.S
@@ -31,18 +31,18 @@
#include
ENTRY(__get_user_1)
-1: T(ldrb) r2, [r0]
+1: TUSER(ldrb) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__get_user_1)
ENTRY(__get_user_2)
#ifdef CONFIG_THUMB2_KERNEL
-2: T(ldrb) r2, [r0]
-3: T(ldrb) r3, [r0, #1]
+2: TUSER(ldrb) r2, [r0]
+3: TUSER(ldrb) r3, [r0, #1]
#else
-2: T(ldrb) r2, [r0], #1
-3: T(ldrb) r3, [r0]
+2: TUSER(ldrb) r2, [r0], #1
+3: TUSER(ldrb) r3, [r0]
#endif
#ifndef __ARMEB__
orr r2, r2, r3, lsl #8
@@ -54,7 +54,7 @@ ENTRY(__get_user_2)
ENDPROC(__get_user_2)
ENTRY(__get_user_4)
-4: T(ldr) r2, [r0]
+4: TUSER(ldr) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__get_user_4)
diff --git a/trunk/arch/arm/lib/putuser.S b/trunk/arch/arm/lib/putuser.S
index c023fc11e86c..7db25990c589 100644
--- a/trunk/arch/arm/lib/putuser.S
+++ b/trunk/arch/arm/lib/putuser.S
@@ -31,7 +31,7 @@
#include
ENTRY(__put_user_1)
-1: T(strb) r2, [r0]
+1: TUSER(strb) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__put_user_1)
@@ -40,19 +40,19 @@ ENTRY(__put_user_2)
mov ip, r2, lsr #8
#ifdef CONFIG_THUMB2_KERNEL
#ifndef __ARMEB__
-2: T(strb) r2, [r0]
-3: T(strb) ip, [r0, #1]
+2: TUSER(strb) r2, [r0]
+3: TUSER(strb) ip, [r0, #1]
#else
-2: T(strb) ip, [r0]
-3: T(strb) r2, [r0, #1]
+2: TUSER(strb) ip, [r0]
+3: TUSER(strb) r2, [r0, #1]
#endif
#else /* !CONFIG_THUMB2_KERNEL */
#ifndef __ARMEB__
-2: T(strb) r2, [r0], #1
-3: T(strb) ip, [r0]
+2: TUSER(strb) r2, [r0], #1
+3: TUSER(strb) ip, [r0]
#else
-2: T(strb) ip, [r0], #1
-3: T(strb) r2, [r0]
+2: TUSER(strb) ip, [r0], #1
+3: TUSER(strb) r2, [r0]
#endif
#endif /* CONFIG_THUMB2_KERNEL */
mov r0, #0
@@ -60,18 +60,18 @@ ENTRY(__put_user_2)
ENDPROC(__put_user_2)
ENTRY(__put_user_4)
-4: T(str) r2, [r0]
+4: TUSER(str) r2, [r0]
mov r0, #0
mov pc, lr
ENDPROC(__put_user_4)
ENTRY(__put_user_8)
#ifdef CONFIG_THUMB2_KERNEL
-5: T(str) r2, [r0]
-6: T(str) r3, [r0, #4]
+5: TUSER(str) r2, [r0]
+6: TUSER(str) r3, [r0, #4]
#else
-5: T(str) r2, [r0], #4
-6: T(str) r3, [r0]
+5: TUSER(str) r2, [r0], #4
+6: TUSER(str) r3, [r0]
#endif
mov r0, #0
mov pc, lr
diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S
index d0ece2aeb70d..5c908b1cb8ed 100644
--- a/trunk/arch/arm/lib/uaccess.S
+++ b/trunk/arch/arm/lib/uaccess.S
@@ -32,11 +32,11 @@
rsb ip, ip, #4
cmp ip, #2
ldrb r3, [r1], #1
-USER( T(strb) r3, [r0], #1) @ May fault
+USER( TUSER( strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( T(strgeb) r3, [r0], #1) @ May fault
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1
-USER( T(strgtb) r3, [r0], #1) @ May fault
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
sub r2, r2, ip
b .Lc2u_dest_aligned
@@ -59,7 +59,7 @@ ENTRY(__copy_to_user)
addmi ip, r2, #4
bmi .Lc2u_0nowords
ldr r3, [r1], #4
-USER( T(str) r3, [r0], #4) @ May fault
+USER( TUSER( str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -88,18 +88,18 @@ USER( T(str) r3, [r0], #4) @ May fault
stmneia r0!, {r3 - r4} @ Shouldnt fault
tst ip, #4
ldrne r3, [r1], #4
- T(strne) r3, [r0], #4 @ Shouldnt fault
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_0fupi
.Lc2u_0nowords: teq ip, #0
beq .Lc2u_finished
.Lc2u_nowords: cmp ip, #2
ldrb r3, [r1], #1
-USER( T(strb) r3, [r0], #1) @ May fault
+USER( TUSER( strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( T(strgeb) r3, [r0], #1) @ May fault
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1
-USER( T(strgtb) r3, [r0], #1) @ May fault
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
.Lc2u_not_enough:
@@ -120,7 +120,7 @@ USER( T(strgtb) r3, [r0], #1) @ May fault
mov r3, r7, pull #8
ldr r7, [r1], #4
orr r3, r3, r7, push #24
-USER( T(str) r3, [r0], #4) @ May fault
+USER( TUSER( str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -155,18 +155,18 @@ USER( T(str) r3, [r0], #4) @ May fault
movne r3, r7, pull #8
ldrne r7, [r1], #4
orrne r3, r3, r7, push #24
- T(strne) r3, [r0], #4 @ Shouldnt fault
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_1fupi
.Lc2u_1nowords: mov r3, r7, get_byte_1
teq ip, #0
beq .Lc2u_finished
cmp ip, #2
-USER( T(strb) r3, [r0], #1) @ May fault
+USER( TUSER( strb) r3, [r0], #1) @ May fault
movge r3, r7, get_byte_2
-USER( T(strgeb) r3, [r0], #1) @ May fault
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
movgt r3, r7, get_byte_3
-USER( T(strgtb) r3, [r0], #1) @ May fault
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
.Lc2u_2fupi: subs r2, r2, #4
@@ -175,7 +175,7 @@ USER( T(strgtb) r3, [r0], #1) @ May fault
mov r3, r7, pull #16
ldr r7, [r1], #4
orr r3, r3, r7, push #16
-USER( T(str) r3, [r0], #4) @ May fault
+USER( TUSER( str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -210,18 +210,18 @@ USER( T(str) r3, [r0], #4) @ May fault
movne r3, r7, pull #16
ldrne r7, [r1], #4
orrne r3, r3, r7, push #16
- T(strne) r3, [r0], #4 @ Shouldnt fault
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_2fupi
.Lc2u_2nowords: mov r3, r7, get_byte_2
teq ip, #0
beq .Lc2u_finished
cmp ip, #2
-USER( T(strb) r3, [r0], #1) @ May fault
+USER( TUSER( strb) r3, [r0], #1) @ May fault
movge r3, r7, get_byte_3
-USER( T(strgeb) r3, [r0], #1) @ May fault
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0
-USER( T(strgtb) r3, [r0], #1) @ May fault
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
.Lc2u_3fupi: subs r2, r2, #4
@@ -230,7 +230,7 @@ USER( T(strgtb) r3, [r0], #1) @ May fault
mov r3, r7, pull #24
ldr r7, [r1], #4
orr r3, r3, r7, push #8
-USER( T(str) r3, [r0], #4) @ May fault
+USER( TUSER( str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -265,18 +265,18 @@ USER( T(str) r3, [r0], #4) @ May fault
movne r3, r7, pull #24
ldrne r7, [r1], #4
orrne r3, r3, r7, push #8
- T(strne) r3, [r0], #4 @ Shouldnt fault
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3
beq .Lc2u_3fupi
.Lc2u_3nowords: mov r3, r7, get_byte_3
teq ip, #0
beq .Lc2u_finished
cmp ip, #2
-USER( T(strb) r3, [r0], #1) @ May fault
+USER( TUSER( strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1
-USER( T(strgeb) r3, [r0], #1) @ May fault
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0
-USER( T(strgtb) r3, [r0], #1) @ May fault
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished
ENDPROC(__copy_to_user)
@@ -295,11 +295,11 @@ ENDPROC(__copy_to_user)
.Lcfu_dest_not_aligned:
rsb ip, ip, #4
cmp ip, #2
-USER( T(ldrb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrb) r3, [r1], #1) @ May fault
strb r3, [r0], #1
-USER( T(ldrgeb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( T(ldrgtb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
sub r2, r2, ip
b .Lcfu_dest_aligned
@@ -322,7 +322,7 @@ ENTRY(__copy_from_user)
.Lcfu_0fupi: subs r2, r2, #4
addmi ip, r2, #4
bmi .Lcfu_0nowords
-USER( T(ldr) r3, [r1], #4)
+USER( TUSER( ldr) r3, [r1], #4)
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0
@@ -351,18 +351,18 @@ USER( T(ldr) r3, [r1], #4)
ldmneia r1!, {r3 - r4} @ Shouldnt fault
stmneia r0!, {r3 - r4}
tst ip, #4
- T(ldrne) r3, [r1], #4 @ Shouldnt fault
+ TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault
strne r3, [r0], #4
ands ip, ip, #3
beq .Lcfu_0fupi
.Lcfu_0nowords: teq ip, #0
beq .Lcfu_finished
.Lcfu_nowords: cmp ip, #2
-USER( T(ldrb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrb) r3, [r1], #1) @ May fault
strb r3, [r0], #1
-USER( T(ldrgeb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( T(ldrgtb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
b .Lcfu_finished
@@ -375,7 +375,7 @@ USER( T(ldrgtb) r3, [r1], #1) @ May fault
.Lcfu_src_not_aligned:
bic r1, r1, #3
-USER( T(ldr) r7, [r1], #4) @ May fault
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
cmp ip, #2
bgt .Lcfu_3fupi
beq .Lcfu_2fupi
@@ -383,7 +383,7 @@ USER( T(ldr) r7, [r1], #4) @ May fault
addmi ip, r2, #4
bmi .Lcfu_1nowords
mov r3, r7, pull #8
-USER( T(ldr) r7, [r1], #4) @ May fault
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #24
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -418,7 +418,7 @@ USER( T(ldr) r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, pull #8
-USER( T(ldrne) r7, [r1], #4) @ May fault
+USER( TUSER( ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #24
strne r3, [r0], #4
ands ip, ip, #3
@@ -438,7 +438,7 @@ USER( T(ldrne) r7, [r1], #4) @ May fault
addmi ip, r2, #4
bmi .Lcfu_2nowords
mov r3, r7, pull #16
-USER( T(ldr) r7, [r1], #4) @ May fault
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #16
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -474,7 +474,7 @@ USER( T(ldr) r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, pull #16
-USER( T(ldrne) r7, [r1], #4) @ May fault
+USER( TUSER( ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #16
strne r3, [r0], #4
ands ip, ip, #3
@@ -486,7 +486,7 @@ USER( T(ldrne) r7, [r1], #4) @ May fault
strb r3, [r0], #1
movge r3, r7, get_byte_3
strgeb r3, [r0], #1
-USER( T(ldrgtb) r3, [r1], #0) @ May fault
+USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault
strgtb r3, [r0], #1
b .Lcfu_finished
@@ -494,7 +494,7 @@ USER( T(ldrgtb) r3, [r1], #0) @ May fault
addmi ip, r2, #4
bmi .Lcfu_3nowords
mov r3, r7, pull #24
-USER( T(ldr) r7, [r1], #4) @ May fault
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #8
str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -529,7 +529,7 @@ USER( T(ldr) r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4}
tst ip, #4
movne r3, r7, pull #24
-USER( T(ldrne) r7, [r1], #4) @ May fault
+USER( TUSER( ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #8
strne r3, [r0], #4
ands ip, ip, #3
@@ -539,9 +539,9 @@ USER( T(ldrne) r7, [r1], #4) @ May fault
beq .Lcfu_finished
cmp ip, #2
strb r3, [r0], #1
-USER( T(ldrgeb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1
-USER( T(ldrgtb) r3, [r1], #1) @ May fault
+USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1
b .Lcfu_finished
ENDPROC(__copy_from_user)
diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig
index 4f991f295284..71feb00a1e99 100644
--- a/trunk/arch/arm/mach-at91/Kconfig
+++ b/trunk/arch/arm/mach-at91/Kconfig
@@ -18,6 +18,12 @@ config HAVE_AT91_USART4
config HAVE_AT91_USART5
bool
+config AT91_SAM9_ALT_RESET
+ bool
+
+config AT91_SAM9G45_RESET
+ bool
+
menu "Atmel AT91 System-on-Chip"
choice
@@ -39,6 +45,7 @@ config ARCH_AT91SAM9260
select HAVE_AT91_USART4
select HAVE_AT91_USART5
select HAVE_NET_MACB
+ select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9261
bool "AT91SAM9261"
@@ -46,6 +53,7 @@ config ARCH_AT91SAM9261
select GENERIC_CLOCKEVENTS
select HAVE_FB_ATMEL
select HAVE_AT91_DBGU0
+ select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9G10
bool "AT91SAM9G10"
@@ -53,6 +61,7 @@ config ARCH_AT91SAM9G10
select GENERIC_CLOCKEVENTS
select HAVE_AT91_DBGU0
select HAVE_FB_ATMEL
+ select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9263
bool "AT91SAM9263"
@@ -61,6 +70,7 @@ config ARCH_AT91SAM9263
select HAVE_FB_ATMEL
select HAVE_NET_MACB
select HAVE_AT91_DBGU1
+ select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
@@ -69,6 +79,7 @@ config ARCH_AT91SAM9RL
select HAVE_AT91_USART3
select HAVE_FB_ATMEL
select HAVE_AT91_DBGU0
+ select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9G20
bool "AT91SAM9G20"
@@ -79,6 +90,7 @@ config ARCH_AT91SAM9G20
select HAVE_AT91_USART4
select HAVE_AT91_USART5
select HAVE_NET_MACB
+ select AT91_SAM9_ALT_RESET
config ARCH_AT91SAM9G45
bool "AT91SAM9G45"
@@ -88,6 +100,7 @@ config ARCH_AT91SAM9G45
select HAVE_FB_ATMEL
select HAVE_NET_MACB
select HAVE_AT91_DBGU1
+ select AT91_SAM9G45_RESET
config ARCH_AT91CAP9
bool "AT91CAP9"
@@ -96,6 +109,7 @@ config ARCH_AT91CAP9
select HAVE_FB_ATMEL
select HAVE_NET_MACB
select HAVE_AT91_DBGU1
+ select AT91_SAM9G45_RESET
config ARCH_AT91X40
bool "AT91x40"
diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile
index 242174f9f355..705e1fbded39 100644
--- a/trunk/arch/arm/mach-at91/Makefile
+++ b/trunk/arch/arm/mach-at91/Makefile
@@ -8,15 +8,17 @@ obj-n :=
obj- :=
obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
+obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
+obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
# CPU-specific support
obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
-obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
diff --git a/trunk/arch/arm/mach-at91/at91cap9.c b/trunk/arch/arm/mach-at91/at91cap9.c
index edb879ac04c8..a42edc25a87e 100644
--- a/trunk/arch/arm/mach-at91/at91cap9.c
+++ b/trunk/arch/arm/mach-at91/at91cap9.c
@@ -21,7 +21,6 @@
#include
#include
#include
-#include
#include "soc.h"
#include "generic.h"
@@ -314,11 +313,6 @@ static struct at91_gpio_bank at91cap9_gpio[] __initdata = {
}
};
-static void at91cap9_restart(char mode, const char *cmd)
-{
- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
/* --------------------------------------------------------------------
* AT91CAP9 processor initialization
* -------------------------------------------------------------------- */
@@ -331,13 +325,14 @@ static void __init at91cap9_map_io(void)
static void __init at91cap9_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC);
+ at91_ioremap_rstc(AT91CAP9_BASE_RSTC);
at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT);
at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC);
}
static void __init at91cap9_initialize(void)
{
- arm_pm_restart = at91cap9_restart;
+ arm_pm_restart = at91sam9g45_restart;
at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
/* Register GPIO subsystem */
diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c
index 5e46e4a96430..d4036ba43612 100644
--- a/trunk/arch/arm/mach-at91/at91sam9260.c
+++ b/trunk/arch/arm/mach-at91/at91sam9260.c
@@ -323,6 +323,7 @@ static void __init at91sam9260_map_io(void)
static void __init at91sam9260_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
+ at91_ioremap_rstc(AT91SAM9260_BASE_RSTC);
at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
}
diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c
index b85b9ea60170..023c2ff138df 100644
--- a/trunk/arch/arm/mach-at91/at91sam9261.c
+++ b/trunk/arch/arm/mach-at91/at91sam9261.c
@@ -281,6 +281,7 @@ static void __init at91sam9261_map_io(void)
static void __init at91sam9261_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
+ at91_ioremap_rstc(AT91SAM9261_BASE_RSTC);
at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
}
diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c
index 79e3669b1117..75e876c258af 100644
--- a/trunk/arch/arm/mach-at91/at91sam9263.c
+++ b/trunk/arch/arm/mach-at91/at91sam9263.c
@@ -301,6 +301,7 @@ static void __init at91sam9263_map_io(void)
static void __init at91sam9263_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
+ at91_ioremap_rstc(AT91SAM9263_BASE_RSTC);
at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0);
at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
diff --git a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S
index d3f931c5942e..518e42377171 100644
--- a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S
+++ b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S
@@ -23,7 +23,8 @@
.globl at91sam9_alt_restart
at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants
- ldr r1, .at91_va_base_rstc_cr
+ ldr r1, =at91_rstc_base
+ ldr r1, [r1]
mov r2, #1
mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
@@ -33,11 +34,9 @@ at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants
str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
- str r4, [r1] @ reset processor
+ str r4, [r1, #AT91_RSTC_CR] @ reset processor
b .
.at91_va_base_sdramc:
.word AT91_VA_BASE_SYS + AT91_SDRAMC0
-.at91_va_base_rstc_cr:
- .word AT91_VA_BASE_SYS + AT91_RSTC_CR
diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c
index 7032dd32cdf0..1cb6a96b1c1e 100644
--- a/trunk/arch/arm/mach-at91/at91sam9g45.c
+++ b/trunk/arch/arm/mach-at91/at91sam9g45.c
@@ -18,7 +18,6 @@
#include
#include
#include
-#include
#include
#include "soc.h"
@@ -318,11 +317,6 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = {
}
};
-static void at91sam9g45_restart(char mode, const char *cmd)
-{
- at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
-}
-
/* --------------------------------------------------------------------
* AT91SAM9G45 processor initialization
* -------------------------------------------------------------------- */
@@ -336,6 +330,7 @@ static void __init at91sam9g45_map_io(void)
static void __init at91sam9g45_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
+ at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC);
at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC);
}
diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_reset.S b/trunk/arch/arm/mach-at91/at91sam9g45_reset.S
new file mode 100644
index 000000000000..0468be10980b
--- /dev/null
+++ b/trunk/arch/arm/mach-at91/at91sam9g45_reset.S
@@ -0,0 +1,40 @@
+/*
+ * reset AT91SAM9G45 as per errata
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD
+ *
+ * unless the SDRAM is cleanly shutdown before we hit the
+ * reset register it can be left driving the data bus and
+ * killing the chance of a subsequent boot from NAND
+ *
+ * GPLv2 Only
+ */
+
+#include
+#include
+#include
+#include
+
+ .arm
+
+ .globl at91sam9g45_restart
+
+at91sam9g45_restart:
+ ldr r0, .at91_va_base_sdramc0 @ preload constants
+ ldr r1, =at91_rstc_base
+ ldr r1, [r1]
+
+ mov r2, #1
+ mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN
+ ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
+
+ .balign 32 @ align to cache line
+
+ str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access
+ str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0
+ str r4, [r1, #AT91_RSTC_CR] @ reset processor
+
+ b .
+
+.at91_va_base_sdramc0:
+ .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c
index d6bcb1da11df..d2c91a841cb8 100644
--- a/trunk/arch/arm/mach-at91/at91sam9rl.c
+++ b/trunk/arch/arm/mach-at91/at91sam9rl.c
@@ -286,6 +286,7 @@ static void __init at91sam9rl_map_io(void)
static void __init at91sam9rl_ioremap_registers(void)
{
at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
+ at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC);
at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
}
diff --git a/trunk/arch/arm/mach-at91/generic.h b/trunk/arch/arm/mach-at91/generic.h
index 4866b8180d66..594133451c0c 100644
--- a/trunk/arch/arm/mach-at91/generic.h
+++ b/trunk/arch/arm/mach-at91/generic.h
@@ -58,7 +58,9 @@ extern void at91_irq_suspend(void);
extern void at91_irq_resume(void);
/* reset */
+extern void at91_ioremap_rstc(u32 base_addr);
extern void at91sam9_alt_restart(char, const char *);
+extern void at91sam9g45_restart(char, const char *);
/* shutdown */
extern void at91_ioremap_shdwc(u32 base_addr);
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h b/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h
index cbd2bf052c1f..875fa336800b 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h
@@ -16,13 +16,25 @@
#ifndef AT91_RSTC_H
#define AT91_RSTC_H
-#define AT91_RSTC_CR (AT91_RSTC + 0x00) /* Reset Controller Control Register */
+#ifndef __ASSEMBLY__
+extern void __iomem *at91_rstc_base;
+
+#define at91_rstc_read(field) \
+ __raw_readl(at91_rstc_base + field)
+
+#define at91_rstc_write(field, value) \
+ __raw_writel(value, at91_rstc_base + field);
+#else
+.extern at91_rstc_base
+#endif
+
+#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */
#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
-#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */
+#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */
#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */
#define AT91_RSTC_RSTTYP_GENERAL (0 << 8)
@@ -33,7 +45,7 @@
#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */
#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */
-#define AT91_RSTC_MR (AT91_RSTC + 0x08) /* Reset Controller Mode Register */
+#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91cap9.h b/trunk/arch/arm/mach-at91/include/mach/at91cap9.h
index 4c0e2f6011d7..61d952902f2b 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91cap9.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91cap9.h
@@ -83,7 +83,6 @@
#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_GPBR (cpu_is_at91cap9_revB() ? \
(0xfffffd50 - AT91_BASE_SYS) : \
(0xfffffd60 - AT91_BASE_SYS))
@@ -96,6 +95,7 @@
#define AT91CAP9_BASE_PIOB 0xfffff400
#define AT91CAP9_BASE_PIOC 0xfffff600
#define AT91CAP9_BASE_PIOD 0xfffff800
+#define AT91CAP9_BASE_RSTC 0xfffffd00
#define AT91CAP9_BASE_SHDWC 0xfffffd10
#define AT91CAP9_BASE_RTT 0xfffffd20
#define AT91CAP9_BASE_PIT 0xfffffd30
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
deleted file mode 100644
index 976f4a6c3353..000000000000
--- a/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
- *
- * (C) 2008 Andrew Victor
- *
- * DDR/SDR Controller (DDRSDRC) - System peripherals registers.
- * Based on AT91CAP9 datasheet revision B.
- *
- * 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.
- */
-
-#ifndef AT91CAP9_DDRSDR_H
-#define AT91CAP9_DDRSDR_H
-
-#define AT91_DDRSDRC_MR 0x00 /* Mode Register */
-#define AT91_DDRSDRC_MODE (0xf << 0) /* Command Mode */
-#define AT91_DDRSDRC_MODE_NORMAL 0
-#define AT91_DDRSDRC_MODE_NOP 1
-#define AT91_DDRSDRC_MODE_PRECHARGE 2
-#define AT91_DDRSDRC_MODE_LMR 3
-#define AT91_DDRSDRC_MODE_REFRESH 4
-#define AT91_DDRSDRC_MODE_EXT_LMR 5
-#define AT91_DDRSDRC_MODE_DEEP 6
-
-#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */
-#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */
-
-#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */
-#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */
-#define AT91_DDRSDRC_NC_SDR8 (0 << 0)
-#define AT91_DDRSDRC_NC_SDR9 (1 << 0)
-#define AT91_DDRSDRC_NC_SDR10 (2 << 0)
-#define AT91_DDRSDRC_NC_SDR11 (3 << 0)
-#define AT91_DDRSDRC_NC_DDR9 (0 << 0)
-#define AT91_DDRSDRC_NC_DDR10 (1 << 0)
-#define AT91_DDRSDRC_NC_DDR11 (2 << 0)
-#define AT91_DDRSDRC_NC_DDR12 (3 << 0)
-#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */
-#define AT91_DDRSDRC_NR_11 (0 << 2)
-#define AT91_DDRSDRC_NR_12 (1 << 2)
-#define AT91_DDRSDRC_NR_13 (2 << 2)
-#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */
-#define AT91_DDRSDRC_CAS_2 (2 << 4)
-#define AT91_DDRSDRC_CAS_3 (3 << 4)
-#define AT91_DDRSDRC_CAS_25 (6 << 4)
-#define AT91_DDRSDRC_DLL (1 << 7) /* Reset DLL */
-#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
-
-#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
-#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
-#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */
-#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */
-#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */
-#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
-#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
-#define AT91_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */
-#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
-
-#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
-#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */
-#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */
-#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
-#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
-
-#define AT91_DDRSDRC_LPR 0x18 /* Low Power Register */
-#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
-#define AT91_DDRSDRC_LPCB_DISABLE 0
-#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
-#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
-#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
-#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
-#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
-#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
-#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
-#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */
-#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12)
-#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12)
-#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12)
-
-#define AT91_DDRSDRC_MDR 0x1C /* Memory Device Register */
-#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
-#define AT91_DDRSDRC_MD_SDR 0
-#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
-#define AT91_DDRSDRC_MD_DDR 2
-#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
-
-#define AT91_DDRSDRC_DLLR 0x20 /* DLL Information Register */
-#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
-#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
-#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
-#define AT91_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */
-#define AT91_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */
-#define AT91_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */
-#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
-#define AT91_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */
-#define AT91_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */
-
-/* Register access macros */
-#define at91_ramc_read(num, reg) \
- at91_sys_read(AT91_DDRSDRC##num + reg)
-#define at91_ramc_write(num, reg, value) \
- at91_sys_write(AT91_DDRSDRC##num + reg, value)
-
-
-#endif
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h
index f937c476bb67..fa5ca278adeb 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -83,7 +83,6 @@
#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
#define AT91SAM9260_BASE_ECC 0xffffe800
@@ -92,6 +91,7 @@
#define AT91SAM9260_BASE_PIOA 0xfffff400
#define AT91SAM9260_BASE_PIOB 0xfffff600
#define AT91SAM9260_BASE_PIOC 0xfffff800
+#define AT91SAM9260_BASE_RSTC 0xfffffd00
#define AT91SAM9260_BASE_SHDWC 0xfffffd10
#define AT91SAM9260_BASE_RTT 0xfffffd20
#define AT91SAM9260_BASE_PIT 0xfffffd30
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h
index 175604e261be..7cde2d36570e 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -68,7 +68,6 @@
#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
#define AT91SAM9261_BASE_SMC 0xffffec00
@@ -76,6 +75,7 @@
#define AT91SAM9261_BASE_PIOA 0xfffff400
#define AT91SAM9261_BASE_PIOB 0xfffff600
#define AT91SAM9261_BASE_PIOC 0xfffff800
+#define AT91SAM9261_BASE_RSTC 0xfffffd00
#define AT91SAM9261_BASE_SHDWC 0xfffffd10
#define AT91SAM9261_BASE_RTT 0xfffffd20
#define AT91SAM9261_BASE_PIT 0xfffffd30
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h
index 80c915002d83..5949abda962b 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h
@@ -78,7 +78,6 @@
#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS)
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
#define AT91SAM9263_BASE_ECC0 0xffffe000
@@ -91,6 +90,7 @@
#define AT91SAM9263_BASE_PIOC 0xfffff600
#define AT91SAM9263_BASE_PIOD 0xfffff800
#define AT91SAM9263_BASE_PIOE 0xfffffa00
+#define AT91SAM9263_BASE_RSTC 0xfffffd00
#define AT91SAM9263_BASE_SHDWC 0xfffffd10
#define AT91SAM9263_BASE_RTT0 0xfffffd20
#define AT91SAM9263_BASE_PIT 0xfffffd30
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
index d27b15ba8ebf..e2f8da8ce5bc 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -46,10 +46,10 @@
#define AT91_DDRSDRC_CAS_25 (6 << 4)
#define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */
#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
-#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL */
-#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver */
-#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared */
-#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y */
+#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL [SAM9 Only] */
+#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */
+#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */
+#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */
#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
@@ -59,7 +59,8 @@
#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */
-#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay */
+#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */
+#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */
#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
@@ -68,13 +69,14 @@
#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
-#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register */
+#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register [SAM9 Only] */
#define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */
#define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */
#define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */
#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */
#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */
+#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */
#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
#define AT91_DDRSDRC_LPCB_DISABLE 0
#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
@@ -92,32 +94,40 @@
#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */
#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */
+#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */
#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
#define AT91_DDRSDRC_MD_SDR 0
#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
+#define AT91CAP9_DDRSDRC_MD_DDR 2
#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
-#define AT91_DDRSDRC_MD_DDR2 6
+#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */
#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
#define AT91_DDRSDRC_DBW_32BITS (0 << 4)
#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */
+#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */
#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
+#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */
+#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */
+#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */
#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
+#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */
+#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */
-#define AT91_DDRSDRC_HS 0x2C /* High Speed Register */
+#define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */
#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */
#define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */
-#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register */
+#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register [SAM9 Only] */
#define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */
#define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */
#define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */
-#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register */
+#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register [SAM9 Only] */
#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */
#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h
index f0c23c960dec..dd9c95ea0862 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h
@@ -90,7 +90,6 @@
#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
#define AT91SAM9G45_BASE_ECC 0xffffe200
@@ -102,6 +101,7 @@
#define AT91SAM9G45_BASE_PIOC 0xfffff600
#define AT91SAM9G45_BASE_PIOD 0xfffff800
#define AT91SAM9G45_BASE_PIOE 0xfffffa00
+#define AT91SAM9G45_BASE_RSTC 0xfffffd00
#define AT91SAM9G45_BASE_SHDWC 0xfffffd10
#define AT91SAM9G45_BASE_RTT 0xfffffd20
#define AT91SAM9G45_BASE_PIT 0xfffffd30
diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h
index 2bb359e60b97..d7bead7118da 100644
--- a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h
+++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h
@@ -72,7 +72,6 @@
#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
#define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS)
#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
@@ -84,6 +83,7 @@
#define AT91SAM9RL_BASE_PIOB 0xfffff600
#define AT91SAM9RL_BASE_PIOC 0xfffff800
#define AT91SAM9RL_BASE_PIOD 0xfffffa00
+#define AT91SAM9RL_BASE_RSTC 0xfffffd00
#define AT91SAM9RL_BASE_SHDWC 0xfffffd10
#define AT91SAM9RL_BASE_RTT 0xfffffd20
#define AT91SAM9RL_BASE_PIT 0xfffffd30
diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h
index d0b377b21bd7..3b33f07b1e11 100644
--- a/trunk/arch/arm/mach-at91/include/mach/board.h
+++ b/trunk/arch/arm/mach-at91/include/mach/board.h
@@ -88,7 +88,7 @@ extern void __init at91_add_device_eth(struct macb_platform_data *data);
struct at91_usbh_data {
u8 ports; /* number of ports on root hub */
int vbus_pin[2]; /* port power-control pin */
- u8 vbus_pin_inverted;
+ u8 vbus_pin_active_low[2];
u8 overcurrent_supported;
int overcurrent_pin[2];
u8 overcurrent_status[2];
diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c
index 62ad95556c36..1606379ac284 100644
--- a/trunk/arch/arm/mach-at91/pm.c
+++ b/trunk/arch/arm/mach-at91/pm.c
@@ -34,7 +34,6 @@
/*
* Show the reason for the previous system reset.
*/
-#if defined(AT91_RSTC)
#include
#include
@@ -58,10 +57,10 @@ static void __init show_reset_status(void)
char *reason, *r2 = reset;
u32 reset_type, wake_type;
- if (!at91_shdwc_base)
+ if (!at91_shdwc_base || !at91_rstc_base)
return;
- reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
+ reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
wake_type = at91_shdwc_read(AT91_SHDW_SR);
switch (reset_type) {
@@ -102,10 +101,6 @@ static void __init show_reset_status(void)
}
pr_info("AT91: Starting after %s %s\n", reason, r2);
}
-#else
-static void __init show_reset_status(void) {}
-#endif
-
static int at91_pm_valid_state(suspend_state_t state)
{
diff --git a/trunk/arch/arm/mach-at91/pm.h b/trunk/arch/arm/mach-at91/pm.h
index ce9a20699111..7eb40d24242f 100644
--- a/trunk/arch/arm/mach-at91/pm.h
+++ b/trunk/arch/arm/mach-at91/pm.h
@@ -25,21 +25,21 @@ static inline u32 sdram_selfrefresh_enable(void)
: : "r" (0))
#elif defined(CONFIG_ARCH_AT91CAP9)
-#include
+#include
static inline u32 sdram_selfrefresh_enable(void)
{
u32 saved_lpr, lpr;
- saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+ saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR);
lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
- at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+ at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
return saved_lpr;
}
-#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr)
+#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr)
#define wait_for_interrupt_enable() cpu_do_idle()
#elif defined(CONFIG_ARCH_AT91SAM9G45)
diff --git a/trunk/arch/arm/mach-at91/pm_slowclock.S b/trunk/arch/arm/mach-at91/pm_slowclock.S
index f7922a436172..92dfb8461392 100644
--- a/trunk/arch/arm/mach-at91/pm_slowclock.S
+++ b/trunk/arch/arm/mach-at91/pm_slowclock.S
@@ -18,9 +18,8 @@
#if defined(CONFIG_ARCH_AT91RM9200)
#include
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include
-#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
#include
#else
#include
diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c
index 8bdcc3cb6012..69d3fc4c46f3 100644
--- a/trunk/arch/arm/mach-at91/setup.c
+++ b/trunk/arch/arm/mach-at91/setup.c
@@ -29,9 +29,12 @@ EXPORT_SYMBOL(at91_soc_initdata);
void __init at91rm9200_set_type(int type)
{
if (type == ARCH_REVISON_9200_PQFP)
- at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
- else
at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
+ else
+ at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
+
+ pr_info("AT91: filled in soc subtype: %s\n",
+ at91_get_soc_subtype(&at91_soc_initdata));
}
void __init at91_init_irq_default(void)
@@ -281,6 +284,15 @@ void __init at91_ioremap_shdwc(u32 base_addr)
pm_power_off = at91sam9_poweroff;
}
+void __iomem *at91_rstc_base;
+
+void __init at91_ioremap_rstc(u32 base_addr)
+{
+ at91_rstc_base = ioremap(base_addr, 16);
+ if (!at91_rstc_base)
+ panic("Impossible to ioremap at91_rstc_base\n");
+}
+
void __init at91_initialize(unsigned long main_clock)
{
at91_boot_soc.ioremap_registers();
diff --git a/trunk/arch/arm/mach-bcmring/arch.c b/trunk/arch/arm/mach-bcmring/arch.c
index 9e5e7552498c..45c97b1ee9b1 100644
--- a/trunk/arch/arm/mach-bcmring/arch.c
+++ b/trunk/arch/arm/mach-bcmring/arch.c
@@ -194,6 +194,6 @@ MACHINE_START(BCMRING, "BCMRING")
.init_early = bcmring_init_early,
.init_irq = bcmring_init_irq,
.timer = &bcmring_timer,
- .init_machine = bcmring_init_machine
+ .init_machine = bcmring_init_machine,
.restart = bcmring_restart,
MACHINE_END
diff --git a/trunk/arch/arm/mach-bcmring/dma.c b/trunk/arch/arm/mach-bcmring/dma.c
index 1a1a27dd5654..1024396797e1 100644
--- a/trunk/arch/arm/mach-bcmring/dma.c
+++ b/trunk/arch/arm/mach-bcmring/dma.c
@@ -33,17 +33,11 @@
#include
-#include
#include
#include
#include
#include
-/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
-/* especially since dc4 doesn't use kmalloc'd memory. */
-
-#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
-
/* ---- Public Variables ------------------------------------------------- */
/* ---- Private Constants and Types -------------------------------------- */
@@ -53,58 +47,18 @@
#define CONTROLLER_FROM_HANDLE(handle) (((handle) >> 4) & 0x0f)
#define CHANNEL_FROM_HANDLE(handle) ((handle) & 0x0f)
-#define DMA_MAP_DEBUG 0
-
-#if DMA_MAP_DEBUG
-# define DMA_MAP_PRINT(fmt, args...) printk("%s: " fmt, __func__, ## args)
-#else
-# define DMA_MAP_PRINT(fmt, args...)
-#endif
/* ---- Private Variables ------------------------------------------------ */
static DMA_Global_t gDMA;
static struct proc_dir_entry *gDmaDir;
-static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
-static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
-
#include "dma_device.c"
/* ---- Private Function Prototypes -------------------------------------- */
/* ---- Functions ------------------------------------------------------- */
-/****************************************************************************/
-/**
-* Displays information for /proc/dma/mem-type
-*/
-/****************************************************************************/
-
-static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
- int count, int *eof, void *data)
-{
- int len = 0;
-
- len += sprintf(buf + len, "dma_map_mem statistics\n");
- len +=
- sprintf(buf + len, "coherent: %d\n",
- atomic_read(&gDmaStatMemTypeCoherent));
- len +=
- sprintf(buf + len, "kmalloc: %d\n",
- atomic_read(&gDmaStatMemTypeKmalloc));
- len +=
- sprintf(buf + len, "vmalloc: %d\n",
- atomic_read(&gDmaStatMemTypeVmalloc));
- len +=
- sprintf(buf + len, "user: %d\n",
- atomic_read(&gDmaStatMemTypeUser));
-
- return len;
-}
-
/****************************************************************************/
/**
* Displays information for /proc/dma/channels
@@ -846,8 +800,6 @@ int dma_init(void)
dma_proc_read_channels, NULL);
create_proc_read_entry("devices", 0, gDmaDir,
dma_proc_read_devices, NULL);
- create_proc_read_entry("mem-type", 0, gDmaDir,
- dma_proc_read_mem_type, NULL);
}
out:
@@ -1565,767 +1517,3 @@ int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for.
}
EXPORT_SYMBOL(dma_set_device_handler);
-
-/****************************************************************************/
-/**
-* Initializes a memory mapping structure
-*/
-/****************************************************************************/
-
-int dma_init_mem_map(DMA_MemMap_t *memMap)
-{
- memset(memMap, 0, sizeof(*memMap));
-
- sema_init(&memMap->lock, 1);
-
- return 0;
-}
-
-EXPORT_SYMBOL(dma_init_mem_map);
-
-/****************************************************************************/
-/**
-* Releases any memory currently being held by a memory mapping structure.
-*/
-/****************************************************************************/
-
-int dma_term_mem_map(DMA_MemMap_t *memMap)
-{
- down(&memMap->lock); /* Just being paranoid */
-
- /* Free up any allocated memory */
-
- up(&memMap->lock);
- memset(memMap, 0, sizeof(*memMap));
-
- return 0;
-}
-
-EXPORT_SYMBOL(dma_term_mem_map);
-
-/****************************************************************************/
-/**
-* Looks at a memory address and categorizes it.
-*
-* @return One of the values from the DMA_MemType_t enumeration.
-*/
-/****************************************************************************/
-
-DMA_MemType_t dma_mem_type(void *addr)
-{
- unsigned long addrVal = (unsigned long)addr;
-
- if (addrVal >= CONSISTENT_BASE) {
- /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
-
- /* dma_alloc_xxx pages are physically and virtually contiguous */
-
- return DMA_MEM_TYPE_DMA;
- }
-
- /* Technically, we could add one more classification. Addresses between VMALLOC_END */
- /* and the beginning of the DMA virtual address could be considered to be I/O space. */
- /* Right now, nobody cares about this particular classification, so we ignore it. */
-
- if (is_vmalloc_addr(addr)) {
- /* Address comes from the vmalloc'd region. Pages are virtually */
- /* contiguous but NOT physically contiguous */
-
- return DMA_MEM_TYPE_VMALLOC;
- }
-
- if (addrVal >= PAGE_OFFSET) {
- /* PAGE_OFFSET is typically 0xC0000000 */
-
- /* kmalloc'd pages are physically contiguous */
-
- return DMA_MEM_TYPE_KMALLOC;
- }
-
- return DMA_MEM_TYPE_USER;
-}
-
-EXPORT_SYMBOL(dma_mem_type);
-
-/****************************************************************************/
-/**
-* Looks at a memory address and determines if we support DMA'ing to/from
-* that type of memory.
-*
-* @return boolean -
-* return value != 0 means dma supported
-* return value == 0 means dma not supported
-*/
-/****************************************************************************/
-
-int dma_mem_supports_dma(void *addr)
-{
- DMA_MemType_t memType = dma_mem_type(addr);
-
- return (memType == DMA_MEM_TYPE_DMA)
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
- || (memType == DMA_MEM_TYPE_KMALLOC)
-#endif
- || (memType == DMA_MEM_TYPE_USER);
-}
-
-EXPORT_SYMBOL(dma_mem_supports_dma);
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- ) {
- int rc;
-
- down(&memMap->lock);
-
- DMA_MAP_PRINT("memMap: %p\n", memMap);
-
- if (memMap->inUse) {
- printk(KERN_ERR "%s: memory map %p is already being used\n",
- __func__, memMap);
- rc = -EBUSY;
- goto out;
- }
-
- memMap->inUse = 1;
- memMap->dir = dir;
- memMap->numRegionsUsed = 0;
-
- rc = 0;
-
-out:
-
- DMA_MAP_PRINT("returning %d", rc);
-
- up(&memMap->lock);
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_start);
-
-/****************************************************************************/
-/**
-* Adds a segment of memory to a memory map. Each segment is both
-* physically and virtually contiguous.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-static int dma_map_add_segment(DMA_MemMap_t *memMap, /* Stores state information about the map */
- DMA_Region_t *region, /* Region that the segment belongs to */
- void *virtAddr, /* Virtual address of the segment being added */
- dma_addr_t physAddr, /* Physical address of the segment being added */
- size_t numBytes /* Number of bytes of the segment being added */
- ) {
- DMA_Segment_t *segment;
-
- DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
- physAddr, numBytes);
-
- /* Sanity check */
-
- if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
- || (((unsigned long)virtAddr + numBytes)) >
- ((unsigned long)region->virtAddr + region->numBytes)) {
- printk(KERN_ERR
- "%s: virtAddr %p is outside region @ %p len: %d\n",
- __func__, virtAddr, region->virtAddr, region->numBytes);
- return -EINVAL;
- }
-
- if (region->numSegmentsUsed > 0) {
- /* Check to see if this segment is physically contiguous with the previous one */
-
- segment = ®ion->segment[region->numSegmentsUsed - 1];
-
- if ((segment->physAddr + segment->numBytes) == physAddr) {
- /* It is - just add on to the end */
-
- DMA_MAP_PRINT("appending %d bytes to last segment\n",
- numBytes);
-
- segment->numBytes += numBytes;
-
- return 0;
- }
- }
-
- /* Reallocate to hold more segments, if required. */
-
- if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
- DMA_Segment_t *newSegment;
- size_t oldSize =
- region->numSegmentsAllocated * sizeof(*newSegment);
- int newAlloc = region->numSegmentsAllocated + 4;
- size_t newSize = newAlloc * sizeof(*newSegment);
-
- newSegment = kmalloc(newSize, GFP_KERNEL);
- if (newSegment == NULL) {
- return -ENOMEM;
- }
- memcpy(newSegment, region->segment, oldSize);
- memset(&((uint8_t *) newSegment)[oldSize], 0,
- newSize - oldSize);
- kfree(region->segment);
-
- region->numSegmentsAllocated = newAlloc;
- region->segment = newSegment;
- }
-
- segment = ®ion->segment[region->numSegmentsUsed];
- region->numSegmentsUsed++;
-
- segment->virtAddr = virtAddr;
- segment->physAddr = physAddr;
- segment->numBytes = numBytes;
-
- DMA_MAP_PRINT("returning success\n");
-
- return 0;
-}
-
-/****************************************************************************/
-/**
-* Adds a region of memory to a memory map. Each region is virtually
-* contiguous, but not necessarily physically contiguous.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *mem, /* Virtual address that we want to get a map of */
- size_t numBytes /* Number of bytes being mapped */
- ) {
- unsigned long addr = (unsigned long)mem;
- unsigned int offset;
- int rc = 0;
- DMA_Region_t *region;
- dma_addr_t physAddr;
-
- down(&memMap->lock);
-
- DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
-
- if (!memMap->inUse) {
- printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
- __func__);
- rc = -EINVAL;
- goto out;
- }
-
- /* Reallocate to hold more regions. */
-
- if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
- DMA_Region_t *newRegion;
- size_t oldSize =
- memMap->numRegionsAllocated * sizeof(*newRegion);
- int newAlloc = memMap->numRegionsAllocated + 4;
- size_t newSize = newAlloc * sizeof(*newRegion);
-
- newRegion = kmalloc(newSize, GFP_KERNEL);
- if (newRegion == NULL) {
- rc = -ENOMEM;
- goto out;
- }
- memcpy(newRegion, memMap->region, oldSize);
- memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
-
- kfree(memMap->region);
-
- memMap->numRegionsAllocated = newAlloc;
- memMap->region = newRegion;
- }
-
- region = &memMap->region[memMap->numRegionsUsed];
- memMap->numRegionsUsed++;
-
- offset = addr & ~PAGE_MASK;
-
- region->memType = dma_mem_type(mem);
- region->virtAddr = mem;
- region->numBytes = numBytes;
- region->numSegmentsUsed = 0;
- region->numLockedPages = 0;
- region->lockedPages = NULL;
-
- switch (region->memType) {
- case DMA_MEM_TYPE_VMALLOC:
- {
- atomic_inc(&gDmaStatMemTypeVmalloc);
-
- /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
-
- /* vmalloc'd pages are not physically contiguous */
-
- rc = -EINVAL;
- break;
- }
-
- case DMA_MEM_TYPE_KMALLOC:
- {
- atomic_inc(&gDmaStatMemTypeKmalloc);
-
- /* kmalloc'd pages are physically contiguous, so they'll have exactly */
- /* one segment */
-
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
- physAddr =
- dma_map_single(NULL, mem, numBytes, memMap->dir);
- rc = dma_map_add_segment(memMap, region, mem, physAddr,
- numBytes);
-#else
- rc = -EINVAL;
-#endif
- break;
- }
-
- case DMA_MEM_TYPE_DMA:
- {
- /* dma_alloc_xxx pages are physically contiguous */
-
- atomic_inc(&gDmaStatMemTypeCoherent);
-
- physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
-
- dma_sync_single_for_cpu(NULL, physAddr, numBytes,
- memMap->dir);
- rc = dma_map_add_segment(memMap, region, mem, physAddr,
- numBytes);
- break;
- }
-
- case DMA_MEM_TYPE_USER:
- {
- size_t firstPageOffset;
- size_t firstPageSize;
- struct page **pages;
- struct task_struct *userTask;
-
- atomic_inc(&gDmaStatMemTypeUser);
-
-#if 1
- /* If the pages are user pages, then the dma_mem_map_set_user_task function */
- /* must have been previously called. */
-
- if (memMap->userTask == NULL) {
- printk(KERN_ERR
- "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
- __func__);
- return -EINVAL;
- }
-
- /* User pages need to be locked. */
-
- firstPageOffset =
- (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
- firstPageSize = PAGE_SIZE - firstPageOffset;
-
- region->numLockedPages = (firstPageOffset
- + region->numBytes +
- PAGE_SIZE - 1) / PAGE_SIZE;
- pages =
- kmalloc(region->numLockedPages *
- sizeof(struct page *), GFP_KERNEL);
-
- if (pages == NULL) {
- region->numLockedPages = 0;
- return -ENOMEM;
- }
-
- userTask = memMap->userTask;
-
- down_read(&userTask->mm->mmap_sem);
- rc = get_user_pages(userTask, /* task */
- userTask->mm, /* mm */
- (unsigned long)region->virtAddr, /* start */
- region->numLockedPages, /* len */
- memMap->dir == DMA_FROM_DEVICE, /* write */
- 0, /* force */
- pages, /* pages (array of pointers to page) */
- NULL); /* vmas */
- up_read(&userTask->mm->mmap_sem);
-
- if (rc != region->numLockedPages) {
- kfree(pages);
- region->numLockedPages = 0;
-
- if (rc >= 0) {
- rc = -EINVAL;
- }
- } else {
- uint8_t *virtAddr = region->virtAddr;
- size_t bytesRemaining;
- int pageIdx;
-
- rc = 0; /* Since get_user_pages returns +ve number */
-
- region->lockedPages = pages;
-
- /* We've locked the user pages. Now we need to walk them and figure */
- /* out the physical addresses. */
-
- /* The first page may be partial */
-
- dma_map_add_segment(memMap,
- region,
- virtAddr,
- PFN_PHYS(page_to_pfn
- (pages[0])) +
- firstPageOffset,
- firstPageSize);
-
- virtAddr += firstPageSize;
- bytesRemaining =
- region->numBytes - firstPageSize;
-
- for (pageIdx = 1;
- pageIdx < region->numLockedPages;
- pageIdx++) {
- size_t bytesThisPage =
- (bytesRemaining >
- PAGE_SIZE ? PAGE_SIZE :
- bytesRemaining);
-
- DMA_MAP_PRINT
- ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
- pageIdx, pages[pageIdx],
- page_to_pfn(pages[pageIdx]),
- PFN_PHYS(page_to_pfn
- (pages[pageIdx])));
-
- dma_map_add_segment(memMap,
- region,
- virtAddr,
- PFN_PHYS(page_to_pfn
- (pages
- [pageIdx])),
- bytesThisPage);
-
- virtAddr += bytesThisPage;
- bytesRemaining -= bytesThisPage;
- }
- }
-#else
- printk(KERN_ERR
- "%s: User mode pages are not yet supported\n",
- __func__);
-
- /* user pages are not physically contiguous */
-
- rc = -EINVAL;
-#endif
- break;
- }
-
- default:
- {
- printk(KERN_ERR "%s: Unsupported memory type: %d\n",
- __func__, region->memType);
-
- rc = -EINVAL;
- break;
- }
- }
-
- if (rc != 0) {
- memMap->numRegionsUsed--;
- }
-
-out:
-
- DMA_MAP_PRINT("returning %d\n", rc);
-
- up(&memMap->lock);
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_add_segment);
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *mem, /* Virtual address that we want to get a map of */
- size_t numBytes, /* Number of bytes being mapped */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- ) {
- int rc;
-
- rc = dma_map_start(memMap, dir);
- if (rc == 0) {
- rc = dma_map_add_region(memMap, mem, numBytes);
- if (rc < 0) {
- /* Since the add fails, this function will fail, and the caller won't */
- /* call unmap, so we need to do it here. */
-
- dma_unmap(memMap, 0);
- }
- }
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_mem);
-
-/****************************************************************************/
-/**
-* Setup a descriptor ring for a given memory map.
-*
-* It is assumed that the descriptor ring has already been initialized, and
-* this routine will only reallocate a new descriptor ring if the existing
-* one is too small.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
- DMA_MemMap_t *memMap, /* Memory map that will be used */
- dma_addr_t devPhysAddr /* Physical address of device */
- ) {
- int rc;
- int numDescriptors;
- DMA_DeviceAttribute_t *devAttr;
- DMA_Region_t *region;
- DMA_Segment_t *segment;
- dma_addr_t srcPhysAddr;
- dma_addr_t dstPhysAddr;
- int regionIdx;
- int segmentIdx;
-
- devAttr = &DMA_gDeviceAttribute[dev];
-
- down(&memMap->lock);
-
- /* Figure out how many descriptors we need */
-
- numDescriptors = 0;
- for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
- region = &memMap->region[regionIdx];
-
- for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
- segmentIdx++) {
- segment = ®ion->segment[segmentIdx];
-
- if (memMap->dir == DMA_TO_DEVICE) {
- srcPhysAddr = segment->physAddr;
- dstPhysAddr = devPhysAddr;
- } else {
- srcPhysAddr = devPhysAddr;
- dstPhysAddr = segment->physAddr;
- }
-
- rc =
- dma_calculate_descriptor_count(dev, srcPhysAddr,
- dstPhysAddr,
- segment->
- numBytes);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_calculate_descriptor_count failed: %d\n",
- __func__, rc);
- goto out;
- }
- numDescriptors += rc;
- }
- }
-
- /* Adjust the size of the ring, if it isn't big enough */
-
- if (numDescriptors > devAttr->ring.descriptorsAllocated) {
- dma_free_descriptor_ring(&devAttr->ring);
- rc =
- dma_alloc_descriptor_ring(&devAttr->ring,
- numDescriptors);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_alloc_descriptor_ring failed: %d\n",
- __func__, rc);
- goto out;
- }
- } else {
- rc =
- dma_init_descriptor_ring(&devAttr->ring,
- numDescriptors);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_init_descriptor_ring failed: %d\n",
- __func__, rc);
- goto out;
- }
- }
-
- /* Populate the descriptors */
-
- for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
- region = &memMap->region[regionIdx];
-
- for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
- segmentIdx++) {
- segment = ®ion->segment[segmentIdx];
-
- if (memMap->dir == DMA_TO_DEVICE) {
- srcPhysAddr = segment->physAddr;
- dstPhysAddr = devPhysAddr;
- } else {
- srcPhysAddr = devPhysAddr;
- dstPhysAddr = segment->physAddr;
- }
-
- rc =
- dma_add_descriptors(&devAttr->ring, dev,
- srcPhysAddr, dstPhysAddr,
- segment->numBytes);
- if (rc < 0) {
- printk(KERN_ERR
- "%s: dma_add_descriptors failed: %d\n",
- __func__, rc);
- goto out;
- }
- }
- }
-
- rc = 0;
-
-out:
-
- up(&memMap->lock);
- return rc;
-}
-
-EXPORT_SYMBOL(dma_map_create_descriptor_ring);
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
- int dirtied /* non-zero if any of the pages were modified */
- ) {
-
- int rc = 0;
- int regionIdx;
- int segmentIdx;
- DMA_Region_t *region;
- DMA_Segment_t *segment;
-
- down(&memMap->lock);
-
- for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
- region = &memMap->region[regionIdx];
-
- for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
- segmentIdx++) {
- segment = ®ion->segment[segmentIdx];
-
- switch (region->memType) {
- case DMA_MEM_TYPE_VMALLOC:
- {
- printk(KERN_ERR
- "%s: vmalloc'd pages are not yet supported\n",
- __func__);
- rc = -EINVAL;
- goto out;
- }
-
- case DMA_MEM_TYPE_KMALLOC:
- {
-#if ALLOW_MAP_OF_KMALLOC_MEMORY
- dma_unmap_single(NULL,
- segment->physAddr,
- segment->numBytes,
- memMap->dir);
-#endif
- break;
- }
-
- case DMA_MEM_TYPE_DMA:
- {
- dma_sync_single_for_cpu(NULL,
- segment->
- physAddr,
- segment->
- numBytes,
- memMap->dir);
- break;
- }
-
- case DMA_MEM_TYPE_USER:
- {
- /* Nothing to do here. */
-
- break;
- }
-
- default:
- {
- printk(KERN_ERR
- "%s: Unsupported memory type: %d\n",
- __func__, region->memType);
- rc = -EINVAL;
- goto out;
- }
- }
-
- segment->virtAddr = NULL;
- segment->physAddr = 0;
- segment->numBytes = 0;
- }
-
- if (region->numLockedPages > 0) {
- int pageIdx;
-
- /* Some user pages were locked. We need to go and unlock them now. */
-
- for (pageIdx = 0; pageIdx < region->numLockedPages;
- pageIdx++) {
- struct page *page =
- region->lockedPages[pageIdx];
-
- if (memMap->dir == DMA_FROM_DEVICE) {
- SetPageDirty(page);
- }
- page_cache_release(page);
- }
- kfree(region->lockedPages);
- region->numLockedPages = 0;
- region->lockedPages = NULL;
- }
-
- region->memType = DMA_MEM_TYPE_NONE;
- region->virtAddr = NULL;
- region->numBytes = 0;
- region->numSegmentsUsed = 0;
- }
- memMap->userTask = NULL;
- memMap->numRegionsUsed = 0;
- memMap->inUse = 0;
-
-out:
- up(&memMap->lock);
-
- return rc;
-}
-
-EXPORT_SYMBOL(dma_unmap);
diff --git a/trunk/arch/arm/mach-bcmring/include/mach/dma.h b/trunk/arch/arm/mach-bcmring/include/mach/dma.h
index 1f2c5319c056..72543781207b 100644
--- a/trunk/arch/arm/mach-bcmring/include/mach/dma.h
+++ b/trunk/arch/arm/mach-bcmring/include/mach/dma.h
@@ -26,15 +26,9 @@
/* ---- Include Files ---------------------------------------------------- */
#include
-#include
#include
#include
#include
-#include
-#include
-#include
-#include
-#include
/* ---- Constants and Types ---------------------------------------------- */
@@ -111,78 +105,6 @@ typedef struct {
} DMA_DescriptorRing_t;
-/****************************************************************************
-*
-* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup
-* DMA chains from a variety of memory sources.
-*
-*****************************************************************************/
-
-#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */
- /* off not being DMA'd. */
-
-typedef enum {
- DMA_MEM_TYPE_NONE, /* Not a valid setting */
- DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */
- DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */
- DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */
- DMA_MEM_TYPE_USER, /* Memory came from user space. */
-
-} DMA_MemType_t;
-
-/* A segment represents a physically and virtually contiguous chunk of memory. */
-/* i.e. each segment can be DMA'd */
-/* A user of the DMA code will add memory regions. Each region may need to be */
-/* represented by one or more segments. */
-
-typedef struct {
- void *virtAddr; /* Virtual address used for this segment */
- dma_addr_t physAddr; /* Physical address this segment maps to */
- size_t numBytes; /* Size of the segment, in bytes */
-
-} DMA_Segment_t;
-
-/* A region represents a virtually contiguous chunk of memory, which may be */
-/* made up of multiple segments. */
-
-typedef struct {
- DMA_MemType_t memType;
- void *virtAddr;
- size_t numBytes;
-
- /* Each region (virtually contiguous) consists of one or more segments. Each */
- /* segment is virtually and physically contiguous. */
-
- int numSegmentsUsed;
- int numSegmentsAllocated;
- DMA_Segment_t *segment;
-
- /* When a region corresponds to user memory, we need to lock all of the pages */
- /* down before we can figure out the physical addresses. The lockedPage array contains */
- /* the pages that were locked, and which subsequently need to be unlocked once the */
- /* memory is unmapped. */
-
- unsigned numLockedPages;
- struct page **lockedPages;
-
-} DMA_Region_t;
-
-typedef struct {
- int inUse; /* Is this mapping currently being used? */
- struct semaphore lock; /* Acquired when using this structure */
- enum dma_data_direction dir; /* Direction this transfer is intended for */
-
- /* In the event that we're mapping user memory, we need to know which task */
- /* the memory is for, so that we can obtain the correct mm locks. */
-
- struct task_struct *userTask;
-
- int numRegionsUsed;
- int numRegionsAllocated;
- DMA_Region_t *region;
-
-} DMA_MemMap_t;
-
/****************************************************************************
*
* The DMA_DeviceAttribute_t contains information which describes a
@@ -568,124 +490,6 @@ int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
size_t numBytes /* Number of bytes in each destination buffer */
);
-/****************************************************************************/
-/**
-* Initializes a DMA_MemMap_t data structure
-*/
-/****************************************************************************/
-
-int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
- );
-
-/****************************************************************************/
-/**
-* Releases any memory currently being held by a memory mapping structure.
-*/
-/****************************************************************************/
-
-int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
- );
-
-/****************************************************************************/
-/**
-* Looks at a memory address and categorizes it.
-*
-* @return One of the values from the DMA_MemType_t enumeration.
-*/
-/****************************************************************************/
-
-DMA_MemType_t dma_mem_type(void *addr);
-
-/****************************************************************************/
-/**
-* Sets the process (aka userTask) associated with a mem map. This is
-* required if user-mode segments will be added to the mapping.
-*/
-/****************************************************************************/
-
-static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
- struct task_struct *task)
-{
- memMap->userTask = task;
-}
-
-/****************************************************************************/
-/**
-* Looks at a memory address and determines if we support DMA'ing to/from
-* that type of memory.
-*
-* @return boolean -
-* return value != 0 means dma supported
-* return value == 0 means dma not supported
-*/
-/****************************************************************************/
-
-int dma_mem_supports_dma(void *addr);
-
-/****************************************************************************/
-/**
-* Initializes a memory map for use. Since this function acquires a
-* sempaphore within the memory map, it is VERY important that dma_unmap
-* be called when you're finished using the map.
-*/
-/****************************************************************************/
-
-int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- );
-
-/****************************************************************************/
-/**
-* Adds a segment of memory to a memory map.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *mem, /* Virtual address that we want to get a map of */
- size_t numBytes /* Number of bytes being mapped */
- );
-
-/****************************************************************************/
-/**
-* Creates a descriptor ring from a memory mapping.
-*
-* @return 0 on success, error code otherwise.
-*/
-/****************************************************************************/
-
-int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
- DMA_MemMap_t *memMap, /* Memory map that will be used */
- dma_addr_t devPhysAddr /* Physical address of device */
- );
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
- void *addr, /* Virtual address that we want to get a map of */
- size_t count, /* Number of bytes being mapped */
- enum dma_data_direction dir /* Direction that the mapping will be going */
- );
-
-/****************************************************************************/
-/**
-* Maps in a memory region such that it can be used for performing a DMA.
-*
-* @return
-*/
-/****************************************************************************/
-
-int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
- int dirtied /* non-zero if any of the pages were modified */
- );
-
/****************************************************************************/
/**
* Initiates a transfer when the descriptors have already been setup.
diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c
index 6b22b543a83f..d5088900af6c 100644
--- a/trunk/arch/arm/mach-davinci/board-da850-evm.c
+++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c
@@ -44,7 +44,7 @@
#include
#include
-#define DA850_EVM_PHY_ID "0:00"
+#define DA850_EVM_PHY_ID "davinci_mdio-0:00"
#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
diff --git a/trunk/arch/arm/mach-davinci/board-dm365-evm.c b/trunk/arch/arm/mach-davinci/board-dm365-evm.c
index 346e1de2f5a8..849311d3cb7c 100644
--- a/trunk/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/trunk/arch/arm/mach-davinci/board-dm365-evm.c
@@ -54,7 +54,7 @@ static inline int have_tvp7002(void)
return 0;
}
-#define DM365_EVM_PHY_ID "0:01"
+#define DM365_EVM_PHY_ID "davinci_mdio-0:01"
/*
* A MAX-II CPLD is used for various board control functions.
*/
diff --git a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c
index a64b49cfedca..1247ecdcf752 100644
--- a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -40,7 +40,7 @@
#include
#include
-#define DM644X_EVM_PHY_ID "0:01"
+#define DM644X_EVM_PHY_ID "davinci_mdio-0:01"
#define LXT971_PHY_ID (0x001378e2)
#define LXT971_PHY_MASK (0xfffffff0)
diff --git a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c
index 64017558860b..872ac69fa049 100644
--- a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -736,7 +736,7 @@ static struct davinci_uart_config uart_config __initdata = {
.enabled_uarts = (1 << 0),
};
-#define DM646X_EVM_PHY_ID "0:01"
+#define DM646X_EVM_PHY_ID "davinci_mdio-0:01"
/*
* The following EDMA channels/slots are not being used by drivers (for
* example: Timer, GPIO, UART events etc) on dm646x, hence they are being
diff --git a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c
index 6c4a16415d47..8d34f513d415 100644
--- a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -39,7 +39,7 @@
#include
#include
-#define NEUROS_OSD2_PHY_ID "0:01"
+#define NEUROS_OSD2_PHY_ID "davinci_mdio-0:01"
#define LXT971_PHY_ID 0x001378e2
#define LXT971_PHY_MASK 0xfffffff0
diff --git a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c
index e7c0c7c53493..45e815760a27 100644
--- a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -21,7 +21,7 @@
#include
#include
-#define HAWKBOARD_PHY_ID "0:07"
+#define HAWKBOARD_PHY_ID "davinci_mdio-0:07"
#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
diff --git a/trunk/arch/arm/mach-davinci/board-sffsdr.c b/trunk/arch/arm/mach-davinci/board-sffsdr.c
index 0b136a831c59..31da3c5b2ba3 100644
--- a/trunk/arch/arm/mach-davinci/board-sffsdr.c
+++ b/trunk/arch/arm/mach-davinci/board-sffsdr.c
@@ -42,7 +42,7 @@
#include
#include
-#define SFFSDR_PHY_ID "0:01"
+#define SFFSDR_PHY_ID "davinci_mdio-0:01"
static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
/* U-Boot Environment: Block 0
* UBL: Block 1
diff --git a/trunk/arch/arm/mach-davinci/da850.c b/trunk/arch/arm/mach-davinci/da850.c
index 0ed7fdb64efb..992c4c410185 100644
--- a/trunk/arch/arm/mach-davinci/da850.c
+++ b/trunk/arch/arm/mach-davinci/da850.c
@@ -153,34 +153,6 @@ static struct clk pll1_sysclk3 = {
.div_reg = PLLDIV3,
};
-static struct clk pll1_sysclk4 = {
- .name = "pll1_sysclk4",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
- .name = "pll1_sysclk5",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
- .name = "pll0_sysclk6",
- .parent = &pll0_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
- .name = "pll1_sysclk7",
- .parent = &pll1_clk,
- .flags = CLK_PLL,
- .div_reg = PLLDIV7,
-};
-
static struct clk i2c0_clk = {
.name = "i2c0",
.parent = &pll0_aux_clk,
@@ -397,10 +369,6 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "pll1_aux", &pll1_aux_clk),
CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
- CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
- CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
- CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
- CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
CLK("i2c_davinci.1", NULL, &i2c0_clk),
CLK(NULL, "timer0", &timerp64_0_clk),
CLK("watchdog", NULL, &timerp64_1_clk),
diff --git a/trunk/arch/arm/mach-exynos/hotplug.c b/trunk/arch/arm/mach-exynos/hotplug.c
index da70e7e39937..dd1ad55524c9 100644
--- a/trunk/arch/arm/mach-exynos/hotplug.c
+++ b/trunk/arch/arm/mach-exynos/hotplug.c
@@ -16,6 +16,7 @@
#include
#include
+#include
#include
diff --git a/trunk/arch/arm/mach-exynos/platsmp.c b/trunk/arch/arm/mach-exynos/platsmp.c
index 683aec786b78..0f2035a1eb6e 100644
--- a/trunk/arch/arm/mach-exynos/platsmp.c
+++ b/trunk/arch/arm/mach-exynos/platsmp.c
@@ -23,6 +23,7 @@
#include
#include
+#include
#include
#include
diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c
index 7afbe1e55beb..8394d512a402 100644
--- a/trunk/arch/arm/mach-highbank/highbank.c
+++ b/trunk/arch/arm/mach-highbank/highbank.c
@@ -25,6 +25,7 @@
#include
#include
+#include
#include
#include
#include
@@ -72,9 +73,7 @@ static void __init highbank_map_io(void)
void highbank_set_cpu_jump(int cpu, void *jump_addr)
{
-#ifdef CONFIG_SMP
cpu = cpu_logical_map(cpu);
-#endif
writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu));
__cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16);
outer_clean_range(HB_JUMP_TABLE_PHYS(cpu),
diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig
index 09f357bcecde..4defb97bbfc8 100644
--- a/trunk/arch/arm/mach-imx/Kconfig
+++ b/trunk/arch/arm/mach-imx/Kconfig
@@ -87,7 +87,6 @@ config SOC_IMX35
config SOC_IMX5
select CPU_V7
- select ARM_L1_CACHE_SHIFT_6
select MXC_TZIC
select ARCH_MXC_IOMUX_V3
select ARCH_MXC_AUDMUX_V2
diff --git a/trunk/arch/arm/mach-imx/clock-imx6q.c b/trunk/arch/arm/mach-imx/clock-imx6q.c
index 9273c2a24b54..2d88f8b9a454 100644
--- a/trunk/arch/arm/mach-imx/clock-imx6q.c
+++ b/trunk/arch/arm/mach-imx/clock-imx6q.c
@@ -814,6 +814,16 @@ DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
+static unsigned long twd_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk twd_clk = {
+ .parent = &arm_clk,
+ .get_rate = twd_clk_get_rate,
+};
+
static unsigned long pll2_200m_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 2;
@@ -1894,6 +1904,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
_REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
_REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
+ _REGISTER_CLOCK("smp_twd", NULL, twd_clk),
_REGISTER_CLOCK(NULL, "ckih", ckih_clk),
_REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
_REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
diff --git a/trunk/arch/arm/mach-imx/mach-mx53_ard.c b/trunk/arch/arm/mach-imx/mach-mx53_ard.c
index 08dfb7628d2d..753f4fc9ec04 100644
--- a/trunk/arch/arm/mach-imx/mach-mx53_ard.c
+++ b/trunk/arch/arm/mach-imx/mach-mx53_ard.c
@@ -188,8 +188,10 @@ static int weim_cs_config(void)
return -ENOMEM;
iomuxc_base = ioremap(MX53_IOMUXC_BASE_ADDR, SZ_4K);
- if (!iomuxc_base)
+ if (!iomuxc_base) {
+ iounmap(weim_base);
return -ENOMEM;
+ }
/* CS1 timings for LAN9220 */
writel(0x20001, (weim_base + 0x18));
diff --git a/trunk/arch/arm/mach-imx/src.c b/trunk/arch/arm/mach-imx/src.c
index 29bd1243781e..e15f1555c59b 100644
--- a/trunk/arch/arm/mach-imx/src.c
+++ b/trunk/arch/arm/mach-imx/src.c
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#define SRC_SCR 0x000
#define SRC_GPR1 0x020
@@ -24,10 +25,6 @@
static void __iomem *src_base;
-#ifndef CONFIG_SMP
-#define cpu_logical_map(cpu) 0
-#endif
-
void imx_enable_cpu(int cpu, bool enable)
{
u32 mask, val;
diff --git a/trunk/arch/arm/mach-msm/hotplug.c b/trunk/arch/arm/mach-msm/hotplug.c
index 41c252de0215..a446fc14221f 100644
--- a/trunk/arch/arm/mach-msm/hotplug.c
+++ b/trunk/arch/arm/mach-msm/hotplug.c
@@ -11,6 +11,7 @@
#include
#include
+#include
extern volatile int pen_release;
diff --git a/trunk/arch/arm/mach-msm/platsmp.c b/trunk/arch/arm/mach-msm/platsmp.c
index 0b3e357c4c8c..db0117ec55f4 100644
--- a/trunk/arch/arm/mach-msm/platsmp.c
+++ b/trunk/arch/arm/mach-msm/platsmp.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig
index a8ba7b96dcd1..d965da45160e 100644
--- a/trunk/arch/arm/mach-omap2/Kconfig
+++ b/trunk/arch/arm/mach-omap2/Kconfig
@@ -33,7 +33,6 @@ config ARCH_OMAP3
default y
select CPU_V7
select USB_ARCH_HAS_EHCI
- select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
select ARCH_HAS_OPP
select PM_OPP if PM
select ARM_CPU_SUSPEND if PM
@@ -214,13 +213,12 @@ config MACH_OMAP3_PANDORA
depends on ARCH_OMAP3
default y
select OMAP_PACKAGE_CBB
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_OMAP3_TOUCHBOOK
bool "OMAP3 Touch Book"
depends on ARCH_OMAP3
default y
- select BACKLIGHT_CLASS_DEVICE
config MACH_OMAP_3430SDP
bool "OMAP 3430 SDP board"
@@ -266,7 +264,7 @@ config MACH_OMAP_ZOOM2
select SERIAL_8250
select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
@@ -276,7 +274,7 @@ config MACH_OMAP_ZOOM3
select SERIAL_8250
select SERIAL_CORE_CONSOLE
select SERIAL_8250_CONSOLE
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_CM_T35
bool "CompuLab CM-T35/CM-T3730 modules"
@@ -335,7 +333,7 @@ config MACH_OMAP_4430SDP
depends on ARCH_OMAP4
select OMAP_PACKAGE_CBL
select OMAP_PACKAGE_CBS
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_OMAP4_PANDA
bool "OMAP4 Panda Board"
@@ -343,7 +341,7 @@ config MACH_OMAP4_PANDA
depends on ARCH_OMAP4
select OMAP_PACKAGE_CBL
select OMAP_PACKAGE_CBS
- select REGULATOR_FIXED_VOLTAGE
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config OMAP3_EMU
bool "OMAP3 debugging peripherals"
diff --git a/trunk/arch/arm/mach-omap2/devices.c b/trunk/arch/arm/mach-omap2/devices.c
index 0b510ad01a00..283d11eae693 100644
--- a/trunk/arch/arm/mach-omap2/devices.c
+++ b/trunk/arch/arm/mach-omap2/devices.c
@@ -405,6 +405,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
break;
default:
pr_err("Invalid McSPI Revision value\n");
+ kfree(pdata);
return -EINVAL;
}
diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c
index 130034bf01d5..dfffbbf4c009 100644
--- a/trunk/arch/arm/mach-omap2/gpmc.c
+++ b/trunk/arch/arm/mach-omap2/gpmc.c
@@ -528,7 +528,13 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
case GPMC_CONFIG_DEV_SIZE:
regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /* clear 2 target bits */
+ regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
+
+ /* set the proper value */
regval |= GPMC_CONFIG1_DEVICESIZE(wval);
+
gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
break;
diff --git a/trunk/arch/arm/mach-omap2/hsmmc.c b/trunk/arch/arm/mach-omap2/hsmmc.c
index bd844af13af5..ad0adb5a1e0e 100644
--- a/trunk/arch/arm/mach-omap2/hsmmc.c
+++ b/trunk/arch/arm/mach-omap2/hsmmc.c
@@ -175,14 +175,15 @@ static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
{
u32 reg;
- if (mmc->slots[0].internal_clock) {
- reg = omap_ctrl_readl(control_devconf1_offset);
+ reg = omap_ctrl_readl(control_devconf1_offset);
+ if (mmc->slots[0].internal_clock)
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
- omap_ctrl_writel(reg, control_devconf1_offset);
- }
+ else
+ reg &= ~OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf1_offset);
}
-static void hsmmc23_before_set_reg(struct device *dev, int slot,
+static void hsmmc2_before_set_reg(struct device *dev, int slot,
int power_on, int vdd)
{
struct omap_mmc_platform_data *mmc = dev->platform_data;
@@ -407,14 +408,13 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
c->caps &= ~MMC_CAP_8_BIT_DATA;
c->caps |= MMC_CAP_4_BIT_DATA;
}
- /* FALLTHROUGH */
- case 3:
if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
/* off-chip level shifting, or none */
- mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
+ mmc->slots[0].before_set_reg = hsmmc2_before_set_reg;
mmc->slots[0].after_set_reg = NULL;
}
break;
+ case 3:
case 4:
case 5:
mmc->slots[0].before_set_reg = NULL;
diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c
index 3f174d51f67f..eb50c29fb644 100644
--- a/trunk/arch/arm/mach-omap2/io.c
+++ b/trunk/arch/arm/mach-omap2/io.c
@@ -388,7 +388,7 @@ static void __init omap_hwmod_init_postsetup(void)
omap_pm_if_early_init();
}
-#ifdef CONFIG_ARCH_OMAP2
+#ifdef CONFIG_SOC_OMAP2420
void __init omap2420_init_early(void)
{
omap2_set_globals_242x();
@@ -400,7 +400,9 @@ void __init omap2420_init_early(void)
omap_hwmod_init_postsetup();
omap2420_clk_init();
}
+#endif
+#ifdef CONFIG_SOC_OMAP2430
void __init omap2430_init_early(void)
{
omap2_set_globals_243x();
diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
index c11273da5dcc..f08e442af397 100644
--- a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
+++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
@@ -55,27 +55,6 @@ struct omap_hwmod_class omap2_dss_hwmod_class = {
.reset = omap_dss_reset,
};
-/*
- * 'dispc' class
- * display controller
- */
-
-static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
- .rev_offs = 0x0000,
- .sysc_offs = 0x0010,
- .syss_offs = 0x0014,
- .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
- SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
- MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
- .sysc_fields = &omap_hwmod_sysc_type1,
-};
-
-struct omap_hwmod_class omap2_dispc_hwmod_class = {
- .name = "dispc",
- .sysc = &omap2_dispc_sysc,
-};
-
/*
* 'rfbi' class
* remote frame buffer interface
diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 177dee20faef..2a6729741b06 100644
--- a/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -28,6 +28,28 @@ struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
{ .name = "dispc", .dma_req = 5 },
{ .dma_req = -1 }
};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2_dispc_sysc,
+};
+
/* OMAP2xxx Timer Common */
static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
.rev_offs = 0x0000,
diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 5324e8d93bc0..3c8dd928628e 100644
--- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1480,6 +1480,28 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
.masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters),
};
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSC_HAS_ENAWAKEUP),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap3_dispc_sysc,
+};
+
/* l4_core -> dss_dispc */
static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
.master = &omap3xxx_l4_core_hwmod,
@@ -1503,7 +1525,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
.name = "dss_dispc",
- .class = &omap2_dispc_hwmod_class,
+ .class = &omap3_dispc_hwmod_class,
.mpu_irqs = omap2_dispc_irqs,
.main_clk = "dss1_alwon_fck",
.prcm = {
@@ -3523,12 +3545,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_uart2_hwmod,
&omap3xxx_uart3_hwmod,
- /* dss class */
- &omap3xxx_dss_dispc_hwmod,
- &omap3xxx_dss_dsi1_hwmod,
- &omap3xxx_dss_rfbi_hwmod,
- &omap3xxx_dss_venc_hwmod,
-
/* i2c class */
&omap3xxx_i2c1_hwmod,
&omap3xxx_i2c2_hwmod,
@@ -3635,6 +3651,15 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = {
NULL
};
+static __initdata struct omap_hwmod *omap3xxx_dss_hwmods[] = {
+ /* dss class */
+ &omap3xxx_dss_dispc_hwmod,
+ &omap3xxx_dss_dsi1_hwmod,
+ &omap3xxx_dss_rfbi_hwmod,
+ &omap3xxx_dss_venc_hwmod,
+ NULL
+};
+
int __init omap3xxx_hwmod_init(void)
{
int r;
@@ -3708,6 +3733,21 @@ int __init omap3xxx_hwmod_init(void)
if (h)
r = omap_hwmod_register(h);
+ if (r < 0)
+ return r;
+
+ /*
+ * DSS code presumes that dss_core hwmod is handled first,
+ * _before_ any other DSS related hwmods so register common
+ * DSS hwmods last to ensure that dss_core is already registered.
+ * Otherwise some change things may happen, for ex. if dispc
+ * is handled before dss_core and DSS is enabled in bootloader
+ * DIPSC will be reset with outputs enabled which sometimes leads
+ * to unrecoverable L3 error.
+ * XXX The long-term fix to this is to ensure modules are set up
+ * in dependency order in the hwmod core code.
+ */
+ r = omap_hwmod_register(omap3xxx_dss_hwmods);
return r;
}
diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index f9f151081760..ef0524c10a84 100644
--- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -1031,6 +1031,7 @@ static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = {
static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = {
{
+ .name = "mpu",
.pa_start = 0x4012e000,
.pa_end = 0x4012e07f,
.flags = ADDR_TYPE_RT
@@ -1049,6 +1050,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = {
{
+ .name = "dma",
.pa_start = 0x4902e000,
.pa_end = 0x4902e07f,
.flags = ADDR_TYPE_RT
diff --git a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c
index c1c4d86a79a8..9ce765407ad5 100644
--- a/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/trunk/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -19,6 +19,7 @@
#include "common.h"
#include
#include
+#include
#include "vp.h"
diff --git a/trunk/arch/arm/mach-omap2/smartreflex.c b/trunk/arch/arm/mach-omap2/smartreflex.c
index 9dd93453e563..7e755bb0ffc4 100644
--- a/trunk/arch/arm/mach-omap2/smartreflex.c
+++ b/trunk/arch/arm/mach-omap2/smartreflex.c
@@ -897,7 +897,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
ret = sr_late_init(sr_info);
if (ret) {
pr_warning("%s: Error in SR late init\n", __func__);
- return ret;
+ goto err_iounmap;
}
}
diff --git a/trunk/arch/arm/mach-omap2/timer.c b/trunk/arch/arm/mach-omap2/timer.c
index 6eeff0e0ae01..5c9acea95761 100644
--- a/trunk/arch/arm/mach-omap2/timer.c
+++ b/trunk/arch/arm/mach-omap2/timer.c
@@ -270,7 +270,7 @@ static struct clocksource clocksource_gpt = {
static u32 notrace dmtimer_read_sched_clock(void)
{
if (clksrc.reserved)
- return __omap_dm_timer_read_counter(clksrc.io_base, 1);
+ return __omap_dm_timer_read_counter(&clksrc, 1);
return 0;
}
diff --git a/trunk/arch/arm/mach-pxa/devices.c b/trunk/arch/arm/mach-pxa/devices.c
index 18fd177073f4..5bc13121eac5 100644
--- a/trunk/arch/arm/mach-pxa/devices.c
+++ b/trunk/arch/arm/mach-pxa/devices.c
@@ -415,29 +415,9 @@ static struct resource pxa_rtc_resources[] = {
},
};
-static struct resource sa1100_rtc_resources[] = {
- [0] = {
- .start = 0x40900000,
- .end = 0x409000ff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_RTC1Hz,
- .end = IRQ_RTC1Hz,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_RTCAlrm,
- .end = IRQ_RTCAlrm,
- .flags = IORESOURCE_IRQ,
- },
-};
-
struct platform_device sa1100_device_rtc = {
.name = "sa1100-rtc",
.id = -1,
- .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
- .resource = sa1100_rtc_resources,
};
struct platform_device pxa_device_rtc = {
diff --git a/trunk/arch/arm/mach-pxa/pxa25x.c b/trunk/arch/arm/mach-pxa/pxa25x.c
index adf058fa97ee..91e4f6c03766 100644
--- a/trunk/arch/arm/mach-pxa/pxa25x.c
+++ b/trunk/arch/arm/mach-pxa/pxa25x.c
@@ -209,8 +209,6 @@ static struct clk_lookup pxa25x_clkregs[] = {
INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
- INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
static struct clk_lookup pxa25x_hwuart_clkreg =
diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c
index 180bd8675d4b..aed6cbcf3866 100644
--- a/trunk/arch/arm/mach-pxa/pxa27x.c
+++ b/trunk/arch/arm/mach-pxa/pxa27x.c
@@ -230,8 +230,6 @@ static struct clk_lookup pxa27x_clkregs[] = {
INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
- INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
#ifdef CONFIG_PM
diff --git a/trunk/arch/arm/mach-pxa/pxa300.c b/trunk/arch/arm/mach-pxa/pxa300.c
index 0388eda7878a..40bb16501d86 100644
--- a/trunk/arch/arm/mach-pxa/pxa300.c
+++ b/trunk/arch/arm/mach-pxa/pxa300.c
@@ -89,7 +89,6 @@ static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0);
static struct clk_lookup common_clkregs[] = {
INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL),
INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0);
diff --git a/trunk/arch/arm/mach-pxa/pxa320.c b/trunk/arch/arm/mach-pxa/pxa320.c
index d487e1ff4c9a..8d614ecd8e99 100644
--- a/trunk/arch/arm/mach-pxa/pxa320.c
+++ b/trunk/arch/arm/mach-pxa/pxa320.c
@@ -83,7 +83,6 @@ static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0);
static struct clk_lookup pxa320_clkregs[] = {
INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL),
INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
static int __init pxa320_init(void)
diff --git a/trunk/arch/arm/mach-pxa/pxa3xx.c b/trunk/arch/arm/mach-pxa/pxa3xx.c
index f107c71c7589..4f402afa6609 100644
--- a/trunk/arch/arm/mach-pxa/pxa3xx.c
+++ b/trunk/arch/arm/mach-pxa/pxa3xx.c
@@ -67,7 +67,6 @@ static struct clk_lookup pxa3xx_clkregs[] = {
INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
/* Power I2C clock is always on */
INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL),
INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"),
INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"),
diff --git a/trunk/arch/arm/mach-pxa/pxa95x.c b/trunk/arch/arm/mach-pxa/pxa95x.c
index fccc644702e6..d082a583df78 100644
--- a/trunk/arch/arm/mach-pxa/pxa95x.c
+++ b/trunk/arch/arm/mach-pxa/pxa95x.c
@@ -217,7 +217,6 @@ static struct clk_lookup pxa95x_clkregs[] = {
INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"),
/* Power I2C clock is always on */
INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL),
INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL),
INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL),
diff --git a/trunk/arch/arm/mach-realview/hotplug.c b/trunk/arch/arm/mach-realview/hotplug.c
index ac1aed2a8da4..eb55f05bef3a 100644
--- a/trunk/arch/arm/mach-realview/hotplug.c
+++ b/trunk/arch/arm/mach-realview/hotplug.c
@@ -13,6 +13,7 @@
#include
#include
+#include
extern volatile int pen_release;
diff --git a/trunk/arch/arm/mach-realview/include/mach/board-eb.h b/trunk/arch/arm/mach-realview/include/mach/board-eb.h
index 794a8d91a6a6..124bce6b4d7b 100644
--- a/trunk/arch/arm/mach-realview/include/mach/board-eb.h
+++ b/trunk/arch/arm/mach-realview/include/mach/board-eb.h
@@ -47,21 +47,23 @@
#define REALVIEW_EB_USB_BASE 0x4F000000 /* USB */
#ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB
-#define REALVIEW_EB11MP_SCU_BASE 0x10100000 /* SCU registers */
-#define REALVIEW_EB11MP_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
-#define REALVIEW_EB11MP_TWD_BASE 0x10100600
-#define REALVIEW_EB11MP_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
+#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000
#define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */
#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */
#else
-#define REALVIEW_EB11MP_SCU_BASE 0x1F000000 /* SCU registers */
-#define REALVIEW_EB11MP_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */
-#define REALVIEW_EB11MP_TWD_BASE 0x1F000600
-#define REALVIEW_EB11MP_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */
+#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000
#define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */
#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */
#endif
+#define REALVIEW_EB11MP_PRIV_MEM_SIZE SZ_8K
+#define REALVIEW_EB11MP_PRIV_MEM_OFF(x) (REALVIEW_EB11MP_PRIV_MEM_BASE + (x))
+
+#define REALVIEW_EB11MP_SCU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0) /* SCU registers */
+#define REALVIEW_EB11MP_GIC_CPU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100) /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB11MP_TWD_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600)
+#define REALVIEW_EB11MP_GIC_DIST_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000) /* Generic interrupt controller distributor */
+
/*
* Core tile identification (REALVIEW_SYS_PROCID)
*/
diff --git a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h
index 7abf918b77e9..aa2d4e02ea2c 100644
--- a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h
+++ b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h
@@ -75,6 +75,8 @@
/*
* Testchip peripheral and fpga gic regions
*/
+#define REALVIEW_TC11MP_PRIV_MEM_BASE 0x1F000000
+#define REALVIEW_TC11MP_PRIV_MEM_SIZE SZ_8K
#define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */
#define REALVIEW_TC11MP_GIC_CPU_BASE 0x1F000100 /* Test chip interrupt controller CPU interface */
#define REALVIEW_TC11MP_TWD_BASE 0x1F000600
diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c
index e62962117763..9578145f2df0 100644
--- a/trunk/arch/arm/mach-realview/realview_eb.c
+++ b/trunk/arch/arm/mach-realview/realview_eb.c
@@ -91,14 +91,9 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
static struct map_desc realview_eb11mp_io_desc[] __initdata = {
{
- .virtual = IO_ADDRESS(REALVIEW_EB11MP_SCU_BASE),
- .pfn = __phys_to_pfn(REALVIEW_EB11MP_SCU_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_DIST_BASE),
- .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_DIST_BASE),
- .length = SZ_4K,
+ .virtual = IO_ADDRESS(REALVIEW_EB11MP_PRIV_MEM_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB11MP_PRIV_MEM_BASE),
+ .length = REALVIEW_EB11MP_PRIV_MEM_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IO_ADDRESS(REALVIEW_EB11MP_L220_BASE),
diff --git a/trunk/arch/arm/mach-realview/realview_pb11mp.c b/trunk/arch/arm/mach-realview/realview_pb11mp.c
index 127a3fd42ab1..2147335f66f5 100644
--- a/trunk/arch/arm/mach-realview/realview_pb11mp.c
+++ b/trunk/arch/arm/mach-realview/realview_pb11mp.c
@@ -64,15 +64,10 @@ static struct map_desc realview_pb11mp_io_desc[] __initdata = {
.pfn = __phys_to_pfn(REALVIEW_PB11MP_GIC_DIST_BASE),
.length = SZ_4K,
.type = MT_DEVICE,
- }, {
- .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_CPU_BASE),
- .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_CPU_BASE),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_DIST_BASE),
- .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_DIST_BASE),
- .length = SZ_4K,
+ }, { /* Maps the SCU, GIC CPU interface, TWD, GIC DIST */
+ .virtual = IO_ADDRESS(REALVIEW_TC11MP_PRIV_MEM_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TC11MP_PRIV_MEM_BASE),
+ .length = REALVIEW_TC11MP_PRIV_MEM_SIZE,
.type = MT_DEVICE,
}, {
.virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
diff --git a/trunk/arch/arm/mach-sa1100/assabet.c b/trunk/arch/arm/mach-sa1100/assabet.c
index ebafe8aa8956..0c4b76ab4d8e 100644
--- a/trunk/arch/arm/mach-sa1100/assabet.c
+++ b/trunk/arch/arm/mach-sa1100/assabet.c
@@ -202,7 +202,6 @@ static struct irda_platform_data assabet_irda_data = {
static struct mcp_plat_data assabet_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
- .codec = "ucb1x00",
};
static void __init assabet_init(void)
@@ -253,17 +252,6 @@ static void __init assabet_init(void)
sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
ARRAY_SIZE(assabet_flash_resources));
sa11x0_register_irda(&assabet_irda_data);
-
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
- ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
sa11x0_register_mcp(&assabet_mcp_data);
}
diff --git a/trunk/arch/arm/mach-sa1100/cerf.c b/trunk/arch/arm/mach-sa1100/cerf.c
index d12d0f48b1dc..11bb6d0b9be3 100644
--- a/trunk/arch/arm/mach-sa1100/cerf.c
+++ b/trunk/arch/arm/mach-sa1100/cerf.c
@@ -124,23 +124,12 @@ static void __init cerf_map_io(void)
static struct mcp_plat_data cerf_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
- .codec = "ucb1x00",
};
static void __init cerf_init(void)
{
platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
-
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
sa11x0_register_mcp(&cerf_mcp_data);
}
diff --git a/trunk/arch/arm/mach-sa1100/clock.c b/trunk/arch/arm/mach-sa1100/clock.c
index d6df9f6c9f7e..dab3c6347a8f 100644
--- a/trunk/arch/arm/mach-sa1100/clock.c
+++ b/trunk/arch/arm/mach-sa1100/clock.c
@@ -11,39 +11,17 @@
#include
#include
#include
-#include
-#include
#include
-struct clkops {
- void (*enable)(struct clk *);
- void (*disable)(struct clk *);
- unsigned long (*getrate)(struct clk *);
-};
-
+/*
+ * Very simple clock implementation - we only have one clock to deal with.
+ */
struct clk {
- const struct clkops *ops;
- unsigned long rate;
unsigned int enabled;
};
-#define INIT_CLKREG(_clk, _devname, _conname) \
- { \
- .clk = _clk, \
- .dev_id = _devname, \
- .con_id = _conname, \
- }
-
-#define DEFINE_CLK(_name, _ops, _rate) \
-struct clk clk_##_name = { \
- .ops = _ops, \
- .rate = _rate, \
- }
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-static void clk_gpio27_enable(struct clk *clk)
+static void clk_gpio27_enable(void)
{
/*
* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -54,22 +32,38 @@ static void clk_gpio27_enable(struct clk *clk)
TUCR = TUCR_3_6864MHz;
}
-static void clk_gpio27_disable(struct clk *clk)
+static void clk_gpio27_disable(void)
{
TUCR = 0;
GPDR &= ~GPIO_32_768kHz;
GAFR &= ~GPIO_32_768kHz;
}
+static struct clk clk_gpio27;
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ const char *devname = dev_name(dev);
+
+ return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
int clk_enable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
- clk->ops->enable(clk);
+ clk_gpio27_enable();
spin_unlock_irqrestore(&clocks_lock, flags);
-
return 0;
}
EXPORT_SYMBOL(clk_enable);
@@ -82,48 +76,13 @@ void clk_disable(struct clk *clk)
spin_lock_irqsave(&clocks_lock, flags);
if (--clk->enabled == 0)
- clk->ops->disable(clk);
+ clk_gpio27_disable();
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
- unsigned long rate;
-
- rate = clk->rate;
- if (clk->ops->getrate)
- rate = clk->ops->getrate(clk);
-
- return rate;
+ return 3686400;
}
EXPORT_SYMBOL(clk_get_rate);
-
-const struct clkops clk_gpio27_ops = {
- .enable = clk_gpio27_enable,
- .disable = clk_gpio27_disable,
-};
-
-static void clk_dummy_enable(struct clk *clk) { }
-static void clk_dummy_disable(struct clk *clk) { }
-
-const struct clkops clk_dummy_ops = {
- .enable = clk_dummy_enable,
- .disable = clk_dummy_disable,
-};
-
-static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400);
-static DEFINE_CLK(dummy, &clk_dummy_ops, 0);
-
-static struct clk_lookup sa11xx_clkregs[] = {
- INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL),
- INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
-};
-
-static int __init sa11xx_clk_init(void)
-{
- clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
- return 0;
-}
-
-postcore_initcall(sa11xx_clk_init);
diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c
index c483912d08af..fd5652118ed1 100644
--- a/trunk/arch/arm/mach-sa1100/collie.c
+++ b/trunk/arch/arm/mach-sa1100/collie.c
@@ -27,7 +27,6 @@
#include
#include
#include
-#include
#include
#include
@@ -86,15 +85,10 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
.num_devs = 1,
};
-static struct ucb1x00_plat_data collie_ucb1x00_data = {
- .gpio_base = COLLIE_TC35143_GPIO_BASE,
-};
-
static struct mcp_plat_data collie_mcp_data = {
.mccr0 = MCCR0_ADM | MCCR0_ExtClk,
.sclk_rate = 9216000,
- .codec = "ucb1x00",
- .codec_pdata = &collie_ucb1x00_data,
+ .gpio_base = COLLIE_TC35143_GPIO_BASE,
};
/*
@@ -144,8 +138,6 @@ static struct pda_power_pdata collie_power_data = {
static struct resource collie_power_resource[] = {
{
.name = "ac",
- .start = gpio_to_irq(COLLIE_GPIO_AC_IN),
- .end = gpio_to_irq(COLLIE_GPIO_AC_IN),
.flags = IORESOURCE_IRQ |
IORESOURCE_IRQ_HIGHEDGE |
IORESOURCE_IRQ_LOWEDGE,
@@ -347,7 +339,8 @@ static void __init collie_init(void)
GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
-
+ collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
+ collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
platform_scoop_config = &collie_pcmcia_config;
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
@@ -357,16 +350,6 @@ static void __init collie_init(void)
sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
ARRAY_SIZE(collie_flash_resources));
-
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
sa11x0_register_mcp(&collie_mcp_data);
sharpsl_save_param();
diff --git a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c
index aaa8acf76b7b..19b2053f5af4 100644
--- a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -228,7 +228,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
return 0;
}
-static struct cpufreq_driver sa1100_driver = {
+static struct cpufreq_driver sa1100_driver __refdata = {
.flags = CPUFREQ_STICKY,
.verify = sa11x0_verify_speed,
.target = sa1100_target,
diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c
index e3a28ca2a7b7..bb10ee2cb89f 100644
--- a/trunk/arch/arm/mach-sa1100/generic.c
+++ b/trunk/arch/arm/mach-sa1100/generic.c
@@ -217,15 +217,10 @@ static struct platform_device sa11x0uart3_device = {
static struct resource sa11x0mcp_resources[] = {
[0] = {
.start = __PREG(Ser4MCCR0),
- .end = __PREG(Ser4MCCR0) + 0x1C - 1,
+ .end = __PREG(Ser4MCCR0) + 0xffff,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = __PREG(Ser4MCCR1),
- .end = __PREG(Ser4MCCR1) + 0x4 - 1,
- .flags = IORESOURCE_MEM,
- },
- [2] = {
.start = IRQ_Ser4MCP,
.end = IRQ_Ser4MCP,
.flags = IORESOURCE_IRQ,
@@ -350,29 +345,9 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
sa11x0_register_device(&sa11x0ir_device, irda);
}
-static struct resource sa11x0rtc_resources[] = {
- [0] = {
- .start = 0x90010000,
- .end = 0x900100ff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_RTC1Hz,
- .end = IRQ_RTC1Hz,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = IRQ_RTCAlrm,
- .end = IRQ_RTCAlrm,
- .flags = IORESOURCE_IRQ,
- },
-};
-
static struct platform_device sa11x0rtc_device = {
.name = "sa1100-rtc",
.id = -1,
- .resource = sa11x0rtc_resources,
- .num_resources = ARRAY_SIZE(sa11x0rtc_resources),
};
static struct platform_device *sa11x0_devices[] __initdata = {
diff --git a/trunk/arch/arm/mach-sa1100/include/mach/mcp.h b/trunk/arch/arm/mach-sa1100/include/mach/mcp.h
index 586cec898b35..ed1a331508a7 100644
--- a/trunk/arch/arm/mach-sa1100/include/mach/mcp.h
+++ b/trunk/arch/arm/mach-sa1100/include/mach/mcp.h
@@ -17,8 +17,6 @@ struct mcp_plat_data {
u32 mccr1;
unsigned int sclk_rate;
int gpio_base;
- const char *codec;
- void *codec_pdata;
};
#endif
diff --git a/trunk/arch/arm/mach-sa1100/jornada720_ssp.c b/trunk/arch/arm/mach-sa1100/jornada720_ssp.c
index f50b00bd18a0..b412fc09c80c 100644
--- a/trunk/arch/arm/mach-sa1100/jornada720_ssp.c
+++ b/trunk/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -198,3 +198,5 @@ static int __init jornada_ssp_init(void)
{
return platform_driver_register(&jornadassp_driver);
}
+
+module_init(jornada_ssp_init);
diff --git a/trunk/arch/arm/mach-sa1100/lart.c b/trunk/arch/arm/mach-sa1100/lart.c
index d117ceab6215..af4e2761f3db 100644
--- a/trunk/arch/arm/mach-sa1100/lart.c
+++ b/trunk/arch/arm/mach-sa1100/lart.c
@@ -24,20 +24,10 @@
static struct mcp_plat_data lart_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
- .codec = "ucb1x00",
};
static void __init lart_init(void)
{
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
sa11x0_register_mcp(&lart_mcp_data);
}
diff --git a/trunk/arch/arm/mach-sa1100/shannon.c b/trunk/arch/arm/mach-sa1100/shannon.c
index 748d34435b3f..318b2b766a0b 100644
--- a/trunk/arch/arm/mach-sa1100/shannon.c
+++ b/trunk/arch/arm/mach-sa1100/shannon.c
@@ -55,22 +55,11 @@ static struct resource shannon_flash_resource = {
static struct mcp_plat_data shannon_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
- .codec = "ucb1x00",
};
static void __init shannon_init(void)
{
sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
-
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
sa11x0_register_mcp(&shannon_mcp_data);
}
diff --git a/trunk/arch/arm/mach-sa1100/simpad.c b/trunk/arch/arm/mach-sa1100/simpad.c
index 458ececefa58..e17c04d6e324 100644
--- a/trunk/arch/arm/mach-sa1100/simpad.c
+++ b/trunk/arch/arm/mach-sa1100/simpad.c
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include
#include
@@ -188,15 +187,10 @@ static struct resource simpad_flash_resources [] = {
}
};
-static struct ucb1x00_plat_data simpad_ucb1x00_data = {
- .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
-};
-
static struct mcp_plat_data simpad_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
- .codec = "ucb1300",
- .codec_pdata = &simpad_ucb1x00_data,
+ .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
};
@@ -384,16 +378,6 @@ static int __init simpad_init(void)
sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
ARRAY_SIZE(simpad_flash_resources));
-
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
sa11x0_register_mcp(&simpad_mcp_data);
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/trunk/arch/arm/mach-shmobile/setup-sh7372.c b/trunk/arch/arm/mach-shmobile/setup-sh7372.c
index 6fcf304d3cdf..a83cf51fc099 100644
--- a/trunk/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/trunk/arch/arm/mach-shmobile/setup-sh7372.c
@@ -662,6 +662,7 @@ static struct sh_dmae_pdata usb_dma0_platform_data = {
.dmaor_is_32bit = 1,
.needs_tend_set = 1,
.no_dmars = 1,
+ .slave_only = 1,
};
static struct resource sh7372_usb_dmae0_resources[] = {
@@ -723,6 +724,7 @@ static struct sh_dmae_pdata usb_dma1_platform_data = {
.dmaor_is_32bit = 1,
.needs_tend_set = 1,
.no_dmars = 1,
+ .slave_only = 1,
};
static struct resource sh7372_usb_dmae1_resources[] = {
diff --git a/trunk/arch/arm/mach-shmobile/smp-r8a7779.c b/trunk/arch/arm/mach-shmobile/smp-r8a7779.c
index cc97ef892d1b..4fe2e9eaf501 100644
--- a/trunk/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/trunk/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c
index be1ade76ccc8..0d159d64a345 100644
--- a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig
index a3e0c8692f0d..52af00446a63 100644
--- a/trunk/arch/arm/mach-ux500/Kconfig
+++ b/trunk/arch/arm/mach-ux500/Kconfig
@@ -7,6 +7,7 @@ config UX500_SOC_COMMON
select HAS_MTU
select ARM_ERRATA_753970
select ARM_ERRATA_754322
+ select ARM_ERRATA_764369
menu "Ux500 SoC"
diff --git a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c
index 23be34b3bb6e..5dde4d4ebe88 100644
--- a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -261,6 +261,8 @@ void __init mop500_sdi_init(void)
void __init snowball_sdi_init(void)
{
+ /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
+ mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
/* On-board eMMC */
db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
/* External Micro SD slot */
diff --git a/trunk/arch/arm/mach-ux500/cache-l2x0.c b/trunk/arch/arm/mach-ux500/cache-l2x0.c
index 122ddde00ba7..da5569d83d58 100644
--- a/trunk/arch/arm/mach-ux500/cache-l2x0.c
+++ b/trunk/arch/arm/mach-ux500/cache-l2x0.c
@@ -12,44 +12,6 @@
static void __iomem *l2x0_base;
-static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
-{
- /* wait for the operation to complete */
- while (readl_relaxed(reg) & mask)
- cpu_relax();
-}
-
-static inline void ux500_cache_sync(void)
-{
- writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC);
- ux500_cache_wait(l2x0_base + L2X0_CACHE_SYNC, 1);
-}
-
-/*
- * The L2 cache cannot be turned off in the non-secure world.
- * Dummy until a secure service is in place.
- */
-static void ux500_l2x0_disable(void)
-{
-}
-
-/*
- * This is only called when doing a kexec, just after turning off the L2
- * and L1 cache, and it is surrounded by a spinlock in the generic version.
- * However, we're not really turning off the L2 cache right now and the
- * PL310 does not support exclusive accesses (used to implement the spinlock).
- * So, the invalidation needs to be done without the spinlock.
- */
-static void ux500_l2x0_inv_all(void)
-{
- uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */
-
- /* invalidate all ways */
- writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
- ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
- ux500_cache_sync();
-}
-
static int __init ux500_l2x0_unlock(void)
{
int i;
@@ -85,9 +47,13 @@ static int __init ux500_l2x0_init(void)
/* 64KB way size, 8 way associativity, force WA */
l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
- /* Override invalidate function */
- outer_cache.disable = ux500_l2x0_disable;
- outer_cache.inv_all = ux500_l2x0_inv_all;
+ /*
+ * We can't disable l2 as we are in non secure mode, currently
+ * this seems be called only during kexec path. So let's
+ * override outer.disable with nasty assignment until we have
+ * some SMI service available.
+ */
+ outer_cache.disable = NULL;
return 0;
}
diff --git a/trunk/arch/arm/mach-ux500/hotplug.c b/trunk/arch/arm/mach-ux500/hotplug.c
index 572015e57cd9..c76f0f456f04 100644
--- a/trunk/arch/arm/mach-ux500/hotplug.c
+++ b/trunk/arch/arm/mach-ux500/hotplug.c
@@ -13,6 +13,7 @@
#include
#include
+#include
extern volatile int pen_release;
diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c
index a19e398dade3..d2058ef8345f 100644
--- a/trunk/arch/arm/mach-ux500/platsmp.c
+++ b/trunk/arch/arm/mach-ux500/platsmp.c
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/arm/mach-ux500/usb.c b/trunk/arch/arm/mach-ux500/usb.c
index 0a01cbdfe063..9f9e1c203061 100644
--- a/trunk/arch/arm/mach-ux500/usb.c
+++ b/trunk/arch/arm/mach-ux500/usb.c
@@ -95,13 +95,7 @@ static struct musb_hdrc_config musb_hdrc_config = {
};
static struct musb_hdrc_platform_data musb_platform_data = {
-#if defined(CONFIG_USB_MUSB_OTG)
.mode = MUSB_OTG,
-#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
- .mode = MUSB_PERIPHERAL,
-#else /* defined(CONFIG_USB_MUSB_HOST) */
- .mode = MUSB_HOST,
-#endif
.config = &musb_hdrc_config,
.board_data = &musb_board_data,
};
diff --git a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c
index 2b1e836a76ed..b1e87c184e54 100644
--- a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -217,7 +217,7 @@ static void __init ct_ca9x4_init(void)
}
#ifdef CONFIG_SMP
-static void ct_ca9x4_init_cpu_map(void)
+static void __init ct_ca9x4_init_cpu_map(void)
{
int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
@@ -233,7 +233,7 @@ static void ct_ca9x4_init_cpu_map(void)
set_smp_cross_call(gic_raise_softirq);
}
-static void ct_ca9x4_smp_enable(unsigned int max_cpus)
+static void __init ct_ca9x4_smp_enable(unsigned int max_cpus)
{
scu_enable(MMIO_P2V(A9_MPCORE_SCU));
}
diff --git a/trunk/arch/arm/mach-vexpress/hotplug.c b/trunk/arch/arm/mach-vexpress/hotplug.c
index 813ee08f96e6..3034a4dab4a1 100644
--- a/trunk/arch/arm/mach-vexpress/hotplug.c
+++ b/trunk/arch/arm/mach-vexpress/hotplug.c
@@ -13,6 +13,7 @@
#include
#include
+#include
#include
extern volatile int pen_release;
diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig
index 4cefb57d9ed2..1a3ca2488164 100644
--- a/trunk/arch/arm/mm/Kconfig
+++ b/trunk/arch/arm/mm/Kconfig
@@ -882,6 +882,7 @@ config CACHE_XSC3L2
config ARM_L1_CACHE_SHIFT_6
bool
+ default y if CPU_V7
help
Setting ARM L1 cache line size to 64 Bytes.
diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c
index 6ec1226fc62d..5dc7d127a40f 100644
--- a/trunk/arch/arm/mm/init.c
+++ b/trunk/arch/arm/mm/init.c
@@ -310,7 +310,7 @@ static void arm_memory_present(void)
static bool arm_memblock_steal_permitted = true;
-phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align)
+phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)
{
phys_addr_t phys;
diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S
index 7e9b5bf910c1..0404ccbb8aa3 100644
--- a/trunk/arch/arm/mm/proc-v7.S
+++ b/trunk/arch/arm/mm/proc-v7.S
@@ -148,10 +148,6 @@ ENDPROC(cpu_v7_do_resume)
* Initialise TLB, Caches, and MMU state ready to switch the MMU
* on. Return in r0 the new CP15 C1 control register setting.
*
- * We automatically detect if we have a Harvard cache, and use the
- * Harvard cache control instructions insead of the unified cache
- * control instructions.
- *
* This should be able to cover all ARMv7 cores.
*
* It is assumed that:
@@ -251,9 +247,7 @@ __v7_setup:
#endif
3: mov r10, #0
-#ifdef HARVARD_CACHE
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
-#endif
dsb
#ifdef CONFIG_MMU
mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
@@ -329,16 +323,6 @@ __v7_ca5mp_proc_info:
__v7_proc __v7_ca5mp_setup
.size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info
- /*
- * ARM Ltd. Cortex A7 processor.
- */
- .type __v7_ca7mp_proc_info, #object
-__v7_ca7mp_proc_info:
- .long 0x410fc070
- .long 0xff0ffff0
- __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV
- .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
-
/*
* ARM Ltd. Cortex A9 processor.
*/
@@ -350,6 +334,16 @@ __v7_ca9mp_proc_info:
.size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
#endif /* CONFIG_ARM_LPAE */
+ /*
+ * ARM Ltd. Cortex A7 processor.
+ */
+ .type __v7_ca7mp_proc_info, #object
+__v7_ca7mp_proc_info:
+ .long 0x410fc070
+ .long 0xff0ffff0
+ __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV
+ .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
+
/*
* ARM Ltd. Cortex A15 processor.
*/
diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h
index 6fa8a707b9a0..f7d18046c04f 100644
--- a/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h
+++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h
@@ -96,6 +96,6 @@ extern int mxc_gpio_mode(int gpio_mode);
extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
const char *label);
-extern int __init imx_iomuxv1_init(void __iomem *base, int numports);
+extern int imx_iomuxv1_init(void __iomem *base, int numports);
#endif /* __MACH_IOMUX_V1_H__ */
diff --git a/trunk/arch/arm/plat-versatile/platsmp.c b/trunk/arch/arm/plat-versatile/platsmp.c
index 92f18d372b69..49c7db48c7f1 100644
--- a/trunk/arch/arm/plat-versatile/platsmp.c
+++ b/trunk/arch/arm/plat-versatile/platsmp.c
@@ -16,6 +16,7 @@
#include
#include
+#include
#include
/*
diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig
index 197e96f70405..3dea7231f637 100644
--- a/trunk/arch/avr32/Kconfig
+++ b/trunk/arch/avr32/Kconfig
@@ -8,6 +8,7 @@ config AVR32
select HAVE_KPROBES
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
+ select GENERIC_ATOMIC64
select HARDIRQS_SW_RESEND
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c
index 4203d101363c..c4ac15c4f065 100644
--- a/trunk/arch/m68k/atari/config.c
+++ b/trunk/arch/m68k/atari/config.c
@@ -414,9 +414,9 @@ void __init config_atari(void)
* FDC val = 4 -> Supervisor only */
asm volatile ("\n"
" .chip 68030\n"
- " pmove %0@,%/tt1\n"
+ " pmove %0,%/tt1\n"
" .chip 68k"
- : : "a" (&tt1_val));
+ : : "m" (tt1_val));
} else {
asm volatile ("\n"
" .chip 68040\n"
@@ -569,10 +569,10 @@ static void atari_reset(void)
: "d0");
} else
asm volatile ("\n"
- " pmove %0@,%%tc\n"
+ " pmove %0,%%tc\n"
" jmp %1@"
: /* no outputs */
- : "a" (&tc_val), "a" (reset_addr));
+ : "m" (tc_val), "a" (reset_addr));
}
diff --git a/trunk/arch/m68k/include/asm/irq.h b/trunk/arch/m68k/include/asm/irq.h
index 0e89fa05de0e..c1155f0e22cc 100644
--- a/trunk/arch/m68k/include/asm/irq.h
+++ b/trunk/arch/m68k/include/asm/irq.h
@@ -50,19 +50,6 @@
#define IRQ_USER 8
-/*
- * various flags for request_irq() - the Amiga now uses the standard
- * mechanism like all other architectures - IRQF_DISABLED and
- * IRQF_SHARED are your friends.
- */
-#ifndef MACH_AMIGA_ONLY
-#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
-#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
-#define IRQ_FLG_FAST (0x0004)
-#define IRQ_FLG_SLOW (0x0008)
-#define IRQ_FLG_STD (0x8000) /* internally used */
-#endif
-
struct irq_data;
struct irq_chip;
struct irq_desc;
diff --git a/trunk/arch/m68k/kernel/process_mm.c b/trunk/arch/m68k/kernel/process_mm.c
index 125f34e00bf0..099283ee1a8f 100644
--- a/trunk/arch/m68k/kernel/process_mm.c
+++ b/trunk/arch/m68k/kernel/process_mm.c
@@ -172,7 +172,7 @@ void flush_thread(void)
current->thread.fs = __USER_DS;
if (!FPU_IS_EMU)
- asm volatile ("frestore %0@" : : "a" (&zero) : "memory");
+ asm volatile("frestore %0": :"m" (zero));
}
/*
diff --git a/trunk/arch/m68k/kernel/process_no.c b/trunk/arch/m68k/kernel/process_no.c
index 69c1803fcf1b..5e1078cabe0e 100644
--- a/trunk/arch/m68k/kernel/process_no.c
+++ b/trunk/arch/m68k/kernel/process_no.c
@@ -163,8 +163,8 @@ void flush_thread(void)
#ifdef CONFIG_FPU
if (!FPU_IS_EMU)
asm volatile (".chip 68k/68881\n\t"
- "frestore %0@\n\t"
- ".chip 68k" : : "a" (&zero));
+ "frestore %0\n\t"
+ ".chip 68k" : : "m" (zero));
#endif
}
diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c
index a76452ca964e..daaa9187654c 100644
--- a/trunk/arch/m68k/kernel/traps.c
+++ b/trunk/arch/m68k/kernel/traps.c
@@ -552,13 +552,13 @@ static inline void bus_error030 (struct frame *fp)
#ifdef DEBUG
asm volatile ("ptestr %3,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (desc)
- : "a" (&temp), "a" (addr), "d" (ssw));
+ "pmove %%psr,%1"
+ : "=a&" (desc), "=m" (temp)
+ : "a" (addr), "d" (ssw));
#else
asm volatile ("ptestr %2,%1@,#7\n\t"
- "pmove %%psr,%0@"
- : : "a" (&temp), "a" (addr), "d" (ssw));
+ "pmove %%psr,%0"
+ : "=m" (temp) : "a" (addr), "d" (ssw));
#endif
mmusr = temp;
@@ -605,20 +605,18 @@ static inline void bus_error030 (struct frame *fp)
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc, ssw);
asm volatile ("ptestr #1,%1@,#0\n\t"
- "pmove %%psr,%0@"
- : /* no outputs */
- : "a" (&temp), "a" (addr));
+ "pmove %%psr,%0"
+ : "=m" (temp)
+ : "a" (addr));
mmusr = temp;
printk ("level 0 mmusr is %#x\n", mmusr);
#if 0
- asm volatile ("pmove %%tt0,%0@"
- : /* no outputs */
- : "a" (&tlong));
+ asm volatile ("pmove %%tt0,%0"
+ : "=m" (tlong));
printk("tt0 is %#lx, ", tlong);
- asm volatile ("pmove %%tt1,%0@"
- : /* no outputs */
- : "a" (&tlong));
+ asm volatile ("pmove %%tt1,%0"
+ : "=m" (tlong));
printk("tt1 is %#lx\n", tlong);
#endif
#ifdef DEBUG
@@ -668,13 +666,13 @@ static inline void bus_error030 (struct frame *fp)
#ifdef DEBUG
asm volatile ("ptestr #1,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (desc)
- : "a" (&temp), "a" (addr));
+ "pmove %%psr,%1"
+ : "=a&" (desc), "=m" (temp)
+ : "a" (addr));
#else
asm volatile ("ptestr #1,%1@,#7\n\t"
- "pmove %%psr,%0@"
- : : "a" (&temp), "a" (addr));
+ "pmove %%psr,%0"
+ : "=m" (temp) : "a" (addr));
#endif
mmusr = temp;
diff --git a/trunk/arch/m68k/mm/cache.c b/trunk/arch/m68k/mm/cache.c
index 95d0bf66e2e2..3d84c1f2ffb2 100644
--- a/trunk/arch/m68k/mm/cache.c
+++ b/trunk/arch/m68k/mm/cache.c
@@ -52,9 +52,9 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr)
unsigned long *descaddr;
asm volatile ("ptestr %3,%2@,#7,%0\n\t"
- "pmove %%psr,%1@"
- : "=a&" (descaddr)
- : "a" (&mmusr), "a" (vaddr), "d" (get_fs().seg));
+ "pmove %%psr,%1"
+ : "=a&" (descaddr), "=m" (mmusr)
+ : "a" (vaddr), "d" (get_fs().seg));
if (mmusr & (MMU_I|MMU_B|MMU_L))
return 0;
descaddr = phys_to_virt((unsigned long)descaddr);
diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig
index 74f23a460ba2..c8d6efb99dbf 100644
--- a/trunk/arch/microblaze/Kconfig
+++ b/trunk/arch/microblaze/Kconfig
@@ -19,6 +19,7 @@ config MICROBLAZE
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
select GENERIC_CPU_DEVICES
+ select GENERIC_ATOMIC64
config SWAP
def_bool n
diff --git a/trunk/arch/microblaze/include/asm/atomic.h b/trunk/arch/microblaze/include/asm/atomic.h
index 6d2e1d418be7..615f53992c65 100644
--- a/trunk/arch/microblaze/include/asm/atomic.h
+++ b/trunk/arch/microblaze/include/asm/atomic.h
@@ -2,6 +2,7 @@
#define _ASM_MICROBLAZE_ATOMIC_H
#include
+#include
/*
* Atomically test *v and decrement if it is greater than 0.
diff --git a/trunk/arch/microblaze/kernel/setup.c b/trunk/arch/microblaze/kernel/setup.c
index d4fc1a971779..604cd9dd1333 100644
--- a/trunk/arch/microblaze/kernel/setup.c
+++ b/trunk/arch/microblaze/kernel/setup.c
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -227,23 +226,5 @@ static int __init setup_bus_notifier(void)
return 0;
}
-arch_initcall(setup_bus_notifier);
-
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
-static int __init topology_init(void)
-{
- int i, ret;
-
- for_each_present_cpu(i) {
- struct cpu *c = &per_cpu(cpu_devices, i);
- ret = register_cpu(c, i);
- if (ret)
- printk(KERN_WARNING "topology_init: register_cpu %d "
- "failed (%d)\n", i, ret);
- }
-
- return 0;
-}
-subsys_initcall(topology_init);
+arch_initcall(setup_bus_notifier);
diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
index 89af62637707..b37da56018b6 100644
--- a/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
+++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi
@@ -236,6 +236,10 @@
};
/include/ "pq3-esdhc-0.dtsi"
+ sdhc@2e000 {
+ compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+ };
+
/include/ "pq3-sec3.0-0.dtsi"
/include/ "pq3-mpic.dtsi"
/include/ "pq3-mpic-timer-B.dtsi"
diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
index bd9e163c764b..a97d1263372c 100644
--- a/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
+++ b/trunk/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
@@ -158,7 +158,8 @@
/include/ "pq3-usb2-dr-0.dtsi"
/include/ "pq3-esdhc-0.dtsi"
sdhc@2e000 {
- fsl,sdhci-auto-cmd12;
+ compatible = "fsl,p1010-esdhc", "fsl,esdhc";
+ sdhci,auto-cmd12;
};
/include/ "pq3-sec4.4-0.dtsi"
diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
index fc924c5ffebe..5de5fc351314 100644
--- a/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
+++ b/trunk/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi
@@ -145,6 +145,10 @@
/include/ "pq3-usb2-dr-1.dtsi"
/include/ "pq3-esdhc-0.dtsi"
+ sdhc@2e000 {
+ compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+ sdhci,auto-cmd12;
+ };
/include/ "pq3-sec3.3-0.dtsi"
/include/ "pq3-mpic.dtsi"
diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
index 16239b199d0a..ff9ed1d87929 100644
--- a/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
+++ b/trunk/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi
@@ -203,7 +203,8 @@
/include/ "pq3-esdhc-0.dtsi"
sdhc@2e000 {
- fsl,sdhci-auto-cmd12;
+ compatible = "fsl,p1022-esdhc", "fsl,esdhc";
+ sdhci,auto-cmd12;
};
/include/ "pq3-sec3.3-0.dtsi"
diff --git a/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
index c041050561a7..332e9e75e6c2 100644
--- a/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
+++ b/trunk/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi
@@ -182,6 +182,10 @@
/include/ "pq3-etsec1-1.dtsi"
/include/ "pq3-etsec1-2.dtsi"
/include/ "pq3-esdhc-0.dtsi"
+ sdhc@2e000 {
+ compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+ };
+
/include/ "pq3-sec3.1-0.dtsi"
/include/ "pq3-mpic.dtsi"
/include/ "pq3-mpic-timer-B.dtsi"
diff --git a/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi b/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi
index b5bd86f4baf2..1fb7e0e0940f 100644
--- a/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi
+++ b/trunk/arch/powerpc/boot/dts/p1020rdb.dtsi
@@ -1,7 +1,7 @@
/*
* P1020 RDB Device Tree Source stub (no addresses or top-level ranges)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -190,17 +190,16 @@
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
- /* USB2 is shared with localbus, so it must be disabled
- by default. We can't put 'status = "disabled";' here
- since U-Boot doesn't clear the status property when
- it enables USB2. OTOH, U-Boot does create a new node
- when there isn't any. So, just comment it out.
+ /* USB2 is shared with localbus. It is used
+ only in case of SPI and SD boot after
+ appropriate device-tree fixup done by uboot */
usb@23000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
- */
mdio@24000 {
phy0: ethernet-phy@0 {
diff --git a/trunk/arch/powerpc/boot/dts/p1021mds.dts b/trunk/arch/powerpc/boot/dts/p1021mds.dts
index d9540791e434..97116f198a37 100644
--- a/trunk/arch/powerpc/boot/dts/p1021mds.dts
+++ b/trunk/arch/powerpc/boot/dts/p1021mds.dts
@@ -1,7 +1,7 @@
/*
* P1021 MDS Device Tree Source
*
- * Copyright 2010 Freescale Semiconductor Inc.
+ * Copyright 2010,2012 Freescale Semiconductor Inc.
*
* 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
@@ -151,6 +151,7 @@
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
mdio@24000 {
diff --git a/trunk/arch/powerpc/boot/dts/p2020ds.dtsi b/trunk/arch/powerpc/boot/dts/p2020ds.dtsi
index c1cf6cef4dd6..d3b939c573b0 100644
--- a/trunk/arch/powerpc/boot/dts/p2020ds.dtsi
+++ b/trunk/arch/powerpc/boot/dts/p2020ds.dtsi
@@ -1,7 +1,7 @@
/*
* P2020DS Device Tree Source stub (no addresses or top-level ranges)
*
- * Copyright 2011 Freescale Semiconductor Inc.
+ * Copyright 2011-2012 Freescale Semiconductor Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -134,6 +134,7 @@
&board_soc {
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
mdio@24520 {
diff --git a/trunk/arch/powerpc/boot/dts/p2020rdb.dts b/trunk/arch/powerpc/boot/dts/p2020rdb.dts
index 26759a591712..eb8a6aa2bda5 100644
--- a/trunk/arch/powerpc/boot/dts/p2020rdb.dts
+++ b/trunk/arch/powerpc/boot/dts/p2020rdb.dts
@@ -1,7 +1,7 @@
/*
* P2020 RDB Device Tree Source
*
- * Copyright 2009-2011 Freescale Semiconductor Inc.
+ * Copyright 2009-2012 Freescale Semiconductor Inc.
*
* 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
@@ -197,6 +197,7 @@
usb@22000 {
phy_type = "ulpi";
+ dr_mode = "host";
};
mdio@24520 {
diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c
index 28be3452e67a..abef75176c07 100644
--- a/trunk/arch/powerpc/kernel/crash.c
+++ b/trunk/arch/powerpc/kernel/crash.c
@@ -46,7 +46,6 @@
/* This keeps a track of which one is the crashing cpu. */
int crashing_cpu = -1;
-static atomic_t cpus_in_crash;
static int time_to_dump;
#define CRASH_HANDLER_MAX 3
@@ -66,6 +65,7 @@ static int handle_fault(struct pt_regs *regs)
#ifdef CONFIG_SMP
+static atomic_t cpus_in_crash;
void crash_ipi_callback(struct pt_regs *regs)
{
static cpumask_t cpus_state_saved = CPU_MASK_NONE;
diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c
index 3fea3689527e..bedd12e1cfbc 100644
--- a/trunk/arch/powerpc/kernel/legacy_serial.c
+++ b/trunk/arch/powerpc/kernel/legacy_serial.c
@@ -442,8 +442,10 @@ static void __init fixup_port_irq(int index,
port->irq = virq;
+#ifdef CONFIG_SERIAL_8250_FSL
if (of_device_is_compatible(np, "fsl,ns16550"))
port->handle_irq = fsl8250_handle_irq;
+#endif
}
static void __init fixup_port_pio(int index,
diff --git a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c
index bb3d84f4046f..b0984ada3f83 100644
--- a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -25,6 +25,7 @@
#include
#include
+#include
#include
#include "smp.h"
diff --git a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c
index f31162cfdaa9..5e155dfc4320 100644
--- a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -204,11 +204,10 @@ static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus,
pr_devel(" -> OBR %s [%x] +%016llx\n",
bus->self ? pci_name(bus->self) : "root", flags, offset);
- for (i = 0; i < 2; i++) {
- r = bus->resource[i];
+ pci_bus_for_each_resource(bus, r, i) {
if (r && (r->flags & flags)) {
- bus->resource[i]->start += offset;
- bus->resource[i]->end += offset;
+ r->start += offset;
+ r->end += offset;
}
}
list_for_each_entry(dev, &bus->devices, bus_list)
@@ -288,12 +287,17 @@ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags,
* assignment algorithm is going to be uber-trivial for now, we
* can try to be smarter later at filling out holes.
*/
- start = bus->self ? 0 : bus->resource[bres]->start;
-
- /* Don't hand out IO 0 */
- if ((flags & IORESOURCE_IO) && !bus->self)
- start += 0x1000;
-
+ if (bus->self) {
+ /* No offset for downstream bridges */
+ start = 0;
+ } else {
+ /* Offset from the root */
+ if (flags & IORESOURCE_IO)
+ /* Don't hand out IO 0 */
+ start = hose->io_resource.start + 0x1000;
+ else
+ start = hose->mem_resources[0].start;
+ }
while(!list_empty(&head)) {
w = list_first_entry(&head, struct resource_wrap, link);
list_del(&w->link);
@@ -321,13 +325,20 @@ static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags,
empty:
/* Only setup P2P's, not the PHB itself */
if (bus->self) {
- WARN_ON(bus->resource[bres] == NULL);
- bus->resource[bres]->start = 0;
- bus->resource[bres]->flags = (*size) ? flags : 0;
- bus->resource[bres]->end = (*size) ? (*size - 1) : 0;
+ struct resource *res = bus->resource[bres];
+
+ if (WARN_ON(res == NULL))
+ return;
- /* Clear prefetch bus resources for now */
- bus->resource[2]->flags = 0;
+ /*
+ * FIXME: We should probably export and call
+ * pci_bridge_check_ranges() to properly re-initialize
+ * the PCI portion of the flags here, and to detect
+ * what the bridge actually supports.
+ */
+ res->start = 0;
+ res->flags = (*size) ? flags : 0;
+ res->end = (*size) ? (*size - 1) : 0;
}
pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n",
diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig
index ae7b6d41fed3..31f22c1f657d 100644
--- a/trunk/arch/powerpc/platforms/pseries/Kconfig
+++ b/trunk/arch/powerpc/platforms/pseries/Kconfig
@@ -122,7 +122,7 @@ config DTL
Say N if you are unsure.
config PSERIES_IDLE
- tristate "Cpuidle driver for pSeries platforms"
+ bool "Cpuidle driver for pSeries platforms"
depends on CPU_IDLE
depends on PPC_PSERIES
default y
diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.c b/trunk/arch/powerpc/sysdev/fsl_pci.c
index 3b61e8cf3421..30eb17ecad49 100644
--- a/trunk/arch/powerpc/sysdev/fsl_pci.c
+++ b/trunk/arch/powerpc/sysdev/fsl_pci.c
@@ -205,12 +205,12 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
if (paddr_hi == paddr_lo) {
pr_err("%s: No outbound window space\n", name);
- return ;
+ goto out;
}
if (paddr_lo == 0) {
pr_err("%s: No space for inbound window\n", name);
- return ;
+ goto out;
}
/* setup PCSRBAR/PEXCSRBAR */
@@ -357,6 +357,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
(u64)hose->dma_window_size);
}
+out:
iounmap(pci);
}
diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile
index e9f353341693..0ad2f1e1ce9e 100644
--- a/trunk/arch/s390/Makefile
+++ b/trunk/arch/s390/Makefile
@@ -88,7 +88,6 @@ KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
KBUILD_AFLAGS += $(aflags-y)
OBJCOPYFLAGS := -O binary
-LDFLAGS_vmlinux := -e start
head-y := arch/s390/kernel/head.o
head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S
index e4c79ebb40e6..21109c63eb12 100644
--- a/trunk/arch/s390/kernel/vmlinux.lds.S
+++ b/trunk/arch/s390/kernel/vmlinux.lds.S
@@ -9,12 +9,12 @@
#ifndef CONFIG_64BIT
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
OUTPUT_ARCH(s390)
-ENTRY(_start)
+ENTRY(startup)
jiffies = jiffies_64 + 4;
#else
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
-ENTRY(_start)
+ENTRY(startup)
jiffies = jiffies_64;
#endif
diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig
index 96657992a72e..ca5580e4d813 100644
--- a/trunk/arch/sparc/Kconfig
+++ b/trunk/arch/sparc/Kconfig
@@ -33,6 +33,7 @@ config SPARC
config SPARC32
def_bool !64BIT
select GENERIC_ATOMIC64
+ select CLZ_TAB
config SPARC64
def_bool 64BIT
diff --git a/trunk/arch/sparc/kernel/sun4m_irq.c b/trunk/arch/sparc/kernel/sun4m_irq.c
index 422c16dad1f6..e61165161dd3 100644
--- a/trunk/arch/sparc/kernel/sun4m_irq.c
+++ b/trunk/arch/sparc/kernel/sun4m_irq.c
@@ -399,6 +399,9 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
timers_global = (void __iomem *)
(unsigned long) addr[num_cpu_timers];
+ /* Every per-cpu timer works in timer mode */
+ sbus_writel(0x00000000, &timers_global->timer_config);
+
sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit);
master_l10_counter = &timers_global->l10_count;
diff --git a/trunk/arch/sparc/lib/divdi3.S b/trunk/arch/sparc/lib/divdi3.S
index 681b3683da9e..d74bc0925f2d 100644
--- a/trunk/arch/sparc/lib/divdi3.S
+++ b/trunk/arch/sparc/lib/divdi3.S
@@ -17,23 +17,9 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
- .data
- .align 8
- .globl __clz_tab
-__clz_tab:
- .byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
- .byte 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
- .byte 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
- .byte 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .byte 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- .size __clz_tab,256
- .global .udiv
-
.text
.align 4
+ .global .udiv
.globl __divdi3
__divdi3:
save %sp,-104,%sp
diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig
index 864cc6e6ac8e..5bed94e189fa 100644
--- a/trunk/arch/x86/Kconfig
+++ b/trunk/arch/x86/Kconfig
@@ -360,7 +360,6 @@ config X86_NUMACHIP
depends on NUMA
depends on SMP
depends on X86_X2APIC
- depends on !EDAC_AMD64
---help---
Adds support for Numascale NumaChip large-SMP systems. Needed to
enable more than ~168 cores.
diff --git a/trunk/arch/x86/boot/compressed/misc.c b/trunk/arch/x86/boot/compressed/misc.c
index 3a19d04cebeb..7116dcba0c9e 100644
--- a/trunk/arch/x86/boot/compressed/misc.c
+++ b/trunk/arch/x86/boot/compressed/misc.c
@@ -321,6 +321,8 @@ static void parse_elf(void *output)
default: /* Ignore other PT_* */ break;
}
}
+
+ free(phdrs);
}
asmlinkage void decompress_kernel(void *rmode, memptr heap,
diff --git a/trunk/arch/x86/include/asm/cmpxchg.h b/trunk/arch/x86/include/asm/cmpxchg.h
index 0c9fa2745f13..b3b733262909 100644
--- a/trunk/arch/x86/include/asm/cmpxchg.h
+++ b/trunk/arch/x86/include/asm/cmpxchg.h
@@ -145,13 +145,13 @@ extern void __add_wrong_size(void)
#ifdef __HAVE_ARCH_CMPXCHG
#define cmpxchg(ptr, old, new) \
- __cmpxchg((ptr), (old), (new), sizeof(*ptr))
+ __cmpxchg(ptr, old, new, sizeof(*(ptr)))
#define sync_cmpxchg(ptr, old, new) \
- __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr))
+ __sync_cmpxchg(ptr, old, new, sizeof(*(ptr)))
#define cmpxchg_local(ptr, old, new) \
- __cmpxchg_local((ptr), (old), (new), sizeof(*ptr))
+ __cmpxchg_local(ptr, old, new, sizeof(*(ptr)))
#endif
/*
diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h
index 17c5d4bdee5e..8d67d428b0f9 100644
--- a/trunk/arch/x86/include/asm/cpufeature.h
+++ b/trunk/arch/x86/include/asm/cpufeature.h
@@ -159,6 +159,7 @@
#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
#define X86_FEATURE_LWP (6*32+15) /* Light Weight Profiling */
#define X86_FEATURE_FMA4 (6*32+16) /* 4 operands MAC instructions */
+#define X86_FEATURE_TCE (6*32+17) /* translation cache extension */
#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */
#define X86_FEATURE_TBM (6*32+21) /* trailing bit manipulations */
#define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */
diff --git a/trunk/arch/x86/include/asm/kvm_emulate.h b/trunk/arch/x86/include/asm/kvm_emulate.h
index ab4092e3214e..7b9cfc4878af 100644
--- a/trunk/arch/x86/include/asm/kvm_emulate.h
+++ b/trunk/arch/x86/include/asm/kvm_emulate.h
@@ -190,6 +190,9 @@ struct x86_emulate_ops {
int (*intercept)(struct x86_emulate_ctxt *ctxt,
struct x86_instruction_info *info,
enum x86_intercept_stage stage);
+
+ bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
};
typedef u32 __attribute__((vector_size(16))) sse128_t;
@@ -298,6 +301,19 @@ struct x86_emulate_ctxt {
#define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
X86EMUL_MODE_PROT64)
+/* CPUID vendors */
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
+#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
+
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
+#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
+
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
+#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
+
enum x86_intercept_stage {
X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */
X86_ICPT_PRE_EXCEPT,
diff --git a/trunk/arch/x86/include/asm/uv/uv_hub.h b/trunk/arch/x86/include/asm/uv/uv_hub.h
index 54a13aaebc40..21f7385badb8 100644
--- a/trunk/arch/x86/include/asm/uv/uv_hub.h
+++ b/trunk/arch/x86/include/asm/uv/uv_hub.h
@@ -318,13 +318,13 @@ uv_gpa_in_mmr_space(unsigned long gpa)
/* UV global physical address --> socket phys RAM */
static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa)
{
- unsigned long paddr = gpa & uv_hub_info->gpa_mask;
+ unsigned long paddr;
unsigned long remap_base = uv_hub_info->lowmem_remap_base;
unsigned long remap_top = uv_hub_info->lowmem_remap_top;
gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) |
((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val);
- gpa = gpa & uv_hub_info->gpa_mask;
+ paddr = gpa & uv_hub_info->gpa_mask;
if (paddr >= remap_base && paddr < remap_base + remap_top)
paddr -= remap_base;
return paddr;
diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c
index 1aae78f775fc..4025fe4f928f 100644
--- a/trunk/arch/x86/kernel/dumpstack.c
+++ b/trunk/arch/x86/kernel/dumpstack.c
@@ -252,7 +252,8 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
unsigned short ss;
unsigned long sp;
#endif
- printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
+ printk(KERN_DEFAULT
+ "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
#ifdef CONFIG_PREEMPT
printk("PREEMPT ");
#endif
diff --git a/trunk/arch/x86/kernel/dumpstack_64.c b/trunk/arch/x86/kernel/dumpstack_64.c
index 6d728d9284bd..17107bd6e1f0 100644
--- a/trunk/arch/x86/kernel/dumpstack_64.c
+++ b/trunk/arch/x86/kernel/dumpstack_64.c
@@ -129,7 +129,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
if (!stack) {
if (regs)
stack = (unsigned long *)regs->sp;
- else if (task && task != current)
+ else if (task != current)
stack = (unsigned long *)task->thread.sp;
else
stack = &dummy;
@@ -269,11 +269,11 @@ void show_registers(struct pt_regs *regs)
unsigned char c;
u8 *ip;
- printk(KERN_EMERG "Stack:\n");
+ printk(KERN_DEFAULT "Stack:\n");
show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
- 0, KERN_EMERG);
+ 0, KERN_DEFAULT);
- printk(KERN_EMERG "Code: ");
+ printk(KERN_DEFAULT "Code: ");
ip = (u8 *)regs->ip - code_prologue;
if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
diff --git a/trunk/arch/x86/kernel/microcode_amd.c b/trunk/arch/x86/kernel/microcode_amd.c
index fe86493f3ed1..ac0417be9131 100644
--- a/trunk/arch/x86/kernel/microcode_amd.c
+++ b/trunk/arch/x86/kernel/microcode_amd.c
@@ -311,13 +311,33 @@ generic_load_microcode(int cpu, const u8 *data, size_t size)
return state;
}
+/*
+ * AMD microcode firmware naming convention, up to family 15h they are in
+ * the legacy file:
+ *
+ * amd-ucode/microcode_amd.bin
+ *
+ * This legacy file is always smaller than 2K in size.
+ *
+ * Starting at family 15h they are in family specific firmware files:
+ *
+ * amd-ucode/microcode_amd_fam15h.bin
+ * amd-ucode/microcode_amd_fam16h.bin
+ * ...
+ *
+ * These might be larger than 2K.
+ */
static enum ucode_state request_microcode_amd(int cpu, struct device *device)
{
- const char *fw_name = "amd-ucode/microcode_amd.bin";
+ char fw_name[36] = "amd-ucode/microcode_amd.bin";
const struct firmware *fw;
enum ucode_state ret = UCODE_NFOUND;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+ if (c->x86 >= 0x15)
+ snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86);
- if (request_firmware(&fw, fw_name, device)) {
+ if (request_firmware(&fw, (const char *)fw_name, device)) {
pr_err("failed to load file %s\n", fw_name);
goto out;
}
diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c
index 37a458b521a6..d840e69a853c 100644
--- a/trunk/arch/x86/kernel/reboot.c
+++ b/trunk/arch/x86/kernel/reboot.c
@@ -39,6 +39,14 @@ static int reboot_mode;
enum reboot_type reboot_type = BOOT_ACPI;
int reboot_force;
+/* This variable is used privately to keep track of whether or not
+ * reboot_type is still set to its default value (i.e., reboot= hasn't
+ * been set on the command line). This is needed so that we can
+ * suppress DMI scanning for reboot quirks. Without it, it's
+ * impossible to override a faulty reboot quirk without recompiling.
+ */
+static int reboot_default = 1;
+
#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
static int reboot_cpu = -1;
#endif
@@ -67,6 +75,12 @@ bool port_cf9_safe = false;
static int __init reboot_setup(char *str)
{
for (;;) {
+ /* Having anything passed on the command line via
+ * reboot= will cause us to disable DMI checking
+ * below.
+ */
+ reboot_default = 0;
+
switch (*str) {
case 'w':
reboot_mode = 0x1234;
@@ -295,14 +309,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
},
},
- { /* Handle problems with rebooting on VersaLogic Menlow boards */
- .callback = set_bios_reboot,
- .ident = "VersaLogic Menlow based board",
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"),
- DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
- },
- },
{ /* Handle reboot issue on Acer Aspire one */
.callback = set_kbd_reboot,
.ident = "Acer Aspire One A110",
@@ -316,7 +322,12 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
static int __init reboot_init(void)
{
- dmi_check_system(reboot_dmi_table);
+ /* Only do the DMI check if reboot_type hasn't been overridden
+ * on the command line
+ */
+ if (reboot_default) {
+ dmi_check_system(reboot_dmi_table);
+ }
return 0;
}
core_initcall(reboot_init);
@@ -465,7 +476,12 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
static int __init pci_reboot_init(void)
{
- dmi_check_system(pci_reboot_dmi_table);
+ /* Only do the DMI check if reboot_type hasn't been overridden
+ * on the command line
+ */
+ if (reboot_default) {
+ dmi_check_system(pci_reboot_dmi_table);
+ }
return 0;
}
core_initcall(pci_reboot_init);
diff --git a/trunk/arch/x86/kvm/emulate.c b/trunk/arch/x86/kvm/emulate.c
index 05a562b85025..0982507b962a 100644
--- a/trunk/arch/x86/kvm/emulate.c
+++ b/trunk/arch/x86/kvm/emulate.c
@@ -1891,6 +1891,51 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
ss->p = 1;
}
+static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
+{
+ struct x86_emulate_ops *ops = ctxt->ops;
+ u32 eax, ebx, ecx, edx;
+
+ /*
+ * syscall should always be enabled in longmode - so only become
+ * vendor specific (cpuid) if other modes are active...
+ */
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
+ return true;
+
+ eax = 0x00000000;
+ ecx = 0x00000000;
+ if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) {
+ /*
+ * Intel ("GenuineIntel")
+ * remark: Intel CPUs only support "syscall" in 64bit
+ * longmode. Also an 64bit guest with a
+ * 32bit compat-app running will #UD !! While this
+ * behaviour can be fixed (by emulating) into AMD
+ * response - CPUs of AMD can't behave like Intel.
+ */
+ if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
+ ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
+ edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
+ return false;
+
+ /* AMD ("AuthenticAMD") */
+ if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
+ ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
+ edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
+ return true;
+
+ /* AMD ("AMDisbetter!") */
+ if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
+ ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
+ edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
+ return true;
+ }
+
+ /* default: (not Intel, not AMD), apply Intel's stricter rules... */
+ return false;
+}
+
static int em_syscall(struct x86_emulate_ctxt *ctxt)
{
struct x86_emulate_ops *ops = ctxt->ops;
@@ -1904,9 +1949,15 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
ctxt->mode == X86EMUL_MODE_VM86)
return emulate_ud(ctxt);
+ if (!(em_syscall_is_enabled(ctxt)))
+ return emulate_ud(ctxt);
+
ops->get_msr(ctxt, MSR_EFER, &efer);
setup_syscalls_segments(ctxt, &cs, &ss);
+ if (!(efer & EFER_SCE))
+ return emulate_ud(ctxt);
+
ops->get_msr(ctxt, MSR_STAR, &msr_data);
msr_data >>= 32;
cs_sel = (u16)(msr_data & 0xfffc);
diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c
index 14d6cadc4ba6..9cbfc0698118 100644
--- a/trunk/arch/x86/kvm/x86.c
+++ b/trunk/arch/x86/kvm/x86.c
@@ -1495,6 +1495,8 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
+ bool pr = false;
+
switch (msr) {
case MSR_EFER:
return set_efer(vcpu, data);
@@ -1635,6 +1637,18 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
"0x%x data 0x%llx\n", msr, data);
break;
+ case MSR_P6_PERFCTR0:
+ case MSR_P6_PERFCTR1:
+ pr = true;
+ case MSR_P6_EVNTSEL0:
+ case MSR_P6_EVNTSEL1:
+ if (kvm_pmu_msr(vcpu, msr))
+ return kvm_pmu_set_msr(vcpu, msr, data);
+
+ if (pr || data != 0)
+ pr_unimpl(vcpu, "disabled perfctr wrmsr: "
+ "0x%x data 0x%llx\n", msr, data);
+ break;
case MSR_K7_CLK_CTL:
/*
* Ignore all writes to this no longer documented MSR.
@@ -1835,6 +1849,14 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_FAM10H_MMIO_CONF_BASE:
data = 0;
break;
+ case MSR_P6_PERFCTR0:
+ case MSR_P6_PERFCTR1:
+ case MSR_P6_EVNTSEL0:
+ case MSR_P6_EVNTSEL1:
+ if (kvm_pmu_msr(vcpu, msr))
+ return kvm_pmu_get_msr(vcpu, msr, pdata);
+ data = 0;
+ break;
case MSR_IA32_UCODE_REV:
data = 0x100000000ULL;
break;
@@ -4180,6 +4202,28 @@ static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
}
+static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt,
+ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
+{
+ struct kvm_cpuid_entry2 *cpuid = NULL;
+
+ if (eax && ecx)
+ cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt),
+ *eax, *ecx);
+
+ if (cpuid) {
+ *eax = cpuid->eax;
+ *ecx = cpuid->ecx;
+ if (ebx)
+ *ebx = cpuid->ebx;
+ if (edx)
+ *edx = cpuid->edx;
+ return true;
+ }
+
+ return false;
+}
+
static struct x86_emulate_ops emulate_ops = {
.read_std = kvm_read_guest_virt_system,
.write_std = kvm_write_guest_virt_system,
@@ -4211,6 +4255,7 @@ static struct x86_emulate_ops emulate_ops = {
.get_fpu = emulator_get_fpu,
.put_fpu = emulator_put_fpu,
.intercept = emulator_intercept,
+ .get_cpuid = emulator_get_cpuid,
};
static void cache_all_regs(struct kvm_vcpu *vcpu)
diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c
index 9d74824a708d..f0b4caf85c1a 100644
--- a/trunk/arch/x86/mm/fault.c
+++ b/trunk/arch/x86/mm/fault.c
@@ -673,7 +673,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
stackend = end_of_stack(tsk);
if (tsk != &init_task && *stackend != STACK_END_MAGIC)
- printk(KERN_ALERT "Thread overran stack, or stack corrupted\n");
+ printk(KERN_EMERG "Thread overran stack, or stack corrupted\n");
tsk->thread.cr2 = address;
tsk->thread.trap_no = 14;
@@ -684,7 +684,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
sig = 0;
/* Executive summary in case the body of the oops scrolled away */
- printk(KERN_EMERG "CR2: %016lx\n", address);
+ printk(KERN_DEFAULT "CR2: %016lx\n", address);
oops_end(flags, regs, sig);
}
diff --git a/trunk/arch/x86/net/bpf_jit_comp.c b/trunk/arch/x86/net/bpf_jit_comp.c
index 7b65f752c5f8..7c1b765ecc59 100644
--- a/trunk/arch/x86/net/bpf_jit_comp.c
+++ b/trunk/arch/x86/net/bpf_jit_comp.c
@@ -151,17 +151,18 @@ void bpf_jit_compile(struct sk_filter *fp)
cleanup_addr = proglen; /* epilogue address */
for (pass = 0; pass < 10; pass++) {
+ u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen;
/* no prologue/epilogue for trivial filters (RET something) */
proglen = 0;
prog = temp;
- if (seen) {
+ if (seen_or_pass0) {
EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */
/* note : must save %rbx in case bpf_error is hit */
- if (seen & (SEEN_XREG | SEEN_DATAREF))
+ if (seen_or_pass0 & (SEEN_XREG | SEEN_DATAREF))
EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */
- if (seen & SEEN_XREG)
+ if (seen_or_pass0 & SEEN_XREG)
CLEAR_X(); /* make sure we dont leek kernel memory */
/*
@@ -170,7 +171,7 @@ void bpf_jit_compile(struct sk_filter *fp)
* r9 = skb->len - skb->data_len
* r8 = skb->data
*/
- if (seen & SEEN_DATAREF) {
+ if (seen_or_pass0 & SEEN_DATAREF) {
if (offsetof(struct sk_buff, len) <= 127)
/* mov off8(%rdi),%r9d */
EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len));
@@ -260,9 +261,14 @@ void bpf_jit_compile(struct sk_filter *fp)
case BPF_S_ALU_DIV_X: /* A /= X; */
seen |= SEEN_XREG;
EMIT2(0x85, 0xdb); /* test %ebx,%ebx */
- if (pc_ret0 != -1)
- EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4));
- else {
+ if (pc_ret0 > 0) {
+ /* addrs[pc_ret0 - 1] is start address of target
+ * (addrs[i] - 4) is the address following this jmp
+ * ("xor %edx,%edx; div %ebx" being 4 bytes long)
+ */
+ EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] -
+ (addrs[i] - 4));
+ } else {
EMIT_COND_JMP(X86_JNE, 2 + 5);
CLEAR_A();
EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */
@@ -335,12 +341,12 @@ void bpf_jit_compile(struct sk_filter *fp)
}
/* fallinto */
case BPF_S_RET_A:
- if (seen) {
+ if (seen_or_pass0) {
if (i != flen - 1) {
EMIT_JMP(cleanup_addr - addrs[i]);
break;
}
- if (seen & SEEN_XREG)
+ if (seen_or_pass0 & SEEN_XREG)
EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */
EMIT1(0xc9); /* leaveq */
}
@@ -483,8 +489,9 @@ common_load: seen |= SEEN_DATAREF;
goto common_load;
case BPF_S_LDX_B_MSH:
if ((int)K < 0) {
- if (pc_ret0 != -1) {
- EMIT_JMP(addrs[pc_ret0] - addrs[i]);
+ if (pc_ret0 > 0) {
+ /* addrs[pc_ret0 - 1] is the start address */
+ EMIT_JMP(addrs[pc_ret0 - 1] - addrs[i]);
break;
}
CLEAR_A();
@@ -599,13 +606,14 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
* use it to give the cleanup instruction(s) addr
*/
cleanup_addr = proglen - 1; /* ret */
- if (seen)
+ if (seen_or_pass0)
cleanup_addr -= 1; /* leaveq */
- if (seen & SEEN_XREG)
+ if (seen_or_pass0 & SEEN_XREG)
cleanup_addr -= 4; /* mov -8(%rbp),%rbx */
if (image) {
- WARN_ON(proglen != oldproglen);
+ if (proglen != oldproglen)
+ pr_err("bpb_jit_compile proglen=%u != oldproglen=%u\n", proglen, oldproglen);
break;
}
if (proglen == oldproglen) {
diff --git a/trunk/arch/x86/platform/uv/tlb_uv.c b/trunk/arch/x86/platform/uv/tlb_uv.c
index 9be4cff00a2d..3ae0e61abd23 100644
--- a/trunk/arch/x86/platform/uv/tlb_uv.c
+++ b/trunk/arch/x86/platform/uv/tlb_uv.c
@@ -1851,6 +1851,8 @@ static void __init init_per_cpu_tunables(void)
bcp->cong_reps = congested_reps;
bcp->cong_period = congested_period;
bcp->clocks_per_100_usec = usec_2_cycles(100);
+ spin_lock_init(&bcp->queue_lock);
+ spin_lock_init(&bcp->uvhub_lock);
}
}
diff --git a/trunk/arch/x86/platform/uv/uv_irq.c b/trunk/arch/x86/platform/uv/uv_irq.c
index 374a05d8ad22..f25c2765a5c9 100644
--- a/trunk/arch/x86/platform/uv/uv_irq.c
+++ b/trunk/arch/x86/platform/uv/uv_irq.c
@@ -25,7 +25,7 @@ struct uv_irq_2_mmr_pnode{
int irq;
};
-static spinlock_t uv_irq_lock;
+static DEFINE_SPINLOCK(uv_irq_lock);
static struct rb_root uv_irq_root;
static int uv_set_irq_affinity(struct irq_data *, const struct cpumask *, bool);
diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c
index cc9b1e182fcf..d69cc6c3f808 100644
--- a/trunk/arch/x86/xen/spinlock.c
+++ b/trunk/arch/x86/xen/spinlock.c
@@ -116,9 +116,26 @@ static inline void spin_time_accum_blocked(u64 start)
}
#endif /* CONFIG_XEN_DEBUG_FS */
+/*
+ * Size struct xen_spinlock so it's the same as arch_spinlock_t.
+ */
+#if NR_CPUS < 256
+typedef u8 xen_spinners_t;
+# define inc_spinners(xl) \
+ asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory");
+# define dec_spinners(xl) \
+ asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory");
+#else
+typedef u16 xen_spinners_t;
+# define inc_spinners(xl) \
+ asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory");
+# define dec_spinners(xl) \
+ asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory");
+#endif
+
struct xen_spinlock {
unsigned char lock; /* 0 -> free; 1 -> locked */
- unsigned short spinners; /* count of waiting cpus */
+ xen_spinners_t spinners; /* count of waiting cpus */
};
static int xen_spin_is_locked(struct arch_spinlock *lock)
@@ -164,8 +181,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
wmb(); /* set lock of interest before count */
- asm(LOCK_PREFIX " incw %0"
- : "+m" (xl->spinners) : : "memory");
+ inc_spinners(xl);
return prev;
}
@@ -176,8 +192,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
*/
static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev)
{
- asm(LOCK_PREFIX " decw %0"
- : "+m" (xl->spinners) : : "memory");
+ dec_spinners(xl);
wmb(); /* decrement count before restoring lock */
__this_cpu_write(lock_spinners, prev);
}
@@ -373,6 +388,8 @@ void xen_uninit_lock_cpu(int cpu)
void __init xen_init_spinlocks(void)
{
+ BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t));
+
pv_lock_ops.spin_is_locked = xen_spin_is_locked;
pv_lock_ops.spin_is_contended = xen_spin_is_contended;
pv_lock_ops.spin_lock = xen_spin_lock;
diff --git a/trunk/arch/xtensa/include/asm/string.h b/trunk/arch/xtensa/include/asm/string.h
index 5fb8c27cbef5..405a8c49ff2c 100644
--- a/trunk/arch/xtensa/include/asm/string.h
+++ b/trunk/arch/xtensa/include/asm/string.h
@@ -118,7 +118,4 @@ extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
/* Don't build bcopy at all ... */
#define __HAVE_ARCH_BCOPY
-#define __HAVE_ARCH_MEMSCAN
-#define memscan memchr
-
#endif /* _XTENSA_STRING_H */
diff --git a/trunk/crypto/sha512_generic.c b/trunk/crypto/sha512_generic.c
index 9ed9f60316e5..88f160b77b1f 100644
--- a/trunk/crypto/sha512_generic.c
+++ b/trunk/crypto/sha512_generic.c
@@ -21,8 +21,6 @@
#include
#include
-static DEFINE_PER_CPU(u64[80], msg_schedule);
-
static inline u64 Ch(u64 x, u64 y, u64 z)
{
return z ^ (x & (y ^ z));
@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
static inline void BLEND_OP(int I, u64 *W)
{
- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
}
static void
@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input)
u64 a, b, c, d, e, f, g, h, t1, t2;
int i;
- u64 *W = get_cpu_var(msg_schedule);
+ u64 W[16];
/* load the input */
for (i = 0; i < 16; i++)
LOAD_OP(i, W, input);
- for (i = 16; i < 80; i++) {
- BLEND_OP(i, W);
- }
-
/* load the state into our registers */
a=state[0]; b=state[1]; c=state[2]; d=state[3];
e=state[4]; f=state[5]; g=state[6]; h=state[7];
- /* now iterate */
- for (i=0; i<80; i+=8) {
- t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ];
- t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2;
- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
- t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2;
- t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
- t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2;
- t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
- t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2;
- t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
- t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2;
- t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
- t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2;
- t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
- t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2;
- t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
+#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \
+ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \
+ t2 = e0(a) + Maj(a, b, c); \
+ d += t1; \
+ h = t1 + t2
+
+#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \
+ BLEND_OP(i, W); \
+ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \
+ t2 = e0(a) + Maj(a, b, c); \
+ d += t1; \
+ h = t1 + t2
+
+ for (i = 0; i < 16; i += 8) {
+ SHA512_0_15(i, a, b, c, d, e, f, g, h);
+ SHA512_0_15(i + 1, h, a, b, c, d, e, f, g);
+ SHA512_0_15(i + 2, g, h, a, b, c, d, e, f);
+ SHA512_0_15(i + 3, f, g, h, a, b, c, d, e);
+ SHA512_0_15(i + 4, e, f, g, h, a, b, c, d);
+ SHA512_0_15(i + 5, d, e, f, g, h, a, b, c);
+ SHA512_0_15(i + 6, c, d, e, f, g, h, a, b);
+ SHA512_0_15(i + 7, b, c, d, e, f, g, h, a);
+ }
+ for (i = 16; i < 80; i += 8) {
+ SHA512_16_79(i, a, b, c, d, e, f, g, h);
+ SHA512_16_79(i + 1, h, a, b, c, d, e, f, g);
+ SHA512_16_79(i + 2, g, h, a, b, c, d, e, f);
+ SHA512_16_79(i + 3, f, g, h, a, b, c, d, e);
+ SHA512_16_79(i + 4, e, f, g, h, a, b, c, d);
+ SHA512_16_79(i + 5, d, e, f, g, h, a, b, c);
+ SHA512_16_79(i + 6, c, d, e, f, g, h, a, b);
+ SHA512_16_79(i + 7, b, c, d, e, f, g, h, a);
}
state[0] += a; state[1] += b; state[2] += c; state[3] += d;
@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input)
/* erase our data */
a = b = c = d = e = f = g = h = t1 = t2 = 0;
- memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
- put_cpu_var(msg_schedule);
}
static int
diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile
index c07f44f05f9d..1567028d2038 100644
--- a/trunk/drivers/acpi/Makefile
+++ b/trunk/drivers/acpi/Makefile
@@ -19,7 +19,6 @@ obj-y += acpi.o \
# All the builtin files are in the "acpi." module_param namespace.
acpi-y += osl.o utils.o reboot.o
-acpi-y += atomicio.o
acpi-y += nvs.o
# sleep related files
diff --git a/trunk/drivers/acpi/apei/apei-base.c b/trunk/drivers/acpi/apei/apei-base.c
index e45350cb6ac8..e5d53b7ddc7e 100644
--- a/trunk/drivers/acpi/apei/apei-base.c
+++ b/trunk/drivers/acpi/apei/apei-base.c
@@ -596,33 +596,19 @@ int apei_read(u64 *val, struct acpi_generic_address *reg)
{
int rc;
u64 address;
- u32 tmp, width = reg->bit_width;
acpi_status status;
rc = apei_check_gar(reg, &address);
if (rc)
return rc;
- if (width == 64)
- width = 32; /* Break into two 32-bit transfers */
-
*val = 0;
switch(reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- status = acpi_os_read_memory((acpi_physical_address)
- address, &tmp, width);
+ status = acpi_os_read_memory64((acpi_physical_address)
+ address, val, reg->bit_width);
if (ACPI_FAILURE(status))
return -EIO;
- *val = tmp;
-
- if (reg->bit_width == 64) {
- /* Read the top 32 bits */
- status = acpi_os_read_memory((acpi_physical_address)
- (address + 4), &tmp, 32);
- if (ACPI_FAILURE(status))
- return -EIO;
- *val |= ((u64)tmp << 32);
- }
break;
case ACPI_ADR_SPACE_SYSTEM_IO:
status = acpi_os_read_port(address, (u32 *)val, reg->bit_width);
@@ -642,31 +628,18 @@ int apei_write(u64 val, struct acpi_generic_address *reg)
{
int rc;
u64 address;
- u32 width = reg->bit_width;
acpi_status status;
rc = apei_check_gar(reg, &address);
if (rc)
return rc;
- if (width == 64)
- width = 32; /* Break into two 32-bit transfers */
-
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- status = acpi_os_write_memory((acpi_physical_address)
- address, ACPI_LODWORD(val),
- width);
+ status = acpi_os_write_memory64((acpi_physical_address)
+ address, val, reg->bit_width);
if (ACPI_FAILURE(status))
return -EIO;
-
- if (reg->bit_width == 64) {
- status = acpi_os_write_memory((acpi_physical_address)
- (address + 4),
- ACPI_HIDWORD(val), 32);
- if (ACPI_FAILURE(status))
- return -EIO;
- }
break;
case ACPI_ADR_SPACE_SYSTEM_IO:
status = acpi_os_write_port(address, val, reg->bit_width);
diff --git a/trunk/drivers/acpi/apei/einj.c b/trunk/drivers/acpi/apei/einj.c
index 5b898d4dda99..4ca087dd5f4f 100644
--- a/trunk/drivers/acpi/apei/einj.c
+++ b/trunk/drivers/acpi/apei/einj.c
@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex);
static void *einj_param;
-#ifndef readq
-static inline __u64 readq(volatile void __iomem *addr)
-{
- return ((__u64)readl(addr+4) << 32) + readl(addr);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(__u64 val, volatile void __iomem *addr)
-{
- writel(val, addr);
- writel(val >> 32, addr+4);
-}
-#endif
-
static void einj_exec_ctx_init(struct apei_exec_context *ctx)
{
apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t)
static void check_vendor_extension(u64 paddr,
struct set_error_type_with_address *v5param)
{
- int offset = readl(&v5param->vendor_extension);
+ int offset = v5param->vendor_extension;
struct vendor_error_type_extension *v;
u32 sbdf;
if (!offset)
return;
- v = ioremap(paddr + offset, sizeof(*v));
+ v = acpi_os_map_memory(paddr + offset, sizeof(*v));
if (!v)
return;
- sbdf = readl(&v->pcie_sbdf);
+ sbdf = v->pcie_sbdf;
sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
sbdf >> 24, (sbdf >> 16) & 0xff,
(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
- readw(&v->vendor_id), readw(&v->device_id),
- readb(&v->rev_id));
- iounmap(v);
+ v->vendor_id, v->device_id, v->rev_id);
+ acpi_os_unmap_memory(v, sizeof(*v));
}
static void *einj_get_parameter_address(void)
@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void)
if (paddrv5) {
struct set_error_type_with_address *v5param;
- v5param = ioremap(paddrv5, sizeof(*v5param));
+ v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
if (v5param) {
acpi5 = 1;
check_vendor_extension(paddrv5, v5param);
@@ -257,17 +241,17 @@ static void *einj_get_parameter_address(void)
if (paddrv4) {
struct einj_parameter *v4param;
- v4param = ioremap(paddrv4, sizeof(*v4param));
+ v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
if (!v4param)
- return 0;
- if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) {
- iounmap(v4param);
- return 0;
+ return NULL;
+ if (v4param->reserved1 || v4param->reserved2) {
+ acpi_os_unmap_memory(v4param, sizeof(*v4param));
+ return NULL;
}
return v4param;
}
- return 0;
+ return NULL;
}
/* do sanity check to trigger table */
@@ -276,7 +260,7 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
return -EINVAL;
if (trigger_tab->table_size > PAGE_SIZE ||
- trigger_tab->table_size <= trigger_tab->header_size)
+ trigger_tab->table_size < trigger_tab->header_size)
return -EINVAL;
if (trigger_tab->entry_count !=
(trigger_tab->table_size - trigger_tab->header_size) /
@@ -340,6 +324,11 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
"The trigger error action table is invalid\n");
goto out_rel_header;
}
+
+ /* No action structures in the TRIGGER_ERROR table, nothing to do */
+ if (!trigger_tab->entry_count)
+ goto out_rel_header;
+
rc = -EIO;
table_size = trigger_tab->table_size;
r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
@@ -435,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
if (acpi5) {
struct set_error_type_with_address *v5param = einj_param;
- writel(type, &v5param->type);
+ v5param->type = type;
if (type & 0x80000000) {
switch (vendor_flags) {
case SETWA_FLAGS_APICID:
- writel(param1, &v5param->apicid);
+ v5param->apicid = param1;
break;
case SETWA_FLAGS_MEM:
- writeq(param1, &v5param->memory_address);
- writeq(param2, &v5param->memory_address_range);
+ v5param->memory_address = param1;
+ v5param->memory_address_range = param2;
break;
case SETWA_FLAGS_PCIE_SBDF:
- writel(param1, &v5param->pcie_sbdf);
+ v5param->pcie_sbdf = param1;
break;
}
- writel(vendor_flags, &v5param->flags);
+ v5param->flags = vendor_flags;
} else {
switch (type) {
case ACPI_EINJ_PROCESSOR_CORRECTABLE:
case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
case ACPI_EINJ_PROCESSOR_FATAL:
- writel(param1, &v5param->apicid);
- writel(SETWA_FLAGS_APICID, &v5param->flags);
+ v5param->apicid = param1;
+ v5param->flags = SETWA_FLAGS_APICID;
break;
case ACPI_EINJ_MEMORY_CORRECTABLE:
case ACPI_EINJ_MEMORY_UNCORRECTABLE:
case ACPI_EINJ_MEMORY_FATAL:
- writeq(param1, &v5param->memory_address);
- writeq(param2, &v5param->memory_address_range);
- writel(SETWA_FLAGS_MEM, &v5param->flags);
+ v5param->memory_address = param1;
+ v5param->memory_address_range = param2;
+ v5param->flags = SETWA_FLAGS_MEM;
break;
case ACPI_EINJ_PCIX_CORRECTABLE:
case ACPI_EINJ_PCIX_UNCORRECTABLE:
case ACPI_EINJ_PCIX_FATAL:
- writel(param1, &v5param->pcie_sbdf);
- writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags);
+ v5param->pcie_sbdf = param1;
+ v5param->flags = SETWA_FLAGS_PCIE_SBDF;
break;
}
}
@@ -479,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
return rc;
if (einj_param) {
struct einj_parameter *v4param = einj_param;
- writeq(param1, &v4param->param1);
- writeq(param2, &v4param->param2);
+ v4param->param1 = param1;
+ v4param->param2 = param2;
}
}
rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
@@ -731,8 +720,13 @@ static int __init einj_init(void)
return 0;
err_unmap:
- if (einj_param)
- iounmap(einj_param);
+ if (einj_param) {
+ acpi_size size = (acpi5) ?
+ sizeof(struct set_error_type_with_address) :
+ sizeof(struct einj_parameter);
+
+ acpi_os_unmap_memory(einj_param, size);
+ }
apei_exec_post_unmap_gars(&ctx);
err_release:
apei_resources_release(&einj_resources);
@@ -748,8 +742,13 @@ static void __exit einj_exit(void)
{
struct apei_exec_context ctx;
- if (einj_param)
- iounmap(einj_param);
+ if (einj_param) {
+ acpi_size size = (acpi5) ?
+ sizeof(struct set_error_type_with_address) :
+ sizeof(struct einj_parameter);
+
+ acpi_os_unmap_memory(einj_param, size);
+ }
einj_exec_ctx_init(&ctx);
apei_exec_post_unmap_gars(&ctx);
apei_resources_release(&einj_resources);
diff --git a/trunk/drivers/acpi/atomicio.c b/trunk/drivers/acpi/atomicio.c
deleted file mode 100644
index d4a5b3d3657b..000000000000
--- a/trunk/drivers/acpi/atomicio.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then
- * accessing in atomic context.
- *
- * This is used for NMI handler to access IO memory area, because
- * ioremap/iounmap can not be used in NMI handler. The IO memory area
- * is pre-mapped in process context and accessed in NMI handler.
- *
- * Copyright (C) 2009-2010, Intel Corp.
- * Author: Huang Ying
- *
- * 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.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define ACPI_PFX "ACPI: "
-
-static LIST_HEAD(acpi_iomaps);
-/*
- * Used for mutual exclusion between writers of acpi_iomaps list, for
- * synchronization between readers and writer, RCU is used.
- */
-static DEFINE_SPINLOCK(acpi_iomaps_lock);
-
-struct acpi_iomap {
- struct list_head list;
- void __iomem *vaddr;
- unsigned long size;
- phys_addr_t paddr;
- struct kref ref;
-};
-
-/* acpi_iomaps_lock or RCU read lock must be held before calling */
-static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr,
- unsigned long size)
-{
- struct acpi_iomap *map;
-
- list_for_each_entry_rcu(map, &acpi_iomaps, list) {
- if (map->paddr + map->size >= paddr + size &&
- map->paddr <= paddr)
- return map;
- }
- return NULL;
-}
-
-/*
- * Atomic "ioremap" used by NMI handler, if the specified IO memory
- * area is not pre-mapped, NULL will be returned.
- *
- * acpi_iomaps_lock or RCU read lock must be held before calling
- */
-static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
- unsigned long size)
-{
- struct acpi_iomap *map;
-
- map = __acpi_find_iomap(paddr, size/8);
- if (map)
- return map->vaddr + (paddr - map->paddr);
- else
- return NULL;
-}
-
-/* acpi_iomaps_lock must be held before calling */
-static void __iomem *__acpi_try_ioremap(phys_addr_t paddr,
- unsigned long size)
-{
- struct acpi_iomap *map;
-
- map = __acpi_find_iomap(paddr, size);
- if (map) {
- kref_get(&map->ref);
- return map->vaddr + (paddr - map->paddr);
- } else
- return NULL;
-}
-
-#ifndef CONFIG_IA64
-#define should_use_kmap(pfn) page_is_ram(pfn)
-#else
-/* ioremap will take care of cache attributes */
-#define should_use_kmap(pfn) 0
-#endif
-
-static void __iomem *acpi_map(phys_addr_t pg_off, unsigned long pg_sz)
-{
- unsigned long pfn;
-
- pfn = pg_off >> PAGE_SHIFT;
- if (should_use_kmap(pfn)) {
- if (pg_sz > PAGE_SIZE)
- return NULL;
- return (void __iomem __force *)kmap(pfn_to_page(pfn));
- } else
- return ioremap(pg_off, pg_sz);
-}
-
-static void acpi_unmap(phys_addr_t pg_off, void __iomem *vaddr)
-{
- unsigned long pfn;
-
- pfn = pg_off >> PAGE_SHIFT;
- if (page_is_ram(pfn))
- kunmap(pfn_to_page(pfn));
- else
- iounmap(vaddr);
-}
-
-/*
- * Used to pre-map the specified IO memory area. First try to find
- * whether the area is already pre-mapped, if it is, increase the
- * reference count (in __acpi_try_ioremap) and return; otherwise, do
- * the real ioremap, and add the mapping into acpi_iomaps list.
- */
-static void __iomem *acpi_pre_map(phys_addr_t paddr,
- unsigned long size)
-{
- void __iomem *vaddr;
- struct acpi_iomap *map;
- unsigned long pg_sz, flags;
- phys_addr_t pg_off;
-
- spin_lock_irqsave(&acpi_iomaps_lock, flags);
- vaddr = __acpi_try_ioremap(paddr, size);
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
- if (vaddr)
- return vaddr;
-
- pg_off = paddr & PAGE_MASK;
- pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off;
- vaddr = acpi_map(pg_off, pg_sz);
- if (!vaddr)
- return NULL;
- map = kmalloc(sizeof(*map), GFP_KERNEL);
- if (!map)
- goto err_unmap;
- INIT_LIST_HEAD(&map->list);
- map->paddr = pg_off;
- map->size = pg_sz;
- map->vaddr = vaddr;
- kref_init(&map->ref);
-
- spin_lock_irqsave(&acpi_iomaps_lock, flags);
- vaddr = __acpi_try_ioremap(paddr, size);
- if (vaddr) {
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
- acpi_unmap(pg_off, map->vaddr);
- kfree(map);
- return vaddr;
- }
- list_add_tail_rcu(&map->list, &acpi_iomaps);
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-
- return map->vaddr + (paddr - map->paddr);
-err_unmap:
- acpi_unmap(pg_off, vaddr);
- return NULL;
-}
-
-/* acpi_iomaps_lock must be held before calling */
-static void __acpi_kref_del_iomap(struct kref *ref)
-{
- struct acpi_iomap *map;
-
- map = container_of(ref, struct acpi_iomap, ref);
- list_del_rcu(&map->list);
-}
-
-/*
- * Used to post-unmap the specified IO memory area. The iounmap is
- * done only if the reference count goes zero.
- */
-static void acpi_post_unmap(phys_addr_t paddr, unsigned long size)
-{
- struct acpi_iomap *map;
- unsigned long flags;
- int del;
-
- spin_lock_irqsave(&acpi_iomaps_lock, flags);
- map = __acpi_find_iomap(paddr, size);
- BUG_ON(!map);
- del = kref_put(&map->ref, __acpi_kref_del_iomap);
- spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-
- if (!del)
- return;
-
- synchronize_rcu();
- acpi_unmap(map->paddr, map->vaddr);
- kfree(map);
-}
-
-/* In NMI handler, should set silent = 1 */
-static int acpi_check_gar(struct acpi_generic_address *reg,
- u64 *paddr, int silent)
-{
- u32 width, space_id;
-
- width = reg->bit_width;
- space_id = reg->space_id;
- /* Handle possible alignment issues */
- memcpy(paddr, ®->address, sizeof(*paddr));
- if (!*paddr) {
- if (!silent)
- pr_warning(FW_BUG ACPI_PFX
- "Invalid physical address in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
- return -EINVAL;
- }
-
- if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
- if (!silent)
- pr_warning(FW_BUG ACPI_PFX
- "Invalid bit width in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
- return -EINVAL;
- }
-
- if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
- space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
- if (!silent)
- pr_warning(FW_BUG ACPI_PFX
- "Invalid address space type in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Pre-map, working on GAR */
-int acpi_pre_map_gar(struct acpi_generic_address *reg)
-{
- u64 paddr;
- void __iomem *vaddr;
- int rc;
-
- if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
- return 0;
-
- rc = acpi_check_gar(reg, &paddr, 0);
- if (rc)
- return rc;
-
- vaddr = acpi_pre_map(paddr, reg->bit_width / 8);
- if (!vaddr)
- return -EIO;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_pre_map_gar);
-
-/* Post-unmap, working on GAR */
-int acpi_post_unmap_gar(struct acpi_generic_address *reg)
-{
- u64 paddr;
- int rc;
-
- if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
- return 0;
-
- rc = acpi_check_gar(reg, &paddr, 0);
- if (rc)
- return rc;
-
- acpi_post_unmap(paddr, reg->bit_width / 8);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_post_unmap_gar);
-
-#ifdef readq
-static inline u64 read64(const volatile void __iomem *addr)
-{
- return readq(addr);
-}
-#else
-static inline u64 read64(const volatile void __iomem *addr)
-{
- u64 l, h;
- l = readl(addr);
- h = readl(addr+4);
- return l | (h << 32);
-}
-#endif
-
-/*
- * Can be used in atomic (including NMI) or process context. RCU read
- * lock can only be released after the IO memory area accessing.
- */
-static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
-{
- void __iomem *addr;
-
- rcu_read_lock();
- addr = __acpi_ioremap_fast(paddr, width);
- switch (width) {
- case 8:
- *val = readb(addr);
- break;
- case 16:
- *val = readw(addr);
- break;
- case 32:
- *val = readl(addr);
- break;
- case 64:
- *val = read64(addr);
- break;
- default:
- return -EINVAL;
- }
- rcu_read_unlock();
-
- return 0;
-}
-
-#ifdef writeq
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
- writeq(val, addr);
-}
-#else
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
- writel(val, addr);
- writel(val>>32, addr+4);
-}
-#endif
-
-static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
-{
- void __iomem *addr;
-
- rcu_read_lock();
- addr = __acpi_ioremap_fast(paddr, width);
- switch (width) {
- case 8:
- writeb(val, addr);
- break;
- case 16:
- writew(val, addr);
- break;
- case 32:
- writel(val, addr);
- break;
- case 64:
- write64(val, addr);
- break;
- default:
- return -EINVAL;
- }
- rcu_read_unlock();
-
- return 0;
-}
-
-/* GAR accessing in atomic (including NMI) or process context */
-int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg)
-{
- u64 paddr;
- int rc;
-
- rc = acpi_check_gar(reg, &paddr, 1);
- if (rc)
- return rc;
-
- *val = 0;
- switch (reg->space_id) {
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- return acpi_atomic_read_mem(paddr, val, reg->bit_width);
- case ACPI_ADR_SPACE_SYSTEM_IO:
- return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width);
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL_GPL(acpi_atomic_read);
-
-int acpi_atomic_write(u64 val, struct acpi_generic_address *reg)
-{
- u64 paddr;
- int rc;
-
- rc = acpi_check_gar(reg, &paddr, 1);
- if (rc)
- return rc;
-
- switch (reg->space_id) {
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
- return acpi_atomic_write_mem(paddr, val, reg->bit_width);
- case ACPI_ADR_SPACE_SYSTEM_IO:
- return acpi_os_write_port(paddr, val, reg->bit_width);
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL_GPL(acpi_atomic_write);
diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c
index fcc12d842bcc..412a1e04a922 100644
--- a/trunk/drivers/acpi/osl.c
+++ b/trunk/drivers/acpi/osl.c
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -321,6 +322,37 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
return NULL;
}
+#ifndef CONFIG_IA64
+#define should_use_kmap(pfn) page_is_ram(pfn)
+#else
+/* ioremap will take care of cache attributes */
+#define should_use_kmap(pfn) 0
+#endif
+
+static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
+{
+ unsigned long pfn;
+
+ pfn = pg_off >> PAGE_SHIFT;
+ if (should_use_kmap(pfn)) {
+ if (pg_sz > PAGE_SIZE)
+ return NULL;
+ return (void __iomem __force *)kmap(pfn_to_page(pfn));
+ } else
+ return acpi_os_ioremap(pg_off, pg_sz);
+}
+
+static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
+{
+ unsigned long pfn;
+
+ pfn = pg_off >> PAGE_SHIFT;
+ if (page_is_ram(pfn))
+ kunmap(pfn_to_page(pfn));
+ else
+ iounmap(vaddr);
+}
+
void __iomem *__init_refok
acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
{
@@ -353,7 +385,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
- virt = acpi_os_ioremap(pg_off, pg_sz);
+ virt = acpi_map(pg_off, pg_sz);
if (!virt) {
mutex_unlock(&acpi_ioremap_lock);
kfree(map);
@@ -384,7 +416,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
{
if (!map->refcount) {
synchronize_rcu();
- iounmap(map->virt);
+ acpi_unmap(map->phys, map->virt);
kfree(map);
}
}
@@ -710,6 +742,67 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
return AE_OK;
}
+#ifdef readq
+static inline u64 read64(const volatile void __iomem *addr)
+{
+ return readq(addr);
+}
+#else
+static inline u64 read64(const volatile void __iomem *addr)
+{
+ u64 l, h;
+ l = readl(addr);
+ h = readl(addr+4);
+ return l | (h << 32);
+}
+#endif
+
+acpi_status
+acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
+{
+ void __iomem *virt_addr;
+ unsigned int size = width / 8;
+ bool unmap = false;
+ u64 dummy;
+
+ rcu_read_lock();
+ virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
+ if (!virt_addr) {
+ rcu_read_unlock();
+ virt_addr = acpi_os_ioremap(phys_addr, size);
+ if (!virt_addr)
+ return AE_BAD_ADDRESS;
+ unmap = true;
+ }
+
+ if (!value)
+ value = &dummy;
+
+ switch (width) {
+ case 8:
+ *(u8 *) value = readb(virt_addr);
+ break;
+ case 16:
+ *(u16 *) value = readw(virt_addr);
+ break;
+ case 32:
+ *(u32 *) value = readl(virt_addr);
+ break;
+ case 64:
+ *(u64 *) value = read64(virt_addr);
+ break;
+ default:
+ BUG();
+ }
+
+ if (unmap)
+ iounmap(virt_addr);
+ else
+ rcu_read_unlock();
+
+ return AE_OK;
+}
+
acpi_status
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
{
@@ -749,6 +842,61 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
return AE_OK;
}
+#ifdef writeq
+static inline void write64(u64 val, volatile void __iomem *addr)
+{
+ writeq(val, addr);
+}
+#else
+static inline void write64(u64 val, volatile void __iomem *addr)
+{
+ writel(val, addr);
+ writel(val>>32, addr+4);
+}
+#endif
+
+acpi_status
+acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width)
+{
+ void __iomem *virt_addr;
+ unsigned int size = width / 8;
+ bool unmap = false;
+
+ rcu_read_lock();
+ virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
+ if (!virt_addr) {
+ rcu_read_unlock();
+ virt_addr = acpi_os_ioremap(phys_addr, size);
+ if (!virt_addr)
+ return AE_BAD_ADDRESS;
+ unmap = true;
+ }
+
+ switch (width) {
+ case 8:
+ writeb(value, virt_addr);
+ break;
+ case 16:
+ writew(value, virt_addr);
+ break;
+ case 32:
+ writel(value, virt_addr);
+ break;
+ case 64:
+ write64(value, virt_addr);
+ break;
+ default:
+ BUG();
+ }
+
+ if (unmap)
+ iounmap(virt_addr);
+ else
+ rcu_read_unlock();
+
+ return AE_OK;
+}
+
acpi_status
acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
u64 *value, u32 width)
diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c
index 0034ede38710..2b805d7ef317 100644
--- a/trunk/drivers/acpi/processor_driver.c
+++ b/trunk/drivers/acpi/processor_driver.c
@@ -84,7 +84,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type);
static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
static int acpi_processor_handle_eject(struct acpi_processor *pr);
-
+static int acpi_processor_start(struct acpi_processor *pr);
static const struct acpi_device_id processor_device_ids[] = {
{ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -423,10 +423,29 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) {
- acpi_processor_ppc_has_changed(pr, 0);
- acpi_processor_hotplug(pr);
- acpi_processor_reevaluate_tstate(pr, action);
- acpi_processor_tstate_has_changed(pr);
+ /* CPU got physically hotplugged and onlined the first time:
+ * Initialize missing things
+ */
+ if (pr->flags.need_hotplug_init) {
+ struct cpuidle_driver *idle_driver =
+ cpuidle_get_driver();
+
+ printk(KERN_INFO "Will online and init hotplugged "
+ "CPU: %d\n", pr->id);
+ WARN(acpi_processor_start(pr), "Failed to start CPU:"
+ " %d\n", pr->id);
+ pr->flags.need_hotplug_init = 0;
+ if (idle_driver && !strcmp(idle_driver->name,
+ "intel_idle")) {
+ intel_idle_cpu_init(pr->id);
+ }
+ /* Normal CPU soft online event */
+ } else {
+ acpi_processor_ppc_has_changed(pr, 0);
+ acpi_processor_cst_has_changed(pr);
+ acpi_processor_reevaluate_tstate(pr, action);
+ acpi_processor_tstate_has_changed(pr);
+ }
}
if (action == CPU_DEAD && pr) {
/* invalidate the flag.throttling after one CPU is offline */
@@ -440,6 +459,71 @@ static struct notifier_block acpi_cpu_notifier =
.notifier_call = acpi_cpu_soft_notify,
};
+/*
+ * acpi_processor_start() is called by the cpu_hotplug_notifier func:
+ * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the
+ * root cause seem to be that acpi_processor_uninstall_hotplug_notify()
+ * is in the module_exit (__exit) func. Allowing acpi_processor_start()
+ * to not be in __cpuinit section, but being called from __cpuinit funcs
+ * via __ref looks like the right thing to do here.
+ */
+static __ref int acpi_processor_start(struct acpi_processor *pr)
+{
+ struct acpi_device *device = per_cpu(processor_device_array, pr->id);
+ int result = 0;
+
+#ifdef CONFIG_CPU_FREQ
+ acpi_processor_ppc_has_changed(pr, 0);
+#endif
+ acpi_processor_get_throttling_info(pr);
+ acpi_processor_get_limit_info(pr);
+
+ if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
+ acpi_processor_power_init(pr, device);
+
+ pr->cdev = thermal_cooling_device_register("Processor", device,
+ &processor_cooling_ops);
+ if (IS_ERR(pr->cdev)) {
+ result = PTR_ERR(pr->cdev);
+ goto err_power_exit;
+ }
+
+ dev_dbg(&device->dev, "registered as cooling_device%d\n",
+ pr->cdev->id);
+
+ result = sysfs_create_link(&device->dev.kobj,
+ &pr->cdev->device.kobj,
+ "thermal_cooling");
+ if (result) {
+ printk(KERN_ERR PREFIX "Create sysfs link\n");
+ goto err_thermal_unregister;
+ }
+ result = sysfs_create_link(&pr->cdev->device.kobj,
+ &device->dev.kobj,
+ "device");
+ if (result) {
+ printk(KERN_ERR PREFIX "Create sysfs link\n");
+ goto err_remove_sysfs_thermal;
+ }
+
+ return 0;
+
+err_remove_sysfs_thermal:
+ sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+err_thermal_unregister:
+ thermal_cooling_device_unregister(pr->cdev);
+err_power_exit:
+ acpi_processor_power_exit(pr, device);
+
+ return result;
+}
+
+/*
+ * Do not put anything in here which needs the core to be online.
+ * For example MSR access or setting up things which check for cpuinfo_x86
+ * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
+ * Such things have to be put in and set up above in acpi_processor_start()
+ */
static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
struct acpi_processor *pr = NULL;
@@ -495,48 +579,27 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
goto err_free_cpumask;
}
-#ifdef CONFIG_CPU_FREQ
- acpi_processor_ppc_has_changed(pr, 0);
-#endif
- acpi_processor_get_throttling_info(pr);
- acpi_processor_get_limit_info(pr);
-
- if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
- acpi_processor_power_init(pr, device);
-
- pr->cdev = thermal_cooling_device_register("Processor", device,
- &processor_cooling_ops);
- if (IS_ERR(pr->cdev)) {
- result = PTR_ERR(pr->cdev);
- goto err_power_exit;
- }
+ /*
+ * Do not start hotplugged CPUs now, but when they
+ * are onlined the first time
+ */
+ if (pr->flags.need_hotplug_init)
+ return 0;
- dev_dbg(&device->dev, "registered as cooling_device%d\n",
- pr->cdev->id);
+ /*
+ * Do not start hotplugged CPUs now, but when they
+ * are onlined the first time
+ */
+ if (pr->flags.need_hotplug_init)
+ return 0;
- result = sysfs_create_link(&device->dev.kobj,
- &pr->cdev->device.kobj,
- "thermal_cooling");
- if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
- goto err_thermal_unregister;
- }
- result = sysfs_create_link(&pr->cdev->device.kobj,
- &device->dev.kobj,
- "device");
- if (result) {
- printk(KERN_ERR PREFIX "Create sysfs link\n");
+ result = acpi_processor_start(pr);
+ if (result)
goto err_remove_sysfs;
- }
return 0;
err_remove_sysfs:
- sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
- thermal_cooling_device_unregister(pr->cdev);
-err_power_exit:
- acpi_processor_power_exit(pr, device);
sysfs_remove_link(&device->dev.kobj, "sysdev");
err_free_cpumask:
free_cpumask_var(pr->throttling.shared_cpu_map);
@@ -735,6 +798,17 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
return AE_ERROR;
}
+ /* CPU got hot-plugged, but cpu_data is not initialized yet
+ * Set flag to delay cpu_idle/throttling initialization
+ * in:
+ * acpi_processor_add()
+ * acpi_processor_get_info()
+ * and do it when the CPU gets online the first time
+ * TBD: Cleanup above functions and try to do this more elegant.
+ */
+ printk(KERN_INFO "CPU %d got hotplugged\n", pr->id);
+ pr->flags.need_hotplug_init = 1;
+
return AE_OK;
}
diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c
index 0a7ed69546ba..ca191ff97844 100644
--- a/trunk/drivers/acpi/sleep.c
+++ b/trunk/drivers/acpi/sleep.c
@@ -438,6 +438,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
},
{
.callback = init_nvs_nosave,
+ .ident = "Sony Vaio VPCCW29FX",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
+ },
+ },
+ {
+ .callback = init_nvs_nosave,
.ident = "Averatec AV1020-ED2",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile
index 2c8272dd93c4..610f9997a403 100644
--- a/trunk/drivers/base/Makefile
+++ b/trunk/drivers/base/Makefile
@@ -1,6 +1,6 @@
# Makefile for the Linux device tree
-obj-y := core.o sys.o bus.o dd.o syscore.o \
+obj-y := core.o bus.o dd.o syscore.o \
driver.o class.o platform.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o \
diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c
index 4a67cc0c8b37..74dda4f697f9 100644
--- a/trunk/drivers/base/core.c
+++ b/trunk/drivers/base/core.c
@@ -632,6 +632,11 @@ static void klist_children_put(struct klist_node *n)
* may be used for reference counting of @dev after calling this
* function.
*
+ * All fields in @dev must be initialized by the caller to 0, except
+ * for those explicitly set to some other value. The simplest
+ * approach is to use kzalloc() to allocate the structure containing
+ * @dev.
+ *
* NOTE: Use put_device() to give up your reference instead of freeing
* @dev directly once you have called this function.
*/
@@ -930,6 +935,13 @@ int device_private_init(struct device *dev)
* to the global and sibling lists for the device, then
* adds it to the other relevant subsystems of the driver model.
*
+ * Do not call this routine or device_register() more than once for
+ * any device structure. The driver model core is not designed to work
+ * with devices that get unregistered and then spring back to life.
+ * (Among other things, it's very hard to guarantee that all references
+ * to the previous incarnation of @dev have been dropped.) Allocate
+ * and register a fresh new struct device instead.
+ *
* NOTE: _Never_ directly free @dev after calling this function, even
* if it returned an error! Always use put_device() to give up your
* reference instead.
@@ -1022,7 +1034,7 @@ int device_add(struct device *dev)
device_pm_add(dev);
/* Notify clients of device addition. This call must come
- * after dpm_sysf_add() and before kobject_uevent().
+ * after dpm_sysfs_add() and before kobject_uevent().
*/
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
@@ -1090,6 +1102,9 @@ int device_add(struct device *dev)
* have a clearly defined need to use and refcount the device
* before it is added to the hierarchy.
*
+ * For more information, see the kerneldoc for device_initialize()
+ * and device_add().
+ *
* NOTE: _Never_ directly free @dev after calling this function, even
* if it returned an error! Always use put_device() to give up the
* reference initialized in this function instead.
diff --git a/trunk/drivers/base/regmap/regmap.c b/trunk/drivers/base/regmap/regmap.c
index be10a4ff6609..65558034318f 100644
--- a/trunk/drivers/base/regmap/regmap.c
+++ b/trunk/drivers/base/regmap/regmap.c
@@ -284,6 +284,9 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
map->precious_reg = config->precious_reg;
map->cache_type = config->cache_type;
+ map->cache_bypass = false;
+ map->cache_only = false;
+
ret = regcache_init(map, config);
mutex_unlock(&map->lock);
diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c
deleted file mode 100644
index 409f5ce78829..000000000000
--- a/trunk/drivers/base/sys.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc)
- *
- * Copyright (c) 2002-3 Patrick Mochel
- * 2002-3 Open Source Development Lab
- *
- * This file is released under the GPLv2
- *
- * This exports a 'system' bus type.
- * By default, a 'sys' bus gets added to the root of the system. There will
- * always be core system devices. Devices can use sysdev_register() to
- * add themselves as children of the system bus.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "base.h"
-
-#define to_sysdev(k) container_of(k, struct sys_device, kobj)
-#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr)
-
-
-static ssize_t
-sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
-{
- struct sys_device *sysdev = to_sysdev(kobj);
- struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
-
- if (sysdev_attr->show)
- return sysdev_attr->show(sysdev, sysdev_attr, buffer);
- return -EIO;
-}
-
-
-static ssize_t
-sysdev_store(struct kobject *kobj, struct attribute *attr,
- const char *buffer, size_t count)
-{
- struct sys_device *sysdev = to_sysdev(kobj);
- struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
-
- if (sysdev_attr->store)
- return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
- return -EIO;
-}
-
-static const struct sysfs_ops sysfs_ops = {
- .show = sysdev_show,
- .store = sysdev_store,
-};
-
-static struct kobj_type ktype_sysdev = {
- .sysfs_ops = &sysfs_ops,
-};
-
-
-int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
-{
- return sysfs_create_file(&s->kobj, &a->attr);
-}
-
-
-void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
-{
- sysfs_remove_file(&s->kobj, &a->attr);
-}
-
-EXPORT_SYMBOL_GPL(sysdev_create_file);
-EXPORT_SYMBOL_GPL(sysdev_remove_file);
-
-#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj)
-#define to_sysdev_class_attr(a) container_of(a, \
- struct sysdev_class_attribute, attr)
-
-static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
- char *buffer)
-{
- struct sysdev_class *class = to_sysdev_class(kobj);
- struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
-
- if (class_attr->show)
- return class_attr->show(class, class_attr, buffer);
- return -EIO;
-}
-
-static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
- const char *buffer, size_t count)
-{
- struct sysdev_class *class = to_sysdev_class(kobj);
- struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
-
- if (class_attr->store)
- return class_attr->store(class, class_attr, buffer, count);
- return -EIO;
-}
-
-static const struct sysfs_ops sysfs_class_ops = {
- .show = sysdev_class_show,
- .store = sysdev_class_store,
-};
-
-static struct kobj_type ktype_sysdev_class = {
- .sysfs_ops = &sysfs_class_ops,
-};
-
-int sysdev_class_create_file(struct sysdev_class *c,
- struct sysdev_class_attribute *a)
-{
- return sysfs_create_file(&c->kset.kobj, &a->attr);
-}
-EXPORT_SYMBOL_GPL(sysdev_class_create_file);
-
-void sysdev_class_remove_file(struct sysdev_class *c,
- struct sysdev_class_attribute *a)
-{
- sysfs_remove_file(&c->kset.kobj, &a->attr);
-}
-EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
-
-extern struct kset *system_kset;
-
-int sysdev_class_register(struct sysdev_class *cls)
-{
- int retval;
-
- pr_debug("Registering sysdev class '%s'\n", cls->name);
-
- INIT_LIST_HEAD(&cls->drivers);
- memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
- cls->kset.kobj.parent = &system_kset->kobj;
- cls->kset.kobj.ktype = &ktype_sysdev_class;
- cls->kset.kobj.kset = system_kset;
-
- retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name);
- if (retval)
- return retval;
-
- retval = kset_register(&cls->kset);
- if (!retval && cls->attrs)
- retval = sysfs_create_files(&cls->kset.kobj,
- (const struct attribute **)cls->attrs);
- return retval;
-}
-
-void sysdev_class_unregister(struct sysdev_class *cls)
-{
- pr_debug("Unregistering sysdev class '%s'\n",
- kobject_name(&cls->kset.kobj));
- if (cls->attrs)
- sysfs_remove_files(&cls->kset.kobj,
- (const struct attribute **)cls->attrs);
- kset_unregister(&cls->kset);
-}
-
-EXPORT_SYMBOL_GPL(sysdev_class_register);
-EXPORT_SYMBOL_GPL(sysdev_class_unregister);
-
-static DEFINE_MUTEX(sysdev_drivers_lock);
-
-/*
- * @dev != NULL means that we're unwinding because some drv->add()
- * failed for some reason. You need to grab sysdev_drivers_lock before
- * calling this.
- */
-static void __sysdev_driver_remove(struct sysdev_class *cls,
- struct sysdev_driver *drv,
- struct sys_device *from_dev)
-{
- struct sys_device *dev = from_dev;
-
- list_del_init(&drv->entry);
- if (!cls)
- return;
-
- if (!drv->remove)
- goto kset_put;
-
- if (dev)
- list_for_each_entry_continue_reverse(dev, &cls->kset.list,
- kobj.entry)
- drv->remove(dev);
- else
- list_for_each_entry(dev, &cls->kset.list, kobj.entry)
- drv->remove(dev);
-
-kset_put:
- kset_put(&cls->kset);
-}
-
-/**
- * sysdev_driver_register - Register auxiliary driver
- * @cls: Device class driver belongs to.
- * @drv: Driver.
- *
- * @drv is inserted into @cls->drivers to be
- * called on each operation on devices of that class. The refcount
- * of @cls is incremented.
- */
-int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
-{
- struct sys_device *dev = NULL;
- int err = 0;
-
- if (!cls) {
- WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n",
- __func__);
- return -EINVAL;
- }
-
- /* Check whether this driver has already been added to a class. */
- if (drv->entry.next && !list_empty(&drv->entry))
- WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already"
- " been registered to a class, something is wrong, but "
- "will forge on!\n", cls->name, drv);
-
- mutex_lock(&sysdev_drivers_lock);
- if (cls && kset_get(&cls->kset)) {
- list_add_tail(&drv->entry, &cls->drivers);
-
- /* If devices of this class already exist, tell the driver */
- if (drv->add) {
- list_for_each_entry(dev, &cls->kset.list, kobj.entry) {
- err = drv->add(dev);
- if (err)
- goto unwind;
- }
- }
- } else {
- err = -EINVAL;
- WARN(1, KERN_ERR "%s: invalid device class\n", __func__);
- }
-
- goto unlock;
-
-unwind:
- __sysdev_driver_remove(cls, drv, dev);
-
-unlock:
- mutex_unlock(&sysdev_drivers_lock);
- return err;
-}
-
-/**
- * sysdev_driver_unregister - Remove an auxiliary driver.
- * @cls: Class driver belongs to.
- * @drv: Driver.
- */
-void sysdev_driver_unregister(struct sysdev_class *cls,
- struct sysdev_driver *drv)
-{
- mutex_lock(&sysdev_drivers_lock);
- __sysdev_driver_remove(cls, drv, NULL);
- mutex_unlock(&sysdev_drivers_lock);
-}
-EXPORT_SYMBOL_GPL(sysdev_driver_register);
-EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
-
-/**
- * sysdev_register - add a system device to the tree
- * @sysdev: device in question
- *
- */
-int sysdev_register(struct sys_device *sysdev)
-{
- int error;
- struct sysdev_class *cls = sysdev->cls;
-
- if (!cls)
- return -EINVAL;
-
- pr_debug("Registering sys device of class '%s'\n",
- kobject_name(&cls->kset.kobj));
-
- /* initialize the kobject to 0, in case it had previously been used */
- memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
-
- /* Make sure the kset is set */
- sysdev->kobj.kset = &cls->kset;
-
- /* Register the object */
- error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL,
- "%s%d", kobject_name(&cls->kset.kobj),
- sysdev->id);
-
- if (!error) {
- struct sysdev_driver *drv;
-
- pr_debug("Registering sys device '%s'\n",
- kobject_name(&sysdev->kobj));
-
- mutex_lock(&sysdev_drivers_lock);
- /* Generic notification is implicit, because it's that
- * code that should have called us.
- */
-
- /* Notify class auxiliary drivers */
- list_for_each_entry(drv, &cls->drivers, entry) {
- if (drv->add)
- drv->add(sysdev);
- }
- mutex_unlock(&sysdev_drivers_lock);
- kobject_uevent(&sysdev->kobj, KOBJ_ADD);
- }
-
- return error;
-}
-
-void sysdev_unregister(struct sys_device *sysdev)
-{
- struct sysdev_driver *drv;
-
- mutex_lock(&sysdev_drivers_lock);
- list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
- if (drv->remove)
- drv->remove(sysdev);
- }
- mutex_unlock(&sysdev_drivers_lock);
-
- kobject_put(&sysdev->kobj);
-}
-
-EXPORT_SYMBOL_GPL(sysdev_register);
-EXPORT_SYMBOL_GPL(sysdev_unregister);
-
-#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
-
-ssize_t sysdev_store_ulong(struct sys_device *sysdev,
- struct sysdev_attribute *attr,
- const char *buf, size_t size)
-{
- struct sysdev_ext_attribute *ea = to_ext_attr(attr);
- char *end;
- unsigned long new = simple_strtoul(buf, &end, 0);
- if (end == buf)
- return -EINVAL;
- *(unsigned long *)(ea->var) = new;
- /* Always return full write size even if we didn't consume all */
- return size;
-}
-EXPORT_SYMBOL_GPL(sysdev_store_ulong);
-
-ssize_t sysdev_show_ulong(struct sys_device *sysdev,
- struct sysdev_attribute *attr,
- char *buf)
-{
- struct sysdev_ext_attribute *ea = to_ext_attr(attr);
- return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
-}
-EXPORT_SYMBOL_GPL(sysdev_show_ulong);
-
-ssize_t sysdev_store_int(struct sys_device *sysdev,
- struct sysdev_attribute *attr,
- const char *buf, size_t size)
-{
- struct sysdev_ext_attribute *ea = to_ext_attr(attr);
- char *end;
- long new = simple_strtol(buf, &end, 0);
- if (end == buf || new > INT_MAX || new < INT_MIN)
- return -EINVAL;
- *(int *)(ea->var) = new;
- /* Always return full write size even if we didn't consume all */
- return size;
-}
-EXPORT_SYMBOL_GPL(sysdev_store_int);
-
-ssize_t sysdev_show_int(struct sys_device *sysdev,
- struct sysdev_attribute *attr,
- char *buf)
-{
- struct sysdev_ext_attribute *ea = to_ext_attr(attr);
- return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
-}
-EXPORT_SYMBOL_GPL(sysdev_show_int);
-
diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c
index 3fd31dec8c9c..a6278e7e61a0 100644
--- a/trunk/drivers/block/rbd.c
+++ b/trunk/drivers/block/rbd.c
@@ -380,6 +380,7 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
rbdc = __rbd_client_find(opt);
if (rbdc) {
ceph_destroy_options(opt);
+ kfree(rbd_opts);
/* using an existing client */
kref_get(&rbdc->kref);
@@ -406,15 +407,15 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
/*
* Destroy ceph client
+ *
+ * Caller must hold node_lock.
*/
static void rbd_client_release(struct kref *kref)
{
struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref);
dout("rbd_release_client %p\n", rbdc);
- spin_lock(&node_lock);
list_del(&rbdc->node);
- spin_unlock(&node_lock);
ceph_destroy_client(rbdc->client);
kfree(rbdc->rbd_opts);
@@ -427,7 +428,9 @@ static void rbd_client_release(struct kref *kref)
*/
static void rbd_put_client(struct rbd_device *rbd_dev)
{
+ spin_lock(&node_lock);
kref_put(&rbd_dev->rbd_client->kref, rbd_client_release);
+ spin_unlock(&node_lock);
rbd_dev->rbd_client = NULL;
rbd_dev->client = NULL;
}
diff --git a/trunk/drivers/char/agp/backend.c b/trunk/drivers/char/agp/backend.c
index 4b71647782d0..317c28ce8328 100644
--- a/trunk/drivers/char/agp/backend.c
+++ b/trunk/drivers/char/agp/backend.c
@@ -194,10 +194,10 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
err_out:
if (bridge->driver->needs_scratch_page) {
- void *va = page_address(bridge->scratch_page_page);
+ struct page *page = bridge->scratch_page_page;
- bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
- bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
+ bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP);
+ bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE);
}
if (got_gatt)
bridge->driver->free_gatt_table(bridge);
@@ -221,10 +221,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page) {
- void *va = page_address(bridge->scratch_page_page);
+ struct page *page = bridge->scratch_page_page;
- bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
- bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
+ bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP);
+ bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE);
}
}
diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c
index 97f87b29b9f3..f4aed5fc2cb6 100644
--- a/trunk/drivers/dma/at_hdmac.c
+++ b/trunk/drivers/dma/at_hdmac.c
@@ -1343,7 +1343,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
tasklet_init(&atchan->tasklet, atc_tasklet,
(unsigned long)atchan);
- atc_enable_irq(atchan);
+ atc_enable_chan_irq(atdma, i);
}
/* set base routines */
@@ -1410,7 +1410,7 @@ static int __exit at_dma_remove(struct platform_device *pdev)
struct at_dma_chan *atchan = to_at_dma_chan(chan);
/* Disable interrupts */
- atc_disable_irq(atchan);
+ atc_disable_chan_irq(atdma, chan->chan_id);
tasklet_disable(&atchan->tasklet);
tasklet_kill(&atchan->tasklet);
diff --git a/trunk/drivers/dma/at_hdmac_regs.h b/trunk/drivers/dma/at_hdmac_regs.h
index dcaedfc181cf..a8d3277d60b5 100644
--- a/trunk/drivers/dma/at_hdmac_regs.h
+++ b/trunk/drivers/dma/at_hdmac_regs.h
@@ -327,28 +327,27 @@ static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli)
}
-static void atc_setup_irq(struct at_dma_chan *atchan, int on)
+static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on)
{
- struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
- u32 ebci;
+ u32 ebci;
/* enable interrupts on buffer transfer completion & error */
- ebci = AT_DMA_BTC(atchan->chan_common.chan_id)
- | AT_DMA_ERR(atchan->chan_common.chan_id);
+ ebci = AT_DMA_BTC(chan_id)
+ | AT_DMA_ERR(chan_id);
if (on)
dma_writel(atdma, EBCIER, ebci);
else
dma_writel(atdma, EBCIDR, ebci);
}
-static inline void atc_enable_irq(struct at_dma_chan *atchan)
+static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id)
{
- atc_setup_irq(atchan, 1);
+ atc_setup_irq(atdma, chan_id, 1);
}
-static inline void atc_disable_irq(struct at_dma_chan *atchan)
+static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id)
{
- atc_setup_irq(atchan, 0);
+ atc_setup_irq(atdma, chan_id, 0);
}
diff --git a/trunk/drivers/dma/dmatest.c b/trunk/drivers/dma/dmatest.c
index 2b8661b54eaf..24225f0fdcd8 100644
--- a/trunk/drivers/dma/dmatest.c
+++ b/trunk/drivers/dma/dmatest.c
@@ -599,7 +599,7 @@ static int dmatest_add_channel(struct dma_chan *chan)
}
if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
cnt = dmatest_add_threads(dtc, DMA_PQ);
- thread_count += cnt > 0 ?: 0;
+ thread_count += cnt > 0 ? cnt : 0;
}
pr_info("dmatest: Started %u threads using %s\n",
diff --git a/trunk/drivers/dma/imx-sdma.c b/trunk/drivers/dma/imx-sdma.c
index a8af379680c1..8bc5acf36ee5 100644
--- a/trunk/drivers/dma/imx-sdma.c
+++ b/trunk/drivers/dma/imx-sdma.c
@@ -1102,11 +1102,13 @@ static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
case DMA_SLAVE_CONFIG:
if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
sdmac->per_address = dmaengine_cfg->src_addr;
- sdmac->watermark_level = dmaengine_cfg->src_maxburst;
+ sdmac->watermark_level = dmaengine_cfg->src_maxburst *
+ dmaengine_cfg->src_addr_width;
sdmac->word_size = dmaengine_cfg->src_addr_width;
} else {
sdmac->per_address = dmaengine_cfg->dst_addr;
- sdmac->watermark_level = dmaengine_cfg->dst_maxburst;
+ sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
+ dmaengine_cfg->dst_addr_width;
sdmac->word_size = dmaengine_cfg->dst_addr_width;
}
sdmac->direction = dmaengine_cfg->direction;
diff --git a/trunk/drivers/dma/shdma.c b/trunk/drivers/dma/shdma.c
index 54043cd831c8..812fd76e9c18 100644
--- a/trunk/drivers/dma/shdma.c
+++ b/trunk/drivers/dma/shdma.c
@@ -1262,7 +1262,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&shdev->common.channels);
- dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
+ if (!pdata->slave_only)
+ dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
if (pdata->slave && pdata->slave_num)
dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
diff --git a/trunk/drivers/firewire/ohci.c b/trunk/drivers/firewire/ohci.c
index 6628feaa7622..7f5f0da726da 100644
--- a/trunk/drivers/firewire/ohci.c
+++ b/trunk/drivers/firewire/ohci.c
@@ -263,6 +263,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
+#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
#define PCI_DEVICE_ID_TI_TSB12LV26 0x8020
@@ -289,6 +290,9 @@ static const struct {
{PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
QUIRK_NO_MSI},
+ {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID,
+ QUIRK_RESET_PACKET},
+
{PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
QUIRK_NO_MSI},
@@ -299,7 +303,7 @@ static const struct {
QUIRK_NO_MSI},
{PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
- QUIRK_CYCLE_TIMER},
+ QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
{PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
diff --git a/trunk/drivers/gpio/gpio-lpc32xx.c b/trunk/drivers/gpio/gpio-lpc32xx.c
index 5b6948081f8f..ddfacc5ce56d 100644
--- a/trunk/drivers/gpio/gpio-lpc32xx.c
+++ b/trunk/drivers/gpio/gpio-lpc32xx.c
@@ -96,7 +96,7 @@ static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
};
static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
- "gpi000", "gpio01", "gpio02", "gpio03",
+ "gpio00", "gpio01", "gpio02", "gpio03",
"gpio04", "gpio05"
};
diff --git a/trunk/drivers/gpio/gpio-ml-ioh.c b/trunk/drivers/gpio/gpio-ml-ioh.c
index 03d6dd5dcb77..f0febe5b8221 100644
--- a/trunk/drivers/gpio/gpio-ml-ioh.c
+++ b/trunk/drivers/gpio/gpio-ml-ioh.c
@@ -448,6 +448,7 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
chip->reg = chip->base;
chip->ch = i;
mutex_init(&chip->lock);
+ spin_lock_init(&chip->spinlock);
ioh_gpio_setup(chip, num_ports[i]);
ret = gpiochip_add(&chip->gpio);
if (ret) {
diff --git a/trunk/drivers/gpio/gpio-pch.c b/trunk/drivers/gpio/gpio-pch.c
index 68fa55e86eb1..e8729cc2ba2b 100644
--- a/trunk/drivers/gpio/gpio-pch.c
+++ b/trunk/drivers/gpio/gpio-pch.c
@@ -392,6 +392,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev,
chip->reg = chip->base;
pci_set_drvdata(pdev, chip);
mutex_init(&chip->lock);
+ spin_lock_init(&chip->spinlock);
pch_gpio_setup(chip);
ret = gpiochip_add(&chip->gpio);
if (ret) {
diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c
index a7661773c052..0a79a1167a25 100644
--- a/trunk/drivers/gpio/gpio-samsung.c
+++ b/trunk/drivers/gpio/gpio-samsung.c
@@ -2387,27 +2387,30 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
};
#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
-static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,
- const void *gpio_spec, u32 *flags)
+static int exynos4_gpio_xlate(struct gpio_chip *gc,
+ const struct of_phandle_args *gpiospec, u32 *flags)
{
- const __be32 *gpio = gpio_spec;
- const u32 n = be32_to_cpup(gpio);
- unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
+ unsigned int pin;
if (WARN_ON(gc->of_gpio_n_cells < 4))
return -EINVAL;
- if (n > gc->ngpio)
+ if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
return -EINVAL;
- if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1]))))
+ if (gpiospec->args[0] > gc->ngpio)
+ return -EINVAL;
+
+ pin = gc->base + gpiospec->args[0];
+
+ if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
pr_warn("gpio_xlate: failed to set pin function\n");
- if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2])))
+ if (s3c_gpio_setpull(pin, gpiospec->args[2]))
pr_warn("gpio_xlate: failed to set pin pull up/down\n");
- if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3])))
+ if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
pr_warn("gpio_xlate: failed to set pin drive strength\n");
- return n;
+ return gpiospec->args[0];
}
static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
diff --git a/trunk/drivers/gpu/drm/drm_auth.c b/trunk/drivers/gpu/drm/drm_auth.c
index 3f46772f0cb2..ba23790450e9 100644
--- a/trunk/drivers/gpu/drm/drm_auth.c
+++ b/trunk/drivers/gpu/drm/drm_auth.c
@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv,
* Searches and unlinks the entry in drm_device::magiclist with the magic
* number hash key, while holding the drm_device::struct_mutex lock.
*/
-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
{
struct drm_magic_entry *pt;
struct drm_hash_item *hash;
@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
* If there is a magic number in drm_file::magic then use it, otherwise
* searches an unique non-zero magic number and add it associating it with \p
* file_priv.
+ * This ioctl needs protection by the drm_global_mutex, which protects
+ * struct drm_file::magic and struct drm_magic_entry::priv.
*/
int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
* \return zero if authentication successed, or a negative number otherwise.
*
* Checks if \p file_priv is associated with the magic number passed in \arg.
+ * This ioctl needs protection by the drm_global_mutex, which protects
+ * struct drm_file::magic and struct drm_magic_entry::priv.
*/
int drm_authmagic(struct drm_device *dev, void *data,
struct drm_file *file_priv)
diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c
index c00cf154cc0b..6263b0147598 100644
--- a/trunk/drivers/gpu/drm/drm_fops.c
+++ b/trunk/drivers/gpu/drm/drm_fops.c
@@ -487,6 +487,11 @@ int drm_release(struct inode *inode, struct file *filp)
(long)old_encode_dev(file_priv->minor->device),
dev->open_count);
+ /* Release any auth tokens that might point to this file_priv,
+ (do that under the drm_global_mutex) */
+ if (file_priv->magic)
+ (void) drm_remove_magic(file_priv->master, file_priv->magic);
+
/* if the master has gone away we can't do anything with the lock */
if (file_priv->minor->master)
drm_master_release(dev, filp);
diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c
index 396e60ce8114..f8625e290728 100644
--- a/trunk/drivers/gpu/drm/drm_gem.c
+++ b/trunk/drivers/gpu/drm/drm_gem.c
@@ -140,7 +140,7 @@ int drm_gem_object_init(struct drm_device *dev,
obj->dev = dev;
obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
if (IS_ERR(obj->filp))
- return -ENOMEM;
+ return PTR_ERR(obj->filp);
kref_init(&obj->refcount);
atomic_set(&obj->handle_count, 0);
diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig
index f9aaa56eae07..b9e5266c341b 100644
--- a/trunk/drivers/gpu/drm/exynos/Kconfig
+++ b/trunk/drivers/gpu/drm/exynos/Kconfig
@@ -13,7 +13,7 @@ config DRM_EXYNOS
config DRM_EXYNOS_FIMD
tristate "Exynos DRM FIMD"
- depends on DRM_EXYNOS
+ depends on DRM_EXYNOS && !FB_S3C
default n
help
Choose this option if you want to use Exynos FIMD for DRM.
@@ -21,7 +21,7 @@ config DRM_EXYNOS_FIMD
config DRM_EXYNOS_HDMI
tristate "Exynos DRM HDMI"
- depends on DRM_EXYNOS
+ depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
help
Choose this option if you want to use Exynos HDMI for DRM.
If M is selected, the module will be called exynos_drm_hdmi
diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index ca83139cd309..b6a737d196ae 100644
--- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -158,7 +158,8 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- pm_runtime_put_sync(subdrv_dev);
+ if (!ctx->suspended)
+ pm_runtime_put_sync(subdrv_dev);
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -734,6 +735,46 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
writel(val, ctx->regs + SHADOWCON);
}
+static int fimd_power_on(struct fimd_context *ctx, bool enable)
+{
+ struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
+ struct device *dev = subdrv->manager.dev;
+
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ if (enable != false && enable != true)
+ return -EINVAL;
+
+ if (enable) {
+ int ret;
+
+ ret = clk_enable(ctx->bus_clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(ctx->lcd_clk);
+ if (ret < 0) {
+ clk_disable(ctx->bus_clk);
+ return ret;
+ }
+
+ ctx->suspended = false;
+
+ /* if vblank was enabled status, enable it again. */
+ if (test_and_clear_bit(0, &ctx->irq_flags))
+ fimd_enable_vblank(dev);
+
+ fimd_apply(dev);
+ } else {
+ clk_disable(ctx->lcd_clk);
+ clk_disable(ctx->bus_clk);
+
+ ctx->suspended = true;
+ }
+
+ return 0;
+}
+
static int __devinit fimd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -911,39 +952,30 @@ static int __devexit fimd_remove(struct platform_device *pdev)
#ifdef CONFIG_PM_SLEEP
static int fimd_suspend(struct device *dev)
{
- int ret;
+ struct fimd_context *ctx = get_fimd_context(dev);
if (pm_runtime_suspended(dev))
return 0;
- ret = pm_runtime_suspend(dev);
- if (ret < 0)
- return ret;
-
- return 0;
+ /*
+ * do not use pm_runtime_suspend(). if pm_runtime_suspend() is
+ * called here, an error would be returned by that interface
+ * because the usage_count of pm runtime is more than 1.
+ */
+ return fimd_power_on(ctx, false);
}
static int fimd_resume(struct device *dev)
{
- int ret;
-
- ret = pm_runtime_resume(dev);
- if (ret < 0) {
- DRM_ERROR("failed to resume runtime pm.\n");
- return ret;
- }
-
- pm_runtime_disable(dev);
-
- ret = pm_runtime_set_active(dev);
- if (ret < 0) {
- DRM_ERROR("failed to active runtime pm.\n");
- pm_runtime_enable(dev);
- pm_runtime_suspend(dev);
- return ret;
- }
+ struct fimd_context *ctx = get_fimd_context(dev);
- pm_runtime_enable(dev);
+ /*
+ * if entered to sleep when lcd panel was on, the usage_count
+ * of pm runtime would still be 1 so in this case, fimd driver
+ * should be on directly not drawing on pm runtime interface.
+ */
+ if (!pm_runtime_suspended(dev))
+ return fimd_power_on(ctx, true);
return 0;
}
@@ -956,39 +988,16 @@ static int fimd_runtime_suspend(struct device *dev)
DRM_DEBUG_KMS("%s\n", __FILE__);
- clk_disable(ctx->lcd_clk);
- clk_disable(ctx->bus_clk);
-
- ctx->suspended = true;
- return 0;
+ return fimd_power_on(ctx, false);
}
static int fimd_runtime_resume(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
- int ret;
DRM_DEBUG_KMS("%s\n", __FILE__);
- ret = clk_enable(ctx->bus_clk);
- if (ret < 0)
- return ret;
-
- ret = clk_enable(ctx->lcd_clk);
- if (ret < 0) {
- clk_disable(ctx->bus_clk);
- return ret;
- }
-
- ctx->suspended = false;
-
- /* if vblank was enabled status, enable it again. */
- if (test_and_clear_bit(0, &ctx->irq_flags))
- fimd_enable_vblank(dev);
-
- fimd_apply(dev);
-
- return 0;
+ return fimd_power_on(ctx, true);
}
#endif
diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c
index f48f7ce92f5f..3429d3fd93f3 100644
--- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1116,8 +1116,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
err_iomap:
iounmap(hdata->regs);
err_req_region:
- release_resource(hdata->regs_res);
- kfree(hdata->regs_res);
+ release_mem_region(hdata->regs_res->start,
+ resource_size(hdata->regs_res));
err_resource:
hdmi_resources_cleanup(hdata);
err_data:
@@ -1145,8 +1145,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev)
iounmap(hdata->regs);
- release_resource(hdata->regs_res);
- kfree(hdata->regs_res);
+ release_mem_region(hdata->regs_res->start,
+ resource_size(hdata->regs_res));
/* hdmiphy i2c driver */
i2c_del_driver(&hdmiphy_driver);
diff --git a/trunk/drivers/gpu/drm/gma500/framebuffer.c b/trunk/drivers/gpu/drm/gma500/framebuffer.c
index 791c0ef1a65b..830dfdd6bf15 100644
--- a/trunk/drivers/gpu/drm/gma500/framebuffer.c
+++ b/trunk/drivers/gpu/drm/gma500/framebuffer.c
@@ -113,12 +113,12 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info)
void psbfb_suspend(struct drm_device *dev)
{
- struct drm_framebuffer *fb = 0;
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
+ struct drm_framebuffer *fb;
console_lock();
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
+ struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct fb_info *info = psbfb->fbdev;
fb_set_suspend(info, 1);
drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
@@ -129,12 +129,12 @@ void psbfb_suspend(struct drm_device *dev)
void psbfb_resume(struct drm_device *dev)
{
- struct drm_framebuffer *fb = 0;
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
+ struct drm_framebuffer *fb;
console_lock();
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
+ struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct fb_info *info = psbfb->fbdev;
fb_set_suspend(info, 0);
drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
diff --git a/trunk/drivers/gpu/drm/gma500/gtt.c b/trunk/drivers/gpu/drm/gma500/gtt.c
index e770bd190a5c..5d5330f667f1 100644
--- a/trunk/drivers/gpu/drm/gma500/gtt.c
+++ b/trunk/drivers/gpu/drm/gma500/gtt.c
@@ -20,6 +20,7 @@
*/
#include
+#include
#include "psb_drv.h"
@@ -203,9 +204,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
gt->npage = pages;
for (i = 0; i < pages; i++) {
- /* FIXME: needs updating as per mail from Hugh Dickins */
- p = read_cache_page_gfp(mapping, i,
- __GFP_COLD | GFP_KERNEL);
+ p = shmem_read_mapping_page(mapping, i);
if (IS_ERR(p))
goto err;
gt->pages[i] = p;
diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c
index f7c17b239833..7f4b4e10246e 100644
--- a/trunk/drivers/gpu/drm/i810/i810_dma.c
+++ b/trunk/drivers/gpu/drm/i810/i810_dma.c
@@ -886,7 +886,7 @@ static int i810_flush_queue(struct drm_device *dev)
}
/* Must be called with the lock held */
-void i810_driver_reclaim_buffers(struct drm_device *dev,
+static void i810_reclaim_buffers(struct drm_device *dev,
struct drm_file *file_priv)
{
struct drm_device_dma *dma = dev->dma;
@@ -1223,17 +1223,12 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
if (dev_priv->page_flipping)
i810_do_cleanup_pageflip(dev);
}
+}
- if (file_priv->master && file_priv->master->lock.hw_lock) {
- drm_idlelock_take(&file_priv->master->lock);
- i810_driver_reclaim_buffers(dev, file_priv);
- drm_idlelock_release(&file_priv->master->lock);
- } else {
- /* master disappeared, clean up stuff anyway and hope nothing
- * goes wrong */
- i810_driver_reclaim_buffers(dev, file_priv);
- }
-
+void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
+ struct drm_file *file_priv)
+{
+ i810_reclaim_buffers(dev, file_priv);
}
int i810_driver_dma_quiescent(struct drm_device *dev)
diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.c b/trunk/drivers/gpu/drm/i810/i810_drv.c
index 053f1ee58393..ec12f7dc717a 100644
--- a/trunk/drivers/gpu/drm/i810/i810_drv.c
+++ b/trunk/drivers/gpu/drm/i810/i810_drv.c
@@ -63,6 +63,7 @@ static struct drm_driver driver = {
.lastclose = i810_driver_lastclose,
.preclose = i810_driver_preclose,
.device_is_agp = i810_driver_device_is_agp,
+ .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
.dma_quiescent = i810_driver_dma_quiescent,
.ioctls = i810_ioctls,
.fops = &i810_driver_fops,
diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.h b/trunk/drivers/gpu/drm/i810/i810_drv.h
index 6e0acad9e0f5..c9339f481795 100644
--- a/trunk/drivers/gpu/drm/i810/i810_drv.h
+++ b/trunk/drivers/gpu/drm/i810/i810_drv.h
@@ -116,12 +116,14 @@ typedef struct drm_i810_private {
/* i810_dma.c */
extern int i810_driver_dma_quiescent(struct drm_device *dev);
-void i810_driver_reclaim_buffers(struct drm_device *dev,
- struct drm_file *file_priv);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
+ struct drm_file *file_priv);
extern int i810_driver_load(struct drm_device *, unsigned long flags);
extern void i810_driver_lastclose(struct drm_device *dev);
extern void i810_driver_preclose(struct drm_device *dev,
struct drm_file *file_priv);
+extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev,
+ struct drm_file *file_priv);
extern int i810_driver_device_is_agp(struct drm_device *dev);
extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c
index 11807989f918..deaa657292b4 100644
--- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c
@@ -121,11 +121,11 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
- seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s",
+ seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s",
&obj->base,
get_pin_flag(obj),
get_tiling_flag(obj),
- obj->base.size,
+ obj->base.size / 1024,
obj->base.read_domains,
obj->base.write_domain,
obj->last_rendering_seqno,
@@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
seq_printf(m, " Size : %08x\n", ring->size);
seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring));
seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring));
- if (IS_GEN6(dev)) {
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring));
seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring));
}
@@ -1075,6 +1075,7 @@ static int gen6_drpc_info(struct seq_file *m)
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 rpmodectl1, gt_core_status, rcctl1;
+ unsigned forcewake_count;
int count=0, ret;
@@ -1082,9 +1083,13 @@ static int gen6_drpc_info(struct seq_file *m)
if (ret)
return ret;
- if (atomic_read(&dev_priv->forcewake_count)) {
- seq_printf(m, "RC information inaccurate because userspace "
- "holds a reference \n");
+ spin_lock_irq(&dev_priv->gt_lock);
+ forcewake_count = dev_priv->forcewake_count;
+ spin_unlock_irq(&dev_priv->gt_lock);
+
+ if (forcewake_count) {
+ seq_printf(m, "RC information inaccurate because somebody "
+ "holds a forcewake reference \n");
} else {
/* NB: we cannot use forcewake, else we read the wrong values */
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
@@ -1106,7 +1111,7 @@ static int gen6_drpc_info(struct seq_file *m)
seq_printf(m, "SW control enabled: %s\n",
yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
GEN6_RP_MEDIA_SW_MODE));
- seq_printf(m, "RC6 Enabled: %s\n",
+ seq_printf(m, "RC1e Enabled: %s\n",
yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
seq_printf(m, "RC6 Enabled: %s\n",
yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
@@ -1398,9 +1403,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned forcewake_count;
+
+ spin_lock_irq(&dev_priv->gt_lock);
+ forcewake_count = dev_priv->forcewake_count;
+ spin_unlock_irq(&dev_priv->gt_lock);
- seq_printf(m, "forcewake count = %d\n",
- atomic_read(&dev_priv->forcewake_count));
+ seq_printf(m, "forcewake count = %u\n", forcewake_count);
return 0;
}
@@ -1665,7 +1674,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
- if (!IS_GEN6(dev))
+ if (INTEL_INFO(dev)->gen < 6)
return 0;
ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -1682,7 +1691,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file)
struct drm_device *dev = inode->i_private;
struct drm_i915_private *dev_priv = dev->dev_private;
- if (!IS_GEN6(dev))
+ if (INTEL_INFO(dev)->gen < 6)
return 0;
/*
diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c
index 5f4d5893e983..ddfe3d902b2a 100644
--- a/trunk/drivers/gpu/drm/i915/i915_dma.c
+++ b/trunk/drivers/gpu/drm/i915/i915_dma.c
@@ -2045,6 +2045,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);
+ spin_lock_init(&dev_priv->gt_lock);
spin_lock_init(&dev_priv->irq_lock);
spin_lock_init(&dev_priv->error_lock);
spin_lock_init(&dev_priv->rps_lock);
diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c
index 8f7187915b0d..308f81913562 100644
--- a/trunk/drivers/gpu/drm/i915/i915_drv.c
+++ b/trunk/drivers/gpu/drm/i915/i915_drv.c
@@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
*/
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
- WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+ unsigned long irqflags;
- /* Forcewake is atomic in case we get in here without the lock */
- if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+ if (dev_priv->forcewake_count++ == 0)
dev_priv->display.force_wake_get(dev_priv);
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}
void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
@@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
*/
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
- WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+ unsigned long irqflags;
- if (atomic_dec_and_test(&dev_priv->forcewake_count))
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+ if (--dev_priv->forcewake_count == 0)
dev_priv->display.force_wake_put(dev_priv);
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -597,9 +600,36 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags)
static int gen6_do_reset(struct drm_device *dev, u8 flags)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ int ret;
+ unsigned long irqflags;
- I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL);
- return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
+ /* Hold gt_lock across reset to prevent any register access
+ * with forcewake not set correctly
+ */
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
+
+ /* Reset the chip */
+
+ /* GEN6_GDRST is not in the gt power well, no need to check
+ * for fifo space for the write or forcewake the chip for
+ * the read
+ */
+ I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL);
+
+ /* Spin waiting for the device to ack the reset request */
+ ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500);
+
+ /* If reset with a user forcewake, try to restore, otherwise turn it off */
+ if (dev_priv->forcewake_count)
+ dev_priv->display.force_wake_get(dev_priv);
+ else
+ dev_priv->display.force_wake_put(dev_priv);
+
+ /* Restore fifo count */
+ dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
+
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
+ return ret;
}
/**
@@ -643,9 +673,6 @@ int i915_reset(struct drm_device *dev, u8 flags)
case 7:
case 6:
ret = gen6_do_reset(dev, flags);
- /* If reset with a user forcewake, try to restore */
- if (atomic_read(&dev_priv->forcewake_count))
- __gen6_gt_force_wake_get(dev_priv);
break;
case 5:
ret = ironlake_do_reset(dev, flags);
@@ -927,9 +954,14 @@ MODULE_LICENSE("GPL and additional rights");
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
u##x val = 0; \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
- gen6_gt_force_wake_get(dev_priv); \
+ unsigned long irqflags; \
+ spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
+ if (dev_priv->forcewake_count == 0) \
+ dev_priv->display.force_wake_get(dev_priv); \
val = read##y(dev_priv->regs + reg); \
- gen6_gt_force_wake_put(dev_priv); \
+ if (dev_priv->forcewake_count == 0) \
+ dev_priv->display.force_wake_put(dev_priv); \
+ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
} else { \
val = read##y(dev_priv->regs + reg); \
} \
diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h
index 602bc80baabb..9689ca38b2b3 100644
--- a/trunk/drivers/gpu/drm/i915/i915_drv.h
+++ b/trunk/drivers/gpu/drm/i915/i915_drv.h
@@ -288,7 +288,13 @@ typedef struct drm_i915_private {
int relative_constants_mode;
void __iomem *regs;
- u32 gt_fifo_count;
+ /** gt_fifo_count and the subsequent register write are synchronized
+ * with dev->struct_mutex. */
+ unsigned gt_fifo_count;
+ /** forcewake_count is protected by gt_lock */
+ unsigned forcewake_count;
+ /** gt_lock is also taken in irq contexts. */
+ struct spinlock gt_lock;
struct intel_gmbus {
struct i2c_adapter adapter;
@@ -741,8 +747,6 @@ typedef struct drm_i915_private {
struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property;
-
- atomic_t forcewake_count;
} drm_i915_private_t;
enum i915_cache_level {
diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c
index 5d433fc11ace..5bd4361ea84d 100644
--- a/trunk/drivers/gpu/drm/i915/i915_irq.c
+++ b/trunk/drivers/gpu/drm/i915/i915_irq.c
@@ -1751,7 +1751,8 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
I915_WRITE(HWSTAM, 0xeffe);
- if (IS_GEN6(dev) || IS_GEN7(dev)) {
+
+ if (IS_GEN6(dev)) {
/* Workaround stalls observed on Sandy Bridge GPUs by
* making the blitter command streamer generate a
* write to the Hardware Status Page for
diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c
index 7886e4fb60e3..2b5eb229ff2c 100644
--- a/trunk/drivers/gpu/drm/i915/i915_suspend.c
+++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c
@@ -28,14 +28,19 @@
#include "drm.h"
#include "i915_drm.h"
#include "intel_drv.h"
+#include "i915_reg.h"
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 dpll_reg;
+ /* On IVB, 3rd pipe shares PLL with another one */
+ if (pipe > 1)
+ return false;
+
if (HAS_PCH_SPLIT(dev))
- dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B;
+ dpll_reg = PCH_DPLL(pipe);
else
dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B;
@@ -822,7 +827,7 @@ int i915_save_state(struct drm_device *dev)
if (IS_IRONLAKE_M(dev))
ironlake_disable_drps(dev);
- if (IS_GEN6(dev))
+ if (INTEL_INFO(dev)->gen >= 6)
gen6_disable_rps(dev);
/* Cache mode state */
@@ -881,7 +886,7 @@ int i915_restore_state(struct drm_device *dev)
intel_init_emon(dev);
}
- if (IS_GEN6(dev)) {
+ if (INTEL_INFO(dev)->gen >= 6) {
gen6_enable_rps(dev_priv);
gen6_update_ring_freq(dev_priv);
}
diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.h b/trunk/drivers/gpu/drm/i915/intel_bios.h
index 8af3735e27c6..dbda6e3bdf07 100644
--- a/trunk/drivers/gpu/drm/i915/intel_bios.h
+++ b/trunk/drivers/gpu/drm/i915/intel_bios.h
@@ -467,8 +467,12 @@ struct edp_link_params {
struct bdb_edp {
struct edp_power_seq power_seqs[16];
u32 color_depth;
- u32 sdrrs_msa_timing_delay;
struct edp_link_params link_params[16];
+ u32 sdrrs_msa_timing_delay;
+
+ /* ith bit indicates enabled/disabled for (i+1)th panel */
+ u16 edp_s3d_feature;
+ u16 edp_t3_optimization;
} __attribute__ ((packed));
void intel_setup_bios(struct drm_device *dev);
diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c
index fee0ad02c6d0..dd729d46a61f 100644
--- a/trunk/drivers/gpu/drm/i915/intel_crt.c
+++ b/trunk/drivers/gpu/drm/i915/intel_crt.c
@@ -24,6 +24,7 @@
* Eric Anholt
*/
+#include
#include
#include
#include "drmP.h"
@@ -540,6 +541,24 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
.destroy = intel_encoder_destroy,
};
+static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id)
+{
+ DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident);
+ return 1;
+}
+
+static const struct dmi_system_id intel_no_crt[] = {
+ {
+ .callback = intel_no_crt_dmi_callback,
+ .ident = "ACER ZGB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"),
+ },
+ },
+ { }
+};
+
void intel_crt_init(struct drm_device *dev)
{
struct drm_connector *connector;
@@ -547,6 +566,10 @@ void intel_crt_init(struct drm_device *dev)
struct intel_connector *intel_connector;
struct drm_i915_private *dev_priv = dev->dev_private;
+ /* Skip machines without VGA that falsely report hotplug events */
+ if (dmi_check_system(intel_no_crt))
+ return;
+
crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL);
if (!crt)
return;
diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c
index 2a3f707caab8..b3b51c43dad0 100644
--- a/trunk/drivers/gpu/drm/i915/intel_display.c
+++ b/trunk/drivers/gpu/drm/i915/intel_display.c
@@ -5808,12 +5808,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
if (is_lvds) {
temp = I915_READ(PCH_LVDS);
temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
- if (HAS_PCH_CPT(dev))
+ if (HAS_PCH_CPT(dev)) {
+ temp &= ~PORT_TRANS_SEL_MASK;
temp |= PORT_TRANS_SEL_CPT(pipe);
- else if (pipe == 1)
- temp |= LVDS_PIPEB_SELECT;
- else
- temp &= ~LVDS_PIPEB_SELECT;
+ } else {
+ if (pipe == 1)
+ temp |= LVDS_PIPEB_SELECT;
+ else
+ temp &= ~LVDS_PIPEB_SELECT;
+ }
/* set the corresponsding LVDS_BORDER bit */
temp |= dev_priv->lvds_border_bits;
@@ -9025,12 +9028,9 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
- if (HAS_PCH_SPLIT(dev)) {
- ret = intel_plane_init(dev, i);
- if (ret)
- DRM_ERROR("plane %d init failed: %d\n",
- i, ret);
- }
+ ret = intel_plane_init(dev, i);
+ if (ret)
+ DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret);
}
/* Just disable it once at startup */
diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c
index e44191132ac4..798f6e1aa544 100644
--- a/trunk/drivers/gpu/drm/i915/intel_lvds.c
+++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c
@@ -708,6 +708,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
},
},
{
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Clientron E830",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "E830"),
+ },
+ },
+ {
.callback = intel_no_lvds_dmi_callback,
.ident = "Asus EeeBox PC EB1007",
.matches = {
diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c
index 77e729d4e4f0..1ab842c6032e 100644
--- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -635,6 +635,19 @@ render_ring_add_request(struct intel_ring_buffer *ring,
return 0;
}
+static u32
+gen6_ring_get_seqno(struct intel_ring_buffer *ring)
+{
+ struct drm_device *dev = ring->dev;
+
+ /* Workaround to force correct ordering between irq and seqno writes on
+ * ivb (and maybe also on snb) by reading from a CS register (like
+ * ACTHD) before reading the status page. */
+ if (IS_GEN7(dev))
+ intel_ring_get_active_head(ring);
+ return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
+}
+
static u32
ring_get_seqno(struct intel_ring_buffer *ring)
{
@@ -791,17 +804,6 @@ ring_add_request(struct intel_ring_buffer *ring,
return 0;
}
-static bool
-gen7_blt_ring_get_irq(struct intel_ring_buffer *ring)
-{
- /* The BLT ring on IVB appears to have broken synchronization
- * between the seqno write and the interrupt, so that the
- * interrupt appears first. Returning false here makes
- * i915_wait_request() do a polling loop, instead.
- */
- return false;
-}
-
static bool
gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
{
@@ -811,6 +813,12 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
if (!dev->irq_enabled)
return false;
+ /* It looks like we need to prevent the gt from suspending while waiting
+ * for an notifiy irq, otherwise irqs seem to get lost on at least the
+ * blt/bsd rings on ivb. */
+ if (IS_GEN7(dev))
+ gen6_gt_force_wake_get(dev_priv);
+
spin_lock(&ring->irq_lock);
if (ring->irq_refcount++ == 0) {
ring->irq_mask &= ~rflag;
@@ -835,6 +843,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
ironlake_disable_irq(dev_priv, gflag);
}
spin_unlock(&ring->irq_lock);
+
+ if (IS_GEN7(dev))
+ gen6_gt_force_wake_put(dev_priv);
}
static bool
@@ -1341,7 +1352,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = {
.write_tail = gen6_bsd_ring_write_tail,
.flush = gen6_ring_flush,
.add_request = gen6_add_request,
- .get_seqno = ring_get_seqno,
+ .get_seqno = gen6_ring_get_seqno,
.irq_get = gen6_bsd_ring_get_irq,
.irq_put = gen6_bsd_ring_put_irq,
.dispatch_execbuffer = gen6_ring_dispatch_execbuffer,
@@ -1476,7 +1487,7 @@ static const struct intel_ring_buffer gen6_blt_ring = {
.write_tail = ring_write_tail,
.flush = blt_ring_flush,
.add_request = gen6_add_request,
- .get_seqno = ring_get_seqno,
+ .get_seqno = gen6_ring_get_seqno,
.irq_get = blt_ring_get_irq,
.irq_put = blt_ring_put_irq,
.dispatch_execbuffer = gen6_ring_dispatch_execbuffer,
@@ -1499,6 +1510,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
ring->flush = gen6_render_ring_flush;
ring->irq_get = gen6_render_ring_get_irq;
ring->irq_put = gen6_render_ring_put_irq;
+ ring->get_seqno = gen6_ring_get_seqno;
} else if (IS_GEN5(dev)) {
ring->add_request = pc_render_add_request;
ring->get_seqno = pc_render_get_seqno;
@@ -1577,8 +1589,5 @@ int intel_init_blt_ring_buffer(struct drm_device *dev)
*ring = gen6_blt_ring;
- if (IS_GEN7(dev))
- ring->irq_get = gen7_blt_ring_get_irq;
-
return intel_init_ring_buffer(dev, ring);
}
diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c
index f7b9268df266..e334ec33a47d 100644
--- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1066,15 +1066,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
/* Set the SDVO control regs. */
if (INTEL_INFO(dev)->gen >= 4) {
- sdvox = 0;
+ /* The real mode polarity is set by the SDVO commands, using
+ * struct intel_sdvo_dtd. */
+ sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
if (intel_sdvo->is_hdmi)
sdvox |= intel_sdvo->color_range;
if (INTEL_INFO(dev)->gen < 5)
sdvox |= SDVO_BORDER_ENABLE;
- if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
- sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
- if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
- sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
} else {
sdvox = I915_READ(intel_sdvo->sdvo_reg);
switch (intel_sdvo->sdvo_reg) {
diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c
index d13989fda501..2288abf88cce 100644
--- a/trunk/drivers/gpu/drm/i915/intel_sprite.c
+++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c
@@ -466,10 +466,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
- if (ret) {
- DRM_ERROR("failed to pin object\n");
+ if (ret)
goto out_unlock;
- }
intel_plane->obj = obj;
@@ -632,10 +630,8 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
unsigned long possible_crtcs;
int ret;
- if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
- DRM_ERROR("new plane code only for SNB+\n");
+ if (!(IS_GEN6(dev) || IS_GEN7(dev)))
return -ENODEV;
- }
intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
if (!intel_plane)
diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c
index f3c6a9a8b081..1571be37ce3e 100644
--- a/trunk/drivers/gpu/drm/i915/intel_tv.c
+++ b/trunk/drivers/gpu/drm/i915/intel_tv.c
@@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = {
{
.name = "NTSC-M",
.clock = 108000,
- .refresh = 29970,
+ .refresh = 59940,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
@@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = {
{
.name = "NTSC-443",
.clock = 108000,
- .refresh = 29970,
+ .refresh = 59940,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
@@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = {
{
.name = "NTSC-J",
.clock = 108000,
- .refresh = 29970,
+ .refresh = 59940,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = {
{
.name = "PAL-M",
.clock = 108000,
- .refresh = 29970,
+ .refresh = 59940,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = {
/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
.name = "PAL-N",
.clock = 108000,
- .refresh = 25000,
+ .refresh = 50000,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = {
/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
.name = "PAL",
.clock = 108000,
- .refresh = 25000,
+ .refresh = 50000,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -673,78 +673,6 @@ static const struct tv_mode tv_modes[] = {
.filter_table = filter_table,
},
- {
- .name = "480p@59.94Hz",
- .clock = 107520,
- .refresh = 59940,
- .oversample = TV_OVERSAMPLE_4X,
- .component_only = 1,
-
- .hsync_end = 64, .hblank_end = 122,
- .hblank_start = 842, .htotal = 857,
-
- .progressive = true, .trilevel_sync = false,
-
- .vsync_start_f1 = 12, .vsync_start_f2 = 12,
- .vsync_len = 12,
-
- .veq_ena = false,
-
- .vi_end_f1 = 44, .vi_end_f2 = 44,
- .nbr_end = 479,
-
- .burst_ena = false,
-
- .filter_table = filter_table,
- },
- {
- .name = "480p@60Hz",
- .clock = 107520,
- .refresh = 60000,
- .oversample = TV_OVERSAMPLE_4X,
- .component_only = 1,
-
- .hsync_end = 64, .hblank_end = 122,
- .hblank_start = 842, .htotal = 856,
-
- .progressive = true, .trilevel_sync = false,
-
- .vsync_start_f1 = 12, .vsync_start_f2 = 12,
- .vsync_len = 12,
-
- .veq_ena = false,
-
- .vi_end_f1 = 44, .vi_end_f2 = 44,
- .nbr_end = 479,
-
- .burst_ena = false,
-
- .filter_table = filter_table,
- },
- {
- .name = "576p",
- .clock = 107520,
- .refresh = 50000,
- .oversample = TV_OVERSAMPLE_4X,
- .component_only = 1,
-
- .hsync_end = 64, .hblank_end = 139,
- .hblank_start = 859, .htotal = 863,
-
- .progressive = true, .trilevel_sync = false,
-
- .vsync_start_f1 = 10, .vsync_start_f2 = 10,
- .vsync_len = 10,
-
- .veq_ena = false,
-
- .vi_end_f1 = 48, .vi_end_f2 = 48,
- .nbr_end = 575,
-
- .burst_ena = false,
-
- .filter_table = filter_table,
- },
{
.name = "720p@60Hz",
.clock = 148800,
@@ -769,30 +697,6 @@ static const struct tv_mode tv_modes[] = {
.filter_table = filter_table,
},
- {
- .name = "720p@59.94Hz",
- .clock = 148800,
- .refresh = 59940,
- .oversample = TV_OVERSAMPLE_2X,
- .component_only = 1,
-
- .hsync_end = 80, .hblank_end = 300,
- .hblank_start = 1580, .htotal = 1651,
-
- .progressive = true, .trilevel_sync = true,
-
- .vsync_start_f1 = 10, .vsync_start_f2 = 10,
- .vsync_len = 10,
-
- .veq_ena = false,
-
- .vi_end_f1 = 29, .vi_end_f2 = 29,
- .nbr_end = 719,
-
- .burst_ena = false,
-
- .filter_table = filter_table,
- },
{
.name = "720p@50Hz",
.clock = 148800,
@@ -821,7 +725,7 @@ static const struct tv_mode tv_modes[] = {
{
.name = "1080i@50Hz",
.clock = 148800,
- .refresh = 25000,
+ .refresh = 50000,
.oversample = TV_OVERSAMPLE_2X,
.component_only = 1,
@@ -847,7 +751,7 @@ static const struct tv_mode tv_modes[] = {
{
.name = "1080i@60Hz",
.clock = 148800,
- .refresh = 30000,
+ .refresh = 60000,
.oversample = TV_OVERSAMPLE_2X,
.component_only = 1,
@@ -868,32 +772,6 @@ static const struct tv_mode tv_modes[] = {
.burst_ena = false,
- .filter_table = filter_table,
- },
- {
- .name = "1080i@59.94Hz",
- .clock = 148800,
- .refresh = 29970,
- .oversample = TV_OVERSAMPLE_2X,
- .component_only = 1,
-
- .hsync_end = 88, .hblank_end = 235,
- .hblank_start = 2155, .htotal = 2201,
-
- .progressive = false, .trilevel_sync = true,
-
- .vsync_start_f1 = 4, .vsync_start_f2 = 5,
- .vsync_len = 10,
-
- .veq_ena = true, .veq_start_f1 = 4,
- .veq_start_f2 = 4, .veq_len = 10,
-
-
- .vi_end_f1 = 21, .vi_end_f2 = 22,
- .nbr_end = 539,
-
- .burst_ena = false,
-
.filter_table = filter_table,
},
};
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h
index 1e382ad5a2b8..a37c31e358aa 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -54,9 +54,10 @@ struct bit_entry {
int bit_table(struct drm_device *, u8 id, struct bit_entry *);
enum dcb_gpio_tag {
- DCB_GPIO_TVDAC0 = 0xc,
+ DCB_GPIO_PANEL_POWER = 0x01,
+ DCB_GPIO_TVDAC0 = 0x0c,
DCB_GPIO_TVDAC1 = 0x2d,
- DCB_GPIO_PWM_FAN = 0x9,
+ DCB_GPIO_PWM_FAN = 0x09,
DCB_GPIO_FAN_SENSE = 0x3d,
DCB_GPIO_UNUSED = 0xff
};
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
index 724b41a2b9e9..ec54364ac828 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -812,6 +812,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nouveau_vma *vma;
+ /* ttm can now (stupidly) pass the driver bos it didn't create... */
+ if (bo->destroy != nouveau_bo_del_ttm)
+ return;
+
list_for_each_entry(vma, &nvbo->vma_list, head) {
if (new_mem && new_mem->mem_type == TTM_PL_VRAM) {
nouveau_vm_map(vma, new_mem->mm_node);
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c
index 3cb52bc52b21..795a9e3c990a 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -219,6 +219,16 @@ nouveau_display_init(struct drm_device *dev)
if (ret)
return ret;
+ /* power on internal panel if it's not already. the init tables of
+ * some vbios default this to off for some reason, causing the
+ * panel to not work after resume
+ */
+ if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) {
+ nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true);
+ msleep(300);
+ }
+
+ /* enable polling for external displays */
drm_kms_helper_poll_enable(dev);
/* enable hotplug interrupts */
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c
index e4a7cfe7898d..81d7962e7252 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n");
int nouveau_ctxfw;
module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
-MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n");
+MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n");
int nouveau_mxmdcb = 1;
module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400);
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c
index 5f0bc57fdaab..7ce3fde40743 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -379,6 +379,25 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
return 0;
}
+static int
+validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
+{
+ struct nouveau_fence *fence = NULL;
+ int ret = 0;
+
+ spin_lock(&nvbo->bo.bdev->fence_lock);
+ if (nvbo->bo.sync_obj)
+ fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+ spin_unlock(&nvbo->bo.bdev->fence_lock);
+
+ if (fence) {
+ ret = nouveau_fence_sync(fence, chan);
+ nouveau_fence_unref(&fence);
+ }
+
+ return ret;
+}
+
static int
validate_list(struct nouveau_channel *chan, struct list_head *list,
struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr)
@@ -393,7 +412,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
list_for_each_entry(nvbo, list, entry) {
struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index];
- ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
+ ret = validate_sync(chan, nvbo);
if (unlikely(ret)) {
NV_ERROR(dev, "fail pre-validate sync\n");
return ret;
@@ -416,7 +435,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
return ret;
}
- ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan);
+ ret = validate_sync(chan, nvbo);
if (unlikely(ret)) {
NV_ERROR(dev, "fail post-validate sync\n");
return ret;
diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c
index 8bccddf4eff0..e5a64f0f4cb7 100644
--- a/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c
+++ b/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c
@@ -656,7 +656,16 @@ nouveau_mxm_init(struct drm_device *dev)
if (mxm_shadow(dev, mxm[0])) {
MXM_MSG(dev, "failed to locate valid SIS\n");
+#if 0
+ /* we should, perhaps, fall back to some kind of limited
+ * mode here if the x86 vbios hasn't already done the
+ * work for us (so we prevent loading with completely
+ * whacked vbios tables).
+ */
return -EINVAL;
+#else
+ return 0;
+#endif
}
MXM_MSG(dev, "MXMS Version %d.%d\n",
diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_pm.c b/trunk/drivers/gpu/drm/nouveau/nv50_pm.c
index 03937212e9d8..ec5481dfcd82 100644
--- a/trunk/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/trunk/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv50_pm_state *info;
struct pll_lims pll;
- int ret = -EINVAL;
+ int clk, ret = -EINVAL;
int N, M, P1, P2;
- u32 clk, out;
+ u32 out;
if (dev_priv->chipset == 0xaa ||
dev_priv->chipset == 0xac)
diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c
index 0fda830ef806..742f17f009a9 100644
--- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -355,15 +355,12 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}
-static void atombios_disable_ss(struct drm_crtc *crtc)
+static void atombios_disable_ss(struct radeon_device *rdev, int pll_id)
{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
u32 ss_cntl;
if (ASIC_IS_DCE4(rdev)) {
- switch (radeon_crtc->pll_id) {
+ switch (pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
@@ -379,7 +376,7 @@ static void atombios_disable_ss(struct drm_crtc *crtc)
return;
}
} else if (ASIC_IS_AVIVO(rdev)) {
- switch (radeon_crtc->pll_id) {
+ switch (pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
ss_cntl &= ~1;
@@ -406,13 +403,11 @@ union atom_enable_ss {
ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3;
};
-static void atombios_crtc_program_ss(struct drm_crtc *crtc,
+static void atombios_crtc_program_ss(struct radeon_device *rdev,
int enable,
int pll_id,
struct radeon_atom_ss *ss)
{
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);
union atom_enable_ss args;
@@ -479,7 +474,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
} else if (ASIC_IS_AVIVO(rdev)) {
if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
(ss->type & ATOM_EXTERNAL_SS_MASK)) {
- atombios_disable_ss(crtc);
+ atombios_disable_ss(rdev, pll_id);
return;
}
args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
@@ -491,7 +486,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
} else {
if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
(ss->type & ATOM_EXTERNAL_SS_MASK)) {
- atombios_disable_ss(crtc);
+ atombios_disable_ss(rdev, pll_id);
return;
}
args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
@@ -523,6 +518,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
int encoder_mode = 0;
u32 dp_clock = mode->clock;
int bpc = 8;
+ bool is_duallink = false;
/* reset the pll flags */
pll->flags = 0;
@@ -557,6 +553,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (connector && connector->display_info.bpc)
bpc = connector->display_info.bpc;
encoder_mode = atombios_get_encoder_mode(encoder);
+ is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
(radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) {
if (connector) {
@@ -652,7 +649,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (dig->coherent_mode)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE;
- if (mode->clock > 165000)
+ if (is_duallink)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_DUAL_LINK;
}
@@ -702,11 +699,9 @@ union set_pixel_clock {
/* on DCE5, make sure the voltage is high enough to support the
* required disp clk.
*/
-static void atombios_crtc_set_dcpll(struct drm_crtc *crtc,
+static void atombios_crtc_set_dcpll(struct radeon_device *rdev,
u32 dispclk)
{
- struct drm_device *dev = crtc->dev;
- struct radeon_device *rdev = dev->dev_private;
u8 frev, crev;
int index;
union set_pixel_clock args;
@@ -996,7 +991,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div);
- atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
+ atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
encoder_mode, radeon_encoder->encoder_id, mode->clock,
@@ -1019,7 +1014,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
ss.step = step_size;
}
- atombios_crtc_program_ss(crtc, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
+ atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss);
}
}
@@ -1189,7 +1184,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
- crtc->mode.vdisplay);
+ target_fb->height);
x &= ~3;
y &= ~1;
WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
@@ -1358,7 +1353,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
- crtc->mode.vdisplay);
+ target_fb->height);
x &= ~3;
y &= ~1;
WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
@@ -1494,6 +1489,24 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
}
+void radeon_atom_dcpll_init(struct radeon_device *rdev)
+{
+ /* always set DCPLL */
+ if (ASIC_IS_DCE4(rdev)) {
+ struct radeon_atom_ss ss;
+ bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
+ ASIC_INTERNAL_SS_ON_DCPLL,
+ rdev->clock.default_dispclk);
+ if (ss_enabled)
+ atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
+ /* XXX: DCE5, make sure voltage, dispclk is high enough */
+ atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk);
+ if (ss_enabled)
+ atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
+ }
+
+}
+
int atombios_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
@@ -1515,19 +1528,6 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
}
}
- /* always set DCPLL */
- if (ASIC_IS_DCE4(rdev)) {
- struct radeon_atom_ss ss;
- bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
- ASIC_INTERNAL_SS_ON_DCPLL,
- rdev->clock.default_dispclk);
- if (ss_enabled)
- atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss);
- /* XXX: DCE5, make sure voltage, dispclk is high enough */
- atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk);
- if (ss_enabled)
- atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss);
- }
atombios_crtc_set_pll(crtc, adjusted_mode);
if (ASIC_IS_DCE4(rdev))
diff --git a/trunk/drivers/gpu/drm/radeon/atombios_dp.c b/trunk/drivers/gpu/drm/radeon/atombios_dp.c
index 6fb335a4fdda..552b436451fd 100644
--- a/trunk/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/trunk/drivers/gpu/drm/radeon/atombios_dp.c
@@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
return false;
}
-static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
- struct drm_connector *connector)
+int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
+ struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
@@ -558,28 +558,33 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
if (!ASIC_IS_DCE4(rdev))
- return;
+ return panel_mode;
if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
ENCODER_OBJECT_ID_NUTMEG)
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
- ENCODER_OBJECT_ID_TRAVIS)
- panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
- else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ ENCODER_OBJECT_ID_TRAVIS) {
+ u8 id[6];
+ int i;
+ for (i = 0; i < 6; i++)
+ id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i);
+ if (id[0] == 0x73 &&
+ id[1] == 0x69 &&
+ id[2] == 0x76 &&
+ id[3] == 0x61 &&
+ id[4] == 0x72 &&
+ id[5] == 0x54)
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
+ else
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+ } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
- atombios_dig_encoder_setup(encoder,
- ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
- panel_mode);
-
- if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
- (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
- radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
- }
+ return panel_mode;
}
void radeon_dp_set_link_config(struct drm_connector *connector,
@@ -717,6 +722,8 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
u8 tmp;
/* power up the sink */
@@ -732,7 +739,10 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
radeon_write_dpcd_reg(dp_info->radeon_connector,
DP_DOWNSPREAD_CTRL, 0);
- radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector);
+ if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
+ (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
+ radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
+ }
/* set the lane count on the sink */
tmp = dp_info->dp_lane_count;
diff --git a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c
index f1f06ca9f1f5..b88c4608731b 100644
--- a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -57,22 +57,6 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
}
}
-static struct drm_connector *
-radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
-{
- struct drm_device *dev = encoder->dev;
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct drm_connector *connector;
- struct radeon_connector *radeon_connector;
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- radeon_connector = to_radeon_connector(connector);
- if (radeon_encoder->devices & radeon_connector->devices)
- return connector;
- }
- return NULL;
-}
-
static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -253,7 +237,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
/* R4xx, R5xx */
args.ext_tmds.sXTmdsEncoder.ucEnable = action;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
@@ -265,7 +249,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
/* DFP1, CRT1, TV1 depending on the type of port */
args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
break;
case 3:
@@ -349,7 +333,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
} else {
if (dig->linkb)
args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
/*if (pScrn->rgbBits == 8) */
args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
@@ -388,7 +372,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
} else {
if (dig->linkb)
args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
}
break;
@@ -432,7 +416,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
- if (drm_detect_monitor_audio(radeon_connector->edid) &&
+ if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
return ATOM_ENCODER_MODE_HDMI;
else if (radeon_connector->use_digital)
@@ -443,7 +427,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
case DRM_MODE_CONNECTOR_DVID:
case DRM_MODE_CONNECTOR_HDMIA:
default:
- if (drm_detect_monitor_audio(radeon_connector->edid) &&
+ if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
return ATOM_ENCODER_MODE_HDMI;
else
@@ -457,7 +441,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
return ATOM_ENCODER_MODE_DP;
- else if (drm_detect_monitor_audio(radeon_connector->edid) &&
+ else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
radeon_audio)
return ATOM_ENCODER_MODE_HDMI;
else
@@ -587,7 +571,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v1.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.ucLaneNum = 8;
else
args.v1.ucLaneNum = 4;
@@ -622,7 +606,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v3.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.ucLaneNum = 8;
else
args.v3.ucLaneNum = 4;
@@ -662,7 +646,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v4.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.ucLaneNum = 8;
else
args.v4.ucLaneNum = 4;
@@ -806,7 +790,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v1.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -821,7 +805,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if ((rdev->flags & RADEON_IS_IGP) &&
(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
- if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
+ if (is_dp ||
+ !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) {
if (igp_lane_info & 0x1)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
else if (igp_lane_info & 0x2)
@@ -848,7 +833,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
}
break;
@@ -863,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v2.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -891,7 +876,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
} else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v2.acConfig.fCoherentMode = 1;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v2.acConfig.fDualLinkConnector = 1;
}
break;
@@ -906,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v3.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -914,7 +899,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v3.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.ucLaneNum = 8;
else
args.v3.ucLaneNum = 4;
@@ -951,7 +936,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v3.acConfig.fCoherentMode = 1;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.acConfig.fDualLinkConnector = 1;
}
break;
@@ -966,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v4.usPixelClock =
cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
else
args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
@@ -974,7 +959,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
if (is_dp)
args.v4.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.ucLaneNum = 8;
else
args.v4.ucLaneNum = 4;
@@ -1014,7 +999,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode)
args.v4.acConfig.fCoherentMode = 1;
- if (radeon_encoder->pixel_clock > 165000)
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v4.acConfig.fDualLinkConnector = 1;
}
break;
@@ -1137,7 +1122,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
if (dp_clock == 270000)
args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
- } else if (radeon_encoder->pixel_clock > 165000)
+ } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v1.sDigEncoder.ucLaneNum = 8;
else
args.v1.sDigEncoder.ucLaneNum = 4;
@@ -1156,7 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
else if (dp_clock == 540000)
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
- } else if (radeon_encoder->pixel_clock > 165000)
+ } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
args.v3.sExtEncoder.ucLaneNum = 8;
else
args.v3.sExtEncoder.ucLaneNum = 4;
@@ -1341,7 +1326,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
/* some early dce3.2 boards have a bug in their transmitter control table */
- if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
+ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) ||
+ ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
else
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
@@ -1351,8 +1337,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
ATOM_TRANSMITTER_ACTION_POWER_ON);
radeon_dig_connector->edp_on = true;
}
- if (ASIC_IS_DCE4(rdev))
- atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
radeon_dp_link_train(encoder, connector);
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
@@ -1363,7 +1347,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ else
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
@@ -1810,7 +1797,21 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- if (ASIC_IS_DCE4(rdev)) {
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+
+ if (!connector)
+ dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+ else
+ dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
+
+ /* setup and enable the encoder */
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
+ atombios_dig_encoder_setup(encoder,
+ ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
+ dig->panel_mode);
+ } else if (ASIC_IS_DCE4(rdev)) {
/* disable the transmitter */
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
/* setup and enable the encoder */
diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c
index 636660fca8c2..ae09fe82afbc 100644
--- a/trunk/drivers/gpu/drm/radeon/evergreen.c
+++ b/trunk/drivers/gpu/drm/radeon/evergreen.c
@@ -1455,6 +1455,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)
#endif
WREG32(CP_RB_CNTL, tmp);
WREG32(CP_SEM_WAIT_TIMER, 0x0);
+ WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
/* Set the write pointer delay */
WREG32(CP_RB_WPTR_DELAY, 0);
diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h
index b502216d42af..74713d42df29 100644
--- a/trunk/drivers/gpu/drm/radeon/evergreend.h
+++ b/trunk/drivers/gpu/drm/radeon/evergreend.h
@@ -108,6 +108,7 @@
#define CP_RB_WPTR_ADDR_HI 0xC11C
#define CP_RB_WPTR_DELAY 0x8704
#define CP_SEM_WAIT_TIMER 0x85BC
+#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8
#define CP_DEBUG 0xC1FC
diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c
index 321137295400..db09065e68fd 100644
--- a/trunk/drivers/gpu/drm/radeon/ni.c
+++ b/trunk/drivers/gpu/drm/radeon/ni.c
@@ -1219,6 +1219,7 @@ int cayman_cp_resume(struct radeon_device *rdev)
RREG32(GRBM_SOFT_RESET);
WREG32(CP_SEM_WAIT_TIMER, 0x0);
+ WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
/* Set the write pointer delay */
WREG32(CP_RB_WPTR_DELAY, 0);
diff --git a/trunk/drivers/gpu/drm/radeon/nid.h b/trunk/drivers/gpu/drm/radeon/nid.h
index f9df2a645e79..9a7f3b6e02de 100644
--- a/trunk/drivers/gpu/drm/radeon/nid.h
+++ b/trunk/drivers/gpu/drm/radeon/nid.h
@@ -222,6 +222,7 @@
#define SCRATCH_UMSK 0x8540
#define SCRATCH_ADDR 0x8544
#define CP_SEM_WAIT_TIMER 0x85BC
+#define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8
#define CP_COHER_CNTL2 0x85E8
#define CP_ME_CNTL 0x86D8
#define CP_ME_HALT (1 << 28)
diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c
index d996f4381130..accc032c103f 100644
--- a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -468,27 +468,42 @@ set_default_state(struct radeon_device *rdev)
radeon_ring_write(ring, sq_stack_resource_mgmt_2);
}
+#define I2F_MAX_BITS 15
+#define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1)
+#define I2F_SHIFT (24 - I2F_MAX_BITS)
+
+/*
+ * Converts unsigned integer into 32-bit IEEE floating point representation.
+ * Conversion is not universal and only works for the range from 0
+ * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between
+ * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary,
+ * I2F_MAX_BITS can be increased, but that will add to the loop iterations
+ * and slow us down. Conversion is done by shifting the input and counting
+ * down until the first 1 reaches bit position 23. The resulting counter
+ * and the shifted input are, respectively, the exponent and the fraction.
+ * The sign is always zero.
+ */
static uint32_t i2f(uint32_t input)
{
u32 result, i, exponent, fraction;
- if ((input & 0x3fff) == 0)
- result = 0; /* 0 is a special case */
+ WARN_ON_ONCE(input > I2F_MAX_INPUT);
+
+ if ((input & I2F_MAX_INPUT) == 0)
+ result = 0;
else {
- exponent = 140; /* exponent biased by 127; */
- fraction = (input & 0x3fff) << 10; /* cheat and only
- handle numbers below 2^^15 */
- for (i = 0; i < 14; i++) {
+ exponent = 126 + I2F_MAX_BITS;
+ fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT;
+
+ for (i = 0; i < I2F_MAX_BITS; i++) {
if (fraction & 0x800000)
break;
else {
- fraction = fraction << 1; /* keep
- shifting left until top bit = 1 */
+ fraction = fraction << 1;
exponent = exponent - 1;
}
}
- result = exponent << 23 | (fraction & 0x7fffff); /* mask
- off top bit; assumed 1 */
+ result = exponent << 23 | (fraction & 0x7fffff);
}
return result;
}
diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h
index 73e05cb85eca..1668ec1ee770 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon.h
+++ b/trunk/drivers/gpu/drm/radeon/radeon.h
@@ -156,6 +156,47 @@ static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
bool radeon_get_bios(struct radeon_device *rdev);
+/*
+ * Mutex which allows recursive locking from the same process.
+ */
+struct radeon_mutex {
+ struct mutex mutex;
+ struct task_struct *owner;
+ int level;
+};
+
+static inline void radeon_mutex_init(struct radeon_mutex *mutex)
+{
+ mutex_init(&mutex->mutex);
+ mutex->owner = NULL;
+ mutex->level = 0;
+}
+
+static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
+{
+ if (mutex_trylock(&mutex->mutex)) {
+ /* The mutex was unlocked before, so it's ours now */
+ mutex->owner = current;
+ } else if (mutex->owner != current) {
+ /* Another process locked the mutex, take it */
+ mutex_lock(&mutex->mutex);
+ mutex->owner = current;
+ }
+ /* Otherwise the mutex was already locked by this process */
+
+ mutex->level++;
+}
+
+static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
+{
+ if (--mutex->level > 0)
+ return;
+
+ mutex->owner = NULL;
+ mutex_unlock(&mutex->mutex);
+}
+
+
/*
* Dummy page
*/
@@ -598,7 +639,7 @@ struct radeon_ib {
* mutex protects scheduled_ibs, ready, alloc_bm
*/
struct radeon_ib_pool {
- struct mutex mutex;
+ struct radeon_mutex mutex;
struct radeon_sa_manager sa_manager;
struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
bool ready;
@@ -1354,47 +1395,6 @@ struct r600_vram_scratch {
};
-/*
- * Mutex which allows recursive locking from the same process.
- */
-struct radeon_mutex {
- struct mutex mutex;
- struct task_struct *owner;
- int level;
-};
-
-static inline void radeon_mutex_init(struct radeon_mutex *mutex)
-{
- mutex_init(&mutex->mutex);
- mutex->owner = NULL;
- mutex->level = 0;
-}
-
-static inline void radeon_mutex_lock(struct radeon_mutex *mutex)
-{
- if (mutex_trylock(&mutex->mutex)) {
- /* The mutex was unlocked before, so it's ours now */
- mutex->owner = current;
- } else if (mutex->owner != current) {
- /* Another process locked the mutex, take it */
- mutex_lock(&mutex->mutex);
- mutex->owner = current;
- }
- /* Otherwise the mutex was already locked by this process */
-
- mutex->level++;
-}
-
-static inline void radeon_mutex_unlock(struct radeon_mutex *mutex)
-{
- if (--mutex->level > 0)
- return;
-
- mutex->owner = NULL;
- mutex_unlock(&mutex->mutex);
-}
-
-
/*
* Core structure, functions and helpers.
*/
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 9d95792bea3e..98724fcb0088 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -58,7 +58,8 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
}
obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, len);
+ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+ len = obj->buffer.length;
kfree(buffer.pointer);
return len;
}
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c
index 229a20f10e2b..501f4881e5aa 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c
@@ -120,7 +120,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
ret = radeon_atrm_get_bios_chunk(rdev->bios,
(i * ATRM_BIOS_PAGE),
ATRM_BIOS_PAGE);
- if (ret <= 0)
+ if (ret < ATRM_BIOS_PAGE)
break;
}
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c
index 0afb13bd8dca..49f7cb7e226b 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_device.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c
@@ -720,7 +720,7 @@ int radeon_device_init(struct radeon_device *rdev,
/* mutex initialization are all done here so we
* can recall function without having locking issues */
radeon_mutex_init(&rdev->cs_mutex);
- mutex_init(&rdev->ib_pool.mutex);
+ radeon_mutex_init(&rdev->ib_pool.mutex);
for (i = 0; i < RADEON_NUM_RINGS; ++i)
mutex_init(&rdev->ring[i].mutex);
mutex_init(&rdev->dc_hw_i2c_mutex);
@@ -883,6 +883,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
+ drm_kms_helper_poll_disable(dev);
+
/* turn off display hw */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
@@ -959,9 +961,11 @@ int radeon_resume_kms(struct drm_device *dev)
radeon_fbdev_set_suspend(rdev, 0);
console_unlock();
- /* init dig PHYs */
- if (rdev->is_atom_bios)
+ /* init dig PHYs, disp eng pll */
+ if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev);
+ radeon_atom_dcpll_init(rdev);
+ }
/* reset hpd state */
radeon_hpd_init(rdev);
/* blat the mode back in */
@@ -970,6 +974,8 @@ int radeon_resume_kms(struct drm_device *dev)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
}
+
+ drm_kms_helper_poll_enable(dev);
return 0;
}
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c
index d3ffc18774a6..8c49fef1ce78 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_display.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c
@@ -1305,9 +1305,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
return ret;
}
- /* init dig PHYs */
- if (rdev->is_atom_bios)
+ /* init dig PHYs, disp eng pll */
+ if (rdev->is_atom_bios) {
radeon_atom_encoder_init(rdev);
+ radeon_atom_dcpll_init(rdev);
+ }
/* initialize hpd */
radeon_hpd_init(rdev);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c
index 4b27efa4405b..9419c51bcf50 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -202,6 +202,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder)
return NULL;
}
+struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ radeon_connector = to_radeon_connector(connector);
+ if (radeon_encoder->devices & radeon_connector->devices)
+ return connector;
+ }
+ return NULL;
+}
+
struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
@@ -288,3 +304,64 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder,
}
+bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
+ u32 pixel_clock)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
+ struct radeon_connector_atom_dig *dig_connector;
+
+ connector = radeon_get_connector_for_encoder(encoder);
+ /* if we don't have an active device yet, just use one of
+ * the connectors tied to the encoder.
+ */
+ if (!connector)
+ connector = radeon_get_connector_for_encoder_init(encoder);
+ radeon_connector = to_radeon_connector(connector);
+
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ if (radeon_connector->use_digital) {
+ /* HDMI 1.3 supports up to 340 Mhz over single link */
+ if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (pixel_clock > 340000)
+ return true;
+ else
+ return false;
+ } else {
+ if (pixel_clock > 165000)
+ return true;
+ else
+ return false;
+ }
+ } else
+ return false;
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ dig_connector = radeon_connector->con_priv;
+ if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+ (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+ return false;
+ else {
+ /* HDMI 1.3 supports up to 340 Mhz over single link */
+ if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
+ if (pixel_clock > 340000)
+ return true;
+ else
+ return false;
+ } else {
+ if (pixel_clock > 165000)
+ return true;
+ else
+ return false;
+ }
+ }
+ default:
+ return false;
+ }
+}
+
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c
index 7bb1b079f480..98a8ad680109 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -897,6 +897,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
+ i2c->adapter.dev.parent = &dev->pdev->dev;
i2c->dev = dev;
i2c_set_adapdata(&i2c->adapter, i2c);
if (rec->mm_i2c ||
@@ -957,6 +958,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
i2c->rec = *rec;
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.class = I2C_CLASS_DDC;
+ i2c->adapter.dev.parent = &dev->pdev->dev;
i2c->dev = dev;
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon aux bus %s", name);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
index be38921bf761..66d5fe1c8174 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -135,6 +135,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
(rdev->pdev->subsystem_device == 0x30c2))
return true;
+ /* Dell RS690 only seems to work with MSIs. */
+ if ((rdev->pdev->device == 0x791f) &&
+ (rdev->pdev->subsystem_vendor == 0x1028) &&
+ (rdev->pdev->subsystem_device == 0x01fc))
+ return true;
+
/* Dell RS690 only seems to work with MSIs. */
if ((rdev->pdev->device == 0x791f) &&
(rdev->pdev->subsystem_vendor == 0x1028) &&
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h
index 08ff857c8fd6..4330e3253573 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h
@@ -362,6 +362,7 @@ struct radeon_encoder_atom_dig {
struct backlight_device *bl_dev;
int dpms_mode;
uint8_t backlight_level;
+ int panel_mode;
};
struct radeon_encoder_atom_dac {
@@ -466,6 +467,10 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev);
extern struct drm_connector *
radeon_get_connector_for_encoder(struct drm_encoder *encoder);
+extern struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder);
+extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
+ u32 pixel_clock);
extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder);
extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector);
@@ -482,8 +487,11 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder,
extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
+extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
+ struct drm_connector *connector);
extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);
extern void radeon_atom_encoder_init(struct radeon_device *rdev);
+extern void radeon_atom_dcpll_init(struct radeon_device *rdev);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num,
uint8_t lane_set);
diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ring.c b/trunk/drivers/gpu/drm/radeon/radeon_ring.c
index e8bc70933d1b..30a4c5014c8b 100644
--- a/trunk/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/trunk/drivers/gpu/drm/radeon/radeon_ring.c
@@ -109,12 +109,12 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
return r;
}
- mutex_lock(&rdev->ib_pool.mutex);
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
idx = rdev->ib_pool.head_id;
retry:
if (cretry > 5) {
dev_err(rdev->dev, "failed to get an ib after 5 retry\n");
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
radeon_fence_unref(&fence);
return -ENOMEM;
}
@@ -139,7 +139,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
*/
rdev->ib_pool.head_id = (1 + idx);
rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1);
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
return 0;
}
}
@@ -158,7 +158,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring,
}
idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1);
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
radeon_fence_unref(&fence);
return r;
}
@@ -171,12 +171,12 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
if (tmp == NULL) {
return;
}
- mutex_lock(&rdev->ib_pool.mutex);
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
if (tmp->fence && !tmp->fence->emitted) {
radeon_sa_bo_free(rdev, &tmp->sa_bo);
radeon_fence_unref(&tmp->fence);
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
}
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
@@ -204,22 +204,25 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
int radeon_ib_pool_init(struct radeon_device *rdev)
{
+ struct radeon_sa_manager tmp;
int i, r;
- mutex_lock(&rdev->ib_pool.mutex);
- if (rdev->ib_pool.ready) {
- mutex_unlock(&rdev->ib_pool.mutex);
- return 0;
- }
-
- r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager,
+ r = radeon_sa_bo_manager_init(rdev, &tmp,
RADEON_IB_POOL_SIZE*64*1024,
RADEON_GEM_DOMAIN_GTT);
if (r) {
- mutex_unlock(&rdev->ib_pool.mutex);
return r;
}
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
+ if (rdev->ib_pool.ready) {
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_sa_bo_manager_fini(rdev, &tmp);
+ return 0;
+ }
+
+ rdev->ib_pool.sa_manager = tmp;
+ INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo);
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
rdev->ib_pool.ibs[i].fence = NULL;
rdev->ib_pool.ibs[i].idx = i;
@@ -236,7 +239,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
if (radeon_debugfs_ring_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for rings !\n");
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
return 0;
}
@@ -244,7 +247,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
{
unsigned i;
- mutex_lock(&rdev->ib_pool.mutex);
+ radeon_mutex_lock(&rdev->ib_pool.mutex);
if (rdev->ib_pool.ready) {
for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo);
@@ -253,7 +256,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager);
rdev->ib_pool.ready = false;
}
- mutex_unlock(&rdev->ib_pool.mutex);
+ radeon_mutex_unlock(&rdev->ib_pool.mutex);
}
int radeon_ib_pool_start(struct radeon_device *rdev)
diff --git a/trunk/drivers/gpu/drm/sis/sis_drv.c b/trunk/drivers/gpu/drm/sis/sis_drv.c
index 06da063ece2e..573220cc5269 100644
--- a/trunk/drivers/gpu/drm/sis/sis_drv.c
+++ b/trunk/drivers/gpu/drm/sis/sis_drv.c
@@ -40,7 +40,6 @@ static struct pci_device_id pciidlist[] = {
static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
{
drm_sis_private_t *dev_priv;
- int ret;
dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL);
if (dev_priv == NULL)
@@ -50,7 +49,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->chipset = chipset;
idr_init(&dev->object_name_idr);
- return ret;
+ return 0;
}
static int sis_driver_unload(struct drm_device *dev)
diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c
index 2f0eab66ece6..7c3a57de8187 100644
--- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c
@@ -404,6 +404,9 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
}
}
+ if (bdev->driver->move_notify)
+ bdev->driver->move_notify(bo, mem);
+
if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem);
@@ -413,11 +416,17 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
else
ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem);
- if (ret)
- goto out_err;
+ if (ret) {
+ if (bdev->driver->move_notify) {
+ struct ttm_mem_reg tmp_mem = *mem;
+ *mem = bo->mem;
+ bo->mem = tmp_mem;
+ bdev->driver->move_notify(bo, mem);
+ bo->mem = *mem;
+ }
- if (bdev->driver->move_notify)
- bdev->driver->move_notify(bo, mem);
+ goto out_err;
+ }
moved:
if (bo->evicted) {
diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 0af6ebdf205d..b66ef0e3cde1 100644
--- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
unsigned int *handle)
{
if (handle)
- handle = 0;
+ *handle = 0;
return 0;
}
diff --git a/trunk/drivers/hid/hid-hyperv.c b/trunk/drivers/hid/hid-hyperv.c
index 0c33ae9cf0f0..406632472c1b 100644
--- a/trunk/drivers/hid/hid-hyperv.c
+++ b/trunk/drivers/hid/hid-hyperv.c
@@ -548,6 +548,7 @@ static int mousevsc_remove(struct hv_device *dev)
struct mousevsc_dev *input_dev = hv_get_drvdata(dev);
vmbus_close(dev->channel);
+ hid_hw_stop(input_dev->hid_device);
hid_destroy_device(input_dev->hid_device);
mousevsc_free_device(input_dev);
diff --git a/trunk/drivers/hid/hid-wacom.c b/trunk/drivers/hid/hid-wacom.c
index b47e58b52d9f..acab74cde727 100644
--- a/trunk/drivers/hid/hid-wacom.c
+++ b/trunk/drivers/hid/hid-wacom.c
@@ -531,7 +531,6 @@ static int wacom_probe(struct hid_device *hdev,
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
- power_supply_powers(&wdata->battery, &hdev->dev);
ret = power_supply_register(&hdev->dev, &wdata->battery);
if (ret) {
@@ -540,6 +539,8 @@ static int wacom_probe(struct hid_device *hdev,
goto err_battery;
}
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
wdata->ac.properties = wacom_ac_props;
wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
wdata->ac.get_property = wacom_ac_get_property;
@@ -547,14 +548,14 @@ static int wacom_probe(struct hid_device *hdev,
wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
wdata->ac.use_for_apm = 0;
- power_supply_powers(&wdata->battery, &hdev->dev);
-
ret = power_supply_register(&hdev->dev, &wdata->ac);
if (ret) {
hid_warn(hdev,
"can't create ac battery attribute, err: %d\n", ret);
goto err_ac;
}
+
+ power_supply_powers(&wdata->ac, &hdev->dev);
#endif
return 0;
diff --git a/trunk/drivers/hid/hid-wiimote-core.c b/trunk/drivers/hid/hid-wiimote-core.c
index fc253b472f9d..cac3589b1ed5 100644
--- a/trunk/drivers/hid/hid-wiimote-core.c
+++ b/trunk/drivers/hid/hid-wiimote-core.c
@@ -1226,14 +1226,14 @@ static int wiimote_hid_probe(struct hid_device *hdev,
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
- power_supply_powers(&wdata->battery, &hdev->dev);
-
ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
if (ret) {
hid_err(hdev, "Cannot register battery device\n");
goto err_battery;
}
+ power_supply_powers(&wdata->battery, &hdev->dev);
+
ret = wiimote_leds_create(wdata);
if (ret)
goto err_free;
diff --git a/trunk/drivers/hid/usbhid/hiddev.c b/trunk/drivers/hid/usbhid/hiddev.c
index 7c297d305d5d..b1ec0e2aeb57 100644
--- a/trunk/drivers/hid/usbhid/hiddev.c
+++ b/trunk/drivers/hid/usbhid/hiddev.c
@@ -922,11 +922,11 @@ void hiddev_disconnect(struct hid_device *hid)
struct hiddev *hiddev = hid->hiddev;
struct usbhid_device *usbhid = hid->driver_data;
+ usb_deregister_dev(usbhid->intf, &hiddev_class);
+
mutex_lock(&hiddev->existancelock);
hiddev->exist = 0;
- usb_deregister_dev(usbhid->intf, &hiddev_class);
-
if (hiddev->open) {
mutex_unlock(&hiddev->existancelock);
usbhid_close(hiddev->hid);
diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c
index 92f949767ece..6dbfd3e516e4 100644
--- a/trunk/drivers/hwmon/f71805f.c
+++ b/trunk/drivers/hwmon/f71805f.c
@@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg)
static inline u8 temp_to_reg(long val)
{
- if (val < 0)
- val = 0;
- else if (val > 1000 * 0xff)
- val = 0xff;
- return ((val + 500) / 1000);
+ if (val <= 0)
+ return 0;
+ if (val >= 1000 * 0xff)
+ return 0xff;
+ return (val + 500) / 1000;
}
/*
diff --git a/trunk/drivers/hwmon/sht15.c b/trunk/drivers/hwmon/sht15.c
index 6ddeae049058..91fdd1fe18b0 100644
--- a/trunk/drivers/hwmon/sht15.c
+++ b/trunk/drivers/hwmon/sht15.c
@@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb,
static int __devinit sht15_probe(struct platform_device *pdev)
{
- int ret = 0;
+ int ret;
struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
u8 status = 0;
@@ -901,6 +901,7 @@ static int __devinit sht15_probe(struct platform_device *pdev)
init_waitqueue_head(&data->wait_queue);
if (pdev->dev.platform_data == NULL) {
+ ret = -EINVAL;
dev_err(&pdev->dev, "no platform data supplied\n");
goto err_free_data;
}
diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c
index 0e0af0445222..4d383e7e051d 100644
--- a/trunk/drivers/hwmon/w83627ehf.c
+++ b/trunk/drivers/hwmon/w83627ehf.c
@@ -1319,6 +1319,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct w83627ehf_sio_data *sio_data = dev->platform_data;
int nr = sensor_attr->index;
unsigned long val;
int err;
@@ -1330,6 +1331,11 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
if (val > 1)
return -EINVAL;
+
+ /* On NCT67766F, DC mode is only supported for pwm1 */
+ if (sio_data->kind == nct6776 && nr && val != 1)
+ return -EINVAL;
+
mutex_lock(&data->update_lock);
reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
data->pwm_mode[nr] = val;
@@ -1914,9 +1920,26 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
fan4min = 0;
fan5pin = 0;
} else if (sio_data->kind == nct6776) {
- fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
- fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
- fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+ bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
+
+ superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+ regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
+
+ if (regval & 0x80)
+ fan3pin = gpok;
+ else
+ fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
+
+ if (regval & 0x40)
+ fan4pin = gpok;
+ else
+ fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
+
+ if (regval & 0x20)
+ fan5pin = gpok;
+ else
+ fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+
fan4min = fan4pin;
} else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
fan3pin = 1;
diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c
index f713eac55047..801df6000e9b 100644
--- a/trunk/drivers/i2c/busses/i2c-omap.c
+++ b/trunk/drivers/i2c/busses/i2c-omap.c
@@ -1018,7 +1018,7 @@ omap_i2c_probe(struct platform_device *pdev)
goto err_release_region;
}
- match = of_match_device(omap_i2c_of_match, &pdev->dev);
+ match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
if (match) {
u32 freq = 100000; /* default to 100000 Hz */
diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c
index 20bce51c2e82..54ab97bae042 100644
--- a/trunk/drivers/idle/intel_idle.c
+++ b/trunk/drivers/idle/intel_idle.c
@@ -527,7 +527,7 @@ int intel_idle_cpu_init(int cpu)
return 0;
}
-
+EXPORT_SYMBOL_GPL(intel_idle_cpu_init);
static int __init intel_idle_init(void)
{
diff --git a/trunk/drivers/infiniband/core/ucma.c b/trunk/drivers/infiniband/core/ucma.c
index b37b0c02a7b9..5034a87cc72d 100644
--- a/trunk/drivers/infiniband/core/ucma.c
+++ b/trunk/drivers/infiniband/core/ucma.c
@@ -808,9 +808,12 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,
return PTR_ERR(ctx);
if (cmd.conn_param.valid) {
- ctx->uid = cmd.uid;
ucma_copy_conn_param(&conn_param, &cmd.conn_param);
+ mutex_lock(&file->mut);
ret = rdma_accept(ctx->cm_id, &conn_param);
+ if (!ret)
+ ctx->uid = cmd.uid;
+ mutex_unlock(&file->mut);
} else
ret = rdma_accept(ctx->cm_id, NULL);
diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c
index b930da4c0c63..4d27e4c3fe34 100644
--- a/trunk/drivers/infiniband/core/uverbs_cmd.c
+++ b/trunk/drivers/infiniband/core/uverbs_cmd.c
@@ -1485,6 +1485,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
qp->event_handler = attr.event_handler;
qp->qp_context = attr.qp_context;
qp->qp_type = attr.qp_type;
+ atomic_set(&qp->usecnt, 0);
atomic_inc(&pd->usecnt);
atomic_inc(&attr.send_cq->usecnt);
if (attr.recv_cq)
diff --git a/trunk/drivers/infiniband/core/verbs.c b/trunk/drivers/infiniband/core/verbs.c
index 602b1bd723a9..575b78045aaf 100644
--- a/trunk/drivers/infiniband/core/verbs.c
+++ b/trunk/drivers/infiniband/core/verbs.c
@@ -421,6 +421,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->uobject = NULL;
qp->qp_type = qp_init_attr->qp_type;
+ atomic_set(&qp->usecnt, 0);
if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
qp->event_handler = __ib_shared_qp_event_handler;
qp->qp_context = qp;
@@ -430,7 +431,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->xrcd = qp_init_attr->xrcd;
atomic_inc(&qp_init_attr->xrcd->usecnt);
INIT_LIST_HEAD(&qp->open_list);
- atomic_set(&qp->usecnt, 0);
real_qp = qp;
qp = __ib_open_qp(real_qp, qp_init_attr->event_handler,
diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c
index b7d4216db3c3..a4de9d58e9b4 100644
--- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -89,7 +89,7 @@ static int create_file(const char *name, umode_t mode,
error = ipathfs_mknod(parent->d_inode, *dentry,
mode, fops, data);
else
- error = PTR_ERR(dentry);
+ error = PTR_ERR(*dentry);
mutex_unlock(&parent->d_inode->i_mutex);
return error;
diff --git a/trunk/drivers/infiniband/hw/mlx4/mad.c b/trunk/drivers/infiniband/hw/mlx4/mad.c
index 95c94d8f0254..259b0670b51c 100644
--- a/trunk/drivers/infiniband/hw/mlx4/mad.c
+++ b/trunk/drivers/infiniband/hw/mlx4/mad.c
@@ -257,12 +257,9 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
return IB_MAD_RESULT_SUCCESS;
/*
- * Don't process SMInfo queries or vendor-specific
- * MADs -- the SMA can't handle them.
+ * Don't process SMInfo queries -- the SMA can't handle them.
*/
- if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO ||
- ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) ==
- IB_SMP_ATTR_VENDOR_MASK))
+ if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO)
return IB_MAD_RESULT_SUCCESS;
} else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 ||
diff --git a/trunk/drivers/infiniband/hw/nes/nes.c b/trunk/drivers/infiniband/hw/nes/nes.c
index 7013da5e9eda..7140199f562e 100644
--- a/trunk/drivers/infiniband/hw/nes/nes.c
+++ b/trunk/drivers/infiniband/hw/nes/nes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/trunk/drivers/infiniband/hw/nes/nes.h b/trunk/drivers/infiniband/hw/nes/nes.h
index 568b4f11380a..c438e4691b3c 100644
--- a/trunk/drivers/infiniband/hw/nes/nes.h
+++ b/trunk/drivers/infiniband/hw/nes/nes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c
index 425065b36b8c..a4972abedef1 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_cm.c
+++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -233,6 +233,7 @@ static int send_mpa_reject(struct nes_cm_node *cm_node)
u8 *start_ptr = &start_addr;
u8 **start_buff = &start_ptr;
u16 buff_len = 0;
+ struct ietf_mpa_v1 *mpa_frame;
skb = dev_alloc_skb(MAX_CM_BUFFER);
if (!skb) {
@@ -242,6 +243,8 @@ static int send_mpa_reject(struct nes_cm_node *cm_node)
/* send an MPA reject frame */
cm_build_mpa_frame(cm_node, start_buff, &buff_len, NULL, MPA_KEY_REPLY);
+ mpa_frame = (struct ietf_mpa_v1 *)*start_buff;
+ mpa_frame->flags |= IETF_MPA_FLAGS_REJECT;
form_cm_frame(skb, cm_node, NULL, 0, *start_buff, buff_len, SET_ACK | SET_FIN);
cm_node->state = NES_CM_STATE_FIN_WAIT1;
@@ -1360,8 +1363,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
neigh->ha, ETH_ALEN)) {
/* Mac address same as in nes_arp_table */
- ip_rt_put(rt);
- return rc;
+ goto out;
}
nes_manage_arp_cache(nesvnic->netdev,
@@ -1377,6 +1379,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
neigh_event_send(neigh, NULL);
}
}
+
+out:
rcu_read_unlock();
ip_rt_put(rt);
return rc;
diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.h b/trunk/drivers/infiniband/hw/nes/nes_cm.h
index bdfa1fbb35fc..4646e6666087 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_cm.h
+++ b/trunk/drivers/infiniband/hw/nes/nes_cm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_context.h b/trunk/drivers/infiniband/hw/nes/nes_context.h
index b4393a16099d..a69eef16d72d 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_context.h
+++ b/trunk/drivers/infiniband/hw/nes/nes_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.c b/trunk/drivers/infiniband/hw/nes/nes_hw.c
index 055f4b545df0..d42c9f435b1b 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_hw.c
+++ b/trunk/drivers/infiniband/hw/nes/nes_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.h b/trunk/drivers/infiniband/hw/nes/nes_hw.h
index 0b590e152c6a..d748e4b31b8d 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_hw.h
+++ b/trunk/drivers/infiniband/hw/nes/nes_hw.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+* Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_mgt.c b/trunk/drivers/infiniband/hw/nes/nes_mgt.c
index b3b2a240c6e9..3ba7be369452 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_mgt.c
+++ b/trunk/drivers/infiniband/hw/nes/nes_mgt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_mgt.h b/trunk/drivers/infiniband/hw/nes/nes_mgt.h
index 8c8af254555a..4f7f701c4a81 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_mgt.h
+++ b/trunk/drivers/infiniband/hw/nes/nes_mgt.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2010 Intel-NE, Inc. All rights reserved.
+* Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_nic.c b/trunk/drivers/infiniband/hw/nes/nes_nic.c
index 4b3fa711a247..f3a3ecf8d09e 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_nic.c
+++ b/trunk/drivers/infiniband/hw/nes/nes_nic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_user.h b/trunk/drivers/infiniband/hw/nes/nes_user.h
index 71e133ab209b..4926de744488 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_user.h
+++ b/trunk/drivers/infiniband/hw/nes/nes_user.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
diff --git a/trunk/drivers/infiniband/hw/nes/nes_utils.c b/trunk/drivers/infiniband/hw/nes/nes_utils.c
index 8b4c2ff54888..e98f4fc0b768 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_utils.c
+++ b/trunk/drivers/infiniband/hw/nes/nes_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.c b/trunk/drivers/infiniband/hw/nes/nes_verbs.c
index 5095bc41c6cc..0927b5cc65d3 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -3427,6 +3427,8 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
set_wqe_32bit_value(wqe->wqe_words,
NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX,
ib_wr->wr.fast_reg.length);
+ set_wqe_32bit_value(wqe->wqe_words,
+ NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0);
set_wqe_32bit_value(wqe->wqe_words,
NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX,
ib_wr->wr.fast_reg.rkey);
@@ -3724,7 +3726,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
entry->opcode = IB_WC_SEND;
break;
case NES_IWARP_SQ_OP_LOCINV:
- entry->opcode = IB_WR_LOCAL_INV;
+ entry->opcode = IB_WC_LOCAL_INV;
break;
case NES_IWARP_SQ_OP_FAST_REG:
entry->opcode = IB_WC_FAST_REG_MR;
diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.h b/trunk/drivers/infiniband/hw/nes/nes_verbs.h
index fe6b6e92fa90..0eff7c44d76b 100644
--- a/trunk/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
+ * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c
index 4f18e2d332df..d0c64d514813 100644
--- a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -2105,7 +2105,7 @@ static void alloc_dummy_hdrq(struct qib_devdata *dd)
dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev,
dd->rcd[0]->rcvhdrq_size,
&dd->cspec->dummy_hdrq_phys,
- GFP_KERNEL | __GFP_COMP);
+ GFP_ATOMIC | __GFP_COMP);
if (!dd->cspec->dummy_hdrq) {
qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n");
/* fallback to just 0'ing */
diff --git a/trunk/drivers/infiniband/hw/qib/qib_pcie.c b/trunk/drivers/infiniband/hw/qib/qib_pcie.c
index f695061d688e..0fde788e1100 100644
--- a/trunk/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/trunk/drivers/infiniband/hw/qib/qib_pcie.c
@@ -560,7 +560,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd)
* BIOS may not set PCIe bus-utilization parameters for best performance.
* Check and optionally adjust them to maximize our throughput.
*/
-static int qib_pcie_caps = 0x51;
+static int qib_pcie_caps;
module_param_named(pcie_caps, qib_pcie_caps, int, S_IRUGO);
MODULE_PARM_DESC(pcie_caps, "Max PCIe tuning: Payload (0..3), ReadReq (4..7)");
diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c
index 76457d50bc34..afc166fcc3d9 100644
--- a/trunk/drivers/input/evdev.c
+++ b/trunk/drivers/input/evdev.c
@@ -386,7 +386,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
struct input_event event;
- int retval;
+ int retval = 0;
if (count < input_event_size())
return -EINVAL;
diff --git a/trunk/drivers/input/keyboard/twl4030_keypad.c b/trunk/drivers/input/keyboard/twl4030_keypad.c
index a588578037eb..67bec14e8b96 100644
--- a/trunk/drivers/input/keyboard/twl4030_keypad.c
+++ b/trunk/drivers/input/keyboard/twl4030_keypad.c
@@ -34,7 +34,6 @@
#include
#include
-
/*
* The TWL4030 family chips include a keypad controller that supports
* up to an 8x8 switch matrix. The controller can issue system wakeup
@@ -302,7 +301,7 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp)
if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0)
return -EIO;
- /* Set timeout period to 100 ms */
+ /* Set timeout period to 200 ms */
i = KEYP_PERIOD_US(200000, PTV_PRESCALER);
if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0)
return -EIO;
@@ -466,4 +465,3 @@ MODULE_AUTHOR("Texas Instruments");
MODULE_DESCRIPTION("TWL4030 Keypad Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:twl4030_keypad");
-
diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h
index b4cfc6c8be89..5ec774d6c82b 100644
--- a/trunk/drivers/input/serio/i8042-x86ia64io.h
+++ b/trunk/drivers/input/serio/i8042-x86ia64io.h
@@ -512,6 +512,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
},
},
+ {
+ /* Lenovo Ideapad U455 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
+ },
+ },
{ }
};
diff --git a/trunk/drivers/input/serio/serio_raw.c b/trunk/drivers/input/serio/serio_raw.c
index 8250299fd64f..4494233d331a 100644
--- a/trunk/drivers/input/serio/serio_raw.c
+++ b/trunk/drivers/input/serio/serio_raw.c
@@ -164,7 +164,8 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
struct serio_raw_client *client = file->private_data;
struct serio_raw *serio_raw = client->serio_raw;
char uninitialized_var(c);
- ssize_t retval = 0;
+ ssize_t read = 0;
+ int retval;
if (serio_raw->dead)
return -ENODEV;
@@ -180,13 +181,15 @@ static ssize_t serio_raw_read(struct file *file, char __user *buffer,
if (serio_raw->dead)
return -ENODEV;
- while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
- if (put_user(c, buffer++))
- return -EFAULT;
- retval++;
+ while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
+ if (put_user(c, buffer++)) {
+ retval = -EFAULT;
+ break;
+ }
+ read++;
}
- return retval;
+ return read ?: retval;
}
static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
diff --git a/trunk/drivers/media/dvb/dvb-usb/anysee.c b/trunk/drivers/media/dvb/dvb-usb/anysee.c
index 1455e2644ab5..cf0c318d6989 100644
--- a/trunk/drivers/media/dvb/dvb-usb/anysee.c
+++ b/trunk/drivers/media/dvb/dvb-usb/anysee.c
@@ -887,8 +887,7 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
/* attach demod */
adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach,
- &anysee_cxd2820r_config, &adap->dev->i2c_adap,
- NULL);
+ &anysee_cxd2820r_config, &adap->dev->i2c_adap);
state->has_ci = true;
@@ -1189,6 +1188,14 @@ static int anysee_ci_init(struct dvb_usb_device *d)
if (ret)
return ret;
+ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
+ if (ret)
+ return ret;
+
+ ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
+ if (ret)
+ return ret;
+
ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
if (ret)
return ret;
diff --git a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
index 8a57ed8272de..1efc028a76c9 100644
--- a/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
+++ b/trunk/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
@@ -276,14 +276,15 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe)
param.flags = 0;
switch (fep->bandwidth_hz) {
+ default:
case 8000000:
- param.bandwidth = 0;
+ param.bandwidth = 8;
break;
case 7000000:
- param.bandwidth = 1;
+ param.bandwidth = 7;
break;
case 6000000:
- param.bandwidth = 2;
+ param.bandwidth = 6;
break;
}
diff --git a/trunk/drivers/media/dvb/frontends/cxd2820r.h b/trunk/drivers/media/dvb/frontends/cxd2820r.h
index cf0f546aa1d1..5aa306ebb7ef 100644
--- a/trunk/drivers/media/dvb/frontends/cxd2820r.h
+++ b/trunk/drivers/media/dvb/frontends/cxd2820r.h
@@ -77,14 +77,12 @@ struct cxd2820r_config {
(defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
extern struct dvb_frontend *cxd2820r_attach(
const struct cxd2820r_config *config,
- struct i2c_adapter *i2c,
- struct dvb_frontend *fe
+ struct i2c_adapter *i2c
);
#else
static inline struct dvb_frontend *cxd2820r_attach(
const struct cxd2820r_config *config,
- struct i2c_adapter *i2c,
- struct dvb_frontend *fe
+ struct i2c_adapter *i2c
)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/trunk/drivers/media/dvb/frontends/cxd2820r_core.c b/trunk/drivers/media/dvb/frontends/cxd2820r_core.c
index caae7f79c837..5c7c2aaf9bf5 100644
--- a/trunk/drivers/media/dvb/frontends/cxd2820r_core.c
+++ b/trunk/drivers/media/dvb/frontends/cxd2820r_core.c
@@ -482,10 +482,19 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
/* switch between DVB-T and DVB-T2 when tune fails */
if (priv->last_tune_failed) {
- if (priv->delivery_system == SYS_DVBT)
+ if (priv->delivery_system == SYS_DVBT) {
+ ret = cxd2820r_sleep_t(fe);
+ if (ret)
+ goto error;
+
c->delivery_system = SYS_DVBT2;
- else if (priv->delivery_system == SYS_DVBT2)
+ } else if (priv->delivery_system == SYS_DVBT2) {
+ ret = cxd2820r_sleep_t2(fe);
+ if (ret)
+ goto error;
+
c->delivery_system = SYS_DVBT;
+ }
}
/* set frontend */
@@ -562,7 +571,7 @@ static const struct dvb_frontend_ops cxd2820r_ops = {
.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
/* default: DVB-T/T2 */
.info = {
- .name = "Sony CXD2820R (DVB-T/T2)",
+ .name = "Sony CXD2820R",
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
@@ -572,7 +581,9 @@ static const struct dvb_frontend_ops cxd2820r_ops = {
FE_CAN_FEC_AUTO |
FE_CAN_QPSK |
FE_CAN_QAM_16 |
+ FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
@@ -602,8 +613,7 @@ static const struct dvb_frontend_ops cxd2820r_ops = {
};
struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
- struct i2c_adapter *i2c,
- struct dvb_frontend *fe)
+ struct i2c_adapter *i2c)
{
struct cxd2820r_priv *priv = NULL;
int ret;
diff --git a/trunk/drivers/media/video/atmel-isi.c b/trunk/drivers/media/video/atmel-isi.c
index 9fe4519176a4..ec3f6a06f9c3 100644
--- a/trunk/drivers/media/video/atmel-isi.c
+++ b/trunk/drivers/media/video/atmel-isi.c
@@ -922,7 +922,9 @@ static int __devexit atmel_isi_remove(struct platform_device *pdev)
isi->fb_descriptors_phys);
iounmap(isi->regs);
+ clk_unprepare(isi->mck);
clk_put(isi->mck);
+ clk_unprepare(isi->pclk);
clk_put(isi->pclk);
kfree(isi);
@@ -955,6 +957,10 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
if (IS_ERR(pclk))
return PTR_ERR(pclk);
+ ret = clk_prepare(pclk);
+ if (ret)
+ goto err_clk_prepare_pclk;
+
isi = kzalloc(sizeof(struct atmel_isi), GFP_KERNEL);
if (!isi) {
ret = -ENOMEM;
@@ -978,6 +984,10 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
goto err_clk_get;
}
+ ret = clk_prepare(isi->mck);
+ if (ret)
+ goto err_clk_prepare_mck;
+
/* Set ISI_MCK's frequency, it should be faster than pixel clock */
ret = clk_set_rate(isi->mck, pdata->mck_hz);
if (ret < 0)
@@ -1059,10 +1069,14 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
isi->fb_descriptors_phys);
err_alloc_descriptors:
err_set_mck_rate:
+ clk_unprepare(isi->mck);
+err_clk_prepare_mck:
clk_put(isi->mck);
err_clk_get:
kfree(isi);
err_alloc_isi:
+ clk_unprepare(pclk);
+err_clk_prepare_pclk:
clk_put(pclk);
return ret;
diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c
index 9449423098e0..aabbf4854f66 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c
@@ -853,8 +853,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
case EM28174_BOARD_PCTV_290E:
dvb->fe[0] = dvb_attach(cxd2820r_attach,
&em28xx_cxd2820r_config,
- &dev->i2c_adap,
- NULL);
+ &dev->i2c_adap);
if (dvb->fe[0]) {
/* FE 0 attach tuner */
if (!dvb_attach(tda18271_attach,
diff --git a/trunk/drivers/mfd/mcp-core.c b/trunk/drivers/mfd/mcp-core.c
index 63be60bc3455..86cc3f7841cd 100644
--- a/trunk/drivers/mfd/mcp-core.c
+++ b/trunk/drivers/mfd/mcp-core.c
@@ -26,35 +26,9 @@
#define to_mcp(d) container_of(d, struct mcp, attached_device)
#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
-static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id,
- const char *codec)
-{
- while (id->name[0]) {
- if (strcmp(codec, id->name) == 0)
- return id;
- id++;
- }
- return NULL;
-}
-
-const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp)
-{
- const struct mcp_driver *driver =
- to_mcp_driver(mcp->attached_device.driver);
-
- return mcp_match_id(driver->id_table, mcp->codec);
-}
-EXPORT_SYMBOL(mcp_get_device_id);
-
static int mcp_bus_match(struct device *dev, struct device_driver *drv)
{
- const struct mcp *mcp = to_mcp(dev);
- const struct mcp_driver *driver = to_mcp_driver(drv);
-
- if (driver->id_table)
- return !!mcp_match_id(driver->id_table, mcp->codec);
-
- return 0;
+ return 1;
}
static int mcp_bus_probe(struct device *dev)
@@ -100,18 +74,9 @@ static int mcp_bus_resume(struct device *dev)
return ret;
}
-static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct mcp *mcp = to_mcp(dev);
-
- add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec);
- return 0;
-}
-
static struct bus_type mcp_bus_type = {
.name = "mcp",
.match = mcp_bus_match,
- .uevent = mcp_bus_uevent,
.probe = mcp_bus_probe,
.remove = mcp_bus_remove,
.suspend = mcp_bus_suspend,
@@ -128,9 +93,11 @@ static struct bus_type mcp_bus_type = {
*/
void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
{
- spin_lock_irq(&mcp->lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mcp->lock, flags);
mcp->ops->set_telecom_divisor(mcp, div);
- spin_unlock_irq(&mcp->lock);
+ spin_unlock_irqrestore(&mcp->lock, flags);
}
EXPORT_SYMBOL(mcp_set_telecom_divisor);
@@ -143,9 +110,11 @@ EXPORT_SYMBOL(mcp_set_telecom_divisor);
*/
void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
{
- spin_lock_irq(&mcp->lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mcp->lock, flags);
mcp->ops->set_audio_divisor(mcp, div);
- spin_unlock_irq(&mcp->lock);
+ spin_unlock_irqrestore(&mcp->lock, flags);
}
EXPORT_SYMBOL(mcp_set_audio_divisor);
@@ -198,10 +167,11 @@ EXPORT_SYMBOL(mcp_reg_read);
*/
void mcp_enable(struct mcp *mcp)
{
- spin_lock_irq(&mcp->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&mcp->lock, flags);
if (mcp->use_count++ == 0)
mcp->ops->enable(mcp);
- spin_unlock_irq(&mcp->lock);
+ spin_unlock_irqrestore(&mcp->lock, flags);
}
EXPORT_SYMBOL(mcp_enable);
@@ -247,14 +217,9 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
}
EXPORT_SYMBOL(mcp_host_alloc);
-int mcp_host_register(struct mcp *mcp, void *pdata)
+int mcp_host_register(struct mcp *mcp)
{
- if (!mcp->codec)
- return -EINVAL;
-
- mcp->attached_device.platform_data = pdata;
dev_set_name(&mcp->attached_device, "mcp0");
- request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec);
return device_register(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_register);
diff --git a/trunk/drivers/mfd/mcp-sa11x0.c b/trunk/drivers/mfd/mcp-sa11x0.c
index 9adc2eb69492..02c53a0766c4 100644
--- a/trunk/drivers/mfd/mcp-sa11x0.c
+++ b/trunk/drivers/mfd/mcp-sa11x0.c
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
#include