diff --git a/[refs] b/[refs] index eff50a2412df..680c79cebca8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8e6d91ae0917bf934ed86411148f79d904728d51 +refs/heads/master: 2a7851bffb008ff4882eee673da74718997b4265 diff --git a/trunk/Documentation/devicetree/bindings/video/exynos_hdmi.txt b/trunk/Documentation/devicetree/bindings/drm/exynos/hdmi.txt similarity index 100% rename from trunk/Documentation/devicetree/bindings/video/exynos_hdmi.txt rename to trunk/Documentation/devicetree/bindings/drm/exynos/hdmi.txt diff --git a/trunk/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt b/trunk/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt similarity index 100% rename from trunk/Documentation/devicetree/bindings/video/exynos_hdmiddc.txt rename to trunk/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt diff --git a/trunk/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt b/trunk/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt similarity index 100% rename from trunk/Documentation/devicetree/bindings/video/exynos_hdmiphy.txt rename to trunk/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt diff --git a/trunk/Documentation/devicetree/bindings/video/exynos_mixer.txt b/trunk/Documentation/devicetree/bindings/drm/exynos/mixer.txt similarity index 100% rename from trunk/Documentation/devicetree/bindings/video/exynos_mixer.txt rename to trunk/Documentation/devicetree/bindings/drm/exynos/mixer.txt diff --git a/trunk/Documentation/devicetree/usage-model.txt b/trunk/Documentation/devicetree/usage-model.txt index 0efedaad5165..ef9d06c9f8fd 100644 --- a/trunk/Documentation/devicetree/usage-model.txt +++ b/trunk/Documentation/devicetree/usage-model.txt @@ -191,11 +191,9 @@ Linux it will look something like this: }; The bootargs property contains the kernel arguments, and the initrd-* -properties define the address and size of an initrd blob. Note that -initrd-end is the first address after the initrd image, so this doesn't -match the usual semantic of struct resource. The chosen node may also -optionally contain an arbitrary number of additional properties for -platform-specific configuration data. +properties define the address and size of an initrd blob. The +chosen node may also optionally contain an arbitrary number of +additional properties for platform-specific configuration data. During early boot, the architecture setup code calls of_scan_flat_dt() several times with different helper callbacks to parse device tree diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 6e3b18a8afc6..c3bfacb92910 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -3005,27 +3005,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Force threading of all interrupt handlers except those marked explicitly IRQF_NO_THREAD. - tmem [KNL,XEN] - Enable the Transcendent memory driver if built-in. - - tmem.cleancache=0|1 [KNL, XEN] - Default is on (1). Disable the usage of the cleancache - API to send anonymous pages to the hypervisor. - - tmem.frontswap=0|1 [KNL, XEN] - Default is on (1). Disable the usage of the frontswap - API to send swap pages to the hypervisor. If disabled - the selfballooning and selfshrinking are force disabled. - - tmem.selfballooning=0|1 [KNL, XEN] - Default is on (1). Disable the driving of swap pages - to the hypervisor. - - tmem.selfshrinking=0|1 [KNL, XEN] - Default is on (1). Partial swapoff that immediately - transfers pages from Xen hypervisor back to the - kernel based on different criteria. - topology= [S390] Format: {off | on} Specify if the kernel should make use of the cpu diff --git a/trunk/Documentation/kernel-per-CPU-kthreads.txt b/trunk/Documentation/kernel-per-CPU-kthreads.txt deleted file mode 100644 index cbf7ae412da4..000000000000 --- a/trunk/Documentation/kernel-per-CPU-kthreads.txt +++ /dev/null @@ -1,202 +0,0 @@ -REDUCING OS JITTER DUE TO PER-CPU KTHREADS - -This document lists per-CPU kthreads in the Linux kernel and presents -options to control their OS jitter. Note that non-per-CPU kthreads are -not listed here. To reduce OS jitter from non-per-CPU kthreads, bind -them to a "housekeeping" CPU dedicated to such work. - - -REFERENCES - -o Documentation/IRQ-affinity.txt: Binding interrupts to sets of CPUs. - -o Documentation/cgroups: Using cgroups to bind tasks to sets of CPUs. - -o man taskset: Using the taskset command to bind tasks to sets - of CPUs. - -o man sched_setaffinity: Using the sched_setaffinity() system - call to bind tasks to sets of CPUs. - -o /sys/devices/system/cpu/cpuN/online: Control CPU N's hotplug state, - writing "0" to offline and "1" to online. - -o In order to locate kernel-generated OS jitter on CPU N: - - cd /sys/kernel/debug/tracing - echo 1 > max_graph_depth # Increase the "1" for more detail - echo function_graph > current_tracer - # run workload - cat per_cpu/cpuN/trace - - -KTHREADS - -Name: ehca_comp/%u -Purpose: Periodically process Infiniband-related work. -To reduce its OS jitter, do any of the following: -1. Don't use eHCA Infiniband hardware, instead choosing hardware - that does not require per-CPU kthreads. This will prevent these - kthreads from being created in the first place. (This will - work for most people, as this hardware, though important, is - relatively old and is produced in relatively low unit volumes.) -2. Do all eHCA-Infiniband-related work on other CPUs, including - interrupts. -3. Rework the eHCA driver so that its per-CPU kthreads are - provisioned only on selected CPUs. - - -Name: irq/%d-%s -Purpose: Handle threaded interrupts. -To reduce its OS jitter, do the following: -1. Use irq affinity to force the irq threads to execute on - some other CPU. - -Name: kcmtpd_ctr_%d -Purpose: Handle Bluetooth work. -To reduce its OS jitter, do one of the following: -1. Don't use Bluetooth, in which case these kthreads won't be - created in the first place. -2. Use irq affinity to force Bluetooth-related interrupts to - occur on some other CPU and furthermore initiate all - Bluetooth activity on some other CPU. - -Name: ksoftirqd/%u -Purpose: Execute softirq handlers when threaded or when under heavy load. -To reduce its OS jitter, each softirq vector must be handled -separately as follows: -TIMER_SOFTIRQ: Do all of the following: -1. To the extent possible, keep the CPU out of the kernel when it - is non-idle, for example, by avoiding system calls and by forcing - both kernel threads and interrupts to execute elsewhere. -2. Build with CONFIG_HOTPLUG_CPU=y. After boot completes, force - the CPU offline, then bring it back online. This forces - recurring timers to migrate elsewhere. If you are concerned - with multiple CPUs, force them all offline before bringing the - first one back online. Once you have onlined the CPUs in question, - do not offline any other CPUs, because doing so could force the - timer back onto one of the CPUs in question. -NET_TX_SOFTIRQ and NET_RX_SOFTIRQ: Do all of the following: -1. Force networking interrupts onto other CPUs. -2. Initiate any network I/O on other CPUs. -3. Once your application has started, prevent CPU-hotplug operations - from being initiated from tasks that might run on the CPU to - be de-jittered. (It is OK to force this CPU offline and then - bring it back online before you start your application.) -BLOCK_SOFTIRQ: Do all of the following: -1. Force block-device interrupts onto some other CPU. -2. Initiate any block I/O on other CPUs. -3. Once your application has started, prevent CPU-hotplug operations - from being initiated from tasks that might run on the CPU to - be de-jittered. (It is OK to force this CPU offline and then - bring it back online before you start your application.) -BLOCK_IOPOLL_SOFTIRQ: Do all of the following: -1. Force block-device interrupts onto some other CPU. -2. Initiate any block I/O and block-I/O polling on other CPUs. -3. Once your application has started, prevent CPU-hotplug operations - from being initiated from tasks that might run on the CPU to - be de-jittered. (It is OK to force this CPU offline and then - bring it back online before you start your application.) -TASKLET_SOFTIRQ: Do one or more of the following: -1. Avoid use of drivers that use tasklets. (Such drivers will contain - calls to things like tasklet_schedule().) -2. Convert all drivers that you must use from tasklets to workqueues. -3. Force interrupts for drivers using tasklets onto other CPUs, - and also do I/O involving these drivers on other CPUs. -SCHED_SOFTIRQ: Do all of the following: -1. Avoid sending scheduler IPIs to the CPU to be de-jittered, - for example, ensure that at most one runnable kthread is present - on that CPU. If a thread that expects to run on the de-jittered - CPU awakens, the scheduler will send an IPI that can result in - a subsequent SCHED_SOFTIRQ. -2. Build with CONFIG_RCU_NOCB_CPU=y, CONFIG_RCU_NOCB_CPU_ALL=y, - CONFIG_NO_HZ_FULL=y, and, in addition, ensure that the CPU - to be de-jittered is marked as an adaptive-ticks CPU using the - "nohz_full=" boot parameter. This reduces the number of - scheduler-clock interrupts that the de-jittered CPU receives, - minimizing its chances of being selected to do the load balancing - work that runs in SCHED_SOFTIRQ context. -3. To the extent possible, keep the CPU out of the kernel when it - is non-idle, for example, by avoiding system calls and by - forcing both kernel threads and interrupts to execute elsewhere. - This further reduces the number of scheduler-clock interrupts - received by the de-jittered CPU. -HRTIMER_SOFTIRQ: Do all of the following: -1. To the extent possible, keep the CPU out of the kernel when it - is non-idle. For example, avoid system calls and force both - kernel threads and interrupts to execute elsewhere. -2. Build with CONFIG_HOTPLUG_CPU=y. Once boot completes, force the - CPU offline, then bring it back online. This forces recurring - timers to migrate elsewhere. If you are concerned with multiple - CPUs, force them all offline before bringing the first one - back online. Once you have onlined the CPUs in question, do not - offline any other CPUs, because doing so could force the timer - back onto one of the CPUs in question. -RCU_SOFTIRQ: Do at least one of the following: -1. Offload callbacks and keep the CPU in either dyntick-idle or - adaptive-ticks state by doing all of the following: - a. Build with CONFIG_RCU_NOCB_CPU=y, CONFIG_RCU_NOCB_CPU_ALL=y, - CONFIG_NO_HZ_FULL=y, and, in addition ensure that the CPU - to be de-jittered is marked as an adaptive-ticks CPU using - the "nohz_full=" boot parameter. Bind the rcuo kthreads - to housekeeping CPUs, which can tolerate OS jitter. - b. To the extent possible, keep the CPU out of the kernel - when it is non-idle, for example, by avoiding system - calls and by forcing both kernel threads and interrupts - to execute elsewhere. -2. Enable RCU to do its processing remotely via dyntick-idle by - doing all of the following: - a. Build with CONFIG_NO_HZ=y and CONFIG_RCU_FAST_NO_HZ=y. - b. Ensure that the CPU goes idle frequently, allowing other - CPUs to detect that it has passed through an RCU quiescent - state. If the kernel is built with CONFIG_NO_HZ_FULL=y, - userspace execution also allows other CPUs to detect that - the CPU in question has passed through a quiescent state. - c. To the extent possible, keep the CPU out of the kernel - when it is non-idle, for example, by avoiding system - calls and by forcing both kernel threads and interrupts - to execute elsewhere. - -Name: rcuc/%u -Purpose: Execute RCU callbacks in CONFIG_RCU_BOOST=y kernels. -To reduce its OS jitter, do at least one of the following: -1. Build the kernel with CONFIG_PREEMPT=n. This prevents these - kthreads from being created in the first place, and also obviates - the need for RCU priority boosting. This approach is feasible - for workloads that do not require high degrees of responsiveness. -2. Build the kernel with CONFIG_RCU_BOOST=n. This prevents these - kthreads from being created in the first place. This approach - is feasible only if your workload never requires RCU priority - boosting, for example, if you ensure frequent idle time on all - CPUs that might execute within the kernel. -3. Build with CONFIG_RCU_NOCB_CPU=y and CONFIG_RCU_NOCB_CPU_ALL=y, - which offloads all RCU callbacks to kthreads that can be moved - off of CPUs susceptible to OS jitter. This approach prevents the - rcuc/%u kthreads from having any work to do, so that they are - never awakened. -4. Ensure that the CPU never enters the kernel, and, in particular, - avoid initiating any CPU hotplug operations on this CPU. This is - another way of preventing any callbacks from being queued on the - CPU, again preventing the rcuc/%u kthreads from having any work - to do. - -Name: rcuob/%d, rcuop/%d, and rcuos/%d -Purpose: Offload RCU callbacks from the corresponding CPU. -To reduce its OS jitter, do at least one of the following: -1. Use affinity, cgroups, or other mechanism to force these kthreads - to execute on some other CPU. -2. Build with CONFIG_RCU_NOCB_CPUS=n, which will prevent these - kthreads from being created in the first place. However, please - note that this will not eliminate OS jitter, but will instead - shift it to RCU_SOFTIRQ. - -Name: watchdog/%u -Purpose: Detect software lockups on each CPU. -To reduce its OS jitter, do at least one of the following: -1. Build with CONFIG_LOCKUP_DETECTOR=n, which will prevent these - kthreads from being created in the first place. -2. Echo a zero to /proc/sys/kernel/watchdog to disable the - watchdog timer. -3. Echo a large number of /proc/sys/kernel/watchdog_thresh in - order to reduce the frequency of OS jitter due to the watchdog - timer down to a level that is acceptable for your workload. diff --git a/trunk/Documentation/power/devices.txt b/trunk/Documentation/power/devices.txt index a66c9821b5ce..504dfe4d52eb 100644 --- a/trunk/Documentation/power/devices.txt +++ b/trunk/Documentation/power/devices.txt @@ -268,7 +268,7 @@ situations. System Power Management Phases ------------------------------ Suspending or resuming the system is done in several phases. Different phases -are used for freeze, standby, and memory sleep states ("suspend-to-RAM") and the +are used for standby or memory sleep states ("suspend-to-RAM") and the hibernation state ("suspend-to-disk"). Each phase involves executing callbacks for every device before the next phase begins. Not all busses or classes support all these callbacks and not all drivers use all the callbacks. The @@ -309,8 +309,7 @@ execute the corresponding method from dev->driver->pm instead if there is one. Entering System Suspend ----------------------- -When the system goes into the freeze, standby or memory sleep state, -the phases are: +When the system goes into the standby or memory sleep state, the phases are: prepare, suspend, suspend_late, suspend_noirq. @@ -369,7 +368,7 @@ the devices that were suspended. Leaving System Suspend ---------------------- -When resuming from freeze, standby or memory sleep, the phases are: +When resuming from standby or memory sleep, the phases are: resume_noirq, resume_early, resume, complete. @@ -434,8 +433,8 @@ the system log. Entering Hibernation -------------------- -Hibernating the system is more complicated than putting it into the other -sleep states, because it involves creating and saving a system image. +Hibernating the system is more complicated than putting it into the standby or +memory sleep state, because it involves creating and saving a system image. Therefore there are more phases for hibernation, with a different set of callbacks. These phases always run after tasks have been frozen and memory has been freed. @@ -486,8 +485,8 @@ image forms an atomic snapshot of the system state. At this point the system image is saved, and the devices then need to be prepared for the upcoming system shutdown. This is much like suspending them -before putting the system into the freeze, standby or memory sleep state, -and the phases are similar. +before putting the system into the standby or memory sleep state, and the phases +are similar. 9. The prepare phase is discussed above. diff --git a/trunk/Documentation/power/interface.txt b/trunk/Documentation/power/interface.txt index f1f0f59a7c47..c537834af005 100644 --- a/trunk/Documentation/power/interface.txt +++ b/trunk/Documentation/power/interface.txt @@ -7,8 +7,8 @@ running. The interface exists in /sys/power/ directory (assuming sysfs is mounted at /sys). /sys/power/state controls system power state. Reading from this file -returns what states are supported, which is hard-coded to 'freeze', -'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk' +returns what states are supported, which is hard-coded to 'standby' +(Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk' (Suspend-to-Disk). Writing to this file one of those strings causes the system to diff --git a/trunk/Documentation/power/notifiers.txt b/trunk/Documentation/power/notifiers.txt index a81fa254303d..c2a4a346c0d9 100644 --- a/trunk/Documentation/power/notifiers.txt +++ b/trunk/Documentation/power/notifiers.txt @@ -15,10 +15,8 @@ A suspend/hibernation notifier may be used for this purpose. The subsystems or drivers having such needs can register suspend notifiers that will be called upon the following events by the PM core: -PM_HIBERNATION_PREPARE The system is going to hibernate, tasks will be frozen - immediately. This is different from PM_SUSPEND_PREPARE - below because here we do additional work between notifiers - and drivers freezing. +PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will + be frozen immediately. PM_POST_HIBERNATION The system memory state has been restored from a hibernation image or an error occurred during diff --git a/trunk/Documentation/power/states.txt b/trunk/Documentation/power/states.txt index 442d43df9b25..4416b28630df 100644 --- a/trunk/Documentation/power/states.txt +++ b/trunk/Documentation/power/states.txt @@ -2,26 +2,12 @@ System Power Management States -The kernel supports four power management states generically, though -one is generic and the other three are dependent on platform support -code to implement the low-level details for each state. -This file describes each state, what they are +The kernel supports three power management states generically, though +each is dependent on platform support code to implement the low-level +details for each state. This file describes each state, what they are commonly called, what ACPI state they map to, and what string to write to /sys/power/state to enter that state -state: Freeze / Low-Power Idle -ACPI state: S0 -String: "freeze" - -This state is a generic, pure software, light-weight, low-power state. -It allows more energy to be saved relative to idle by freezing user -space and putting all I/O devices into low-power states (possibly -lower-power than available at run time), such that the processors can -spend more time in their idle states. -This state can be used for platforms without Standby/Suspend-to-RAM -support, or it can be used in addition to Suspend-to-RAM (memory sleep) -to provide reduced resume latency. - State: Standby / Power-On Suspend ACPI State: S1 @@ -36,6 +22,9 @@ We try to put devices in a low-power state equivalent to D1, which also offers low power savings, but low resume latency. Not all devices support D1, and those that don't are left on. +A transition from Standby to the On state should take about 1-2 +seconds. + State: Suspend-to-RAM ACPI State: S3 @@ -53,6 +42,9 @@ transition back to the On state. For at least ACPI, STR requires some minimal boot-strapping code to resume the system from STR. This may be true on other platforms. +A transition from Suspend-to-RAM to the On state should take about +3-5 seconds. + State: Suspend-to-disk ACPI State: S4 @@ -82,3 +74,7 @@ low-power state (like ACPI S4), or it may simply power down. Powering down offers greater savings, and allows this mechanism to work on any system. However, entering a real low-power state allows the user to trigger wake up events (e.g. pressing a key or opening a laptop lid). + +A transition from Suspend-to-Disk to the On state should take about 30 +seconds, though it's typically a bit more with the current +implementation. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index b645a3d5fd30..50955f90ed7e 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3865,16 +3865,9 @@ M: K. Y. Srinivasan M: Haiyang Zhang L: devel@linuxdriverproject.org S: Maintained -F: arch/x86/include/asm/mshyperv.h -F: arch/x86/include/uapi/asm/hyperv.h -F: arch/x86/kernel/cpu/mshyperv.c -F: drivers/hid/hid-hyperv.c F: drivers/hv/ +F: drivers/hid/hid-hyperv.c F: drivers/net/hyperv/ -F: drivers/scsi/storvsc_drv.c -F: drivers/video/hyperv_fb.c -F: include/linux/hyperv.h -F: tools/hv/ I2C OVER PARALLEL PORT M: Jean Delvare @@ -4648,13 +4641,12 @@ F: include/linux/sunrpc/ F: include/uapi/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) +M: Marcelo Tosatti M: Gleb Natapov -M: Paolo Bonzini L: kvm@vger.kernel.org -W: http://linux-kvm.org +W: http://kvm.qumranet.com S: Supported -F: Documentation/*/kvm*.txt -F: Documentation/virtual/kvm/ +F: Documentation/*/kvm.txt F: arch/*/kvm/ F: arch/*/include/asm/kvm* F: include/linux/kvm* @@ -4984,13 +4976,6 @@ S: Maintained F: Documentation/hwmon/lm90 F: drivers/hwmon/lm90.c -LM95234 HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/lm95234 -F: drivers/hwmon/lm95234.c - LME2510 MEDIA DRIVER M: Malcolm Priestley L: linux-media@vger.kernel.org @@ -7869,7 +7854,7 @@ L: linux-scsi@vger.kernel.org L: target-devel@vger.kernel.org L: http://groups.google.com/group/linux-iscsi-target-dev W: http://www.linux-iscsi.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master +T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core.git master S: Supported F: drivers/target/ F: include/target/ @@ -8197,13 +8182,6 @@ F: drivers/mmc/host/sh_mobile_sdhi.c F: include/linux/mmc/tmio.h F: include/linux/mmc/sh_mobile_sdhi.h -TMP401 HARDWARE MONITOR DRIVER -M: Guenter Roeck -L: lm-sensors@lm-sensors.org -S: Maintained -F: Documentation/hwmon/tmp401 -F: drivers/hwmon/tmp401.c - TMPFS (SHMEM FILESYSTEM) M: Hugh Dickins L: linux-mm@kvack.org diff --git a/trunk/Makefile b/trunk/Makefile index 93875f5122a3..cd11e8857604 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 10 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc1 NAME = Unicycling Gorilla # *DOCUMENTATION* diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index a4429bcd609e..dd0e8eb8042f 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -213,9 +213,6 @@ config USE_GENERIC_SMP_HELPERS config GENERIC_SMP_IDLE_THREAD bool -config GENERIC_IDLE_POLL_SETUP - bool - # Select if arch init_task initializer is different to init/init_task.c config ARCH_INIT_TASK bool diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 49d993cee512..d423d58f938d 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -38,7 +38,6 @@ config ARM select HAVE_GENERIC_HARDIRQS select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_IDE if PCI || ISA || PCMCIA - select HAVE_IRQ_TIME_ACCOUNTING select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZMA select HAVE_KERNEL_LZO @@ -489,7 +488,7 @@ config ARCH_IXP4XX config ARCH_DOVE bool "Marvell Dove" select ARCH_REQUIRE_GPIOLIB - select CPU_PJ4 + select CPU_V7 select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select PINCTRL diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 1ba358ba16b8..47374085befd 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -309,7 +309,7 @@ define archhelp echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)' echo ' uImage - U-Boot wrapped zImage' - echo ' bootpImage - Combined zImage and initial RAM disk' + echo ' bootpImage - Combined zImage and initial RAM disk' echo ' (supply initrd image via make variable INITRD=)' echo '* dtbs - Build device tree blobs for enabled boards' echo ' install - Install uncompressed kernel' diff --git a/trunk/arch/arm/common/mcpm_platsmp.c b/trunk/arch/arm/common/mcpm_platsmp.c index 3caed0db6986..52b88d81b7bb 100644 --- a/trunk/arch/arm/common/mcpm_platsmp.c +++ b/trunk/arch/arm/common/mcpm_platsmp.c @@ -15,6 +15,8 @@ #include #include +#include + #include #include #include @@ -47,6 +49,7 @@ static int __cpuinit mcpm_boot_secondary(unsigned int cpu, struct task_struct *i static void __cpuinit mcpm_secondary_init(unsigned int cpu) { mcpm_cpu_powered_up(); + gic_secondary_init(0); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/trunk/arch/arm/configs/omap1_defconfig b/trunk/arch/arm/configs/omap1_defconfig index 9940f7b4e438..7e0ebb64a7f9 100644 --- a/trunk/arch/arm/configs/omap1_defconfig +++ b/trunk/arch/arm/configs/omap1_defconfig @@ -199,6 +199,7 @@ CONFIG_USB_PHY=y CONFIG_USB_DEBUG=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/trunk/arch/arm/configs/omap2plus_defconfig b/trunk/arch/arm/configs/omap2plus_defconfig index 435d69b83e32..c1ef64bc5abd 100644 --- a/trunk/arch/arm/configs/omap2plus_defconfig +++ b/trunk/arch/arm/configs/omap2plus_defconfig @@ -204,6 +204,7 @@ CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y +CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y diff --git a/trunk/arch/arm/include/asm/cmpxchg.h b/trunk/arch/arm/include/asm/cmpxchg.h index 4f009c10540d..7eb18c1d8d6c 100644 --- a/trunk/arch/arm/include/asm/cmpxchg.h +++ b/trunk/arch/arm/include/asm/cmpxchg.h @@ -233,15 +233,15 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, ((__typeof__(*(ptr)))atomic64_cmpxchg(container_of((ptr), \ atomic64_t, \ counter), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) + (unsigned long)(o), \ + (unsigned long)(n))) #define cmpxchg64_local(ptr, o, n) \ ((__typeof__(*(ptr)))local64_cmpxchg(container_of((ptr), \ local64_t, \ a), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) + (unsigned long)(o), \ + (unsigned long)(n))) #endif /* __LINUX_ARM_ARCH__ >= 6 */ diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 550d63cef68e..47ab90563bf4 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -251,7 +251,7 @@ void __ref cpu_die(void) * this returns, power and/or clocks can be removed at any point * from this CPU and its cache by platform_cpu_kill(). */ - complete(&cpu_died); + RCU_NONIDLE(complete(&cpu_died)); /* * Ensure that the cache lines associated with that completion are diff --git a/trunk/arch/arm/mach-tegra/tegra2_emc.c b/trunk/arch/arm/mach-tegra/tegra2_emc.c index 31e69a019bdd..9e8bdfa2b369 100644 --- a/trunk/arch/arm/mach-tegra/tegra2_emc.c +++ b/trunk/arch/arm/mach-tegra/tegra2_emc.c @@ -307,6 +307,11 @@ static int tegra_emc_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "missing register base\n"); + return -ENOMEM; + } + emc_regbase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(emc_regbase)) return PTR_ERR(emc_regbase); diff --git a/trunk/arch/arm/plat-samsung/adc.c b/trunk/arch/arm/plat-samsung/adc.c index 79690f2f6d3f..ca07cb1b155a 100644 --- a/trunk/arch/arm/plat-samsung/adc.c +++ b/trunk/arch/arm/plat-samsung/adc.c @@ -381,6 +381,11 @@ static int s3c_adc_probe(struct platform_device *pdev) } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(dev, "failed to find registers\n"); + return -ENXIO; + } + adc->regs = devm_ioremap_resource(dev, regs); if (IS_ERR(adc->regs)) return PTR_ERR(adc->regs); diff --git a/trunk/arch/arm/xen/enlighten.c b/trunk/arch/arm/xen/enlighten.c index 13609e01f4b7..d30042e39974 100644 --- a/trunk/arch/arm/xen/enlighten.c +++ b/trunk/arch/arm/xen/enlighten.c @@ -152,12 +152,11 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma, } EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range); -static void __init xen_percpu_init(void *unused) +static int __init xen_secondary_init(unsigned int cpu) { struct vcpu_register_vcpu_info info; struct vcpu_info *vcpup; int err; - int cpu = get_cpu(); pr_info("Xen: initializing cpu%d\n", cpu); vcpup = per_cpu_ptr(xen_vcpu_info, cpu); @@ -166,10 +165,14 @@ static void __init xen_percpu_init(void *unused) info.offset = offset_in_page(vcpup); err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); - BUG_ON(err); - per_cpu(xen_vcpu, cpu) = vcpup; - - enable_percpu_irq(xen_events_irq, 0); + if (err) { + pr_debug("register_vcpu_info failed: err=%d\n", err); + } else { + /* This cpu is using the registered vcpu info, even if + later ones fail to. */ + per_cpu(xen_vcpu, cpu) = vcpup; + } + return 0; } static void xen_restart(char str, const char *cmd) @@ -205,6 +208,7 @@ static int __init xen_guest_init(void) const char *version = NULL; const char *xen_prefix = "xen,xen-"; struct resource res; + int i; node = of_find_compatible_node(NULL, NULL, "xen,xen"); if (!node) { @@ -261,23 +265,19 @@ static int __init xen_guest_init(void) sizeof(struct vcpu_info)); if (xen_vcpu_info == NULL) return -ENOMEM; + for_each_online_cpu(i) + xen_secondary_init(i); gnttab_init(); if (!xen_initial_domain()) xenbus_probe(NULL); - return 0; -} -core_initcall(xen_guest_init); - -static int __init xen_pm_init(void) -{ pm_power_off = xen_power_off; arm_pm_restart = xen_restart; return 0; } -subsys_initcall(xen_pm_init); +core_initcall(xen_guest_init); static irqreturn_t xen_arm_callback(int irq, void *arg) { @@ -285,6 +285,11 @@ static irqreturn_t xen_arm_callback(int irq, void *arg) return IRQ_HANDLED; } +static __init void xen_percpu_enable_events(void *unused) +{ + enable_percpu_irq(xen_events_irq, 0); +} + static int __init xen_init_events(void) { if (!xen_domain() || xen_events_irq < 0) @@ -298,7 +303,7 @@ static int __init xen_init_events(void) return -EINVAL; } - on_each_cpu(xen_percpu_init, NULL, 0); + on_each_cpu(xen_percpu_enable_events, NULL, 0); return 0; } diff --git a/trunk/arch/arm64/Kconfig b/trunk/arch/arm64/Kconfig index 56b3f6d447ae..48347dcf0566 100644 --- a/trunk/arch/arm64/Kconfig +++ b/trunk/arch/arm64/Kconfig @@ -122,6 +122,8 @@ endmenu menu "Kernel Features" +source "kernel/time/Kconfig" + config ARM64_64K_PAGES bool "Enable 64KB pages support" help diff --git a/trunk/arch/arm64/include/asm/assembler.h b/trunk/arch/arm64/include/asm/assembler.h index 5aceb83b3f5c..c8eedc604984 100644 --- a/trunk/arch/arm64/include/asm/assembler.h +++ b/trunk/arch/arm64/include/asm/assembler.h @@ -82,7 +82,7 @@ .macro enable_dbg_if_not_stepping, tmp mrs \tmp, mdscr_el1 - tbnz \tmp, #0, 9990f + tbnz \tmp, #1, 9990f enable_dbg 9990: .endm diff --git a/trunk/arch/arm64/kernel/debug-monitors.c b/trunk/arch/arm64/kernel/debug-monitors.c index f4726dc054b3..0c3ba9f51376 100644 --- a/trunk/arch/arm64/kernel/debug-monitors.c +++ b/trunk/arch/arm64/kernel/debug-monitors.c @@ -136,6 +136,8 @@ void disable_debug_monitors(enum debug_el el) */ static void clear_os_lock(void *unused) { + asm volatile("msr mdscr_el1, %0" : : "r" (0)); + isb(); asm volatile("msr oslar_el1, %0" : : "r" (0)); isb(); } diff --git a/trunk/arch/arm64/kernel/early_printk.c b/trunk/arch/arm64/kernel/early_printk.c index fbb6e1843659..ac974f48a7a2 100644 --- a/trunk/arch/arm64/kernel/early_printk.c +++ b/trunk/arch/arm64/kernel/early_printk.c @@ -95,7 +95,7 @@ static void early_write(struct console *con, const char *s, unsigned n) } } -static struct console early_console_dev = { +static struct console early_console = { .name = "earlycon", .write = early_write, .flags = CON_PRINTBUFFER | CON_BOOT, @@ -145,8 +145,7 @@ static int __init setup_early_printk(char *buf) early_base = early_io_map(paddr, EARLYCON_IOBASE); printch = match->printch; - early_console = &early_console_dev; - register_console(&early_console_dev); + register_console(&early_console); return 0; } diff --git a/trunk/arch/arm64/kernel/setup.c b/trunk/arch/arm64/kernel/setup.c index add6ea616843..6a9a53292590 100644 --- a/trunk/arch/arm64/kernel/setup.c +++ b/trunk/arch/arm64/kernel/setup.c @@ -282,13 +282,12 @@ void __init setup_arch(char **cmdline_p) #endif } -static int __init arm64_device_init(void) +static int __init arm64_of_clk_init(void) { of_clk_init(NULL); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); return 0; } -arch_initcall(arm64_device_init); +arch_initcall(arm64_of_clk_init); static DEFINE_PER_CPU(struct cpu, cpu_data); @@ -306,6 +305,13 @@ static int __init topology_init(void) } subsys_initcall(topology_init); +static int __init arm64_device_probe(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + return 0; +} +device_initcall(arm64_device_probe); + static const char *hwcap_str[] = { "fp", "asimd", diff --git a/trunk/arch/arm64/mm/cache.S b/trunk/arch/arm64/mm/cache.S index 48a386094fa3..abe69b80cf7f 100644 --- a/trunk/arch/arm64/mm/cache.S +++ b/trunk/arch/arm64/mm/cache.S @@ -52,7 +52,7 @@ loop1: add x2, x2, #4 // add 4 (line length offset) mov x4, #0x3ff and x4, x4, x1, lsr #3 // find maximum number on the way size - clz w5, w4 // find bit position of way size increment + clz x5, x4 // find bit position of way size increment mov x7, #0x7fff and x7, x7, x1, lsr #13 // extract max number of the index size loop2: diff --git a/trunk/arch/arm64/mm/proc.S b/trunk/arch/arm64/mm/proc.S index a82ae8868077..f1d8b9bbfdad 100644 --- a/trunk/arch/arm64/mm/proc.S +++ b/trunk/arch/arm64/mm/proc.S @@ -119,7 +119,8 @@ ENTRY(__cpu_setup) mov x0, #3 << 20 msr cpacr_el1, x0 // Enable FP/ASIMD - msr mdscr_el1, xzr // Reset mdscr_el1 + mov x0, #1 + msr oslar_el1, x0 // Set the debug OS lock tlbi vmalle1is // invalidate I + D TLBs /* * Memory region attributes for LPAE: diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index 549903cfc2cb..bdc35589277f 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -205,11 +205,6 @@ config ARCH_DISCONTIGMEM_ENABLE config ARCH_SPARSEMEM_ENABLE def_bool n -config NODES_SHIFT - int - default "2" - depends on NEED_MULTIPLE_NODES - source "mm/Kconfig" config OWNERSHIP_TRACE diff --git a/trunk/arch/avr32/include/asm/Kbuild b/trunk/arch/avr32/include/asm/Kbuild index d22af851f3f6..4dd4f78d3dcc 100644 --- a/trunk/arch/avr32/include/asm/Kbuild +++ b/trunk/arch/avr32/include/asm/Kbuild @@ -2,4 +2,3 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h -generic-y += param.h diff --git a/trunk/arch/avr32/include/asm/numnodes.h b/trunk/arch/avr32/include/asm/numnodes.h new file mode 100644 index 000000000000..0b864d7ce330 --- /dev/null +++ b/trunk/arch/avr32/include/asm/numnodes.h @@ -0,0 +1,7 @@ +#ifndef __ASM_AVR32_NUMNODES_H +#define __ASM_AVR32_NUMNODES_H + +/* Max 4 nodes */ +#define NODES_SHIFT 2 + +#endif /* __ASM_AVR32_NUMNODES_H */ diff --git a/trunk/arch/avr32/include/asm/param.h b/trunk/arch/avr32/include/asm/param.h new file mode 100644 index 000000000000..009a167aea1f --- /dev/null +++ b/trunk/arch/avr32/include/asm/param.h @@ -0,0 +1,9 @@ +#ifndef __ASM_AVR32_PARAM_H +#define __ASM_AVR32_PARAM_H + +#include + +# define HZ CONFIG_HZ +# define USER_HZ 100 /* User interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ +#endif /* __ASM_AVR32_PARAM_H */ diff --git a/trunk/arch/avr32/include/uapi/asm/Kbuild b/trunk/arch/avr32/include/uapi/asm/Kbuild index 3b85eaddf525..df53e7a46774 100644 --- a/trunk/arch/avr32/include/uapi/asm/Kbuild +++ b/trunk/arch/avr32/include/uapi/asm/Kbuild @@ -33,4 +33,3 @@ header-y += termbits.h header-y += termios.h header-y += types.h header-y += unistd.h -generic-y += param.h diff --git a/trunk/arch/avr32/include/uapi/asm/param.h b/trunk/arch/avr32/include/uapi/asm/param.h new file mode 100644 index 000000000000..d28aa5ee6d37 --- /dev/null +++ b/trunk/arch/avr32/include/uapi/asm/param.h @@ -0,0 +1,18 @@ +#ifndef _UAPI__ASM_AVR32_PARAM_H +#define _UAPI__ASM_AVR32_PARAM_H + + +#ifndef HZ +# define HZ 100 +#endif + +/* TODO: Should be configurable */ +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +# define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 + +#endif /* _UAPI__ASM_AVR32_PARAM_H */ diff --git a/trunk/arch/avr32/kernel/module.c b/trunk/arch/avr32/kernel/module.c index 2c9412908024..596f7305d93f 100644 --- a/trunk/arch/avr32/kernel/module.c +++ b/trunk/arch/avr32/kernel/module.c @@ -264,7 +264,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, break; case R_AVR32_GOT18SW: if ((relocation & 0xfffe0003) != 0 - && (relocation & 0xfffc0000) != 0xfffc0000) + && (relocation & 0xfffc0003) != 0xffff0000) return reloc_overflow(module, "R_AVR32_GOT18SW", relocation); relocation >>= 2; diff --git a/trunk/arch/mips/alchemy/board-gpr.c b/trunk/arch/mips/alchemy/board-gpr.c index 9edc35ff8cf1..cb0f6afb7389 100644 --- a/trunk/arch/mips/alchemy/board-gpr.c +++ b/trunk/arch/mips/alchemy/board-gpr.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/alchemy/common/time.c b/trunk/arch/mips/alchemy/common/time.c index 93fa586d52e2..38afb11ba2c4 100644 --- a/trunk/arch/mips/alchemy/common/time.c +++ b/trunk/arch/mips/alchemy/common/time.c @@ -36,7 +36,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/ath79/setup.c b/trunk/arch/mips/ath79/setup.c index 8be4e856b8b8..a0233a2c1988 100644 --- a/trunk/arch/mips/ath79/setup.c +++ b/trunk/arch/mips/ath79/setup.c @@ -19,7 +19,6 @@ #include #include -#include #include /* for mips_hpt_frequency */ #include /* for _machine_{restart,halt} */ #include diff --git a/trunk/arch/mips/cobalt/reset.c b/trunk/arch/mips/cobalt/reset.c index 4eedd481dd00..516b4428df4e 100644 --- a/trunk/arch/mips/cobalt/reset.c +++ b/trunk/arch/mips/cobalt/reset.c @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/configs/db1000_defconfig b/trunk/arch/mips/configs/db1000_defconfig index bac26b971c5e..face9d26e6d5 100644 --- a/trunk/arch/mips/configs/db1000_defconfig +++ b/trunk/arch/mips/configs/db1000_defconfig @@ -228,6 +228,7 @@ CONFIG_HIDRAW=y CONFIG_USB_HID=y CONFIG_USB_SUPPORT=y CONFIG_USB=y +CONFIG_USB_SUSPEND=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y diff --git a/trunk/arch/mips/configs/db1235_defconfig b/trunk/arch/mips/configs/db1235_defconfig index e2b4ad55462f..14752dde7540 100644 --- a/trunk/arch/mips/configs/db1235_defconfig +++ b/trunk/arch/mips/configs/db1235_defconfig @@ -344,6 +344,7 @@ CONFIG_UHID=y CONFIG_USB_HIDDEV=y CONFIG_USB=y CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_SUSPEND=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_EHCI_ROOT_HUB_TT=y diff --git a/trunk/arch/mips/configs/lemote2f_defconfig b/trunk/arch/mips/configs/lemote2f_defconfig index 343bebc4b63b..b6acd2f256b6 100644 --- a/trunk/arch/mips/configs/lemote2f_defconfig +++ b/trunk/arch/mips/configs/lemote2f_defconfig @@ -300,6 +300,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_SUSPEND=y CONFIG_USB_OTG_WHITELIST=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y diff --git a/trunk/arch/mips/include/asm/clock.h b/trunk/arch/mips/include/asm/clock.h index 778e32d817bc..c9456e7a7283 100644 --- a/trunk/arch/mips/include/asm/clock.h +++ b/trunk/arch/mips/include/asm/clock.h @@ -6,6 +6,8 @@ #include #include +extern void (*cpu_wait) (void); + struct clk; struct clk_ops { diff --git a/trunk/arch/mips/include/asm/idle.h b/trunk/arch/mips/include/asm/idle.h deleted file mode 100644 index d192158886b1..000000000000 --- a/trunk/arch/mips/include/asm/idle.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __ASM_IDLE_H -#define __ASM_IDLE_H - -#include - -extern void (*cpu_wait)(void); -extern void r4k_wait(void); -extern asmlinkage void __r4k_wait(void); -extern void r4k_wait_irqoff(void); -extern void __pastwait(void); - -static inline int using_rollback_handler(void) -{ - return cpu_wait == r4k_wait; -} - -static inline int address_is_in_r4k_wait_irqoff(unsigned long addr) -{ - return addr >= (unsigned long)r4k_wait_irqoff && - addr < (unsigned long)__pastwait; -} - -#endif /* __ASM_IDLE_H */ diff --git a/trunk/arch/mips/include/asm/io.h b/trunk/arch/mips/include/asm/io.h index b7e59853fd33..1be13727323f 100644 --- a/trunk/arch/mips/include/asm/io.h +++ b/trunk/arch/mips/include/asm/io.h @@ -118,7 +118,7 @@ static inline void set_io_port_base(unsigned long base) */ static inline unsigned long virt_to_phys(volatile const void *address) { - return __pa(address); + return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; } /* diff --git a/trunk/arch/mips/include/uapi/asm/kvm.h b/trunk/arch/mips/include/asm/kvm.h similarity index 100% rename from trunk/arch/mips/include/uapi/asm/kvm.h rename to trunk/arch/mips/include/asm/kvm.h diff --git a/trunk/arch/mips/include/asm/kvm_host.h b/trunk/arch/mips/include/asm/kvm_host.h index 143875c6c95a..e68781e18387 100644 --- a/trunk/arch/mips/include/asm/kvm_host.h +++ b/trunk/arch/mips/include/asm/kvm_host.h @@ -336,7 +336,7 @@ enum emulation_result { #define VPN2_MASK 0xffffe000 #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && ((x).tlb_lo1 & MIPS3_PG_G)) #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) -#define TLB_ASID(x) ((x).tlb_hi & ASID_MASK) +#define TLB_ASID(x) (ASID_MASK((x).tlb_hi)) #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) ? ((x).tlb_lo1 & MIPS3_PG_V) : ((x).tlb_lo0 & MIPS3_PG_V)) struct kvm_mips_tlb { diff --git a/trunk/arch/mips/include/asm/mmu_context.h b/trunk/arch/mips/include/asm/mmu_context.h index 820116067c10..1554721e4808 100644 --- a/trunk/arch/mips/include/asm/mmu_context.h +++ b/trunk/arch/mips/include/asm/mmu_context.h @@ -67,45 +67,68 @@ extern unsigned long pgd_current[]; TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define ASID_INC 0x40 -#define ASID_MASK 0xfc0 - -#elif defined(CONFIG_CPU_R8000) - -#define ASID_INC 0x10 -#define ASID_MASK 0xff0 - -#elif defined(CONFIG_MIPS_MT_SMTC) - -#define ASID_INC 0x1 -extern unsigned long smtc_asid_mask; -#define ASID_MASK (smtc_asid_mask) -#define HW_ASID_MASK 0xff -/* End SMTC/34K debug hack */ -#else /* FIXME: not correct for R6000 */ - -#define ASID_INC 0x1 -#define ASID_MASK 0xff +#define ASID_INC(asid) \ +({ \ + unsigned long __asid = asid; \ + __asm__("1:\taddiu\t%0,1\t\t\t\t# patched\n\t" \ + ".section\t__asid_inc,\"a\"\n\t" \ + ".word\t1b\n\t" \ + ".previous" \ + :"=r" (__asid) \ + :"0" (__asid)); \ + __asid; \ +}) +#define ASID_MASK(asid) \ +({ \ + unsigned long __asid = asid; \ + __asm__("1:\tandi\t%0,%1,0xfc0\t\t\t# patched\n\t" \ + ".section\t__asid_mask,\"a\"\n\t" \ + ".word\t1b\n\t" \ + ".previous" \ + :"=r" (__asid) \ + :"r" (__asid)); \ + __asid; \ +}) +#define ASID_VERSION_MASK \ +({ \ + unsigned long __asid; \ + __asm__("1:\taddiu\t%0,$0,0xff00\t\t\t\t# patched\n\t" \ + ".section\t__asid_version_mask,\"a\"\n\t" \ + ".word\t1b\n\t" \ + ".previous" \ + :"=r" (__asid)); \ + __asid; \ +}) +#define ASID_FIRST_VERSION \ +({ \ + unsigned long __asid = asid; \ + __asm__("1:\tli\t%0,0x100\t\t\t\t# patched\n\t" \ + ".section\t__asid_first_version,\"a\"\n\t" \ + ".word\t1b\n\t" \ + ".previous" \ + :"=r" (__asid)); \ + __asid; \ +}) + +#define ASID_FIRST_VERSION_R3000 0x1000 +#define ASID_FIRST_VERSION_R4000 0x100 +#define ASID_FIRST_VERSION_R8000 0x1000 +#define ASID_FIRST_VERSION_RM9000 0x1000 +#ifdef CONFIG_MIPS_MT_SMTC +#define SMTC_HW_ASID_MASK 0xff +extern unsigned int smtc_asid_mask; #endif #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) -#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) +#define cpu_asid(cpu, mm) ASID_MASK(cpu_context((cpu), (mm))) #define asid_cache(cpu) (cpu_data[cpu].asid_cache) static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } -/* - * All unused by hardware upper bits will be considered - * as a software asid extension. - */ -#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) -#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) - #ifndef CONFIG_MIPS_MT_SMTC /* Normal, classic MIPS get_new_mmu_context */ static inline void @@ -114,7 +137,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) extern void kvm_local_flush_tlb_all(void); unsigned long asid = asid_cache(cpu); - if (! ((asid += ASID_INC) & ASID_MASK) ) { + if (!ASID_MASK((asid = ASID_INC(asid)))) { if (cpu_has_vtag_icache) flush_icache_all(); #ifdef CONFIG_VIRTUALIZATION @@ -177,7 +200,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * free up the ASID value for use and flush any old * instances of it from the TLB. */ - oldasid = (read_c0_entryhi() & ASID_MASK); + oldasid = ASID_MASK(read_c0_entryhi()); if(smtc_live_asid[mytlb][oldasid]) { smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); if(smtc_live_asid[mytlb][oldasid] == 0) @@ -188,7 +211,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * having ASID_MASK smaller than the hardware maximum, * make sure no "soft" bits become "hard"... */ - write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | + write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) | cpu_asid(cpu, next)); ehb(); /* Make sure it propagates to TCStatus */ evpe(mtflags); @@ -241,15 +264,15 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) #ifdef CONFIG_MIPS_MT_SMTC /* See comments for similar code above */ mtflags = dvpe(); - oldasid = read_c0_entryhi() & ASID_MASK; + oldasid = ASID_MASK(read_c0_entryhi()); if(smtc_live_asid[mytlb][oldasid]) { smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); if(smtc_live_asid[mytlb][oldasid] == 0) smtc_flush_tlb_asid(oldasid); } /* See comments for similar code above */ - write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | - cpu_asid(cpu, next)); + write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) | + cpu_asid(cpu, next)); ehb(); /* Make sure it propagates to TCStatus */ evpe(mtflags); #else @@ -286,14 +309,14 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu) #ifdef CONFIG_MIPS_MT_SMTC /* See comments for similar code above */ prevvpe = dvpe(); - oldasid = (read_c0_entryhi() & ASID_MASK); + oldasid = ASID_MASK(read_c0_entryhi()); if (smtc_live_asid[mytlb][oldasid]) { smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); if(smtc_live_asid[mytlb][oldasid] == 0) smtc_flush_tlb_asid(oldasid); } /* See comments for similar code above */ - write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) + write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) | cpu_asid(cpu, mm)); ehb(); /* Make sure it propagates to TCStatus */ evpe(prevvpe); diff --git a/trunk/arch/mips/include/asm/page.h b/trunk/arch/mips/include/asm/page.h index f59552fae917..eab99e536b5c 100644 --- a/trunk/arch/mips/include/asm/page.h +++ b/trunk/arch/mips/include/asm/page.h @@ -46,6 +46,7 @@ #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */ #include +#include extern void build_clear_page(void); extern void build_copy_page(void); @@ -150,7 +151,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) #endif #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) -#include /* * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad @@ -171,13 +171,14 @@ typedef struct { unsigned long pgprot; } pgprot_t; #ifdef CONFIG_FLATMEM -static inline int pfn_valid(unsigned long pfn) -{ - /* avoid include hell */ - extern unsigned long max_mapnr; - - return pfn >= ARCH_PFN_OFFSET && pfn < max_mapnr; -} +#define pfn_valid(pfn) \ +({ \ + unsigned long __pfn = (pfn); \ + /* avoid include hell */ \ + extern unsigned long min_low_pfn; \ + \ + __pfn >= min_low_pfn && __pfn < max_mapnr; \ +}) #elif defined(CONFIG_SPARSEMEM) diff --git a/trunk/arch/mips/include/asm/processor.h b/trunk/arch/mips/include/asm/processor.h index 1470b7b68b0e..71686c897dea 100644 --- a/trunk/arch/mips/include/asm/processor.h +++ b/trunk/arch/mips/include/asm/processor.h @@ -28,6 +28,7 @@ /* * System setup and hardware flags.. */ +extern void (*cpu_wait)(void); extern unsigned int vced_count, vcei_count; diff --git a/trunk/arch/mips/include/uapi/asm/unistd.h b/trunk/arch/mips/include/uapi/asm/unistd.h index 1dee279f9665..16338b84fa79 100644 --- a/trunk/arch/mips/include/uapi/asm/unistd.h +++ b/trunk/arch/mips/include/uapi/asm/unistd.h @@ -694,17 +694,16 @@ #define __NR_process_vm_writev (__NR_Linux + 305) #define __NR_kcmp (__NR_Linux + 306) #define __NR_finit_module (__NR_Linux + 307) -#define __NR_getdents64 (__NR_Linux + 308) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 308 +#define __NR_Linux_syscalls 307 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 308 +#define __NR_64_Linux_syscalls 307 #if _MIPS_SIM == _MIPS_SIM_NABI32 diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index 423d871a946b..6ad9e04bdf62 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o vmlinux.lds -obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ +obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ prom.o ptrace.o reset.o setup.o signal.o syscall.o \ time.o topology.o traps.o unaligned.o watch.o vdso.o diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index c6568bf4b1b0..4bbffdb9024f 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -27,6 +27,105 @@ #include #include +/* + * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, + * the implementation of the "wait" feature differs between CPU families. This + * points to the function that implements CPU specific wait. + * The wait instruction stops the pipeline and reduces the power consumption of + * the CPU very much. + */ +void (*cpu_wait)(void); +EXPORT_SYMBOL(cpu_wait); + +static void r3081_wait(void) +{ + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); +} + +static void r39xx_wait(void) +{ + local_irq_disable(); + if (!need_resched()) + write_c0_conf(read_c0_conf() | TX39_CONF_HALT); + local_irq_enable(); +} + +extern void r4k_wait(void); + +/* + * This variant is preferable as it allows testing need_resched and going to + * sleep depending on the outcome atomically. Unfortunately the "It is + * implementation-dependent whether the pipeline restarts when a non-enabled + * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes + * using this version a gamble. + */ +void r4k_wait_irqoff(void) +{ + local_irq_disable(); + if (!need_resched()) + __asm__(" .set push \n" + " .set mips3 \n" + " wait \n" + " .set pop \n"); + local_irq_enable(); + __asm__(" .globl __pastwait \n" + "__pastwait: \n"); +} + +/* + * The RM7000 variant has to handle erratum 38. The workaround is to not + * have any pending stores when the WAIT instruction is executed. + */ +static void rm7k_wait_irqoff(void) +{ + local_irq_disable(); + if (!need_resched()) + __asm__( + " .set push \n" + " .set mips3 \n" + " .set noat \n" + " mfc0 $1, $12 \n" + " sync \n" + " mtc0 $1, $12 # stalls until W stage \n" + " wait \n" + " mtc0 $1, $12 # stalls until W stage \n" + " .set pop \n"); + local_irq_enable(); +} + +/* + * The Au1xxx wait is available only if using 32khz counter or + * external timer source, but specifically not CP0 Counter. + * alchemy/common/time.c may override cpu_wait! + */ +static void au1k_wait(void) +{ + __asm__(" .set mips3 \n" + " cache 0x14, 0(%0) \n" + " cache 0x14, 32(%0) \n" + " sync \n" + " nop \n" + " wait \n" + " nop \n" + " nop \n" + " nop \n" + " nop \n" + " .set mips0 \n" + : : "r" (au1k_wait)); +} + +static int __initdata nowait; + +static int __init wait_disable(char *s) +{ + nowait = 1; + + return 1; +} + +__setup("nowait", wait_disable); + static int __cpuinitdata mips_fpu_disabled; static int __init fpu_disable(char *s) @@ -51,6 +150,105 @@ static int __init dsp_disable(char *s) __setup("nodsp", dsp_disable); +void __init check_wait(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + if (nowait) { + printk("Wait instruction disabled.\n"); + return; + } + + switch (c->cputype) { + case CPU_R3081: + case CPU_R3081E: + cpu_wait = r3081_wait; + break; + case CPU_TX3927: + cpu_wait = r39xx_wait; + break; + case CPU_R4200: +/* case CPU_R4300: */ + case CPU_R4600: + case CPU_R4640: + case CPU_R4650: + case CPU_R4700: + case CPU_R5000: + case CPU_R5500: + case CPU_NEVADA: + case CPU_4KC: + case CPU_4KEC: + case CPU_4KSC: + case CPU_5KC: + case CPU_25KF: + case CPU_PR4450: + case CPU_BMIPS3300: + case CPU_BMIPS4350: + case CPU_BMIPS4380: + case CPU_BMIPS5000: + case CPU_CAVIUM_OCTEON: + case CPU_CAVIUM_OCTEON_PLUS: + case CPU_CAVIUM_OCTEON2: + case CPU_JZRISC: + case CPU_LOONGSON1: + case CPU_XLR: + case CPU_XLP: + cpu_wait = r4k_wait; + break; + + case CPU_RM7000: + cpu_wait = rm7k_wait_irqoff; + break; + + case CPU_M14KC: + case CPU_M14KEC: + case CPU_24K: + case CPU_34K: + case CPU_1004K: + cpu_wait = r4k_wait; + if (read_c0_config7() & MIPS_CONF7_WII) + cpu_wait = r4k_wait_irqoff; + break; + + case CPU_74K: + cpu_wait = r4k_wait; + if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) + cpu_wait = r4k_wait_irqoff; + break; + + case CPU_TX49XX: + cpu_wait = r4k_wait_irqoff; + break; + case CPU_ALCHEMY: + cpu_wait = au1k_wait; + break; + case CPU_20KC: + /* + * WAIT on Rev1.0 has E1, E2, E3 and E16. + * WAIT on Rev2.0 and Rev3.0 has E16. + * Rev3.1 WAIT is nop, why bother + */ + if ((c->processor_id & 0xff) <= 0x64) + break; + + /* + * Another rev is incremeting c0_count at a reduced clock + * rate while in WAIT mode. So we basically have the choice + * between using the cp0 timer as clocksource or avoiding + * the WAIT instruction. Until more details are known, + * disable the use of WAIT for 20Kc entirely. + cpu_wait = r4k_wait; + */ + break; + case CPU_RM9000: + if ((c->processor_id & 0x00ff) >= 0x40) + cpu_wait = r4k_wait; + break; + default: + break; + } +} + static inline void check_errata(void) { struct cpuinfo_mips *c = ¤t_cpu_data; diff --git a/trunk/arch/mips/kernel/crash_dump.c b/trunk/arch/mips/kernel/crash_dump.c index 3be9e7bb30ff..35bed0d2342c 100644 --- a/trunk/arch/mips/kernel/crash_dump.c +++ b/trunk/arch/mips/kernel/crash_dump.c @@ -2,7 +2,6 @@ #include #include #include -#include static int __init parse_savemaxmem(char *p) { diff --git a/trunk/arch/mips/kernel/genex.S b/trunk/arch/mips/kernel/genex.S index 31fa856829cb..5c2ba9f08a80 100644 --- a/trunk/arch/mips/kernel/genex.S +++ b/trunk/arch/mips/kernel/genex.S @@ -122,7 +122,7 @@ handle_vcei: __FINIT .align 5 /* 32 byte rollback region */ -LEAF(__r4k_wait) +LEAF(r4k_wait) .set push .set noreorder /* start of rollback region */ @@ -146,14 +146,14 @@ LEAF(__r4k_wait) jr ra nop .set pop - END(__r4k_wait) + END(r4k_wait) .macro BUILD_ROLLBACK_PROLOGUE handler FEXPORT(rollback_\handler) .set push .set noat MFC0 k0, CP0_EPC - PTR_LA k1, __r4k_wait + PTR_LA k1, r4k_wait ori k0, 0x1f /* 32 byte rollback region */ xori k0, 0x1f bne k0, k1, 9f @@ -493,7 +493,7 @@ NESTED(nmi_handler, PT_SIZE, sp) .set noreorder /* check if TLB contains a entry for EPC */ MFC0 k1, CP0_ENTRYHI - andi k1, 0xff /* ASID_MASK */ + andi k1, 0xff /* ASID_MASK patched at run-time!! */ MFC0 k0, CP0_EPC PTR_SRL k0, _PAGE_SHIFT + 1 PTR_SLL k0, _PAGE_SHIFT + 1 diff --git a/trunk/arch/mips/kernel/idle.c b/trunk/arch/mips/kernel/idle.c deleted file mode 100644 index 3b09b888afa9..000000000000 --- a/trunk/arch/mips/kernel/idle.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * MIPS idle loop and WAIT instruction support. - * - * Copyright (C) xxxx the Anonymous - * Copyright (C) 1994 - 2006 Ralf Baechle - * Copyright (C) 2003, 2004 Maciej W. Rozycki - * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, 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 Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, - * the implementation of the "wait" feature differs between CPU families. This - * points to the function that implements CPU specific wait. - * The wait instruction stops the pipeline and reduces the power consumption of - * the CPU very much. - */ -void (*cpu_wait)(void); -EXPORT_SYMBOL(cpu_wait); - -static void r3081_wait(void) -{ - unsigned long cfg = read_c0_conf(); - write_c0_conf(cfg | R30XX_CONF_HALT); - local_irq_enable(); -} - -static void r39xx_wait(void) -{ - if (!need_resched()) - write_c0_conf(read_c0_conf() | TX39_CONF_HALT); - local_irq_enable(); -} - -void r4k_wait(void) -{ - local_irq_enable(); - __r4k_wait(); -} - -/* - * This variant is preferable as it allows testing need_resched and going to - * sleep depending on the outcome atomically. Unfortunately the "It is - * implementation-dependent whether the pipeline restarts when a non-enabled - * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes - * using this version a gamble. - */ -void r4k_wait_irqoff(void) -{ - if (!need_resched()) - __asm__( - " .set push \n" - " .set mips3 \n" - " wait \n" - " .set pop \n"); - local_irq_enable(); - __asm__( - " .globl __pastwait \n" - "__pastwait: \n"); -} - -/* - * The RM7000 variant has to handle erratum 38. The workaround is to not - * have any pending stores when the WAIT instruction is executed. - */ -static void rm7k_wait_irqoff(void) -{ - if (!need_resched()) - __asm__( - " .set push \n" - " .set mips3 \n" - " .set noat \n" - " mfc0 $1, $12 \n" - " sync \n" - " mtc0 $1, $12 # stalls until W stage \n" - " wait \n" - " mtc0 $1, $12 # stalls until W stage \n" - " .set pop \n"); - local_irq_enable(); -} - -/* - * The Au1xxx wait is available only if using 32khz counter or - * external timer source, but specifically not CP0 Counter. - * alchemy/common/time.c may override cpu_wait! - */ -static void au1k_wait(void) -{ - __asm__( - " .set mips3 \n" - " cache 0x14, 0(%0) \n" - " cache 0x14, 32(%0) \n" - " sync \n" - " nop \n" - " wait \n" - " nop \n" - " nop \n" - " nop \n" - " nop \n" - " .set mips0 \n" - : : "r" (au1k_wait)); - local_irq_enable(); -} - -static int __initdata nowait; - -static int __init wait_disable(char *s) -{ - nowait = 1; - - return 1; -} - -__setup("nowait", wait_disable); - -void __init check_wait(void) -{ - struct cpuinfo_mips *c = ¤t_cpu_data; - - if (nowait) { - printk("Wait instruction disabled.\n"); - return; - } - - switch (c->cputype) { - case CPU_R3081: - case CPU_R3081E: - cpu_wait = r3081_wait; - break; - case CPU_TX3927: - cpu_wait = r39xx_wait; - break; - case CPU_R4200: -/* case CPU_R4300: */ - case CPU_R4600: - case CPU_R4640: - case CPU_R4650: - case CPU_R4700: - case CPU_R5000: - case CPU_R5500: - case CPU_NEVADA: - case CPU_4KC: - case CPU_4KEC: - case CPU_4KSC: - case CPU_5KC: - case CPU_25KF: - case CPU_PR4450: - case CPU_BMIPS3300: - case CPU_BMIPS4350: - case CPU_BMIPS4380: - case CPU_BMIPS5000: - case CPU_CAVIUM_OCTEON: - case CPU_CAVIUM_OCTEON_PLUS: - case CPU_CAVIUM_OCTEON2: - case CPU_JZRISC: - case CPU_LOONGSON1: - case CPU_XLR: - case CPU_XLP: - cpu_wait = r4k_wait; - break; - - case CPU_RM7000: - cpu_wait = rm7k_wait_irqoff; - break; - - case CPU_M14KC: - case CPU_M14KEC: - case CPU_24K: - case CPU_34K: - case CPU_1004K: - cpu_wait = r4k_wait; - if (read_c0_config7() & MIPS_CONF7_WII) - cpu_wait = r4k_wait_irqoff; - break; - - case CPU_74K: - cpu_wait = r4k_wait; - if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) - cpu_wait = r4k_wait_irqoff; - break; - - case CPU_TX49XX: - cpu_wait = r4k_wait_irqoff; - break; - case CPU_ALCHEMY: - cpu_wait = au1k_wait; - break; - case CPU_20KC: - /* - * WAIT on Rev1.0 has E1, E2, E3 and E16. - * WAIT on Rev2.0 and Rev3.0 has E16. - * Rev3.1 WAIT is nop, why bother - */ - if ((c->processor_id & 0xff) <= 0x64) - break; - - /* - * Another rev is incremeting c0_count at a reduced clock - * rate while in WAIT mode. So we basically have the choice - * between using the cp0 timer as clocksource or avoiding - * the WAIT instruction. Until more details are known, - * disable the use of WAIT for 20Kc entirely. - cpu_wait = r4k_wait; - */ - break; - case CPU_RM9000: - if ((c->processor_id & 0x00ff) >= 0x40) - cpu_wait = r4k_wait; - break; - default: - break; - } -} - -static void smtc_idle_hook(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - void smtc_idle_loop_hook(void); - - smtc_idle_loop_hook(); -#endif -} - -void arch_cpu_idle(void) -{ - smtc_idle_hook(); - if (cpu_wait) - cpu_wait(); - else - local_irq_enable(); -} diff --git a/trunk/arch/mips/kernel/kprobes.c b/trunk/arch/mips/kernel/kprobes.c index 1f8187ab0997..12bc4ebdf55b 100644 --- a/trunk/arch/mips/kernel/kprobes.c +++ b/trunk/arch/mips/kernel/kprobes.c @@ -207,10 +207,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { - if (p->ainsn.insn) { - free_insn_slot(p->ainsn.insn, 0); - p->ainsn.insn = NULL; - } + free_insn_slot(p->ainsn.insn, 0); } static void save_previous_kprobe(struct kprobe_ctlblk *kcb) diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index acb34373679e..a3e461408b7e 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index c6a041d9d05d..eb902c1f0cad 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -51,6 +51,19 @@ void arch_cpu_idle_dead(void) } #endif +void arch_cpu_idle(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + extern void smtc_idle_loop_hook(void); + + smtc_idle_loop_hook(); +#endif + if (cpu_wait) + (*cpu_wait)(); + else + local_irq_enable(); +} + asmlinkage void ret_from_fork(void); asmlinkage void ret_from_kernel_thread(void); @@ -211,9 +224,6 @@ struct mips_frame_info { int pc_offset; }; -#define J_TARGET(pc,target) \ - (((unsigned long)(pc) & 0xf0000000) | ((target) << 2)) - static inline int is_ra_save_ins(union mips_instruction *ip) { #ifdef CONFIG_CPU_MICROMIPS @@ -254,7 +264,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip) #endif } -static inline int is_jump_ins(union mips_instruction *ip) +static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) { #ifdef CONFIG_CPU_MICROMIPS /* @@ -278,8 +288,6 @@ static inline int is_jump_ins(union mips_instruction *ip) return 0; return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); #else - if (ip->j_format.opcode == j_op) - return 1; if (ip->j_format.opcode == jal_op) return 1; if (ip->r_format.opcode != spec_op) @@ -342,7 +350,7 @@ static int get_frame_info(struct mips_frame_info *info) for (i = 0; i < max_insns; i++, ip++) { - if (is_jump_ins(ip)) + if (is_jal_jalr_jr_ins(ip)) break; if (!info->frame_size) { if (is_sp_move_ins(ip)) @@ -385,42 +393,15 @@ static int get_frame_info(struct mips_frame_info *info) static struct mips_frame_info schedule_mfi __read_mostly; -#ifdef CONFIG_KALLSYMS -static unsigned long get___schedule_addr(void) -{ - return kallsyms_lookup_name("__schedule"); -} -#else -static unsigned long get___schedule_addr(void) -{ - union mips_instruction *ip = (void *)schedule; - int max_insns = 8; - int i; - - for (i = 0; i < max_insns; i++, ip++) { - if (ip->j_format.opcode == j_op) - return J_TARGET(ip, ip->j_format.target); - } - return 0; -} -#endif - static int __init frame_info_init(void) { unsigned long size = 0; #ifdef CONFIG_KALLSYMS unsigned long ofs; -#endif - unsigned long addr; - - addr = get___schedule_addr(); - if (!addr) - addr = (unsigned long)schedule; -#ifdef CONFIG_KALLSYMS - kallsyms_lookup_size_offset(addr, &size, &ofs); + kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); #endif - schedule_mfi.func = (void *)addr; + schedule_mfi.func = schedule; schedule_mfi.func_size = size; get_frame_info(&schedule_mfi); diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index 97a5909a61cf..36cfd4060e1f 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -423,5 +423,4 @@ sys_call_table: PTR sys_process_vm_writev /* 5305 */ PTR sys_kcmp PTR sys_finit_module - PTR sys_getdents64 .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index 6e7862ab46cc..c17619fe18e3 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 75a4fd709841..31d22f3121c9 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -112,7 +111,7 @@ static int vpe0limit; static int ipibuffers; static int nostlb; static int asidmask; -unsigned long smtc_asid_mask = 0xff; +unsigned int smtc_asid_mask = 0xff; static int __init vpe0tcs(char *str) { @@ -859,6 +858,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) unsigned long flags; int mtflags; unsigned long tcrestart; + extern void r4k_wait_irqoff(void), __pastwait(void); int set_resched_flag = (type == LINUX_SMP_IPI && action == SMP_RESCHEDULE_YOURSELF); @@ -914,7 +914,8 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) */ if (cpu_wait == r4k_wait_irqoff) { tcrestart = read_tc_c0_tcrestart(); - if (address_is_in_r4k_wait_irqoff(tcrestart)) { + if (tcrestart >= (unsigned long)r4k_wait_irqoff + && tcrestart < (unsigned long)__pastwait) { write_tc_c0_tcrestart(__pastwait); tcstatus &= ~TCSTATUS_IXMT; write_tc_c0_tcstatus(tcstatus); @@ -1394,7 +1395,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) asid = asid_cache(cpu); do { - if (!((asid += ASID_INC) & ASID_MASK) ) { + if (!ASID_MASK(ASID_INC(asid))) { if (cpu_has_vtag_icache) flush_icache_all(); /* Traverse all online CPUs (hack requires contiguous range) */ @@ -1413,7 +1414,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) mips_ihb(); } tcstat = read_tc_c0_tcstatus(); - smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i); + smtc_live_asid[tlb][ASID_MASK(tcstat)] |= (asiduse)(0x1 << i); if (!prevhalt) write_tc_c0_tchalt(0); } @@ -1422,7 +1423,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) asid = ASID_FIRST_VERSION; local_flush_tlb_all(); /* start new asid cycle */ } - } while (smtc_live_asid[tlb][(asid & ASID_MASK)]); + } while (smtc_live_asid[tlb][ASID_MASK(asid)]); /* * SMTC shares the TLB within VPEs and possibly across all VPEs. @@ -1460,7 +1461,7 @@ void smtc_flush_tlb_asid(unsigned long asid) tlb_read(); ehb(); ehi = read_c0_entryhi(); - if ((ehi & ASID_MASK) == asid) { + if (ASID_MASK(ehi) == asid) { /* * Invalidate only entries with specified ASID, * makiing sure all entries differ. diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index e3be67012d78..77cff1f6d050 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -58,6 +57,7 @@ #include extern void check_wait(void); +extern asmlinkage void r4k_wait(void); extern asmlinkage void rollback_handle_int(void); extern asmlinkage void handle_int(void); extern u32 handle_tlbl[]; @@ -1542,7 +1542,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) extern char except_vec_vi, except_vec_vi_lui; extern char except_vec_vi_ori, except_vec_vi_end; extern char rollback_except_vec_vi; - char *vec_start = using_rollback_handler() ? + char *vec_start = (cpu_wait == r4k_wait) ? &rollback_except_vec_vi : &except_vec_vi; #ifdef CONFIG_MIPS_MT_SMTC /* @@ -1656,6 +1656,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) unsigned int cpu = smp_processor_id(); unsigned int status_set = ST0_CU0; unsigned int hwrena = cpu_hwrena_impl_bits; + unsigned long asid = 0; #ifdef CONFIG_MIPS_MT_SMTC int secondaryTC = 0; int bootTC = (cpu == 0); @@ -1739,8 +1740,9 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) } #endif /* CONFIG_MIPS_MT_SMTC */ - if (!cpu_data[cpu].asid_cache) - cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; + asid = ASID_FIRST_VERSION; + cpu_data[cpu].asid_cache = asid; + TLBMISS_HANDLER_SETUP(); atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; @@ -1812,8 +1814,10 @@ void __init trap_init(void) extern char except_vec4; extern char except_vec3_r4000; unsigned long i; + int rollback; check_wait(); + rollback = (cpu_wait == r4k_wait); #if defined(CONFIG_KGDB) if (kgdb_early_setup) @@ -1890,8 +1894,7 @@ void __init trap_init(void) if (board_be_init) board_be_init(); - set_except_vector(0, using_rollback_handler() ? rollback_handle_int - : handle_int); + set_except_vector(0, rollback ? rollback_handle_int : handle_int); set_except_vector(1, handle_tlbm); set_except_vector(2, handle_tlbl); set_except_vector(3, handle_tlbs); diff --git a/trunk/arch/mips/kvm/kvm_mips_emul.c b/trunk/arch/mips/kvm/kvm_mips_emul.c index 4b6274b47f33..2b2bac9a40aa 100644 --- a/trunk/arch/mips/kvm/kvm_mips_emul.c +++ b/trunk/arch/mips/kvm/kvm_mips_emul.c @@ -525,18 +525,16 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause, printk("MTCz, cop0->reg[EBASE]: %#lx\n", kvm_read_c0_guest_ebase(cop0)); } else if (rd == MIPS_CP0_TLB_HI && sel == 0) { - uint32_t nasid = - vcpu->arch.gprs[rt] & ASID_MASK; + uint32_t nasid = ASID_MASK(vcpu->arch.gprs[rt]); if ((KSEGX(vcpu->arch.gprs[rt]) != CKSEG0) && - ((kvm_read_c0_guest_entryhi(cop0) & - ASID_MASK) != nasid)) { + (ASID_MASK(kvm_read_c0_guest_entryhi(cop0)) + != nasid)) { kvm_debug ("MTCz, change ASID from %#lx to %#lx\n", - kvm_read_c0_guest_entryhi(cop0) & - ASID_MASK, - vcpu->arch.gprs[rt] & ASID_MASK); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0)), + ASID_MASK(vcpu->arch.gprs[rt])); /* Blow away the shadow host TLBs */ kvm_mips_flush_host_tlb(1); @@ -988,8 +986,7 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause, * resulting handler will do the right thing */ index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) | - (kvm_read_c0_guest_entryhi - (cop0) & ASID_MASK)); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0))); if (index < 0) { vcpu->arch.host_cp0_entryhi = (va & VPN2_MASK); @@ -1154,7 +1151,7 @@ kvm_mips_emulate_tlbmiss_ld(unsigned long cause, uint32_t *opc, struct kvm_vcpu_arch *arch = &vcpu->arch; enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu->arch. host_cp0_badvaddr & VPN2_MASK) | - (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { /* save old pc */ @@ -1201,7 +1198,7 @@ kvm_mips_emulate_tlbinv_ld(unsigned long cause, uint32_t *opc, enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | - (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { /* save old pc */ @@ -1246,7 +1243,7 @@ kvm_mips_emulate_tlbmiss_st(unsigned long cause, uint32_t *opc, struct kvm_vcpu_arch *arch = &vcpu->arch; enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | - (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { /* save old pc */ @@ -1290,7 +1287,7 @@ kvm_mips_emulate_tlbinv_st(unsigned long cause, uint32_t *opc, struct kvm_vcpu_arch *arch = &vcpu->arch; enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | - (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { /* save old pc */ @@ -1359,7 +1356,7 @@ kvm_mips_emulate_tlbmod(unsigned long cause, uint32_t *opc, { struct mips_coproc *cop0 = vcpu->arch.cop0; unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) | - (kvm_read_c0_guest_entryhi(cop0) & ASID_MASK); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); struct kvm_vcpu_arch *arch = &vcpu->arch; enum emulation_result er = EMULATE_DONE; @@ -1786,8 +1783,8 @@ kvm_mips_handle_tlbmiss(unsigned long cause, uint32_t *opc, */ index = kvm_mips_guest_tlb_lookup(vcpu, (va & VPN2_MASK) | - (kvm_read_c0_guest_entryhi - (vcpu->arch.cop0) & ASID_MASK)); + ASID_MASK(kvm_read_c0_guest_entryhi + (vcpu->arch.cop0))); if (index < 0) { if (exccode == T_TLB_LD_MISS) { er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu); diff --git a/trunk/arch/mips/kvm/kvm_tlb.c b/trunk/arch/mips/kvm/kvm_tlb.c index c777dd36d4a8..89511a9258d3 100644 --- a/trunk/arch/mips/kvm/kvm_tlb.c +++ b/trunk/arch/mips/kvm/kvm_tlb.c @@ -17,8 +17,6 @@ #include #include #include -#include - #include #include @@ -53,13 +51,13 @@ EXPORT_SYMBOL(kvm_mips_is_error_pfn); uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) { - return vcpu->arch.guest_kernel_asid[smp_processor_id()] & ASID_MASK; + return ASID_MASK(vcpu->arch.guest_kernel_asid[smp_processor_id()]); } uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) { - return vcpu->arch.guest_user_asid[smp_processor_id()] & ASID_MASK; + return ASID_MASK(vcpu->arch.guest_user_asid[smp_processor_id()]); } inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu) @@ -86,7 +84,7 @@ void kvm_mips_dump_host_tlbs(void) old_pagemask = read_c0_pagemask(); printk("HOST TLBs:\n"); - printk("ASID: %#lx\n", read_c0_entryhi() & ASID_MASK); + printk("ASID: %#lx\n", ASID_MASK(read_c0_entryhi())); for (i = 0; i < current_cpu_data.tlbsize; i++) { write_c0_index(i); @@ -171,27 +169,21 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) } } -static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) { - int srcu_idx, err = 0; pfn_t pfn; if (kvm->arch.guest_pmap[gfn] != KVM_INVALID_PAGE) - return 0; + return; - srcu_idx = srcu_read_lock(&kvm->srcu); pfn = kvm_mips_gfn_to_pfn(kvm, gfn); if (kvm_mips_is_error_pfn(pfn)) { - kvm_err("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn); - err = -EFAULT; - goto out; + panic("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn); } kvm->arch.guest_pmap[gfn] = pfn; -out: - srcu_read_unlock(&kvm->srcu, srcu_idx); - return err; + return; } /* Translate guest KSEG0 addresses to Host PA */ @@ -215,10 +207,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu, gva); return KVM_INVALID_PAGE; } - - if (kvm_mips_map_page(vcpu->kvm, gfn) < 0) - return KVM_INVALID_ADDR; - + kvm_mips_map_page(vcpu->kvm, gfn); return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset; } @@ -321,11 +310,8 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr, even = !(gfn & 0x1); vaddr = badvaddr & (PAGE_MASK << 1); - if (kvm_mips_map_page(vcpu->kvm, gfn) < 0) - return -1; - - if (kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1) < 0) - return -1; + kvm_mips_map_page(vcpu->kvm, gfn); + kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1); if (even) { pfn0 = kvm->arch.guest_pmap[gfn]; @@ -403,11 +389,8 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, pfn0 = 0; pfn1 = 0; } else { - if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT) < 0) - return -1; - - if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT) < 0) - return -1; + kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT); + kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT); pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT]; pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT]; @@ -445,7 +428,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi) for (i = 0; i < KVM_MIPS_GUEST_TLB_SIZE; i++) { if (((TLB_VPN2(tlb[i]) & ~tlb[i].tlb_mask) == ((entryhi & VPN2_MASK) & ~tlb[i].tlb_mask)) && - (TLB_IS_GLOBAL(tlb[i]) || (TLB_ASID(tlb[i]) == (entryhi & ASID_MASK)))) { + (TLB_IS_GLOBAL(tlb[i]) || (TLB_ASID(tlb[i]) == ASID_MASK(entryhi)))) { index = i; break; } @@ -643,7 +626,7 @@ kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu, { unsigned long asid = asid_cache(cpu); - if (!((asid += ASID_INC) & ASID_MASK)) { + if (!(ASID_MASK(ASID_INC(asid)))) { if (cpu_has_vtag_icache) { flush_icache_all(); } @@ -821,8 +804,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (!newasid) { /* If we preempted while the guest was executing, then reload the pre-empted ASID */ if (current->flags & PF_VCPU) { - write_c0_entryhi(vcpu->arch. - preempt_entryhi & ASID_MASK); + write_c0_entryhi(ASID_MASK(vcpu->arch.preempt_entryhi)); ehb(); } } else { @@ -834,13 +816,11 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) */ if (current->flags & PF_VCPU) { if (KVM_GUEST_KERNEL_MODE(vcpu)) - write_c0_entryhi(vcpu->arch. - guest_kernel_asid[cpu] & - ASID_MASK); + write_c0_entryhi(ASID_MASK(vcpu->arch. + guest_kernel_asid[cpu])); else - write_c0_entryhi(vcpu->arch. - guest_user_asid[cpu] & - ASID_MASK); + write_c0_entryhi(ASID_MASK(vcpu->arch. + guest_user_asid[cpu])); ehb(); } } @@ -899,8 +879,7 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) kvm_mips_guest_tlb_lookup(vcpu, ((unsigned long) opc & VPN2_MASK) | - (kvm_read_c0_guest_entryhi - (cop0) & ASID_MASK)); + ASID_MASK(kvm_read_c0_guest_entryhi(cop0))); if (index < 0) { kvm_err ("%s: get_user_failed for %p, vcpu: %p, ASID: %#lx\n", diff --git a/trunk/arch/mips/lantiq/xway/gptu.c b/trunk/arch/mips/lantiq/xway/gptu.c index 850821df924c..9861c8669fab 100644 --- a/trunk/arch/mips/lantiq/xway/gptu.c +++ b/trunk/arch/mips/lantiq/xway/gptu.c @@ -144,6 +144,10 @@ static int gptu_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get resource\n"); + return -ENOMEM; + } /* remap gptu register range */ gptu_membase = devm_ioremap_resource(&pdev->dev, res); @@ -165,8 +169,6 @@ static int gptu_probe(struct platform_device *pdev) if (((gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) { dev_err(&pdev->dev, "Failed to find magic\n"); gptu_hwexit(); - clk_disable(clk); - clk_put(clk); return -ENAVAIL; } diff --git a/trunk/arch/mips/lib/dump_tlb.c b/trunk/arch/mips/lib/dump_tlb.c index 32b9f21bfd85..8a12d00908e0 100644 --- a/trunk/arch/mips/lib/dump_tlb.c +++ b/trunk/arch/mips/lib/dump_tlb.c @@ -11,6 +11,7 @@ #include #include #include +#include static inline const char *msk2str(unsigned int mask) { @@ -55,7 +56,7 @@ static void dump_tlb(int first, int last) s_pagemask = read_c0_pagemask(); s_entryhi = read_c0_entryhi(); s_index = read_c0_index(); - asid = s_entryhi & 0xff; + asid = ASID_MASK(s_entryhi); for (i = first; i <= last; i++) { write_c0_index(i); @@ -85,7 +86,7 @@ static void dump_tlb(int first, int last) printk("va=%0*lx asid=%02lx\n", width, (entryhi & ~0x1fffUL), - entryhi & 0xff); + ASID_MASK(entryhi)); printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ", width, (entrylo0 << 6) & PAGE_MASK, c0, diff --git a/trunk/arch/mips/lib/r3k_dump_tlb.c b/trunk/arch/mips/lib/r3k_dump_tlb.c index 91615c2ef0cf..8327698b9937 100644 --- a/trunk/arch/mips/lib/r3k_dump_tlb.c +++ b/trunk/arch/mips/lib/r3k_dump_tlb.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,7 @@ static void dump_tlb(int first, int last) unsigned int asid; unsigned long entryhi, entrylo0; - asid = read_c0_entryhi() & 0xfc0; + asid = ASID_MASK(read_c0_entryhi()); for (i = first; i <= last; i++) { write_c0_index(i<<8); @@ -35,7 +36,7 @@ static void dump_tlb(int first, int last) /* Unused entries have a virtual address of KSEG0. */ if ((entryhi & 0xffffe000) != 0x80000000 - && (entryhi & 0xfc0) == asid) { + && (ASID_MASK(entryhi) == asid)) { /* * Only print entries in use */ @@ -44,7 +45,7 @@ static void dump_tlb(int first, int last) printk("va=%08lx asid=%08lx" " [pa=%06lx n=%d d=%d v=%d g=%d]", (entryhi & 0xffffe000), - entryhi & 0xfc0, + ASID_MASK(entryhi), entrylo0 & PAGE_MASK, (entrylo0 & (1 << 11)) ? 1 : 0, (entrylo0 & (1 << 10)) ? 1 : 0, diff --git a/trunk/arch/mips/loongson/common/reset.c b/trunk/arch/mips/loongson/common/reset.c index 65bfbb5d06f4..35c8c6468494 100644 --- a/trunk/arch/mips/loongson/common/reset.c +++ b/trunk/arch/mips/loongson/common/reset.c @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/loongson1/common/reset.c b/trunk/arch/mips/loongson1/common/reset.c index 547f34b69e4c..d4f610f9604a 100644 --- a/trunk/arch/mips/loongson1/common/reset.c +++ b/trunk/arch/mips/loongson1/common/reset.c @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/mips/mm/tlb-r3k.c b/trunk/arch/mips/mm/tlb-r3k.c index a63d1ed0827f..4a13c150f31b 100644 --- a/trunk/arch/mips/mm/tlb-r3k.c +++ b/trunk/arch/mips/mm/tlb-r3k.c @@ -51,7 +51,7 @@ void local_flush_tlb_all(void) #endif local_irq_save(flags); - old_ctx = read_c0_entryhi() & ASID_MASK; + old_ctx = ASID_MASK(read_c0_entryhi()); write_c0_entrylo0(0); entry = r3k_have_wired_reg ? read_c0_wired() : 8; for (; entry < current_cpu_data.tlbsize; entry++) { @@ -87,13 +87,13 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, #ifdef DEBUG_TLB printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", - cpu_context(cpu, mm) & ASID_MASK, start, end); + ASID_MASK(cpu_context(cpu, mm)), start, end); #endif local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; if (size <= current_cpu_data.tlbsize) { - int oldpid = read_c0_entryhi() & ASID_MASK; - int newpid = cpu_context(cpu, mm) & ASID_MASK; + int oldpid = ASID_MASK(read_c0_entryhi()); + int newpid = ASID_MASK(cpu_context(cpu, mm)); start &= PAGE_MASK; end += PAGE_SIZE - 1; @@ -166,10 +166,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) #ifdef DEBUG_TLB printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); #endif - newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK; + newpid = ASID_MASK(cpu_context(cpu, vma->vm_mm)); page &= PAGE_MASK; local_irq_save(flags); - oldpid = read_c0_entryhi() & ASID_MASK; + oldpid = ASID_MASK(read_c0_entryhi()); write_c0_entryhi(page | newpid); BARRIER; tlb_probe(); @@ -197,10 +197,10 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) if (current->active_mm != vma->vm_mm) return; - pid = read_c0_entryhi() & ASID_MASK; + pid = ASID_MASK(read_c0_entryhi()); #ifdef DEBUG_TLB - if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) { + if ((pid != ASID_MASK(cpu_context(cpu, vma->vm_mm))) || (cpu_context(cpu, vma->vm_mm) == 0)) { printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", (cpu_context(cpu, vma->vm_mm)), pid); } @@ -241,7 +241,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = read_c0_entryhi() & ASID_MASK; + old_ctx = ASID_MASK(read_c0_entryhi()); old_pagemask = read_c0_pagemask(); w = read_c0_wired(); write_c0_wired(w + 1); @@ -264,7 +264,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, #endif local_irq_save(flags); - old_ctx = read_c0_entryhi() & ASID_MASK; + old_ctx = ASID_MASK(read_c0_entryhi()); write_c0_entrylo0(entrylo0); write_c0_entryhi(entryhi); write_c0_index(wired); diff --git a/trunk/arch/mips/mm/tlb-r4k.c b/trunk/arch/mips/mm/tlb-r4k.c index c643de4c473a..09653b290d53 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -287,7 +287,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) ENTER_CRITICAL(flags); - pid = read_c0_entryhi() & ASID_MASK; + pid = ASID_MASK(read_c0_entryhi()); address &= (PAGE_MASK << 1); write_c0_entryhi(address | pid); pgdp = pgd_offset(vma->vm_mm, address); diff --git a/trunk/arch/mips/mm/tlb-r8k.c b/trunk/arch/mips/mm/tlb-r8k.c index 91c2499f806a..122f9207f49e 100644 --- a/trunk/arch/mips/mm/tlb-r8k.c +++ b/trunk/arch/mips/mm/tlb-r8k.c @@ -195,7 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) if (current->active_mm != vma->vm_mm) return; - pid = read_c0_entryhi() & ASID_MASK; + pid = ASID_MASK(read_c0_entryhi()); local_irq_save(flags); address &= PAGE_MASK; diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index ce9818eef7d3..4d46d3787576 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -305,6 +306,78 @@ static struct uasm_reloc relocs[128] __cpuinitdata; static int check_for_high_segbits __cpuinitdata; #endif +static void __cpuinit insn_fixup(unsigned int **start, unsigned int **stop, + unsigned int i_const) +{ + unsigned int **p; + + for (p = start; p < stop; p++) { +#ifndef CONFIG_CPU_MICROMIPS + unsigned int *ip; + + ip = *p; + *ip = (*ip & 0xffff0000) | i_const; +#else + unsigned short *ip; + + ip = ((unsigned short *)((unsigned int)*p - 1)); + if ((*ip & 0xf000) == 0x4000) { + *ip &= 0xfff1; + *ip |= (i_const << 1); + } else if ((*ip & 0xf000) == 0x6000) { + *ip &= 0xfff1; + *ip |= ((i_const >> 2) << 1); + } else { + ip++; + *ip = i_const; + } +#endif + local_flush_icache_range((unsigned long)ip, + (unsigned long)ip + sizeof(*ip)); + } +} + +#define asid_insn_fixup(section, const) \ +do { \ + extern unsigned int *__start_ ## section; \ + extern unsigned int *__stop_ ## section; \ + insn_fixup(&__start_ ## section, &__stop_ ## section, const); \ +} while(0) + +/* + * Caller is assumed to flush the caches before the first context switch. + */ +static void __cpuinit setup_asid(unsigned int inc, unsigned int mask, + unsigned int version_mask, + unsigned int first_version) +{ + extern asmlinkage void handle_ri_rdhwr_vivt(void); + unsigned long *vivt_exc; + +#ifdef CONFIG_CPU_MICROMIPS + /* + * Worst case optimised microMIPS addiu instructions support + * only a 3-bit immediate value. + */ + if(inc > 7) + panic("Invalid ASID increment value!"); +#endif + asid_insn_fixup(__asid_inc, inc); + asid_insn_fixup(__asid_mask, mask); + asid_insn_fixup(__asid_version_mask, version_mask); + asid_insn_fixup(__asid_first_version, first_version); + + /* Patch up the 'handle_ri_rdhwr_vivt' handler. */ + vivt_exc = (unsigned long *) &handle_ri_rdhwr_vivt; +#ifdef CONFIG_CPU_MICROMIPS + vivt_exc = (unsigned long *)((unsigned long) vivt_exc - 1); +#endif + vivt_exc++; + *vivt_exc = (*vivt_exc & ~mask) | mask; + + current_cpu_data.asid_cache = first_version; +} + static int check_for_high_segbits __cpuinitdata; static unsigned int kscratch_used_mask __cpuinitdata; @@ -2183,6 +2256,7 @@ void __cpuinit build_tlb_refill_handler(void) case CPU_TX3922: case CPU_TX3927: #ifndef CONFIG_MIPS_PGD_C0_CONTEXT + setup_asid(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000); if (cpu_has_local_ebase) build_r3000_tlb_refill_handler(); if (!run_once) { @@ -2208,6 +2282,11 @@ void __cpuinit build_tlb_refill_handler(void) break; default: +#ifndef CONFIG_MIPS_MT_SMTC + setup_asid(0x1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000); +#else + setup_asid(0x1, smtc_asid_mask, 0xff00, ASID_FIRST_VERSION_R4000); +#endif if (!run_once) { scratch_reg = allocate_kscratch(); #ifdef CONFIG_MIPS_PGD_C0_CONTEXT diff --git a/trunk/arch/mips/netlogic/xlp/setup.c b/trunk/arch/mips/netlogic/xlp/setup.c index eaa99d28cb8e..af319143b591 100644 --- a/trunk/arch/mips/netlogic/xlp/setup.c +++ b/trunk/arch/mips/netlogic/xlp/setup.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/netlogic/xlr/setup.c b/trunk/arch/mips/netlogic/xlr/setup.c index 89c8c1066632..e3e094100e3e 100644 --- a/trunk/arch/mips/netlogic/xlr/setup.c +++ b/trunk/arch/mips/netlogic/xlr/setup.c @@ -36,7 +36,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/pmcs-msp71xx/msp_prom.c b/trunk/arch/mips/pmcs-msp71xx/msp_prom.c index 1c9897531660..0edb89a63516 100644 --- a/trunk/arch/mips/pmcs-msp71xx/msp_prom.c +++ b/trunk/arch/mips/pmcs-msp71xx/msp_prom.c @@ -83,7 +83,7 @@ static inline unsigned char str2hexnum(unsigned char c) return 0; /* foo */ } -int str2eaddr(unsigned char *ea, unsigned char *str) +static inline int str2eaddr(unsigned char *ea, unsigned char *str) { int index = 0; unsigned char num = 0; diff --git a/trunk/arch/mips/pmcs-msp71xx/msp_setup.c b/trunk/arch/mips/pmcs-msp71xx/msp_setup.c index 396b2967ad85..1651cfdbfe7b 100644 --- a/trunk/arch/mips/pmcs-msp71xx/msp_setup.c +++ b/trunk/arch/mips/pmcs-msp71xx/msp_setup.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/ralink/dts/rt3050.dtsi b/trunk/arch/mips/ralink/dts/rt3050.dtsi index e3203d414fee..ef7da1e227e6 100644 --- a/trunk/arch/mips/ralink/dts/rt3050.dtsi +++ b/trunk/arch/mips/ralink/dts/rt3050.dtsi @@ -55,14 +55,4 @@ reg-shift = <2>; }; }; - - usb@101c0000 { - compatible = "ralink,rt3050-usb", "snps,dwc2"; - reg = <0x101c0000 40000>; - - interrupt-parent = <&intc>; - interrupts = <18>; - - status = "disabled"; - }; }; diff --git a/trunk/arch/mips/ralink/dts/rt3052_eval.dts b/trunk/arch/mips/ralink/dts/rt3052_eval.dts index 0ac73ea28198..c18c9a84f4c4 100644 --- a/trunk/arch/mips/ralink/dts/rt3052_eval.dts +++ b/trunk/arch/mips/ralink/dts/rt3052_eval.dts @@ -43,8 +43,4 @@ reg = <0x50000 0x7b0000>; }; }; - - usb@101c0000 { - status = "ok"; - }; }; diff --git a/trunk/arch/mips/txx9/generic/setup.c b/trunk/arch/mips/txx9/generic/setup.c index 681e7f86c080..5364aabc2102 100644 --- a/trunk/arch/mips/txx9/generic/setup.c +++ b/trunk/arch/mips/txx9/generic/setup.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/mips/vr41xx/common/pmu.c b/trunk/arch/mips/vr41xx/common/pmu.c index d7f755833c3f..70a3f90131d8 100644 --- a/trunk/arch/mips/vr41xx/common/pmu.c +++ b/trunk/arch/mips/vr41xx/common/pmu.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/mips/wrppmc/reset.c b/trunk/arch/mips/wrppmc/reset.c index 80beb188ed47..cc5474b24f06 100644 --- a/trunk/arch/mips/wrppmc/reset.c +++ b/trunk/arch/mips/wrppmc/reset.c @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 6507dabdd5dd..cad060f288cf 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -245,7 +245,7 @@ config SMP config IRQSTACKS bool "Use separate kernel stacks when processing interrupts" - default y + default n help If you say Y here the kernel will use separate kernel stacks for handling hard and soft interrupts. This can help avoid diff --git a/trunk/arch/parisc/Makefile b/trunk/arch/parisc/Makefile index 197690068f88..2f967cc6649e 100644 --- a/trunk/arch/parisc/Makefile +++ b/trunk/arch/parisc/Makefile @@ -23,21 +23,24 @@ NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) +MACHINE := $(shell uname -m) +NATIVE := $(if $(filter parisc%,$(MACHINE)),1,0) + ifdef CONFIG_64BIT UTS_MACHINE := parisc64 CHECKFLAGS += -D__LP64__=1 -m64 -CC_ARCHES = hppa64 +WIDTH := 64 else # 32-bit -CC_ARCHES = hppa hppa2.0 hppa1.1 +WIDTH := endif -ifneq ($(SUBARCH),$(UTS_MACHINE)) - ifeq ($(CROSS_COMPILE),) - CC_SUFFIXES = linux linux-gnu unknown-linux-gnu - CROSS_COMPILE := $(call cc-cross-prefix, \ - $(foreach a,$(CC_ARCHES), \ - $(foreach s,$(CC_SUFFIXES),$(a)-$(s)-))) - endif +# attempt to help out folks who are cross-compiling +ifeq ($(NATIVE),1) +CROSS_COMPILE := hppa$(WIDTH)-linux- +else + ifeq ($(CROSS_COMPILE),) + CROSS_COMPILE := hppa$(WIDTH)-linux-gnu- + endif endif OBJCOPY_FLAGS =-O binary -R .note -R .comment -S diff --git a/trunk/arch/parisc/include/asm/hardirq.h b/trunk/arch/parisc/include/asm/hardirq.h index c19f7138ba48..12373c4dabab 100644 --- a/trunk/arch/parisc/include/asm/hardirq.h +++ b/trunk/arch/parisc/include/asm/hardirq.h @@ -11,18 +11,10 @@ #include #include -#ifdef CONFIG_IRQSTACKS -#define __ARCH_HAS_DO_SOFTIRQ -#endif - typedef struct { unsigned int __softirq_pending; #ifdef CONFIG_DEBUG_STACKOVERFLOW unsigned int kernel_stack_usage; -#ifdef CONFIG_IRQSTACKS - unsigned int irq_stack_usage; - unsigned int irq_stack_counter; -#endif #endif #ifdef CONFIG_SMP unsigned int irq_resched_count; @@ -36,7 +28,6 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); #define __ARCH_IRQ_STAT #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) #define inc_irq_stat(member) this_cpu_inc(irq_stat.member) -#define __inc_irq_stat(member) __this_cpu_inc(irq_stat.member) #define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) #define __ARCH_SET_SOFTIRQ_PENDING diff --git a/trunk/arch/parisc/include/asm/processor.h b/trunk/arch/parisc/include/asm/processor.h index cfbc43929cf6..064015547d1e 100644 --- a/trunk/arch/parisc/include/asm/processor.h +++ b/trunk/arch/parisc/include/asm/processor.h @@ -63,13 +63,10 @@ */ #ifdef __KERNEL__ -#include - #define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ union irq_stack_union { unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; - raw_spinlock_t lock; }; DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index ae27cb6ce19a..4bb96ad9b0b1 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -452,41 +452,9 @@ L2_ptep \pgd,\pte,\index,\va,\fault .endm - /* Acquire pa_dbit_lock lock. */ - .macro dbit_lock spc,tmp,tmp1 -#ifdef CONFIG_SMP - cmpib,COND(=),n 0,\spc,2f - load32 PA(pa_dbit_lock),\tmp -1: LDCW 0(\tmp),\tmp1 - cmpib,COND(=) 0,\tmp1,1b - nop -2: -#endif - .endm - - /* Release pa_dbit_lock lock without reloading lock address. */ - .macro dbit_unlock0 spc,tmp -#ifdef CONFIG_SMP - or,COND(=) %r0,\spc,%r0 - stw \spc,0(\tmp) -#endif - .endm - - /* Release pa_dbit_lock lock. */ - .macro dbit_unlock1 spc,tmp -#ifdef CONFIG_SMP - load32 PA(pa_dbit_lock),\tmp - dbit_unlock0 \spc,\tmp -#endif - .endm - /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and * don't needlessly dirty the cache line if it was already set */ - .macro update_ptep spc,ptep,pte,tmp,tmp1 -#ifdef CONFIG_SMP - or,COND(=) %r0,\spc,%r0 - LDREG 0(\ptep),\pte -#endif + .macro update_ptep ptep,pte,tmp,tmp1 ldi _PAGE_ACCESSED,\tmp1 or \tmp1,\pte,\tmp and,COND(<>) \tmp1,\pte,%r0 @@ -495,11 +463,7 @@ /* Set the dirty bit (and accessed bit). No need to be * clever, this is only used from the dirty fault */ - .macro update_dirty spc,ptep,pte,tmp -#ifdef CONFIG_SMP - or,COND(=) %r0,\spc,%r0 - LDREG 0(\ptep),\pte -#endif + .macro update_dirty ptep,pte,tmp ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp or \tmp,\pte,\pte STREG \pte,0(\ptep) @@ -1147,13 +1111,11 @@ dtlb_miss_20w: L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot idtlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1173,13 +1135,11 @@ nadtlb_miss_20w: L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot idtlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1201,8 +1161,7 @@ dtlb_miss_11: L2_ptep ptp,pte,t0,va,dtlb_check_alias_11 - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot @@ -1213,7 +1172,6 @@ dtlb_miss_11: idtlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ - dbit_unlock1 spc,t0 rfir nop @@ -1234,8 +1192,7 @@ nadtlb_miss_11: L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot @@ -1247,7 +1204,6 @@ nadtlb_miss_11: idtlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ - dbit_unlock1 spc,t0 rfir nop @@ -1268,15 +1224,13 @@ dtlb_miss_20: L2_ptep ptp,pte,t0,va,dtlb_check_alias_20 - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 idtlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1296,15 +1250,13 @@ nadtlb_miss_20: L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 idtlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1405,13 +1357,11 @@ itlb_miss_20w: L3_ptep ptp,pte,t0,va,itlb_fault - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot iitlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1429,13 +1379,11 @@ naitlb_miss_20w: L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot iitlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1457,8 +1405,7 @@ itlb_miss_11: L2_ptep ptp,pte,t0,va,itlb_fault - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot @@ -1469,7 +1416,6 @@ itlb_miss_11: iitlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ - dbit_unlock1 spc,t0 rfir nop @@ -1481,8 +1427,7 @@ naitlb_miss_11: L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb_11 spc,pte,prot @@ -1493,7 +1438,6 @@ naitlb_miss_11: iitlbp prot,(%sr1,va) mtsp t0, %sr1 /* Restore sr1 */ - dbit_unlock1 spc,t0 rfir nop @@ -1515,15 +1459,13 @@ itlb_miss_20: L2_ptep ptp,pte,t0,va,itlb_fault - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 iitlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1535,15 +1477,13 @@ naitlb_miss_20: L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 - dbit_lock spc,t0,t1 - update_ptep spc,ptp,pte,t0,t1 + update_ptep ptp,pte,t0,t1 make_insert_tlb spc,pte,prot f_extend pte,t0 iitlbt pte,prot - dbit_unlock1 spc,t0 rfir nop @@ -1567,13 +1507,29 @@ dbit_trap_20w: L3_ptep ptp,pte,t0,va,dbit_fault - dbit_lock spc,t0,t1 - update_dirty spc,ptp,pte,t1 +#ifdef CONFIG_SMP + cmpib,COND(=),n 0,spc,dbit_nolock_20w + load32 PA(pa_dbit_lock),t0 + +dbit_spin_20w: + LDCW 0(t0),t1 + cmpib,COND(=) 0,t1,dbit_spin_20w + nop + +dbit_nolock_20w: +#endif + update_dirty ptp,pte,t1 make_insert_tlb spc,pte,prot idtlbt pte,prot - dbit_unlock0 spc,t0 +#ifdef CONFIG_SMP + cmpib,COND(=),n 0,spc,dbit_nounlock_20w + ldi 1,t1 + stw t1,0(t0) + +dbit_nounlock_20w: +#endif rfir nop @@ -1587,8 +1543,18 @@ dbit_trap_11: L2_ptep ptp,pte,t0,va,dbit_fault - dbit_lock spc,t0,t1 - update_dirty spc,ptp,pte,t1 +#ifdef CONFIG_SMP + cmpib,COND(=),n 0,spc,dbit_nolock_11 + load32 PA(pa_dbit_lock),t0 + +dbit_spin_11: + LDCW 0(t0),t1 + cmpib,= 0,t1,dbit_spin_11 + nop + +dbit_nolock_11: +#endif + update_dirty ptp,pte,t1 make_insert_tlb_11 spc,pte,prot @@ -1599,7 +1565,13 @@ dbit_trap_11: idtlbp prot,(%sr1,va) mtsp t1, %sr1 /* Restore sr1 */ - dbit_unlock0 spc,t0 +#ifdef CONFIG_SMP + cmpib,COND(=),n 0,spc,dbit_nounlock_11 + ldi 1,t1 + stw t1,0(t0) + +dbit_nounlock_11: +#endif rfir nop @@ -1611,15 +1583,32 @@ dbit_trap_20: L2_ptep ptp,pte,t0,va,dbit_fault - dbit_lock spc,t0,t1 - update_dirty spc,ptp,pte,t1 +#ifdef CONFIG_SMP + cmpib,COND(=),n 0,spc,dbit_nolock_20 + load32 PA(pa_dbit_lock),t0 + +dbit_spin_20: + LDCW 0(t0),t1 + cmpib,= 0,t1,dbit_spin_20 + nop + +dbit_nolock_20: +#endif + update_dirty ptp,pte,t1 make_insert_tlb spc,pte,prot f_extend pte,t1 idtlbt pte,prot - dbit_unlock0 spc,t0 + +#ifdef CONFIG_SMP + cmpib,COND(=),n 0,spc,dbit_nounlock_20 + ldi 1,t1 + stw t1,0(t0) + +dbit_nounlock_20: +#endif rfir nop diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index 55237a70e197..e255db0bb761 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -166,32 +166,22 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%*s: ", prec, "STK"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage); - seq_puts(p, " Kernel stack usage\n"); -# ifdef CONFIG_IRQSTACKS - seq_printf(p, "%*s: ", prec, "IST"); - for_each_online_cpu(j) - seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); - seq_puts(p, " Interrupt stack usage\n"); - seq_printf(p, "%*s: ", prec, "ISC"); - for_each_online_cpu(j) - seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter); - seq_puts(p, " Interrupt stack usage counter\n"); -# endif + seq_printf(p, " Kernel stack usage\n"); #endif #ifdef CONFIG_SMP seq_printf(p, "%*s: ", prec, "RES"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); - seq_puts(p, " Rescheduling interrupts\n"); + seq_printf(p, " Rescheduling interrupts\n"); seq_printf(p, "%*s: ", prec, "CAL"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); - seq_puts(p, " Function call interrupts\n"); + seq_printf(p, " Function call interrupts\n"); #endif seq_printf(p, "%*s: ", prec, "TLB"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); - seq_puts(p, " TLB shootdowns\n"); + seq_printf(p, " TLB shootdowns\n"); return 0; } @@ -388,7 +378,6 @@ static inline void stack_overflow_check(struct pt_regs *regs) unsigned long sp = regs->gr[30]; unsigned long stack_usage; unsigned int *last_usage; - int cpu = smp_processor_id(); /* if sr7 != 0, we interrupted a userspace process which we do not want * to check for stack overflow. We will only check the kernel stack. */ @@ -397,31 +386,7 @@ static inline void stack_overflow_check(struct pt_regs *regs) /* calculate kernel stack usage */ stack_usage = sp - stack_start; -#ifdef CONFIG_IRQSTACKS - if (likely(stack_usage <= THREAD_SIZE)) - goto check_kernel_stack; /* found kernel stack */ - - /* check irq stack usage */ - stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack; - stack_usage = sp - stack_start; - - last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu); - if (unlikely(stack_usage > *last_usage)) - *last_usage = stack_usage; - - if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN))) - return; - - pr_emerg("stackcheck: %s will most likely overflow irq stack " - "(sp:%lx, stk bottom-top:%lx-%lx)\n", - current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE); - goto panic_check; - -check_kernel_stack: -#endif - - /* check kernel stack usage */ - last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu); + last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id()); if (unlikely(stack_usage > *last_usage)) *last_usage = stack_usage; @@ -433,69 +398,31 @@ static inline void stack_overflow_check(struct pt_regs *regs) "(sp:%lx, stk bottom-top:%lx-%lx)\n", current->comm, sp, stack_start, stack_start + THREAD_SIZE); -#ifdef CONFIG_IRQSTACKS -panic_check: -#endif if (sysctl_panic_on_stackoverflow) panic("low stack detected by irq handler - check messages\n"); #endif } #ifdef CONFIG_IRQSTACKS -DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { - .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock) - }; +DEFINE_PER_CPU(union irq_stack_union, irq_stack_union); static void execute_on_irq_stack(void *func, unsigned long param1) { - union irq_stack_union *union_ptr; + unsigned long *irq_stack_start; unsigned long irq_stack; - raw_spinlock_t *irq_stack_in_use; + int cpu = smp_processor_id(); - union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); - irq_stack = (unsigned long) &union_ptr->stack; - irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock), - 64); /* align for stack frame usage */ + irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0]; + irq_stack = (unsigned long) irq_stack_start; + irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */ - /* We may be called recursive. If we are already using the irq stack, - * just continue to use it. Use spinlocks to serialize - * the irq stack usage. - */ - irq_stack_in_use = &union_ptr->lock; - if (!raw_spin_trylock(irq_stack_in_use)) { - void (*direct_call)(unsigned long p1) = func; - - /* We are using the IRQ stack already. - * Do direct call on current stack. */ - direct_call(param1); - return; - } + BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */ + *irq_stack_start = 1; /* This is where we switch to the IRQ stack. */ call_on_stack(param1, func, irq_stack); - __inc_irq_stat(irq_stack_counter); - - /* free up irq stack usage. */ - do_raw_spin_unlock(irq_stack_in_use); -} - -asmlinkage void do_softirq(void) -{ - __u32 pending; - unsigned long flags; - - if (in_interrupt()) - return; - - local_irq_save(flags); - - pending = local_softirq_pending(); - - if (pending) - execute_on_irq_stack(__do_softirq, 0); - - local_irq_restore(flags); + *irq_stack_start = 0; } #endif /* CONFIG_IRQSTACKS */ diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index 1c965642068b..ce939ac8622b 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -1069,7 +1069,7 @@ void flush_tlb_all(void) { int do_recycle; - __inc_irq_stat(irq_tlb_count); + inc_irq_stat(irq_tlb_count); do_recycle = 0; spin_lock(&sid_lock); if (dirty_space_ids > RECYCLE_THRESHOLD) { @@ -1090,7 +1090,7 @@ void flush_tlb_all(void) #else void flush_tlb_all(void) { - __inc_irq_stat(irq_tlb_count); + inc_irq_stat(irq_tlb_count); spin_lock(&sid_lock); flush_tlb_all_local(NULL); recycle_sids(); diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index 863d877e0b5f..5416e28a7538 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -262,31 +262,8 @@ config PPC_EARLY_DEBUG_OPAL_HVSI Select this to enable early debugging for the PowerNV platform using an "hvsi" console -config PPC_EARLY_DEBUG_MEMCONS - bool "In memory console" - help - Select this to enable early debugging using an in memory console. - This console provides input and output buffers stored within the - kernel BSS and should be safe to select on any system. A debugger - can then be used to read kernel output or send input to the console. endchoice -config PPC_MEMCONS_OUTPUT_SIZE - int "In memory console output buffer size" - depends on PPC_EARLY_DEBUG_MEMCONS - default 4096 - help - Selects the size of the output buffer (in bytes) of the in memory - console. - -config PPC_MEMCONS_INPUT_SIZE - int "In memory console input buffer size" - depends on PPC_EARLY_DEBUG_MEMCONS - default 128 - help - Selects the size of the input buffer (in bytes) of the in memory - console. - config PPC_EARLY_DEBUG_OPAL def_bool y depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index 139a8308070c..f79196232917 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -136,6 +136,7 @@ CONFIG_HID_SMARTJOYPLUS=m CONFIG_USB_HIDDEV=y CONFIG_USB=m CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_SUSPEND=y CONFIG_USB_MON=m CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_HCD_PPC_OF is not set diff --git a/trunk/arch/powerpc/include/asm/context_tracking.h b/trunk/arch/powerpc/include/asm/context_tracking.h deleted file mode 100644 index b6f5a33b8ee2..000000000000 --- a/trunk/arch/powerpc/include/asm/context_tracking.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ASM_POWERPC_CONTEXT_TRACKING_H -#define _ASM_POWERPC_CONTEXT_TRACKING_H - -#ifdef CONFIG_CONTEXT_TRACKING -#define SCHEDULE_USER bl .schedule_user -#else -#define SCHEDULE_USER bl .schedule -#endif - -#endif diff --git a/trunk/arch/powerpc/include/asm/firmware.h b/trunk/arch/powerpc/include/asm/firmware.h index 681bc0314b6b..0df54646f968 100644 --- a/trunk/arch/powerpc/include/asm/firmware.h +++ b/trunk/arch/powerpc/include/asm/firmware.h @@ -52,7 +52,6 @@ #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) -#define FW_FEATURE_OPALv3 ASM_CONST(0x0000000400000000) #ifndef __ASSEMBLY__ @@ -70,8 +69,7 @@ enum { FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, FW_FEATURE_PSERIES_ALWAYS = 0, - FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 | - FW_FEATURE_OPALv3, + FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2, FW_FEATURE_POWERNV_ALWAYS = 0, FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, diff --git a/trunk/arch/powerpc/include/asm/hw_irq.h b/trunk/arch/powerpc/include/asm/hw_irq.h index ba713f166fa5..d615b28dda82 100644 --- a/trunk/arch/powerpc/include/asm/hw_irq.h +++ b/trunk/arch/powerpc/include/asm/hw_irq.h @@ -96,12 +96,11 @@ static inline bool arch_irqs_disabled(void) #endif #define hard_irq_disable() do { \ - u8 _was_enabled = get_paca()->soft_enabled; \ __hard_irq_disable(); \ + if (local_paca->soft_enabled) \ + trace_hardirqs_off(); \ get_paca()->soft_enabled = 0; \ get_paca()->irq_happened |= PACA_IRQ_HARD_DIS; \ - if (_was_enabled) \ - trace_hardirqs_off(); \ } while(0) static inline bool lazy_irq_pending(void) diff --git a/trunk/arch/powerpc/include/asm/opal.h b/trunk/arch/powerpc/include/asm/opal.h index cbb9305ab15a..b6c8b58b1d76 100644 --- a/trunk/arch/powerpc/include/asm/opal.h +++ b/trunk/arch/powerpc/include/asm/opal.h @@ -243,8 +243,7 @@ enum OpalMCE_TlbErrorType { enum OpalThreadStatus { OPAL_THREAD_INACTIVE = 0x0, - OPAL_THREAD_STARTED = 0x1, - OPAL_THREAD_UNAVAILABLE = 0x2 /* opal-v3 */ + OPAL_THREAD_STARTED = 0x1 }; enum OpalPciBusCompare { @@ -564,8 +563,6 @@ extern void opal_nvram_init(void); extern int opal_machine_check(struct pt_regs *regs); -extern void opal_shutdown(void); - #endif /* __ASSEMBLY__ */ #endif /* __OPAL_H */ diff --git a/trunk/arch/powerpc/include/asm/pci-bridge.h b/trunk/arch/powerpc/include/asm/pci-bridge.h index 2c1d8cb9b265..8b11b5bd9938 100644 --- a/trunk/arch/powerpc/include/asm/pci-bridge.h +++ b/trunk/arch/powerpc/include/asm/pci-bridge.h @@ -174,8 +174,6 @@ struct pci_dn { /* Get the pointer to a device_node's pci_dn */ #define PCI_DN(dn) ((struct pci_dn *) (dn)->data) -extern struct pci_dn *pci_get_pdn(struct pci_dev *pdev); - extern void * update_dn_pci_info(struct device_node *dn, void *data); static inline int pci_device_from_OF_node(struct device_node *np, diff --git a/trunk/arch/powerpc/include/asm/pgalloc-64.h b/trunk/arch/powerpc/include/asm/pgalloc-64.h index b66ae722a8e9..91acb12bac92 100644 --- a/trunk/arch/powerpc/include/asm/pgalloc-64.h +++ b/trunk/arch/powerpc/include/asm/pgalloc-64.h @@ -186,7 +186,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, static inline pgtable_t pmd_pgtable(pmd_t pmd) { - return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS); + return (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE); } static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, diff --git a/trunk/arch/powerpc/include/asm/processor.h b/trunk/arch/powerpc/include/asm/processor.h index 594db6bc093c..d7e67ca8b4a6 100644 --- a/trunk/arch/powerpc/include/asm/processor.h +++ b/trunk/arch/powerpc/include/asm/processor.h @@ -284,12 +284,6 @@ struct thread_struct { unsigned long ebbrr; unsigned long ebbhr; unsigned long bescr; - unsigned long siar; - unsigned long sdar; - unsigned long sier; - unsigned long mmcr0; - unsigned long mmcr2; - unsigned long mmcra; #endif }; diff --git a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h index d836d945068d..3e13e23e4fdf 100644 --- a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h @@ -47,7 +47,7 @@ * generic accessors and iterators here */ #define __real_pte(e,p) ((real_pte_t) { \ - (e), (pte_val(e) & _PAGE_COMBO) ? \ + (e), ((e) & _PAGE_COMBO) ? \ (pte_val(*((p) + PTRS_PER_PTE))) : 0 }) #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) diff --git a/trunk/arch/powerpc/include/asm/rtas.h b/trunk/arch/powerpc/include/asm/rtas.h index 34fd70488d83..a8bc2bb4adc9 100644 --- a/trunk/arch/powerpc/include/asm/rtas.h +++ b/trunk/arch/powerpc/include/asm/rtas.h @@ -264,8 +264,6 @@ extern void rtas_progress(char *s, unsigned short hex); extern void rtas_initialize(void); extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); -extern int rtas_online_cpus_mask(cpumask_var_t cpus); -extern int rtas_offline_cpus_mask(cpumask_var_t cpus); extern int rtas_ibm_suspend_me(struct rtas_args *); struct rtc_time; diff --git a/trunk/arch/powerpc/include/asm/thread_info.h b/trunk/arch/powerpc/include/asm/thread_info.h index ba7b1973866e..8ceea14d6fe4 100644 --- a/trunk/arch/powerpc/include/asm/thread_info.h +++ b/trunk/arch/powerpc/include/asm/thread_info.h @@ -97,7 +97,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_PERFMON_CTXSW 6 /* perfmon needs ctxsw calls */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SINGLESTEP 8 /* singlestepping active */ -#define TIF_NOHZ 9 /* in adaptive nohz mode */ +#define TIF_MEMDIE 9 /* is terminating due to OOM killer */ #define TIF_SECCOMP 10 /* secure computing */ #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12 /* Force successful syscall return */ @@ -106,7 +106,6 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */ #define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation for stack store? */ -#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< #include #include -#include /* * System calls. @@ -377,6 +376,8 @@ _GLOBAL(ret_from_fork) _GLOBAL(ret_from_kernel_thread) bl .schedule_tail REST_NVGPRS(r1) + li r3,0 + std r3,0(r1) ld r14, 0(r14) mtlr r14 mr r3,r15 @@ -465,20 +466,6 @@ BEGIN_FTR_SECTION std r0, THREAD_EBBHR(r3) mfspr r0, SPRN_EBBRR std r0, THREAD_EBBRR(r3) - - /* PMU registers made user read/(write) by EBB */ - mfspr r0, SPRN_SIAR - std r0, THREAD_SIAR(r3) - mfspr r0, SPRN_SDAR - std r0, THREAD_SDAR(r3) - mfspr r0, SPRN_SIER - std r0, THREAD_SIER(r3) - mfspr r0, SPRN_MMCR0 - std r0, THREAD_MMCR0(r3) - mfspr r0, SPRN_MMCR2 - std r0, THREAD_MMCR2(r3) - mfspr r0, SPRN_MMCRA - std r0, THREAD_MMCRA(r3) END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) #endif @@ -574,20 +561,6 @@ BEGIN_FTR_SECTION ld r0, THREAD_EBBRR(r4) mtspr SPRN_EBBRR, r0 - /* PMU registers made user read/(write) by EBB */ - ld r0, THREAD_SIAR(r4) - mtspr SPRN_SIAR, r0 - ld r0, THREAD_SDAR(r4) - mtspr SPRN_SDAR, r0 - ld r0, THREAD_SIER(r4) - mtspr SPRN_SIER, r0 - ld r0, THREAD_MMCR0(r4) - mtspr SPRN_MMCR0, r0 - ld r0, THREAD_MMCR2(r4) - mtspr SPRN_MMCR2, r0 - ld r0, THREAD_MMCRA(r4) - mtspr SPRN_MMCRA, r0 - ld r0,THREAD_TAR(r4) mtspr SPRN_TAR,r0 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) @@ -661,7 +634,7 @@ _GLOBAL(ret_from_except_lite) andi. r0,r4,_TIF_NEED_RESCHED beq 1f bl .restore_interrupts - SCHEDULE_USER + bl .schedule b .ret_from_except_lite 1: bl .save_nvgprs diff --git a/trunk/arch/powerpc/kernel/exceptions-64e.S b/trunk/arch/powerpc/kernel/exceptions-64e.S index 645170a07ada..42a756eec9ff 100644 --- a/trunk/arch/powerpc/kernel/exceptions-64e.S +++ b/trunk/arch/powerpc/kernel/exceptions-64e.S @@ -489,7 +489,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) */ mfspr r14,SPRN_DBSR /* check single-step/branch taken */ - andis. r15,r14,(DBSR_IC|DBSR_BT)@h + andis. r15,r14,DBSR_IC@h beq+ 1f LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) @@ -500,7 +500,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) bge+ cr1,1f /* here it looks like we got an inappropriate debug exception. */ - lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ + lis r14,DBSR_IC@h /* clear the IC event */ rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */ mtspr SPRN_DBSR,r14 mtspr SPRN_CSRR1,r11 @@ -555,7 +555,7 @@ kernel_dbg_exc: */ mfspr r14,SPRN_DBSR /* check single-step/branch taken */ - andis. r15,r14,(DBSR_IC|DBSR_BT)@h + andis. r15,r14,DBSR_IC@h beq+ 1f LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) @@ -566,7 +566,7 @@ kernel_dbg_exc: bge+ cr1,1f /* here it looks like we got an inappropriate debug exception. */ - lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ + lis r14,DBSR_IC@h /* clear the IC event */ rlwinm r11,r11,0,~MSR_DE /* clear DE in the DSRR1 value */ mtspr SPRN_DBSR,r14 mtspr SPRN_DSRR1,r11 diff --git a/trunk/arch/powerpc/kernel/machine_kexec_64.c b/trunk/arch/powerpc/kernel/machine_kexec_64.c index 611acdf30096..466a2908bb63 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec_64.c +++ b/trunk/arch/powerpc/kernel/machine_kexec_64.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -336,13 +335,10 @@ void default_machine_kexec(struct kimage *image) pr_debug("kexec: Starting switchover sequence.\n"); /* switch to a staticly allocated stack. Based on irq stack code. - * We setup preempt_count to avoid using VMX in memcpy. * XXX: the task struct will likely be invalid once we do the copy! */ kexec_stack.thread_info.task = current_thread_info()->task; kexec_stack.thread_info.flags = 0; - kexec_stack.thread_info.preempt_count = HARDIRQ_OFFSET; - kexec_stack.thread_info.cpu = current_thread_info()->cpu; /* We need a static PACA, too; copy this CPU's PACA over and switch to * it. Also poison per_cpu_offset to catch anyone using non-static diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index e469f30e6eeb..19e096bd0e73 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -657,17 +657,6 @@ _GLOBAL(__ucmpdi2) li r3,2 blr -_GLOBAL(__bswapdi2) - rotlwi r9,r4,8 - rotlwi r10,r3,8 - rlwimi r9,r4,24,0,7 - rlwimi r10,r3,24,0,7 - rlwimi r9,r4,24,16,23 - rlwimi r10,r3,24,16,23 - mr r3,r9 - mr r4,r10 - blr - _GLOBAL(abs) srawi r4,r3,31 xor r3,r3,r4 diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 6820e45f557b..5cfa8008693b 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -234,17 +234,6 @@ _GLOBAL(__flush_dcache_icache) isync blr -_GLOBAL(__bswapdi2) - srdi r8,r3,32 - rlwinm r7,r3,8,0xffffffff - rlwimi r7,r3,24,0,7 - rlwinm r9,r8,8,0xffffffff - rlwimi r7,r3,24,16,23 - rlwimi r9,r8,24,0,7 - rlwimi r9,r8,24,16,23 - sldi r7,r7,32 - or r3,r7,r9 - blr #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) /* diff --git a/trunk/arch/powerpc/kernel/pci-common.c b/trunk/arch/powerpc/kernel/pci-common.c index e9acf50dd5b2..f5c5c90799a7 100644 --- a/trunk/arch/powerpc/kernel/pci-common.c +++ b/trunk/arch/powerpc/kernel/pci-common.c @@ -359,6 +359,7 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, enum pci_mmap_state mmap_state, int write_combine) { + unsigned long prot = pgprot_val(protection); /* Write combine is always 0 on non-memory space mappings. On * memory space, if the user didn't pass 1, we check for a @@ -375,9 +376,9 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, /* XXX would be nice to have a way to ask for write-through */ if (write_combine) - return pgprot_noncached_wc(protection); + return pgprot_noncached_wc(prot); else - return pgprot_noncached(protection); + return pgprot_noncached(prot); } /* @@ -1520,10 +1521,9 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, for (i = 0; i < 3; ++i) { res = &hose->mem_resources[i]; if (!res->flags) { - if (i == 0) - printk(KERN_ERR "PCI: Memory resource 0 not set for " - "host bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + printk(KERN_ERR "PCI: Memory resource 0 not set for " + "host bridge %s (domain %d)\n", + hose->dn->full_name, hose->global_number); continue; } offset = hose->mem_offset[i]; diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 2e8629654ca8..873050d26840 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -266,13 +266,3 @@ int pcibus_to_node(struct pci_bus *bus) } EXPORT_SYMBOL(pcibus_to_node); #endif - -static void quirk_radeon_32bit_msi(struct pci_dev *dev) -{ - struct pci_dn *pdn = pci_get_pdn(dev); - - if (pdn) - pdn->force_32bit_msi = 1; -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi); diff --git a/trunk/arch/powerpc/kernel/pci_dn.c b/trunk/arch/powerpc/kernel/pci_dn.c index df038442548a..e7af165f8b9d 100644 --- a/trunk/arch/powerpc/kernel/pci_dn.c +++ b/trunk/arch/powerpc/kernel/pci_dn.c @@ -32,14 +32,6 @@ #include #include -struct pci_dn *pci_get_pdn(struct pci_dev *pdev) -{ - struct device_node *dn = pci_device_to_OF_node(pdev); - if (!dn) - return NULL; - return PCI_DN(dn); -} - /* * Traverse_func that inits the PCI fields of the device node. * NOTE: this *must* be done before read/write config to the device. diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index c29666586998..78b8766fd79e 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -143,8 +143,7 @@ EXPORT_SYMBOL(__lshrdi3); int __ucmpdi2(unsigned long long, unsigned long long); EXPORT_SYMBOL(__ucmpdi2); #endif -long long __bswapdi2(long long); -EXPORT_SYMBOL(__bswapdi2); + EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index a902723fdc69..ceb4e7b62cf4 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -339,13 +339,6 @@ static void set_debug_reg_defaults(struct thread_struct *thread) static void prime_debug_regs(struct thread_struct *thread) { - /* - * We could have inherited MSR_DE from userspace, since - * it doesn't get cleared on exception entry. Make sure - * MSR_DE is clear before we enable any debug events. - */ - mtmsr(mfmsr() & ~MSR_DE); - mtspr(SPRN_IAC1, thread->iac1); mtspr(SPRN_IAC2, thread->iac2); #if CONFIG_PPC_ADV_DEBUG_IACS > 2 @@ -978,7 +971,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, * do some house keeping and then return from the fork or clone * system call, using the stack frame created above. */ - ((unsigned long *)sp)[0] = 0; sp -= sizeof(struct pt_regs); kregs = (struct pt_regs *) sp; sp -= STACK_FRAME_OVERHEAD; diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index 98c2fc198712..3b14d320e69f 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -1789,8 +1788,6 @@ long do_syscall_trace_enter(struct pt_regs *regs) { long ret = 0; - user_exit(); - secure_computing_strict(regs->gpr[0]); if (test_thread_flag(TIF_SYSCALL_TRACE) && @@ -1835,6 +1832,4 @@ void do_syscall_trace_leave(struct pt_regs *regs) step = test_thread_flag(TIF_SINGLESTEP); if (step || test_thread_flag(TIF_SYSCALL_TRACE)) tracehook_report_syscall_exit(regs, step); - - user_enter(); } diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index 52add6f3e201..1fd6e7b2f390 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -808,95 +807,6 @@ static void rtas_percpu_suspend_me(void *info) __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); } -enum rtas_cpu_state { - DOWN, - UP, -}; - -#ifndef CONFIG_SMP -static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, - cpumask_var_t cpus) -{ - if (!cpumask_empty(cpus)) { - cpumask_clear(cpus); - return -EINVAL; - } else - return 0; -} -#else -/* On return cpumask will be altered to indicate CPUs changed. - * CPUs with states changed will be set in the mask, - * CPUs with status unchanged will be unset in the mask. */ -static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, - cpumask_var_t cpus) -{ - int cpu; - int cpuret = 0; - int ret = 0; - - if (cpumask_empty(cpus)) - return 0; - - for_each_cpu(cpu, cpus) { - switch (state) { - case DOWN: - cpuret = cpu_down(cpu); - break; - case UP: - cpuret = cpu_up(cpu); - break; - } - if (cpuret) { - pr_debug("%s: cpu_%s for cpu#%d returned %d.\n", - __func__, - ((state == UP) ? "up" : "down"), - cpu, cpuret); - if (!ret) - ret = cpuret; - if (state == UP) { - /* clear bits for unchanged cpus, return */ - cpumask_shift_right(cpus, cpus, cpu); - cpumask_shift_left(cpus, cpus, cpu); - break; - } else { - /* clear bit for unchanged cpu, continue */ - cpumask_clear_cpu(cpu, cpus); - } - } - } - - return ret; -} -#endif - -int rtas_online_cpus_mask(cpumask_var_t cpus) -{ - int ret; - - ret = rtas_cpu_state_change_mask(UP, cpus); - - if (ret) { - cpumask_var_t tmp_mask; - - if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY)) - return ret; - - /* Use tmp_mask to preserve cpus mask from first failure */ - cpumask_copy(tmp_mask, cpus); - rtas_offline_cpus_mask(tmp_mask); - free_cpumask_var(tmp_mask); - } - - return ret; -} -EXPORT_SYMBOL(rtas_online_cpus_mask); - -int rtas_offline_cpus_mask(cpumask_var_t cpus) -{ - return rtas_cpu_state_change_mask(DOWN, cpus); -} -EXPORT_SYMBOL(rtas_offline_cpus_mask); - int rtas_ibm_suspend_me(struct rtas_args *args) { long state; @@ -904,8 +814,6 @@ int rtas_ibm_suspend_me(struct rtas_args *args) unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; struct rtas_suspend_me_data data; DECLARE_COMPLETION_ONSTACK(done); - cpumask_var_t offline_mask; - int cpuret; if (!rtas_service_present("ibm,suspend-me")) return -ENOSYS; @@ -929,24 +837,11 @@ int rtas_ibm_suspend_me(struct rtas_args *args) return 0; } - if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) - return -ENOMEM; - atomic_set(&data.working, 0); atomic_set(&data.done, 0); atomic_set(&data.error, 0); data.token = rtas_token("ibm,suspend-me"); data.complete = &done; - - /* All present CPUs must be online */ - cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask); - cpuret = rtas_online_cpus_mask(offline_mask); - if (cpuret) { - pr_err("%s: Could not bring present CPUs online.\n", __func__); - atomic_set(&data.error, cpuret); - goto out; - } - stop_topology_update(); /* Call function on all CPUs. One of us will make the @@ -962,14 +857,6 @@ int rtas_ibm_suspend_me(struct rtas_args *args) start_topology_update(); - /* Take down CPUs not online prior to suspend */ - cpuret = rtas_offline_cpus_mask(offline_mask); - if (cpuret) - pr_warn("%s: Could not restore CPUs to offline state.\n", - __func__); - -out: - free_cpumask_var(offline_mask); return atomic_read(&data.error); } #else /* CONFIG_PPC_PSERIES */ diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 2f3cdb01506d..5b3022470126 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -89,7 +89,6 @@ /* Array sizes */ #define VALIDATE_BUF_SIZE 4096 -#define VALIDATE_MSG_LEN 256 #define RTAS_MSG_MAXLEN 64 /* Quirk - RTAS requires 4k list length and block size */ @@ -467,7 +466,7 @@ static void validate_flash(struct rtas_validate_flash_t *args_buf) } static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, - char *msg, int msglen) + char *msg) { int n; @@ -475,8 +474,7 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, n = sprintf(msg, "%d\n", args_buf->update_results); if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || (args_buf->update_results == VALIDATE_TMP_UPDATE)) - n += snprintf(msg + n, msglen - n, "%s\n", - args_buf->buf); + n += sprintf(msg + n, "%s\n", args_buf->buf); } else { n = sprintf(msg, "%d\n", args_buf->status); } @@ -488,11 +486,11 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, { struct rtas_validate_flash_t *const args_buf = &rtas_validate_flash_data; - char msg[VALIDATE_MSG_LEN]; + char msg[RTAS_MSG_MAXLEN]; int msglen; mutex_lock(&rtas_validate_flash_mutex); - msglen = get_validate_flash_msg(args_buf, msg, VALIDATE_MSG_LEN); + msglen = get_validate_flash_msg(args_buf, msg); mutex_unlock(&rtas_validate_flash_mutex); return simple_read_from_buffer(buf, count, ppos, msg, msglen); diff --git a/trunk/arch/powerpc/kernel/signal.c b/trunk/arch/powerpc/kernel/signal.c index 577a8aa69c6e..cf12eae02de5 100644 --- a/trunk/arch/powerpc/kernel/signal.c +++ b/trunk/arch/powerpc/kernel/signal.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -25,7 +24,7 @@ * through debug.exception-trace sysctl. */ -int show_unhandled_signals = 1; +int show_unhandled_signals = 0; /* * Allocate space for the signal frame @@ -160,8 +159,6 @@ static int do_signal(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { - user_exit(); - if (thread_info_flags & _TIF_UPROBE) uprobe_notify_resume(regs); @@ -172,6 +169,4 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); } - - user_enter(); } diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index a7a648f6b750..83efa2f7d926 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -668,7 +667,6 @@ int machine_check_generic(struct pt_regs *regs) void machine_check_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); int recover = 0; __get_cpu_var(irq_stat).mce_exceptions++; @@ -685,7 +683,7 @@ void machine_check_exception(struct pt_regs *regs) recover = cur_cpu_spec->machine_check(regs); if (recover > 0) - goto bail; + return; #if defined(CONFIG_8xx) && defined(CONFIG_PCI) /* the qspan pci read routines can cause machine checks -- Cort @@ -695,23 +693,20 @@ void machine_check_exception(struct pt_regs *regs) * -- BenH */ bad_page_fault(regs, regs->dar, SIGBUS); - goto bail; + return; #endif if (debugger_fault_handler(regs)) - goto bail; + return; if (check_io_access(regs)) - goto bail; + return; die("Machine check", regs, SIGBUS); /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) panic("Unrecoverable Machine check"); - -bail: - exception_exit(prev_state); } void SMIException(struct pt_regs *regs) @@ -721,29 +716,20 @@ void SMIException(struct pt_regs *regs) void unknown_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); - printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", regs->nip, regs->msr, regs->trap); _exception(SIGTRAP, regs, 0, 0); - - exception_exit(prev_state); } void instruction_breakpoint_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); - if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) - goto bail; + return; if (debugger_iabr_match(regs)) - goto bail; + return; _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); - -bail: - exception_exit(prev_state); } void RunModeException(struct pt_regs *regs) @@ -753,20 +739,15 @@ void RunModeException(struct pt_regs *regs) void __kprobes single_step_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); - clear_single_step(regs); if (notify_die(DIE_SSTEP, "single_step", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) - goto bail; + return; if (debugger_sstep(regs)) - goto bail; + return; _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); - -bail: - exception_exit(prev_state); } /* @@ -1024,7 +1005,6 @@ int is_valid_bugaddr(unsigned long addr) void __kprobes program_check_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); unsigned int reason = get_reason(regs); extern int do_mathemu(struct pt_regs *regs); @@ -1034,26 +1014,26 @@ void __kprobes program_check_exception(struct pt_regs *regs) if (reason & REASON_FP) { /* IEEE FP exception */ parse_fpe(regs); - goto bail; + return; } if (reason & REASON_TRAP) { /* Debugger is first in line to stop recursive faults in * rcu_lock, notify_die, or atomic_notifier_call_chain */ if (debugger_bpt(regs)) - goto bail; + return; /* trap exception */ if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) - goto bail; + return; if (!(regs->msr & MSR_PR) && /* not user-mode */ report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; - goto bail; + return; } _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); - goto bail; + return; } #ifdef CONFIG_PPC_TRANSACTIONAL_MEM if (reason & REASON_TM) { @@ -1069,7 +1049,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) if (!user_mode(regs) && report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; - goto bail; + return; } /* If usermode caused this, it's done something illegal and * gets a SIGILL slap on the wrist. We call it an illegal @@ -1079,7 +1059,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) */ if (user_mode(regs)) { _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); - goto bail; + return; } else { printk(KERN_EMERG "Unexpected TM Bad Thing exception " "at %lx (msr 0x%x)\n", regs->nip, reason); @@ -1103,16 +1083,16 @@ void __kprobes program_check_exception(struct pt_regs *regs) switch (do_mathemu(regs)) { case 0: emulate_single_step(regs); - goto bail; + return; case 1: { int code = 0; code = __parse_fpscr(current->thread.fpscr.val); _exception(SIGFPE, regs, code, regs->nip); - goto bail; + return; } case -EFAULT: _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - goto bail; + return; } /* fall through on any other errors */ #endif /* CONFIG_MATH_EMULATION */ @@ -1123,10 +1103,10 @@ void __kprobes program_check_exception(struct pt_regs *regs) case 0: regs->nip += 4; emulate_single_step(regs); - goto bail; + return; case -EFAULT: _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); - goto bail; + return; } } @@ -1134,14 +1114,10 @@ void __kprobes program_check_exception(struct pt_regs *regs) _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); else _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - -bail: - exception_exit(prev_state); } void alignment_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); int sig, code, fixed = 0; /* We restore the interrupt state now */ @@ -1155,7 +1131,7 @@ void alignment_exception(struct pt_regs *regs) if (fixed == 1) { regs->nip += 4; /* skip over emulated instruction */ emulate_single_step(regs); - goto bail; + return; } /* Operand address was bad */ @@ -1170,9 +1146,6 @@ void alignment_exception(struct pt_regs *regs) _exception(sig, regs, code, regs->dar); else bad_page_fault(regs, regs->dar, sig); - -bail: - exception_exit(prev_state); } void StackOverflow(struct pt_regs *regs) @@ -1201,32 +1174,23 @@ void trace_syscall(struct pt_regs *regs) void kernel_fp_unavailable_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); - printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); - - exception_exit(prev_state); } void altivec_unavailable_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); - if (user_mode(regs)) { /* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); - goto bail; + return; } printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); - -bail: - exception_exit(prev_state); } void vsx_unavailable_exception(struct pt_regs *regs) diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index 9d3fdcd66290..13b867093499 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -64,9 +64,6 @@ void __init udbg_early_init(void) udbg_init_usbgecko(); #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) udbg_init_wsp(); -#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS) - /* In memory console */ - udbg_init_memcons(); #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) udbg_init_ehv_bc(); #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index 8726779e1409..229951ffc351 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -197,7 +196,6 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { - enum ctx_state prev_state = exception_enter(); struct vm_area_struct * vma; struct mm_struct *mm = current->mm; unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; @@ -206,7 +204,6 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, int trap = TRAP(regs); int is_exec = trap == 0x400; int fault; - int rc = 0; #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) /* @@ -233,30 +230,28 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, * look at it */ if (error_code & ICSWX_DSI_UCT) { - rc = acop_handle_fault(regs, address, error_code); + int rc = acop_handle_fault(regs, address, error_code); if (rc) - goto bail; + return rc; } #endif /* CONFIG_PPC_ICSWX */ if (notify_page_fault(regs)) - goto bail; + return 0; if (unlikely(debugger_fault_handler(regs))) - goto bail; + return 0; /* On a kernel SLB miss we can only check for a valid exception entry */ - if (!user_mode(regs) && (address >= TASK_SIZE)) { - rc = SIGSEGV; - goto bail; - } + if (!user_mode(regs) && (address >= TASK_SIZE)) + return SIGSEGV; #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \ defined(CONFIG_PPC_BOOK3S_64)) if (error_code & DSISR_DABRMATCH) { /* breakpoint match */ do_break(regs, address, error_code); - goto bail; + return 0; } #endif @@ -265,10 +260,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, local_irq_enable(); if (in_atomic() || mm == NULL) { - if (!user_mode(regs)) { - rc = SIGSEGV; - goto bail; - } + if (!user_mode(regs)) + return SIGSEGV; /* in_atomic() in user mode is really bad, as is current->mm == NULL. */ printk(KERN_EMERG "Page fault in user mode with " @@ -424,11 +417,9 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, */ fault = handle_mm_fault(mm, vma, address, flags); if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { - rc = mm_fault_error(regs, address, fault); + int rc = mm_fault_error(regs, address, fault); if (rc >= MM_FAULT_RETURN) - goto bail; - else - rc = 0; + return rc; } /* @@ -463,7 +454,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, } up_read(&mm->mmap_sem); - goto bail; + return 0; bad_area: up_read(&mm->mmap_sem); @@ -472,7 +463,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, /* User mode accesses cause a SIGSEGV */ if (user_mode(regs)) { _exception(SIGSEGV, regs, code, address); - goto bail; + return 0; } if (is_exec && (error_code & DSISR_PROTFAULT)) @@ -480,11 +471,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, " page (%lx) - exploit attempt? (uid: %d)\n", address, from_kuid(&init_user_ns, current_uid())); - rc = SIGSEGV; - -bail: - exception_exit(prev_state); - return rc; + return SIGSEGV; } diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index e303a6d74e3a..88ac0eeaadde 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -955,7 +954,6 @@ void hash_failure_debug(unsigned long ea, unsigned long access, */ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) { - enum ctx_state prev_state = exception_enter(); pgd_t *pgdir; unsigned long vsid; struct mm_struct *mm; @@ -975,8 +973,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) mm = current->mm; if (! mm) { DBG_LOW(" user region with no mm !\n"); - rc = 1; - goto bail; + return 1; } psize = get_slice_psize(mm, ea); ssize = user_segment_size(ea); @@ -995,23 +992,19 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) /* Not a valid range * Send the problem up to do_page_fault */ - rc = 1; - goto bail; + return 1; } DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid); /* Bad address. */ if (!vsid) { DBG_LOW("Bad address!\n"); - rc = 1; - goto bail; + return 1; } /* Get pgdir */ pgdir = mm->pgd; - if (pgdir == NULL) { - rc = 1; - goto bail; - } + if (pgdir == NULL) + return 1; /* Check CPU locality */ tmp = cpumask_of(smp_processor_id()); @@ -1034,8 +1027,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) ptep = find_linux_pte_or_hugepte(pgdir, ea, &hugeshift); if (ptep == NULL || !pte_present(*ptep)) { DBG_LOW(" no PTE !\n"); - rc = 1; - goto bail; + return 1; } /* Add _PAGE_PRESENT to the required access perm */ @@ -1046,16 +1038,13 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) */ if (access & ~pte_val(*ptep)) { DBG_LOW(" no access !\n"); - rc = 1; - goto bail; + return 1; } #ifdef CONFIG_HUGETLB_PAGE - if (hugeshift) { - rc = __hash_page_huge(ea, access, vsid, ptep, trap, local, + if (hugeshift) + return __hash_page_huge(ea, access, vsid, ptep, trap, local, ssize, hugeshift, psize); - goto bail; - } #endif /* CONFIG_HUGETLB_PAGE */ #ifndef CONFIG_PPC_64K_PAGES @@ -1135,9 +1124,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) pte_val(*(ptep + PTRS_PER_PTE))); #endif DBG_LOW(" -> rc=%d\n", rc); - -bail: - exception_exit(prev_state); return rc; } EXPORT_SYMBOL_GPL(hash_page); @@ -1273,8 +1259,6 @@ void flush_hash_range(unsigned long number, int local) */ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) { - enum ctx_state prev_state = exception_enter(); - if (user_mode(regs)) { #ifdef CONFIG_PPC_SUBPAGE_PROT if (rc == -2) @@ -1284,8 +1268,6 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc) _exception(SIGBUS, regs, BUS_ADRERR, address); } else bad_page_fault(regs, address, SIGBUS); - - exception_exit(prev_state); } long hpte_insert_repeating(unsigned long hash, unsigned long vpn, diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index a90b9c458990..c2787bf779ca 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -215,8 +215,7 @@ static void __meminit vmemmap_create_mapping(unsigned long start, unsigned long phys) { int mapped = htab_bolt_mapping(start, start + page_size, phys, - pgprot_val(PAGE_KERNEL), - mmu_vmemmap_psize, + PAGE_KERNEL, mmu_vmemmap_psize, mmu_kernel_ssize); BUG_ON(mapped < 0); } diff --git a/trunk/arch/powerpc/perf/core-book3s.c b/trunk/arch/powerpc/perf/core-book3s.c index 426180b84978..c627843c5b2e 100644 --- a/trunk/arch/powerpc/perf/core-book3s.c +++ b/trunk/arch/powerpc/perf/core-book3s.c @@ -13,13 +13,11 @@ #include #include #include -#include #include #include #include #include #include -#include #define BHRB_MAX_ENTRIES 32 #define BHRB_TARGET 0x0000000000000002 @@ -102,10 +100,6 @@ static inline int siar_valid(struct pt_regs *regs) return 1; } -static inline void power_pmu_bhrb_enable(struct perf_event *event) {} -static inline void power_pmu_bhrb_disable(struct perf_event *event) {} -void power_pmu_flush_branch_stack(void) {} -static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} #endif /* CONFIG_PPC32 */ static bool regs_use_siar(struct pt_regs *regs) @@ -314,159 +308,6 @@ static inline int siar_valid(struct pt_regs *regs) return 1; } - -/* Reset all possible BHRB entries */ -static void power_pmu_bhrb_reset(void) -{ - asm volatile(PPC_CLRBHRB); -} - -static void power_pmu_bhrb_enable(struct perf_event *event) -{ - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); - - if (!ppmu->bhrb_nr) - return; - - /* Clear BHRB if we changed task context to avoid data leaks */ - if (event->ctx->task && cpuhw->bhrb_context != event->ctx) { - power_pmu_bhrb_reset(); - cpuhw->bhrb_context = event->ctx; - } - cpuhw->bhrb_users++; -} - -static void power_pmu_bhrb_disable(struct perf_event *event) -{ - struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); - - if (!ppmu->bhrb_nr) - return; - - cpuhw->bhrb_users--; - WARN_ON_ONCE(cpuhw->bhrb_users < 0); - - if (!cpuhw->disabled && !cpuhw->bhrb_users) { - /* BHRB cannot be turned off when other - * events are active on the PMU. - */ - - /* avoid stale pointer */ - cpuhw->bhrb_context = NULL; - } -} - -/* Called from ctxsw to prevent one process's branch entries to - * mingle with the other process's entries during context switch. - */ -void power_pmu_flush_branch_stack(void) -{ - if (ppmu->bhrb_nr) - power_pmu_bhrb_reset(); -} -/* Calculate the to address for a branch */ -static __u64 power_pmu_bhrb_to(u64 addr) -{ - unsigned int instr; - int ret; - __u64 target; - - if (is_kernel_addr(addr)) - return branch_target((unsigned int *)addr); - - /* Userspace: need copy instruction here then translate it */ - pagefault_disable(); - ret = __get_user_inatomic(instr, (unsigned int __user *)addr); - if (ret) { - pagefault_enable(); - return 0; - } - pagefault_enable(); - - target = branch_target(&instr); - if ((!target) || (instr & BRANCH_ABSOLUTE)) - return target; - - /* Translate relative branch target from kernel to user address */ - return target - (unsigned long)&instr + addr; -} - -/* Processing BHRB entries */ -void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) -{ - u64 val; - u64 addr; - int r_index, u_index, pred; - - r_index = 0; - u_index = 0; - while (r_index < ppmu->bhrb_nr) { - /* Assembly read function */ - val = read_bhrb(r_index++); - if (!val) - /* Terminal marker: End of valid BHRB entries */ - break; - else { - addr = val & BHRB_EA; - pred = val & BHRB_PREDICTION; - - if (!addr) - /* invalid entry */ - continue; - - /* Branches are read most recent first (ie. mfbhrb 0 is - * the most recent branch). - * There are two types of valid entries: - * 1) a target entry which is the to address of a - * computed goto like a blr,bctr,btar. The next - * entry read from the bhrb will be branch - * corresponding to this target (ie. the actual - * blr/bctr/btar instruction). - * 2) a from address which is an actual branch. If a - * target entry proceeds this, then this is the - * matching branch for that target. If this is not - * following a target entry, then this is a branch - * where the target is given as an immediate field - * in the instruction (ie. an i or b form branch). - * In this case we need to read the instruction from - * memory to determine the target/to address. - */ - - if (val & BHRB_TARGET) { - /* Target branches use two entries - * (ie. computed gotos/XL form) - */ - cpuhw->bhrb_entries[u_index].to = addr; - cpuhw->bhrb_entries[u_index].mispred = pred; - cpuhw->bhrb_entries[u_index].predicted = ~pred; - - /* Get from address in next entry */ - val = read_bhrb(r_index++); - addr = val & BHRB_EA; - if (val & BHRB_TARGET) { - /* Shouldn't have two targets in a - row.. Reset index and try again */ - r_index--; - addr = 0; - } - cpuhw->bhrb_entries[u_index].from = addr; - } else { - /* Branches to immediate field - (ie I or B form) */ - cpuhw->bhrb_entries[u_index].from = addr; - cpuhw->bhrb_entries[u_index].to = - power_pmu_bhrb_to(addr); - cpuhw->bhrb_entries[u_index].mispred = pred; - cpuhw->bhrb_entries[u_index].predicted = ~pred; - } - u_index++; - - } - } - cpuhw->bhrb_stack.nr = u_index; - return; -} - #endif /* CONFIG_PPC64 */ static void perf_event_interrupt(struct pt_regs *regs); @@ -1063,6 +904,47 @@ static int collect_events(struct perf_event *group, int max_count, return n; } +/* Reset all possible BHRB entries */ +static void power_pmu_bhrb_reset(void) +{ + asm volatile(PPC_CLRBHRB); +} + +void power_pmu_bhrb_enable(struct perf_event *event) +{ + struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + + if (!ppmu->bhrb_nr) + return; + + /* Clear BHRB if we changed task context to avoid data leaks */ + if (event->ctx->task && cpuhw->bhrb_context != event->ctx) { + power_pmu_bhrb_reset(); + cpuhw->bhrb_context = event->ctx; + } + cpuhw->bhrb_users++; +} + +void power_pmu_bhrb_disable(struct perf_event *event) +{ + struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); + + if (!ppmu->bhrb_nr) + return; + + cpuhw->bhrb_users--; + WARN_ON_ONCE(cpuhw->bhrb_users < 0); + + if (!cpuhw->disabled && !cpuhw->bhrb_users) { + /* BHRB cannot be turned off when other + * events are active on the PMU. + */ + + /* avoid stale pointer */ + cpuhw->bhrb_context = NULL; + } +} + /* * Add a event to the PMU. * If all events are not already frozen, then we disable and @@ -1298,6 +1180,15 @@ int power_pmu_commit_txn(struct pmu *pmu) return 0; } +/* Called from ctxsw to prevent one process's branch entries to + * mingle with the other process's entries during context switch. + */ +void power_pmu_flush_branch_stack(void) +{ + if (ppmu->bhrb_nr) + power_pmu_bhrb_reset(); +} + /* * Return 1 if we might be able to put event on a limited PMC, * or 0 if not. @@ -1567,6 +1458,77 @@ struct pmu power_pmu = { .flush_branch_stack = power_pmu_flush_branch_stack, }; +/* Processing BHRB entries */ +void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) +{ + u64 val; + u64 addr; + int r_index, u_index, target, pred; + + r_index = 0; + u_index = 0; + while (r_index < ppmu->bhrb_nr) { + /* Assembly read function */ + val = read_bhrb(r_index); + + /* Terminal marker: End of valid BHRB entries */ + if (val == 0) { + break; + } else { + /* BHRB field break up */ + addr = val & BHRB_EA; + pred = val & BHRB_PREDICTION; + target = val & BHRB_TARGET; + + /* Probable Missed entry: Not applicable for POWER8 */ + if ((addr == 0) && (target == 0) && (pred == 1)) { + r_index++; + continue; + } + + /* Real Missed entry: Power8 based missed entry */ + if ((addr == 0) && (target == 1) && (pred == 1)) { + r_index++; + continue; + } + + /* Reserved condition: Not a valid entry */ + if ((addr == 0) && (target == 1) && (pred == 0)) { + r_index++; + continue; + } + + /* Is a target address */ + if (val & BHRB_TARGET) { + /* First address cannot be a target address */ + if (r_index == 0) { + r_index++; + continue; + } + + /* Update target address for the previous entry */ + cpuhw->bhrb_entries[u_index - 1].to = addr; + cpuhw->bhrb_entries[u_index - 1].mispred = pred; + cpuhw->bhrb_entries[u_index - 1].predicted = ~pred; + + /* Dont increment u_index */ + r_index++; + } else { + /* Update address, flags for current entry */ + cpuhw->bhrb_entries[u_index].from = addr; + cpuhw->bhrb_entries[u_index].mispred = pred; + cpuhw->bhrb_entries[u_index].predicted = ~pred; + + /* Successfully popullated one entry */ + u_index++; + r_index++; + } + } + } + cpuhw->bhrb_stack.nr = u_index; + return; +} + /* * A counter has overflowed; update its count and record * things if requested. Note that interrupts are hard-disabled diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index b62aab3e22ec..a881232a3cce 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -128,7 +128,7 @@ config PPC_RTAS_DAEMON config RTAS_PROC bool "Proc interface to RTAS" - depends on PPC_RTAS && PROC_FS + depends on PPC_RTAS default y config RTAS_FLASH diff --git a/trunk/arch/powerpc/platforms/powernv/Kconfig b/trunk/arch/powerpc/platforms/powernv/Kconfig index c24684c818ab..d3e840d643af 100644 --- a/trunk/arch/powerpc/platforms/powernv/Kconfig +++ b/trunk/arch/powerpc/platforms/powernv/Kconfig @@ -6,7 +6,6 @@ config PPC_POWERNV select PPC_ICP_NATIVE select PPC_P7_NAP select PPC_PCI_CHOICE if EMBEDDED - select EPAPR_BOOT default y config POWERNV_MSI diff --git a/trunk/arch/powerpc/platforms/powernv/opal.c b/trunk/arch/powerpc/platforms/powernv/opal.c index 628c564ceadb..ade4463226c6 100644 --- a/trunk/arch/powerpc/platforms/powernv/opal.c +++ b/trunk/arch/powerpc/platforms/powernv/opal.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -29,8 +28,6 @@ struct opal { static struct device_node *opal_node; static DEFINE_SPINLOCK(opal_write_lock); extern u64 opal_mc_secondary_handler[]; -static unsigned int *opal_irqs; -static unsigned int opal_irq_count; int __init early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data) @@ -56,11 +53,7 @@ int __init early_init_dt_scan_opal(unsigned long node, opal.entry, entryp, entrysz); powerpc_firmware_features |= FW_FEATURE_OPAL; - if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { - powerpc_firmware_features |= FW_FEATURE_OPALv2; - powerpc_firmware_features |= FW_FEATURE_OPALv3; - printk("OPAL V3 detected !\n"); - } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { + if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { powerpc_firmware_features |= FW_FEATURE_OPALv2; printk("OPAL V2 detected !\n"); } else { @@ -151,13 +144,6 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) { len = total_len; rc = opal_console_write(vtermno, &len, data); - - /* Closed or other error drop */ - if (rc != OPAL_SUCCESS && rc != OPAL_BUSY && - rc != OPAL_BUSY_EVENT) { - written = total_len; - break; - } if (rc == OPAL_SUCCESS) { total_len -= len; data += len; @@ -330,8 +316,6 @@ static int __init opal_init(void) irqs = of_get_property(opal_node, "opal-interrupts", &irqlen); pr_debug("opal: Found %d interrupts reserved for OPAL\n", irqs ? (irqlen / 4) : 0); - opal_irq_count = irqlen / 4; - opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL); for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) { unsigned int hwirq = be32_to_cpup(irqs); unsigned int irq = irq_create_mapping(NULL, hwirq); @@ -343,19 +327,7 @@ static int __init opal_init(void) if (rc) pr_warning("opal: Error %d requesting irq %d" " (0x%x)\n", rc, irq, hwirq); - opal_irqs[i] = irq; } return 0; } subsys_initcall(opal_init); - -void opal_shutdown(void) -{ - unsigned int i; - - for (i = 0; i < opal_irq_count; i++) { - if (opal_irqs[i]) - free_irq(opal_irqs[i], 0); - opal_irqs[i] = 0; - } -} diff --git a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c index 9c9d15e4cdf2..1da578b7c1bf 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c @@ -68,6 +68,16 @@ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); +static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) +{ + struct device_node *np; + + np = pci_device_to_OF_node(dev); + if (!np) + return NULL; + return PCI_DN(np); +} + static int pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -100,7 +110,7 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn = pci_get_pdn(dev); + struct pci_dn *pdn = pnv_ioda_get_pdn(dev); if (!pdn) return NULL; @@ -163,7 +173,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) /* Add to all parents PELT-V */ while (parent) { - struct pci_dn *pdn = pci_get_pdn(parent); + struct pci_dn *pdn = pnv_ioda_get_pdn(parent); if (pdn && pdn->pe_number != IODA_INVALID_PE) { rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); @@ -242,7 +252,7 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn = pci_get_pdn(dev); + struct pci_dn *pdn = pnv_ioda_get_pdn(dev); struct pnv_ioda_pe *pe; int pe_num; @@ -313,7 +323,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) struct pci_dev *dev; list_for_each_entry(dev, &bus->devices, bus_list) { - struct pci_dn *pdn = pci_get_pdn(dev); + struct pci_dn *pdn = pnv_ioda_get_pdn(dev); if (pdn == NULL) { pr_warn("%s: No device node associated with device !\n", @@ -426,7 +436,7 @@ static void pnv_pci_ioda_setup_PEs(void) static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev) { - struct pci_dn *pdn = pci_get_pdn(pdev); + struct pci_dn *pdn = pnv_ioda_get_pdn(pdev); struct pnv_ioda_pe *pe; /* @@ -758,7 +768,6 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, unsigned int is_64, struct msi_msg *msg) { struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); - struct pci_dn *pdn = pci_get_pdn(dev); struct irq_data *idata; struct irq_chip *ichip; unsigned int xive_num = hwirq - phb->msi_base; @@ -774,10 +783,6 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, if (pe->mve_number < 0) return -ENXIO; - /* Force 32-bit MSI on some broken devices */ - if (pdn && pdn->force_32bit_msi) - is_64 = 0; - /* Assign XIVE to PE */ rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); if (rc) { @@ -1030,7 +1035,7 @@ static int pnv_pci_enable_device_hook(struct pci_dev *dev) if (!phb->initialized) return 0; - pdn = pci_get_pdn(dev); + pdn = pnv_ioda_get_pdn(dev); if (!pdn || pdn->pe_number == IODA_INVALID_PE) return -EINVAL; @@ -1043,12 +1048,6 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus, return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; } -static void pnv_pci_ioda_shutdown(struct pnv_phb *phb) -{ - opal_pci_reset(phb->opal_id, OPAL_PCI_IODA_TABLE_RESET, - OPAL_ASSERT_RESET); -} - void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type) { struct pci_controller *hose; @@ -1179,9 +1178,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type) /* Setup TCEs */ phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; - /* Setup shutdown function for kexec */ - phb->shutdown = pnv_pci_ioda_shutdown; - /* Setup MSI support */ pnv_pci_init_ioda_msis(phb); diff --git a/trunk/arch/powerpc/platforms/powernv/pci.c b/trunk/arch/powerpc/platforms/powernv/pci.c index 277343cc6a3d..55dfca844ddf 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci.c +++ b/trunk/arch/powerpc/platforms/powernv/pci.c @@ -47,10 +47,6 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type) { struct pci_controller *hose = pci_bus_to_host(pdev->bus); struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn = pci_get_pdn(pdev); - - if (pdn && pdn->force_32bit_msi && !phb->msi32_support) - return -ENODEV; return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV; } @@ -371,7 +367,7 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) while (npages--) *(tcep++) = 0; - if (tbl->it_type & TCE_PCI_SWINV_FREE) + if (tbl->it_type & TCE_PCI_SWINV_CREATE) pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1); } @@ -454,18 +450,6 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev) pnv_pci_dma_fallback_setup(hose, pdev); } -void pnv_pci_shutdown(void) -{ - struct pci_controller *hose; - - list_for_each_entry(hose, &hose_list, list_node) { - struct pnv_phb *phb = hose->private_data; - - if (phb && phb->shutdown) - phb->shutdown(phb); - } -} - /* Fixup wrong class code in p7ioc and p8 root complex */ static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) { diff --git a/trunk/arch/powerpc/platforms/powernv/pci.h b/trunk/arch/powerpc/platforms/powernv/pci.h index 25d76c4df50b..48dc4bb856a1 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci.h +++ b/trunk/arch/powerpc/platforms/powernv/pci.h @@ -86,7 +86,6 @@ struct pnv_phb { void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); void (*fixup_phb)(struct pci_controller *hose); u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); - void (*shutdown)(struct pnv_phb *phb); union { struct { @@ -159,5 +158,4 @@ extern void pnv_pci_init_ioda_hub(struct device_node *np); extern void pnv_pci_init_ioda2_phb(struct device_node *np); extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, u64 *startp, u64 *endp); - #endif /* __POWERNV_PCI_H */ diff --git a/trunk/arch/powerpc/platforms/powernv/powernv.h b/trunk/arch/powerpc/platforms/powernv/powernv.h index a1c6f83fc391..8a9df7f9667e 100644 --- a/trunk/arch/powerpc/platforms/powernv/powernv.h +++ b/trunk/arch/powerpc/platforms/powernv/powernv.h @@ -9,10 +9,8 @@ static inline void pnv_smp_init(void) { } #ifdef CONFIG_PCI extern void pnv_pci_init(void); -extern void pnv_pci_shutdown(void); #else static inline void pnv_pci_init(void) { } -static inline void pnv_pci_shutdown(void) { } #endif #endif /* _POWERNV_H */ diff --git a/trunk/arch/powerpc/platforms/powernv/setup.c b/trunk/arch/powerpc/platforms/powernv/setup.c index d4459bfc92f7..db1ad1c8f68f 100644 --- a/trunk/arch/powerpc/platforms/powernv/setup.c +++ b/trunk/arch/powerpc/platforms/powernv/setup.c @@ -78,9 +78,7 @@ static void pnv_show_cpuinfo(struct seq_file *m) if (root) model = of_get_property(root, "model", NULL); seq_printf(m, "machine\t\t: PowerNV %s\n", model); - if (firmware_has_feature(FW_FEATURE_OPALv3)) - seq_printf(m, "firmware\t: OPAL v3\n"); - else if (firmware_has_feature(FW_FEATURE_OPALv2)) + if (firmware_has_feature(FW_FEATURE_OPALv2)) seq_printf(m, "firmware\t: OPAL v2\n"); else if (firmware_has_feature(FW_FEATURE_OPAL)) seq_printf(m, "firmware\t: OPAL v1\n"); @@ -128,17 +126,6 @@ static void pnv_progress(char *s, unsigned short hex) { } -static void pnv_shutdown(void) -{ - /* Let the PCI code clear up IODA tables */ - pnv_pci_shutdown(); - - /* And unregister all OPAL interrupts so they don't fire - * up while we kexec - */ - opal_shutdown(); -} - #ifdef CONFIG_KEXEC static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) { @@ -200,7 +187,6 @@ define_machine(powernv) { .init_IRQ = pnv_init_IRQ, .show_cpuinfo = pnv_show_cpuinfo, .progress = pnv_progress, - .machine_shutdown = pnv_shutdown, .power_save = power7_idle, .calibrate_decr = generic_calibrate_decr, #ifdef CONFIG_KEXEC diff --git a/trunk/arch/powerpc/platforms/powernv/smp.c b/trunk/arch/powerpc/platforms/powernv/smp.c index 88c9459c3e07..6a3ecca5b725 100644 --- a/trunk/arch/powerpc/platforms/powernv/smp.c +++ b/trunk/arch/powerpc/platforms/powernv/smp.c @@ -71,68 +71,18 @@ int pnv_smp_kick_cpu(int nr) BUG_ON(nr < 0 || nr >= NR_CPUS); - /* - * If we already started or OPALv2 is not supported, we just - * kick the CPU via the PACA + /* On OPAL v2 the CPU are still spinning inside OPAL itself, + * get them back now */ - if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2)) - goto kick; - - /* - * At this point, the CPU can either be spinning on the way in - * from kexec or be inside OPAL waiting to be started for the - * first time. OPAL v3 allows us to query OPAL to know if it - * has the CPUs, so we do that - */ - if (firmware_has_feature(FW_FEATURE_OPALv3)) { - uint8_t status; - - rc = opal_query_cpu_status(pcpu, &status); + if (!paca[nr].cpu_start && firmware_has_feature(FW_FEATURE_OPALv2)) { + pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); + rc = opal_start_cpu(pcpu, start_here); if (rc != OPAL_SUCCESS) { - pr_warn("OPAL Error %ld querying CPU %d state\n", + pr_warn("OPAL Error %ld starting CPU %d\n", rc, nr); return -ENODEV; } - - /* - * Already started, just kick it, probably coming from - * kexec and spinning - */ - if (status == OPAL_THREAD_STARTED) - goto kick; - - /* - * Available/inactive, let's kick it - */ - if (status == OPAL_THREAD_INACTIVE) { - pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", - nr, pcpu); - rc = opal_start_cpu(pcpu, start_here); - if (rc != OPAL_SUCCESS) { - pr_warn("OPAL Error %ld starting CPU %d\n", - rc, nr); - return -ENODEV; - } - } else { - /* - * An unavailable CPU (or any other unknown status) - * shouldn't be started. It should also - * not be in the possible map but currently it can - * happen - */ - pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable" - " (status %d)...\n", nr, pcpu, status); - return -ENODEV; - } - } else { - /* - * On OPAL v2, we just kick it and hope for the best, - * we must not test the error from opal_start_cpu() or - * we would fail to get CPUs from kexec. - */ - opal_start_cpu(pcpu, start_here); } - kick: return smp_generic_kick_cpu(nr); } diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig index 023b288f895b..9a0941bc4d31 100644 --- a/trunk/arch/powerpc/platforms/pseries/Kconfig +++ b/trunk/arch/powerpc/platforms/pseries/Kconfig @@ -18,7 +18,6 @@ config PPC_PSERIES select PPC_PCI_CHOICE if EXPERT select ZLIB_DEFLATE select PPC_DOORBELL - select HAVE_CONTEXT_TRACKING default y config PPC_SPLPAR diff --git a/trunk/arch/powerpc/platforms/pseries/msi.c b/trunk/arch/powerpc/platforms/pseries/msi.c index 6d2f0abce6fa..420524e6f8c9 100644 --- a/trunk/arch/powerpc/platforms/pseries/msi.c +++ b/trunk/arch/powerpc/platforms/pseries/msi.c @@ -26,6 +26,26 @@ static int query_token, change_token; #define RTAS_CHANGE_MSIX_FN 4 #define RTAS_CHANGE_32MSI_FN 5 +static struct pci_dn *get_pdn(struct pci_dev *pdev) +{ + struct device_node *dn; + struct pci_dn *pdn; + + dn = pci_device_to_OF_node(pdev); + if (!dn) { + dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n"); + return NULL; + } + + pdn = PCI_DN(dn); + if (!pdn) { + dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n"); + return NULL; + } + + return pdn; +} + /* RTAS Helpers */ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) @@ -71,7 +91,7 @@ static void rtas_disable_msi(struct pci_dev *pdev) { struct pci_dn *pdn; - pdn = pci_get_pdn(pdev); + pdn = get_pdn(pdev); if (!pdn) return; @@ -132,7 +152,7 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) struct pci_dn *pdn; const u32 *req_msi; - pdn = pci_get_pdn(pdev); + pdn = get_pdn(pdev); if (!pdn) return -ENODEV; @@ -374,23 +394,6 @@ static int check_msix_entries(struct pci_dev *pdev) return 0; } -static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev) -{ - u32 addr_hi, addr_lo; - - /* - * We should only get in here for IODA1 configs. This is based on the - * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS - * support, and we are in a PCIe Gen2 slot. - */ - dev_info(&pdev->dev, - "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n"); - pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi); - addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4); - pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo); - pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0); -} - static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) { struct pci_dn *pdn; @@ -398,9 +401,8 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) struct msi_desc *entry; struct msi_msg msg; int nvec = nvec_in; - int use_32bit_msi_hack = 0; - pdn = pci_get_pdn(pdev); + pdn = get_pdn(pdev); if (!pdn) return -ENODEV; @@ -426,31 +428,15 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) */ again: if (type == PCI_CAP_ID_MSI) { - if (pdn->force_32bit_msi) { + if (pdn->force_32bit_msi) rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); - if (rc < 0) { - /* - * We only want to run the 32 bit MSI hack below if - * the max bus speed is Gen2 speed - */ - if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) - return rc; - - use_32bit_msi_hack = 1; - } - } else - rc = -1; - - if (rc < 0) + else rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); - if (rc < 0) { + if (rc < 0 && !pdn->force_32bit_msi) { pr_debug("rtas_msi: trying the old firmware call.\n"); rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); } - - if (use_32bit_msi_hack && rc > 0) - rtas_hack_32bit_msi_gen2(pdev); } else rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); @@ -532,3 +518,12 @@ static int rtas_msi_init(void) } arch_initcall(rtas_msi_init); +static void quirk_radeon(struct pci_dev *dev) +{ + struct pci_dn *pdn = get_pdn(dev); + + if (pdn) + pdn->force_32bit_msi = 1; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon); diff --git a/trunk/arch/powerpc/platforms/pseries/suspend.c b/trunk/arch/powerpc/platforms/pseries/suspend.c index 5f997e79d570..47226e04126d 100644 --- a/trunk/arch/powerpc/platforms/pseries/suspend.c +++ b/trunk/arch/powerpc/platforms/pseries/suspend.c @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include @@ -127,15 +126,11 @@ static ssize_t store_hibernate(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - cpumask_var_t offline_mask; int rc; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) - return -ENOMEM; - stream_id = simple_strtoul(buf, NULL, 16); do { @@ -145,32 +140,15 @@ static ssize_t store_hibernate(struct device *dev, } while (rc == -EAGAIN); if (!rc) { - /* All present CPUs must be online */ - cpumask_andnot(offline_mask, cpu_present_mask, - cpu_online_mask); - rc = rtas_online_cpus_mask(offline_mask); - if (rc) { - pr_err("%s: Could not bring present CPUs online.\n", - __func__); - goto out; - } - stop_topology_update(); rc = pm_suspend(PM_SUSPEND_MEM); start_topology_update(); - - /* Take down CPUs not online prior to suspend */ - if (!rtas_offline_cpus_mask(offline_mask)) - pr_warn("%s: Could not restore CPUs to offline " - "state.\n", __func__); } stream_id = 0; if (!rc) rc = count; -out: - free_cpumask_var(offline_mask); return rc; } diff --git a/trunk/arch/powerpc/platforms/wsp/ics.c b/trunk/arch/powerpc/platforms/wsp/ics.c index 2d3b1dd9571d..97fe82ee8633 100644 --- a/trunk/arch/powerpc/platforms/wsp/ics.c +++ b/trunk/arch/powerpc/platforms/wsp/ics.c @@ -361,7 +361,7 @@ static int wsp_chip_set_affinity(struct irq_data *d, xive = xive_set_server(xive, get_irq_server(ics, hw_irq)); wsp_ics_set_xive(ics, hw_irq, xive); - return IRQ_SET_MASK_OK; + return 0; } static struct irq_chip wsp_irq_chip = { diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index 99464a7bdb3b..b0a518e97599 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -64,8 +64,6 @@ endif obj-$(CONFIG_PPC_SCOM) += scom.o -obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS) += udbg_memcons.o - subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PPC_XICS) += xics/ diff --git a/trunk/arch/powerpc/sysdev/ehv_pic.c b/trunk/arch/powerpc/sysdev/ehv_pic.c index 9cd0e60716fe..6e0e1005227f 100644 --- a/trunk/arch/powerpc/sysdev/ehv_pic.c +++ b/trunk/arch/powerpc/sysdev/ehv_pic.c @@ -81,7 +81,7 @@ int ehv_pic_set_affinity(struct irq_data *d, const struct cpumask *dest, ev_int_set_config(src, config, prio, cpuid); spin_unlock_irqrestore(&ehv_pic_lock, flags); - return IRQ_SET_MASK_OK; + return 0; } static unsigned int ehv_pic_type_to_vecpri(unsigned int type) diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 0a13ecb270c7..ee21b5e71aec 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -836,7 +836,7 @@ int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, mpic_physmask(mask)); } - return IRQ_SET_MASK_OK; + return 0; } static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) diff --git a/trunk/arch/powerpc/sysdev/udbg_memcons.c b/trunk/arch/powerpc/sysdev/udbg_memcons.c deleted file mode 100644 index ce5a7b489e4b..000000000000 --- a/trunk/arch/powerpc/sysdev/udbg_memcons.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * A udbg backend which logs messages and reads input from in memory - * buffers. - * - * The console output can be read from memcons_output which is a - * circular buffer whose next write position is stored in memcons.output_pos. - * - * Input may be passed by writing into the memcons_input buffer when it is - * empty. The input buffer is empty when both input_pos == input_start and - * *input_start == '\0'. - * - * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp - * Copyright (C) 2013 Alistair Popple, IBM Corp - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -struct memcons { - char *output_start; - char *output_pos; - char *output_end; - char *input_start; - char *input_pos; - char *input_end; -}; - -static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE]; -static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE]; - -struct memcons memcons = { - .output_start = memcons_output, - .output_pos = memcons_output, - .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE], - .input_start = memcons_input, - .input_pos = memcons_input, - .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE], -}; - -void memcons_putc(char c) -{ - char *new_output_pos; - - *memcons.output_pos = c; - wmb(); - new_output_pos = memcons.output_pos + 1; - if (new_output_pos >= memcons.output_end) - new_output_pos = memcons.output_start; - - memcons.output_pos = new_output_pos; -} - -int memcons_getc_poll(void) -{ - char c; - char *new_input_pos; - - if (*memcons.input_pos) { - c = *memcons.input_pos; - - new_input_pos = memcons.input_pos + 1; - if (new_input_pos >= memcons.input_end) - new_input_pos = memcons.input_start; - else if (*new_input_pos == '\0') - new_input_pos = memcons.input_start; - - *memcons.input_pos = '\0'; - wmb(); - memcons.input_pos = new_input_pos; - return c; - } - - return -1; -} - -int memcons_getc(void) -{ - int c; - - while (1) { - c = memcons_getc_poll(); - if (c == -1) - cpu_relax(); - else - break; - } - - return c; -} - -void udbg_init_memcons(void) -{ - udbg_putc = memcons_putc; - udbg_getc = memcons_getc; - udbg_getc_poll = memcons_getc_poll; -} diff --git a/trunk/arch/powerpc/sysdev/xics/ics-opal.c b/trunk/arch/powerpc/sysdev/xics/ics-opal.c index 39d72212655e..f7e8609df0d5 100644 --- a/trunk/arch/powerpc/sysdev/xics/ics-opal.c +++ b/trunk/arch/powerpc/sysdev/xics/ics-opal.c @@ -148,7 +148,7 @@ static int ics_opal_set_affinity(struct irq_data *d, __func__, d->irq, hw_irq, server, rc); return -1; } - return IRQ_SET_MASK_OK; + return 0; } static struct irq_chip ics_opal_irq_chip = { diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index da183c5a103c..2c9789da0e24 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -98,6 +98,7 @@ config S390 select CLONE_BACKWARDS2 select GENERIC_CLOCKEVENTS select GENERIC_CPU_DEVICES if !SMP + select GENERIC_KERNEL_THREAD select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL_OLD select HAVE_ALIGNED_STRUCT_PAGE if SLUB diff --git a/trunk/arch/s390/include/asm/ftrace.h b/trunk/arch/s390/include/asm/ftrace.h index bf246dae1367..b7931faaef6d 100644 --- a/trunk/arch/s390/include/asm/ftrace.h +++ b/trunk/arch/s390/include/asm/ftrace.h @@ -9,6 +9,11 @@ struct dyn_arch_ftrace { }; #define MCOUNT_ADDR ((long)_mcount) +#ifdef CONFIG_64BIT +#define MCOUNT_INSN_SIZE 12 +#else +#define MCOUNT_INSN_SIZE 20 +#endif static inline unsigned long ftrace_call_adjust(unsigned long addr) { @@ -16,11 +21,4 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) } #endif /* __ASSEMBLY__ */ - -#ifdef CONFIG_64BIT -#define MCOUNT_INSN_SIZE 12 -#else -#define MCOUNT_INSN_SIZE 22 -#endif - #endif /* _ASM_S390_FTRACE_H */ diff --git a/trunk/arch/s390/include/asm/page.h b/trunk/arch/s390/include/asm/page.h index 5d64fb7619cc..75ce9b065f9f 100644 --- a/trunk/arch/s390/include/asm/page.h +++ b/trunk/arch/s390/include/asm/page.h @@ -32,7 +32,7 @@ void storage_key_init_range(unsigned long start, unsigned long end); -static inline unsigned long pfmf(unsigned long function, unsigned long address) +static unsigned long pfmf(unsigned long function, unsigned long address) { asm volatile( " .insn rre,0xb9af0000,%[function],%[address]" @@ -44,13 +44,17 @@ static inline unsigned long pfmf(unsigned long function, unsigned long address) static inline void clear_page(void *page) { - register unsigned long reg1 asm ("1") = 0; - register void *reg2 asm ("2") = page; - register unsigned long reg3 asm ("3") = 4096; - asm volatile( - " mvcl 2,0" - : "+d" (reg2), "+d" (reg3) : "d" (reg1) - : "memory", "cc"); + if (MACHINE_HAS_PFMF) { + pfmf(0x10000, (unsigned long)page); + } else { + register unsigned long reg1 asm ("1") = 0; + register void *reg2 asm ("2") = page; + register unsigned long reg3 asm ("3") = 4096; + asm volatile( + " mvcl 2,0" + : "+d" (reg2), "+d" (reg3) : "d" (reg1) + : "memory", "cc"); + } } static inline void copy_page(void *to, void *from) diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index 0f0de30e3e3f..4105b8221fdd 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -306,7 +306,7 @@ extern unsigned long MODULES_END; #define RCP_HC_BIT 0x00200000UL #define RCP_GR_BIT 0x00040000UL #define RCP_GC_BIT 0x00020000UL -#define RCP_IN_BIT 0x00002000UL /* IPTE notify bit */ +#define RCP_IN_BIT 0x00008000UL /* IPTE notify bit */ /* User dirty / referenced bit for KVM's migration feature */ #define KVM_UR_BIT 0x00008000UL @@ -374,7 +374,7 @@ extern unsigned long MODULES_END; #define RCP_HC_BIT 0x0020000000000000UL #define RCP_GR_BIT 0x0004000000000000UL #define RCP_GC_BIT 0x0002000000000000UL -#define RCP_IN_BIT 0x0000200000000000UL /* IPTE notify bit */ +#define RCP_IN_BIT 0x0000800000000000UL /* IPTE notify bit */ /* User dirty / referenced bit for KVM's migration feature */ #define KVM_UR_BIT 0x0000800000000000UL diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index be87d3e05a5b..7f4a4a8c847c 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -1862,8 +1862,6 @@ void print_fn_code(unsigned char *code, unsigned long len) while (len) { ptr = buffer; opsize = insn_length(*code); - if (opsize > len) - break; ptr += sprintf(ptr, "%p: ", code); for (i = 0; i < opsize; i++) ptr += sprintf(ptr, "%02x", code[i]); diff --git a/trunk/arch/s390/kernel/ftrace.c b/trunk/arch/s390/kernel/ftrace.c index e3043aef87a9..78bdf0e5dff7 100644 --- a/trunk/arch/s390/kernel/ftrace.c +++ b/trunk/arch/s390/kernel/ftrace.c @@ -16,6 +16,12 @@ #include #include +#ifdef CONFIG_64BIT +#define MCOUNT_OFFSET_RET 12 +#else +#define MCOUNT_OFFSET_RET 22 +#endif + #ifdef CONFIG_DYNAMIC_FTRACE void ftrace_disable_code(void); @@ -149,10 +155,9 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent, if (unlikely(atomic_read(¤t->tracing_graph_pause))) goto out; - ip = (ip & PSW_ADDR_INSN) - MCOUNT_INSN_SIZE; if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) goto out; - trace.func = ip; + trace.func = (ip & PSW_ADDR_INSN) - MCOUNT_OFFSET_RET; /* Only trace if the calling function expects to. */ if (!ftrace_graph_entry(&trace)) { current->curr_ret_stack--; diff --git a/trunk/arch/s390/kernel/mcount.S b/trunk/arch/s390/kernel/mcount.S index 08dcf21cb8df..4567ce20d900 100644 --- a/trunk/arch/s390/kernel/mcount.S +++ b/trunk/arch/s390/kernel/mcount.S @@ -7,7 +7,6 @@ #include #include -#include .section .kprobes.text, "ax" @@ -34,7 +33,6 @@ ENTRY(ftrace_caller) la %r2,0(%r14) st %r0,__SF_BACKCHAIN(%r15) la %r3,0(%r3) - ahi %r2,-MCOUNT_INSN_SIZE l %r14,0b-0b(%r1) l %r14,0(%r14) basr %r14,%r14 diff --git a/trunk/arch/s390/kernel/mcount64.S b/trunk/arch/s390/kernel/mcount64.S index 1c52eae3396a..11332193db30 100644 --- a/trunk/arch/s390/kernel/mcount64.S +++ b/trunk/arch/s390/kernel/mcount64.S @@ -7,7 +7,6 @@ #include #include -#include .section .kprobes.text, "ax" @@ -30,7 +29,6 @@ ENTRY(ftrace_caller) stg %r1,__SF_BACKCHAIN(%r15) lgr %r2,%r14 lg %r3,168(%r15) - aghi %r2,-MCOUNT_INSN_SIZE larl %r14,ftrace_trace_function lg %r14,0(%r14) basr %r14,%r14 diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 05674b669001..8074cb4b7cbf 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -645,7 +645,7 @@ static int __cpuinit __smp_rescan_cpus(struct sclp_cpu_info *info, continue; pcpu = pcpu_devices + cpu; pcpu->address = info->cpu[i].address; - pcpu->state = (i >= info->configured) ? + pcpu->state = (cpu >= info->configured) ? CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); set_cpu_present(cpu, true); diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 18dc417aaf79..7805ddca833d 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -677,7 +677,8 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long start, unsigned long len) break; } /* Get the page mapped */ - if (fixup_user_fault(current, gmap->mm, addr, FAULT_FLAG_WRITE)) { + if (get_user_pages(current, gmap->mm, addr, 1, 1, 0, + NULL, NULL) != 1) { rc = -EFAULT; break; } diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 685692c94f05..6a154a91c7e7 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -108,6 +108,7 @@ config X86 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC) select GENERIC_TIME_VSYSCALL if X86_64 select KTIME_SCALAR if X86_32 + select ALWAYS_USE_PERSISTENT_CLOCK select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select HAVE_CONTEXT_TRACKING if X86_64 diff --git a/trunk/arch/x86/kernel/head64.c b/trunk/arch/x86/kernel/head64.c index 55b67614ed94..dab95a85f7f8 100644 --- a/trunk/arch/x86/kernel/head64.c +++ b/trunk/arch/x86/kernel/head64.c @@ -34,7 +34,7 @@ extern pgd_t early_level4_pgt[PTRS_PER_PGD]; extern pmd_t early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD]; static unsigned int __initdata next_early_pgt = 2; -pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); +pmdval_t __initdata early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); /* Wipe all early page tables except for the kernel symbol map */ static void __init reset_early_page_tables(void) diff --git a/trunk/arch/x86/kernel/microcode_intel_early.c b/trunk/arch/x86/kernel/microcode_intel_early.c index 2e9e12871c2b..d893e8ed8ac9 100644 --- a/trunk/arch/x86/kernel/microcode_intel_early.c +++ b/trunk/arch/x86/kernel/microcode_intel_early.c @@ -487,7 +487,6 @@ static inline void show_saved_mc(void) #endif #if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU) -static DEFINE_MUTEX(x86_cpu_microcode_mutex); /* * Save this mc into mc_saved_data. So it will be loaded early when a CPU is * hot added or resumes. @@ -508,7 +507,7 @@ int save_mc_for_early(u8 *mc) * Hold hotplug lock so mc_saved_data is not accessed by a CPU in * hotplug. */ - mutex_lock(&x86_cpu_microcode_mutex); + cpu_hotplug_driver_lock(); mc_saved_count_init = mc_saved_data.mc_saved_count; mc_saved_count = mc_saved_data.mc_saved_count; @@ -545,7 +544,7 @@ int save_mc_for_early(u8 *mc) } out: - mutex_unlock(&x86_cpu_microcode_mutex); + cpu_hotplug_driver_unlock(); return ret; } diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index 4e7a37ff03ab..607af0d4d5ef 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -312,8 +312,6 @@ void arch_cpu_idle(void) { if (cpuidle_idle_call()) x86_idle(); - else - local_irq_enable(); } /* @@ -370,6 +368,9 @@ void amd_e400_remove_cpu(int cpu) */ static void amd_e400_idle(void) { + if (need_resched()) + return; + if (!amd_e400_c1e_detected) { u32 lo, hi; diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index eaac1743def7..fdc5dca14fb3 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -359,17 +359,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, } /* - * We need to iterate through the E820 memory map and create direct mappings - * for only E820_RAM and E820_KERN_RESERVED regions. We cannot simply - * create direct mappings for all pfns from [0 to max_low_pfn) and - * [4GB to max_pfn) because of possible memory holes in high addresses - * that cannot be marked as UC by fixed/variable range MTRRs. - * Depending on the alignment of E820 ranges, this may possibly result - * in using smaller size (i.e. 4K instead of 2M or 1G) page tables. - * - * init_mem_mapping() calls init_range_memory_mapping() with big range. - * That range would have hole in the middle or ends, and only ram parts - * will be mapped in init_range_memory_mapping(). + * would have hole in the middle or ends, and only ram parts will be mapped. */ static unsigned long __init init_range_memory_mapping( unsigned long r_start, @@ -429,13 +419,6 @@ void __init init_mem_mapping(void) max_pfn_mapped = 0; /* will get exact value next */ min_pfn_mapped = real_end >> PAGE_SHIFT; last_start = start = real_end; - - /* - * We start from the top (end of memory) and go to the bottom. - * The memblock_find_in_range() gets us a block of RAM from the - * end of RAM in [min_pfn_mapped, max_pfn_mapped) used as new pages - * for page table. - */ while (last_start > ISA_END_ADDRESS) { if (last_start > step_size) { start = round_down(last_start - 1, step_size); diff --git a/trunk/arch/x86/pci/mrst.c b/trunk/arch/x86/pci/mrst.c index 6eb18c42a28a..0e0fabf17342 100644 --- a/trunk/arch/x86/pci/mrst.c +++ b/trunk/arch/x86/pci/mrst.c @@ -141,6 +141,11 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn, */ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) { + if (bus == 0 && (devfn == PCI_DEVFN(2, 0) + || devfn == PCI_DEVFN(0, 0) + || devfn == PCI_DEVFN(3, 0))) + return 1; + /* This is a workaround for A0 LNC bug where PCI status register does * not have new CAP bit set. can not be written by SW either. * @@ -150,10 +155,7 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) */ if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE) return 0; - if (bus == 0 && (devfn == PCI_DEVFN(2, 0) - || devfn == PCI_DEVFN(0, 0) - || devfn == PCI_DEVFN(3, 0))) - return 1; + return 0; /* langwell on others */ } diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index 4f4e741d34b2..00d2efd674df 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #ifdef CONFIG_ACPI_PROCFS_POWER #include #include @@ -76,8 +74,6 @@ static int acpi_ac_resume(struct device *dev); #endif static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); -static int ac_sleep_before_get_state_ms; - static struct acpi_driver acpi_ac_driver = { .name = "ac", .class = ACPI_AC_CLASS, @@ -256,16 +252,6 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) case ACPI_AC_NOTIFY_STATUS: case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: - /* - * A buggy BIOS may notify AC first and then sleep for - * a specific time before doing actual operations in the - * EC event handler (_Qxx). This will cause the AC state - * reported by the ACPI event to be incorrect, so wait for a - * specific time for the EC event handler to make progress. - */ - if (ac_sleep_before_get_state_ms > 0) - msleep(ac_sleep_before_get_state_ms); - acpi_ac_get_state(ac); acpi_bus_generate_proc_event(device, event, (u32) ac->state); acpi_bus_generate_netlink_event(device->pnp.device_class, @@ -278,24 +264,6 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) return; } -static int thinkpad_e530_quirk(const struct dmi_system_id *d) -{ - ac_sleep_before_get_state_ms = 1000; - return 0; -} - -static struct dmi_system_id ac_dmi_table[] = { - { - .callback = thinkpad_e530_quirk, - .ident = "thinkpad e530", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"), - }, - }, - {}, -}; - static int acpi_ac_add(struct acpi_device *device) { int result = 0; @@ -344,7 +312,6 @@ static int acpi_ac_add(struct acpi_device *device) kfree(ac); } - dmi_check_system(ac_dmi_table); return result; } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index edc00818c803..d45b2871d33b 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -223,7 +223,7 @@ static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) static int ec_poll(struct acpi_ec *ec) { unsigned long flags; - int repeat = 5; /* number of command restarts */ + int repeat = 2; /* number of command restarts */ while (repeat--) { unsigned long delay = jiffies + msecs_to_jiffies(ec_delay); @@ -241,6 +241,8 @@ static int ec_poll(struct acpi_ec *ec) } advance_transaction(ec, acpi_ec_read_status(ec)); } while (time_before(jiffies, delay)); + if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) + break; pr_debug(PREFIX "controller reset, restart transaction\n"); spin_lock_irqsave(&ec->lock, flags); start_transaction(ec); diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index e427dc516c76..1dd6f6c85874 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -641,9 +641,7 @@ static void _handle_hotplug_event_root(struct work_struct *work) /* bus enumerate */ printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__, (char *)buffer.pointer); - if (root) - acpiphp_check_host_bridge(handle); - else + if (!root) handle_root_bridge_insertion(handle); break; diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index c266cdc11784..bec717ffd25f 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -95,6 +95,9 @@ static const struct acpi_device_id processor_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); +static SIMPLE_DEV_PM_OPS(acpi_processor_pm, + acpi_processor_suspend, acpi_processor_resume); + static struct acpi_driver acpi_processor_driver = { .name = "processor", .class = ACPI_PROCESSOR_CLASS, @@ -104,6 +107,7 @@ static struct acpi_driver acpi_processor_driver = { .remove = acpi_processor_remove, .notify = acpi_processor_notify, }, + .drv.pm = &acpi_processor_pm, }; #define INSTALL_NOTIFY_HANDLER 1 @@ -930,8 +934,6 @@ static int __init acpi_processor_init(void) if (result < 0) return result; - acpi_processor_syscore_init(); - acpi_processor_install_hotplug_notify(); acpi_thermal_cpufreq_init(); @@ -954,8 +956,6 @@ static void __exit acpi_processor_exit(void) acpi_processor_uninstall_hotplug_notify(); - acpi_processor_syscore_exit(); - acpi_bus_unregister_driver(&acpi_processor_driver); return; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index eb133c77aadb..f0df2c9434d2 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -34,7 +34,6 @@ #include /* need_resched() */ #include #include -#include /* * Include the apic definitions for x86 to have the APIC timer related defines @@ -211,41 +210,33 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, #endif -#ifdef CONFIG_PM_SLEEP static u32 saved_bm_rld; -int acpi_processor_suspend(void) +static void acpi_idle_bm_rld_save(void) { acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); - return 0; } - -void acpi_processor_resume(void) +static void acpi_idle_bm_rld_restore(void) { u32 resumed_bm_rld; acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); - if (resumed_bm_rld == saved_bm_rld) - return; - acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); + if (resumed_bm_rld != saved_bm_rld) + acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); } -static struct syscore_ops acpi_processor_syscore_ops = { - .suspend = acpi_processor_suspend, - .resume = acpi_processor_resume, -}; - -void acpi_processor_syscore_init(void) +int acpi_processor_suspend(struct device *dev) { - register_syscore_ops(&acpi_processor_syscore_ops); + acpi_idle_bm_rld_save(); + return 0; } -void acpi_processor_syscore_exit(void) +int acpi_processor_resume(struct device *dev) { - unregister_syscore_ops(&acpi_processor_syscore_ops); + acpi_idle_bm_rld_restore(); + return 0; } -#endif /* CONFIG_PM_SLEEP */ #if defined(CONFIG_X86) static void tsc_check_state(int state) diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index c1bc608339a6..fe158fd4f1df 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -1785,7 +1785,7 @@ static void acpi_scan_init_hotplug(acpi_handle handle, int type) acpi_set_pnp_ids(handle, &pnp, type); if (!pnp.type.hardware_id) - goto out; + return; /* * This relies on the fact that acpi_install_notify_handler() will not @@ -1800,7 +1800,6 @@ static void acpi_scan_init_hotplug(acpi_handle handle, int type) } } -out: acpi_free_pnp_ids(&pnp); } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 5b32e15a65ce..c3932d0876e0 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -456,14 +456,6 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"), }, }, - { - .callback = video_ignore_initial_backlight, - .ident = "HP 1000 Notebook PC", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"), - }, - }, {} }; diff --git a/trunk/drivers/ata/pata_ep93xx.c b/trunk/drivers/ata/pata_ep93xx.c index 980b88e109fc..c1bfaf43d109 100644 --- a/trunk/drivers/ata/pata_ep93xx.c +++ b/trunk/drivers/ata/pata_ep93xx.c @@ -933,6 +933,11 @@ static int ep93xx_pata_probe(struct platform_device *pdev) } mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + err = -ENXIO; + goto err_rel_gpio; + } + ide_base = devm_ioremap_resource(&pdev->dev, mem_res); if (IS_ERR(ide_base)) { err = PTR_ERR(ide_base); diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index d414331b480e..1a68f947ded8 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -1295,7 +1295,6 @@ int subsys_virtual_register(struct bus_type *subsys, return subsys_register(subsys, groups, virtual_dir); } -EXPORT_SYMBOL_GPL(subsys_virtual_register); int __init buses_init(void) { diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 2499cefdcdf2..016312437577 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -572,11 +572,9 @@ int device_create_file(struct device *dev, if (dev) { WARN(((attr->attr.mode & S_IWUGO) && !attr->store), - "Attribute %s: write permission without 'store'\n", - attr->attr.name); + "Write permission without 'store'\n"); WARN(((attr->attr.mode & S_IRUGO) && !attr->show), - "Attribute %s: read permission without 'show'\n", - attr->attr.name); + "Read permission without 'show'\n"); error = sysfs_create_file(&dev->kobj, &attr->attr); } diff --git a/trunk/drivers/base/power/common.c b/trunk/drivers/base/power/common.c index 5da914041305..39c32529b833 100644 --- a/trunk/drivers/base/power/common.c +++ b/trunk/drivers/base/power/common.c @@ -61,24 +61,24 @@ EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); int dev_pm_put_subsys_data(struct device *dev) { struct pm_subsys_data *psd; - int ret = 1; + int ret = 0; spin_lock_irq(&dev->power.lock); psd = dev_to_psd(dev); - if (!psd) + if (!psd) { + ret = -EINVAL; goto out; + } if (--psd->refcount == 0) { dev->power.subsys_data = NULL; - } else { - psd = NULL; - ret = 0; + kfree(psd); + ret = 1; } out: spin_unlock_irq(&dev->power.lock); - kfree(psd); return ret; } diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index d6d314027b5d..ca63104136e0 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -55,39 +55,6 @@ #define SECTOR_SHIFT 9 #define SECTOR_SIZE (1ULL << SECTOR_SHIFT) -/* - * Increment the given counter and return its updated value. - * If the counter is already 0 it will not be incremented. - * If the counter is already at its maximum value returns - * -EINVAL without updating it. - */ -static int atomic_inc_return_safe(atomic_t *v) -{ - unsigned int counter; - - counter = (unsigned int)__atomic_add_unless(v, 1, 0); - if (counter <= (unsigned int)INT_MAX) - return (int)counter; - - atomic_dec(v); - - return -EINVAL; -} - -/* Decrement the counter. Return the resulting value, or -EINVAL */ -static int atomic_dec_return_safe(atomic_t *v) -{ - int counter; - - counter = atomic_dec_return(v); - if (counter >= 0) - return counter; - - atomic_inc(v); - - return -EINVAL; -} - #define RBD_DRV_NAME "rbd" #define RBD_DRV_NAME_LONG "rbd (rados block device)" @@ -133,20 +100,21 @@ static int atomic_dec_return_safe(atomic_t *v) * block device image metadata (in-memory version) */ struct rbd_image_header { - /* These six fields never change for a given rbd image */ + /* These four fields never change for a given rbd image */ char *object_prefix; + u64 features; __u8 obj_order; __u8 crypt_type; __u8 comp_type; - u64 stripe_unit; - u64 stripe_count; - u64 features; /* Might be changeable someday? */ /* The remaining fields need to be updated occasionally */ u64 image_size; struct ceph_snap_context *snapc; - char *snap_names; /* format 1 only */ - u64 *snap_sizes; /* format 1 only */ + char *snap_names; + u64 *snap_sizes; + + u64 stripe_unit; + u64 stripe_count; }; /* @@ -257,7 +225,6 @@ struct rbd_obj_request { }; }; struct page **copyup_pages; - u32 copyup_page_count; struct ceph_osd_request *osd_req; @@ -290,7 +257,6 @@ struct rbd_img_request { struct rbd_obj_request *obj_request; /* obj req initiator */ }; struct page **copyup_pages; - u32 copyup_page_count; spinlock_t completion_lock;/* protects next_completion */ u32 next_completion; rbd_img_callback_t callback; @@ -345,7 +311,6 @@ struct rbd_device { struct rbd_spec *parent_spec; u64 parent_overlap; - atomic_t parent_ref; struct rbd_device *parent; /* protects updating the header */ @@ -394,8 +359,7 @@ static ssize_t rbd_add(struct bus_type *bus, const char *buf, size_t count); static ssize_t rbd_remove(struct bus_type *bus, const char *buf, size_t count); -static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping); -static void rbd_spec_put(struct rbd_spec *spec); +static int rbd_dev_image_probe(struct rbd_device *rbd_dev); static struct bus_attribute rbd_bus_attrs[] = { __ATTR(add, S_IWUSR, NULL, rbd_add), @@ -462,8 +426,7 @@ static void rbd_img_parent_read(struct rbd_obj_request *obj_request); static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); static int rbd_dev_refresh(struct rbd_device *rbd_dev); -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); -static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev); +static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev); static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u64 snap_id); static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, @@ -763,123 +726,88 @@ static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk) } /* - * Fill an rbd image header with information from the given format 1 - * on-disk header. + * Create a new header structure, translate header format from the on-disk + * header. */ -static int rbd_header_from_disk(struct rbd_device *rbd_dev, +static int rbd_header_from_disk(struct rbd_image_header *header, struct rbd_image_header_ondisk *ondisk) { - struct rbd_image_header *header = &rbd_dev->header; - bool first_time = header->object_prefix == NULL; - struct ceph_snap_context *snapc; - char *object_prefix = NULL; - char *snap_names = NULL; - u64 *snap_sizes = NULL; u32 snap_count; + size_t len; size_t size; - int ret = -ENOMEM; u32 i; - /* Allocate this now to avoid having to handle failure below */ - - if (first_time) { - size_t len; + memset(header, 0, sizeof (*header)); - len = strnlen(ondisk->object_prefix, - sizeof (ondisk->object_prefix)); - object_prefix = kmalloc(len + 1, GFP_KERNEL); - if (!object_prefix) - return -ENOMEM; - memcpy(object_prefix, ondisk->object_prefix, len); - object_prefix[len] = '\0'; - } + snap_count = le32_to_cpu(ondisk->snap_count); - /* Allocate the snapshot context and fill it in */ + len = strnlen(ondisk->object_prefix, sizeof (ondisk->object_prefix)); + header->object_prefix = kmalloc(len + 1, GFP_KERNEL); + if (!header->object_prefix) + return -ENOMEM; + memcpy(header->object_prefix, ondisk->object_prefix, len); + header->object_prefix[len] = '\0'; - snap_count = le32_to_cpu(ondisk->snap_count); - snapc = ceph_create_snap_context(snap_count, GFP_KERNEL); - if (!snapc) - goto out_err; - snapc->seq = le64_to_cpu(ondisk->snap_seq); if (snap_count) { - struct rbd_image_snap_ondisk *snaps; u64 snap_names_len = le64_to_cpu(ondisk->snap_names_len); - /* We'll keep a copy of the snapshot names... */ + /* Save a copy of the snapshot names */ - if (snap_names_len > (u64)SIZE_MAX) - goto out_2big; - snap_names = kmalloc(snap_names_len, GFP_KERNEL); - if (!snap_names) + if (snap_names_len > (u64) SIZE_MAX) + return -EIO; + header->snap_names = kmalloc(snap_names_len, GFP_KERNEL); + if (!header->snap_names) goto out_err; - - /* ...as well as the array of their sizes. */ - - size = snap_count * sizeof (*header->snap_sizes); - snap_sizes = kmalloc(size, GFP_KERNEL); - if (!snap_sizes) - goto out_err; - /* - * Copy the names, and fill in each snapshot's id - * and size. - * - * Note that rbd_dev_v1_header_info() guarantees the - * ondisk buffer we're working with has + * Note that rbd_dev_v1_header_read() guarantees + * the ondisk buffer we're working with has * snap_names_len bytes beyond the end of the * snapshot id array, this memcpy() is safe. */ - memcpy(snap_names, &ondisk->snaps[snap_count], snap_names_len); - snaps = ondisk->snaps; - for (i = 0; i < snap_count; i++) { - snapc->snaps[i] = le64_to_cpu(snaps[i].id); - snap_sizes[i] = le64_to_cpu(snaps[i].image_size); - } - } + memcpy(header->snap_names, &ondisk->snaps[snap_count], + snap_names_len); - /* We won't fail any more, fill in the header */ + /* Record each snapshot's size */ - down_write(&rbd_dev->header_rwsem); - if (first_time) { - header->object_prefix = object_prefix; - header->obj_order = ondisk->options.order; - header->crypt_type = ondisk->options.crypt_type; - header->comp_type = ondisk->options.comp_type; - /* The rest aren't used for format 1 images */ - header->stripe_unit = 0; - header->stripe_count = 0; - header->features = 0; + size = snap_count * sizeof (*header->snap_sizes); + header->snap_sizes = kmalloc(size, GFP_KERNEL); + if (!header->snap_sizes) + goto out_err; + for (i = 0; i < snap_count; i++) + header->snap_sizes[i] = + le64_to_cpu(ondisk->snaps[i].image_size); } else { - ceph_put_snap_context(header->snapc); - kfree(header->snap_names); - kfree(header->snap_sizes); + header->snap_names = NULL; + header->snap_sizes = NULL; } - /* The remaining fields always get updated (when we refresh) */ - - header->image_size = le64_to_cpu(ondisk->image_size); - header->snapc = snapc; - header->snap_names = snap_names; - header->snap_sizes = snap_sizes; + header->features = 0; /* No features support in v1 images */ + header->obj_order = ondisk->options.order; + header->crypt_type = ondisk->options.crypt_type; + header->comp_type = ondisk->options.comp_type; - /* Make sure mapping size is consistent with header info */ + /* Allocate and fill in the snapshot context */ - if (rbd_dev->spec->snap_id == CEPH_NOSNAP || first_time) - if (rbd_dev->mapping.size != header->image_size) - rbd_dev->mapping.size = header->image_size; + header->image_size = le64_to_cpu(ondisk->image_size); - up_write(&rbd_dev->header_rwsem); + header->snapc = ceph_create_snap_context(snap_count, GFP_KERNEL); + if (!header->snapc) + goto out_err; + header->snapc->seq = le64_to_cpu(ondisk->snap_seq); + for (i = 0; i < snap_count; i++) + header->snapc->snaps[i] = le64_to_cpu(ondisk->snaps[i].id); return 0; -out_2big: - ret = -EIO; + out_err: - kfree(snap_sizes); - kfree(snap_names); - ceph_put_snap_context(snapc); - kfree(object_prefix); + kfree(header->snap_sizes); + header->snap_sizes = NULL; + kfree(header->snap_names); + header->snap_names = NULL; + kfree(header->object_prefix); + header->object_prefix = NULL; - return ret; + return -ENOMEM; } static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which) @@ -1006,11 +934,20 @@ static int rbd_snap_features(struct rbd_device *rbd_dev, u64 snap_id, static int rbd_dev_mapping_set(struct rbd_device *rbd_dev) { - u64 snap_id = rbd_dev->spec->snap_id; + const char *snap_name = rbd_dev->spec->snap_name; + u64 snap_id; u64 size = 0; u64 features = 0; int ret; + if (strcmp(snap_name, RBD_SNAP_HEAD_NAME)) { + snap_id = rbd_snap_id_by_name(rbd_dev, snap_name); + if (snap_id == CEPH_NOSNAP) + return -ENOENT; + } else { + snap_id = CEPH_NOSNAP; + } + ret = rbd_snap_size(rbd_dev, snap_id, &size); if (ret) return ret; @@ -1021,6 +958,11 @@ static int rbd_dev_mapping_set(struct rbd_device *rbd_dev) rbd_dev->mapping.size = size; rbd_dev->mapping.features = features; + /* If we are mapping a snapshot it must be marked read-only */ + + if (snap_id != CEPH_NOSNAP) + rbd_dev->mapping.read_only = true; + return 0; } @@ -1028,6 +970,14 @@ static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev) { rbd_dev->mapping.size = 0; rbd_dev->mapping.features = 0; + rbd_dev->mapping.read_only = true; +} + +static void rbd_dev_clear_mapping(struct rbd_device *rbd_dev) +{ + rbd_dev->mapping.size = 0; + rbd_dev->mapping.features = 0; + rbd_dev->mapping.read_only = true; } static const char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset) @@ -1392,18 +1342,20 @@ static void rbd_obj_request_put(struct rbd_obj_request *obj_request) kref_put(&obj_request->kref, rbd_obj_request_destroy); } -static bool img_request_child_test(struct rbd_img_request *img_request); -static void rbd_parent_request_destroy(struct kref *kref); +static void rbd_img_request_get(struct rbd_img_request *img_request) +{ + dout("%s: img %p (was %d)\n", __func__, img_request, + atomic_read(&img_request->kref.refcount)); + kref_get(&img_request->kref); +} + static void rbd_img_request_destroy(struct kref *kref); static void rbd_img_request_put(struct rbd_img_request *img_request) { rbd_assert(img_request != NULL); dout("%s: img %p (was %d)\n", __func__, img_request, atomic_read(&img_request->kref.refcount)); - if (img_request_child_test(img_request)) - kref_put(&img_request->kref, rbd_parent_request_destroy); - else - kref_put(&img_request->kref, rbd_img_request_destroy); + kref_put(&img_request->kref, rbd_img_request_destroy); } static inline void rbd_img_obj_request_add(struct rbd_img_request *img_request, @@ -1520,12 +1472,6 @@ static void img_request_child_set(struct rbd_img_request *img_request) smp_mb(); } -static void img_request_child_clear(struct rbd_img_request *img_request) -{ - clear_bit(IMG_REQ_CHILD, &img_request->flags); - smp_mb(); -} - static bool img_request_child_test(struct rbd_img_request *img_request) { smp_mb(); @@ -1538,12 +1484,6 @@ static void img_request_layered_set(struct rbd_img_request *img_request) smp_mb(); } -static void img_request_layered_clear(struct rbd_img_request *img_request) -{ - clear_bit(IMG_REQ_LAYERED, &img_request->flags); - smp_mb(); -} - static bool img_request_layered_test(struct rbd_img_request *img_request) { smp_mb(); @@ -1887,74 +1827,6 @@ static void rbd_obj_request_destroy(struct kref *kref) kmem_cache_free(rbd_obj_request_cache, obj_request); } -/* It's OK to call this for a device with no parent */ - -static void rbd_spec_put(struct rbd_spec *spec); -static void rbd_dev_unparent(struct rbd_device *rbd_dev) -{ - rbd_dev_remove_parent(rbd_dev); - rbd_spec_put(rbd_dev->parent_spec); - rbd_dev->parent_spec = NULL; - rbd_dev->parent_overlap = 0; -} - -/* - * Parent image reference counting is used to determine when an - * image's parent fields can be safely torn down--after there are no - * more in-flight requests to the parent image. When the last - * reference is dropped, cleaning them up is safe. - */ -static void rbd_dev_parent_put(struct rbd_device *rbd_dev) -{ - int counter; - - if (!rbd_dev->parent_spec) - return; - - counter = atomic_dec_return_safe(&rbd_dev->parent_ref); - if (counter > 0) - return; - - /* Last reference; clean up parent data structures */ - - if (!counter) - rbd_dev_unparent(rbd_dev); - else - rbd_warn(rbd_dev, "parent reference underflow\n"); -} - -/* - * If an image has a non-zero parent overlap, get a reference to its - * parent. - * - * We must get the reference before checking for the overlap to - * coordinate properly with zeroing the parent overlap in - * rbd_dev_v2_parent_info() when an image gets flattened. We - * drop it again if there is no overlap. - * - * Returns true if the rbd device has a parent with a non-zero - * overlap and a reference for it was successfully taken, or - * false otherwise. - */ -static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) -{ - int counter; - - if (!rbd_dev->parent_spec) - return false; - - counter = atomic_inc_return_safe(&rbd_dev->parent_ref); - if (counter > 0 && rbd_dev->parent_overlap) - return true; - - /* Image was flattened, but parent is not yet torn down */ - - if (counter < 0) - rbd_warn(rbd_dev, "parent reference overflow\n"); - - return false; -} - /* * Caller is responsible for filling in the list of object requests * that comprises the image request, and the Linux request pointer @@ -1963,7 +1835,8 @@ static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) static struct rbd_img_request *rbd_img_request_create( struct rbd_device *rbd_dev, u64 offset, u64 length, - bool write_request) + bool write_request, + bool child_request) { struct rbd_img_request *img_request; @@ -1988,7 +1861,9 @@ static struct rbd_img_request *rbd_img_request_create( } else { img_request->snap_id = rbd_dev->spec->snap_id; } - if (rbd_dev_parent_get(rbd_dev)) + if (child_request) + img_request_child_set(img_request); + if (rbd_dev->parent_spec) img_request_layered_set(img_request); spin_lock_init(&img_request->completion_lock); img_request->next_completion = 0; @@ -1998,6 +1873,9 @@ static struct rbd_img_request *rbd_img_request_create( INIT_LIST_HEAD(&img_request->obj_requests); kref_init(&img_request->kref); + rbd_img_request_get(img_request); /* Avoid a warning */ + rbd_img_request_put(img_request); /* TEMPORARY */ + dout("%s: rbd_dev %p %s %llu/%llu -> img %p\n", __func__, rbd_dev, write_request ? "write" : "read", offset, length, img_request); @@ -2019,52 +1897,13 @@ static void rbd_img_request_destroy(struct kref *kref) rbd_img_obj_request_del(img_request, obj_request); rbd_assert(img_request->obj_request_count == 0); - if (img_request_layered_test(img_request)) { - img_request_layered_clear(img_request); - rbd_dev_parent_put(img_request->rbd_dev); - } - if (img_request_write_test(img_request)) ceph_put_snap_context(img_request->snapc); - kmem_cache_free(rbd_img_request_cache, img_request); -} - -static struct rbd_img_request *rbd_parent_request_create( - struct rbd_obj_request *obj_request, - u64 img_offset, u64 length) -{ - struct rbd_img_request *parent_request; - struct rbd_device *rbd_dev; - - rbd_assert(obj_request->img_request); - rbd_dev = obj_request->img_request->rbd_dev; - - parent_request = rbd_img_request_create(rbd_dev->parent, - img_offset, length, false); - if (!parent_request) - return NULL; - - img_request_child_set(parent_request); - rbd_obj_request_get(obj_request); - parent_request->obj_request = obj_request; - - return parent_request; -} - -static void rbd_parent_request_destroy(struct kref *kref) -{ - struct rbd_img_request *parent_request; - struct rbd_obj_request *orig_request; - - parent_request = container_of(kref, struct rbd_img_request, kref); - orig_request = parent_request->obj_request; - - parent_request->obj_request = NULL; - rbd_obj_request_put(orig_request); - img_request_child_clear(parent_request); + if (img_request_child_test(img_request)) + rbd_obj_request_put(img_request->obj_request); - rbd_img_request_destroy(kref); + kmem_cache_free(rbd_img_request_cache, img_request); } static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request) @@ -2275,7 +2114,7 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request) { struct rbd_img_request *img_request; struct rbd_device *rbd_dev; - struct page **pages; + u64 length; u32 page_count; rbd_assert(obj_request->type == OBJ_REQUEST_BIO); @@ -2285,14 +2124,12 @@ rbd_img_obj_copyup_callback(struct rbd_obj_request *obj_request) rbd_dev = img_request->rbd_dev; rbd_assert(rbd_dev); + length = (u64)1 << rbd_dev->header.obj_order; + page_count = (u32)calc_pages_for(0, length); - pages = obj_request->copyup_pages; - rbd_assert(pages != NULL); + rbd_assert(obj_request->copyup_pages); + ceph_release_page_vector(obj_request->copyup_pages, page_count); obj_request->copyup_pages = NULL; - page_count = obj_request->copyup_page_count; - rbd_assert(page_count); - obj_request->copyup_page_count = 0; - ceph_release_page_vector(pages, page_count); /* * We want the transfer count to reflect the size of the @@ -2316,11 +2153,9 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) struct ceph_osd_client *osdc; struct rbd_device *rbd_dev; struct page **pages; - u32 page_count; - int img_result; - u64 parent_length; - u64 offset; - u64 length; + int result; + u64 obj_size; + u64 xferred; rbd_assert(img_request_child_test(img_request)); @@ -2329,74 +2164,46 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) pages = img_request->copyup_pages; rbd_assert(pages != NULL); img_request->copyup_pages = NULL; - page_count = img_request->copyup_page_count; - rbd_assert(page_count); - img_request->copyup_page_count = 0; orig_request = img_request->obj_request; rbd_assert(orig_request != NULL); - rbd_assert(obj_request_type_valid(orig_request->type)); - img_result = img_request->result; - parent_length = img_request->length; - rbd_assert(parent_length == img_request->xferred); - rbd_img_request_put(img_request); + rbd_assert(orig_request->type == OBJ_REQUEST_BIO); + result = img_request->result; + obj_size = img_request->length; + xferred = img_request->xferred; - rbd_assert(orig_request->img_request); - rbd_dev = orig_request->img_request->rbd_dev; + rbd_dev = img_request->rbd_dev; rbd_assert(rbd_dev); + rbd_assert(obj_size == (u64)1 << rbd_dev->header.obj_order); - /* - * If the overlap has become 0 (most likely because the - * image has been flattened) we need to free the pages - * and re-submit the original write request. - */ - if (!rbd_dev->parent_overlap) { - struct ceph_osd_client *osdc; - - ceph_release_page_vector(pages, page_count); - osdc = &rbd_dev->rbd_client->client->osdc; - img_result = rbd_obj_request_submit(osdc, orig_request); - if (!img_result) - return; - } + rbd_img_request_put(img_request); - if (img_result) + if (result) goto out_err; - /* - * The original osd request is of no use to use any more. - * We need a new one that can hold the two ops in a copyup - * request. Allocate the new copyup osd request for the - * original request, and release the old one. - */ - img_result = -ENOMEM; + /* Allocate the new copyup osd request for the original request */ + + result = -ENOMEM; + rbd_assert(!orig_request->osd_req); osd_req = rbd_osd_req_create_copyup(orig_request); if (!osd_req) goto out_err; - rbd_osd_req_destroy(orig_request->osd_req); orig_request->osd_req = osd_req; orig_request->copyup_pages = pages; - orig_request->copyup_page_count = page_count; /* Initialize the copyup op */ osd_req_op_cls_init(osd_req, 0, CEPH_OSD_OP_CALL, "rbd", "copyup"); - osd_req_op_cls_request_data_pages(osd_req, 0, pages, parent_length, 0, + osd_req_op_cls_request_data_pages(osd_req, 0, pages, obj_size, 0, false, false); /* Then the original write request op */ - offset = orig_request->offset; - length = orig_request->length; osd_req_op_extent_init(osd_req, 1, CEPH_OSD_OP_WRITE, - offset, length, 0, 0); - if (orig_request->type == OBJ_REQUEST_BIO) - osd_req_op_extent_osd_data_bio(osd_req, 1, - orig_request->bio_list, length); - else - osd_req_op_extent_osd_data_pages(osd_req, 1, - orig_request->pages, length, - offset & ~PAGE_MASK, false, false); + orig_request->offset, + orig_request->length, 0, 0); + osd_req_op_extent_osd_data_bio(osd_req, 1, orig_request->bio_list, + orig_request->length); rbd_osd_req_format_write(orig_request); @@ -2404,13 +2211,13 @@ rbd_img_obj_parent_read_full_callback(struct rbd_img_request *img_request) orig_request->callback = rbd_img_obj_copyup_callback; osdc = &rbd_dev->rbd_client->client->osdc; - img_result = rbd_obj_request_submit(osdc, orig_request); - if (!img_result) + result = rbd_obj_request_submit(osdc, orig_request); + if (!result) return; out_err: /* Record the error code and complete the request */ - orig_request->result = img_result; + orig_request->result = result; orig_request->xferred = 0; obj_request_done_set(orig_request); rbd_obj_request_complete(orig_request); @@ -2442,13 +2249,22 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request) int result; rbd_assert(obj_request_img_data_test(obj_request)); - rbd_assert(obj_request_type_valid(obj_request->type)); + rbd_assert(obj_request->type == OBJ_REQUEST_BIO); img_request = obj_request->img_request; rbd_assert(img_request != NULL); rbd_dev = img_request->rbd_dev; rbd_assert(rbd_dev->parent != NULL); + /* + * First things first. The original osd request is of no + * use to use any more, we'll need a new one that can hold + * the two ops in a copyup request. We'll get that later, + * but for now we can release the old one. + */ + rbd_osd_req_destroy(obj_request->osd_req); + obj_request->osd_req = NULL; + /* * Determine the byte range covered by the object in the * child image to which the original request was to be sent. @@ -2479,16 +2295,18 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request) } result = -ENOMEM; - parent_request = rbd_parent_request_create(obj_request, - img_offset, length); + parent_request = rbd_img_request_create(rbd_dev->parent, + img_offset, length, + false, true); if (!parent_request) goto out_err; + rbd_obj_request_get(obj_request); + parent_request->obj_request = obj_request; result = rbd_img_request_fill(parent_request, OBJ_REQUEST_PAGES, pages); if (result) goto out_err; parent_request->copyup_pages = pages; - parent_request->copyup_page_count = page_count; parent_request->callback = rbd_img_obj_parent_read_full_callback; result = rbd_img_request_submit(parent_request); @@ -2496,7 +2314,6 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request) return 0; parent_request->copyup_pages = NULL; - parent_request->copyup_page_count = 0; parent_request->obj_request = NULL; rbd_obj_request_put(obj_request); out_err: @@ -2514,7 +2331,6 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request) static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request) { struct rbd_obj_request *orig_request; - struct rbd_device *rbd_dev; int result; rbd_assert(!obj_request_img_data_test(obj_request)); @@ -2537,21 +2353,8 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request) obj_request->xferred, obj_request->length); rbd_obj_request_put(obj_request); - /* - * If the overlap has become 0 (most likely because the - * image has been flattened) we need to free the pages - * and re-submit the original write request. - */ - rbd_dev = orig_request->img_request->rbd_dev; - if (!rbd_dev->parent_overlap) { - struct ceph_osd_client *osdc; - - rbd_obj_request_put(orig_request); - osdc = &rbd_dev->rbd_client->client->osdc; - result = rbd_obj_request_submit(osdc, orig_request); - if (!result) - return; - } + rbd_assert(orig_request); + rbd_assert(orig_request->img_request); /* * Our only purpose here is to determine whether the object @@ -2709,36 +2512,14 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request) struct rbd_obj_request *obj_request; struct rbd_device *rbd_dev; u64 obj_end; - u64 img_xferred; - int img_result; rbd_assert(img_request_child_test(img_request)); - /* First get what we need from the image request and release it */ - obj_request = img_request->obj_request; - img_xferred = img_request->xferred; - img_result = img_request->result; - rbd_img_request_put(img_request); - - /* - * If the overlap has become 0 (most likely because the - * image has been flattened) we need to re-submit the - * original request. - */ rbd_assert(obj_request); rbd_assert(obj_request->img_request); - rbd_dev = obj_request->img_request->rbd_dev; - if (!rbd_dev->parent_overlap) { - struct ceph_osd_client *osdc; - - osdc = &rbd_dev->rbd_client->client->osdc; - img_result = rbd_obj_request_submit(osdc, obj_request); - if (!img_result) - return; - } - obj_request->result = img_result; + obj_request->result = img_request->result; if (obj_request->result) goto out; @@ -2751,6 +2532,7 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request) */ rbd_assert(obj_request->img_offset < U64_MAX - obj_request->length); obj_end = obj_request->img_offset + obj_request->length; + rbd_dev = obj_request->img_request->rbd_dev; if (obj_end > rbd_dev->parent_overlap) { u64 xferred = 0; @@ -2758,39 +2540,43 @@ static void rbd_img_parent_read_callback(struct rbd_img_request *img_request) xferred = rbd_dev->parent_overlap - obj_request->img_offset; - obj_request->xferred = min(img_xferred, xferred); + obj_request->xferred = min(img_request->xferred, xferred); } else { - obj_request->xferred = img_xferred; + obj_request->xferred = img_request->xferred; } out: + rbd_img_request_put(img_request); rbd_img_obj_request_read_callback(obj_request); rbd_obj_request_complete(obj_request); } static void rbd_img_parent_read(struct rbd_obj_request *obj_request) { + struct rbd_device *rbd_dev; struct rbd_img_request *img_request; int result; rbd_assert(obj_request_img_data_test(obj_request)); rbd_assert(obj_request->img_request != NULL); rbd_assert(obj_request->result == (s32) -ENOENT); - rbd_assert(obj_request_type_valid(obj_request->type)); + rbd_assert(obj_request->type == OBJ_REQUEST_BIO); + rbd_dev = obj_request->img_request->rbd_dev; + rbd_assert(rbd_dev->parent != NULL); /* rbd_read_finish(obj_request, obj_request->length); */ - img_request = rbd_parent_request_create(obj_request, + img_request = rbd_img_request_create(rbd_dev->parent, obj_request->img_offset, - obj_request->length); + obj_request->length, + false, true); result = -ENOMEM; if (!img_request) goto out_err; - if (obj_request->type == OBJ_REQUEST_BIO) - result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO, - obj_request->bio_list); - else - result = rbd_img_request_fill(img_request, OBJ_REQUEST_PAGES, - obj_request->pages); + rbd_obj_request_get(obj_request); + img_request->obj_request = obj_request; + + result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO, + obj_request->bio_list); if (result) goto out_err; @@ -2840,7 +2626,6 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev, u64 notify_id) static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data) { struct rbd_device *rbd_dev = (struct rbd_device *)data; - int ret; if (!rbd_dev) return; @@ -2848,9 +2633,7 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data) dout("%s: \"%s\" notify_id %llu opcode %u\n", __func__, rbd_dev->header_name, (unsigned long long)notify_id, (unsigned int)opcode); - ret = rbd_dev_refresh(rbd_dev); - if (ret) - rbd_warn(rbd_dev, ": header refresh error (%d)\n", ret); + (void)rbd_dev_refresh(rbd_dev); rbd_obj_notify_ack(rbd_dev, notify_id); } @@ -2859,7 +2642,7 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data) * Request sync osd watch/unwatch. The value of "start" determines * whether a watch request is being initiated or torn down. */ -static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, bool start) +static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) { struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; struct rbd_obj_request *obj_request; @@ -2893,7 +2676,7 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, bool start) rbd_dev->watch_request->osd_req); osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH, - rbd_dev->watch_event->cookie, 0, start ? 1 : 0); + rbd_dev->watch_event->cookie, 0, start); rbd_osd_req_format_write(obj_request); ret = rbd_obj_request_submit(osdc, obj_request); @@ -3086,16 +2869,9 @@ static void rbd_request_fn(struct request_queue *q) goto end_request; /* Shouldn't happen */ } - result = -EIO; - if (offset + length > rbd_dev->mapping.size) { - rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)\n", - offset, length, rbd_dev->mapping.size); - goto end_request; - } - result = -ENOMEM; img_request = rbd_img_request_create(rbd_dev, offset, length, - write_request); + write_request, false); if (!img_request) goto end_request; @@ -3246,11 +3022,17 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, } /* - * Read the complete header for the given rbd device. On successful - * return, the rbd_dev->header field will contain up-to-date - * information about the image. + * Read the complete header for the given rbd device. + * + * Returns a pointer to a dynamically-allocated buffer containing + * the complete and validated header. Caller can pass the address + * of a variable that will be filled in with the version of the + * header object at the time it was read. + * + * Returns a pointer-coded errno if a failure occurs. */ -static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) +static struct rbd_image_header_ondisk * +rbd_dev_v1_header_read(struct rbd_device *rbd_dev) { struct rbd_image_header_ondisk *ondisk = NULL; u32 snap_count = 0; @@ -3275,22 +3057,22 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) size += names_size; ondisk = kmalloc(size, GFP_KERNEL); if (!ondisk) - return -ENOMEM; + return ERR_PTR(-ENOMEM); ret = rbd_obj_read_sync(rbd_dev, rbd_dev->header_name, 0, size, ondisk); if (ret < 0) - goto out; + goto out_err; if ((size_t)ret < size) { ret = -ENXIO; rbd_warn(rbd_dev, "short header read (want %zd got %d)", size, ret); - goto out; + goto out_err; } if (!rbd_dev_ondisk_valid(ondisk)) { ret = -ENXIO; rbd_warn(rbd_dev, "invalid header"); - goto out; + goto out_err; } names_size = le64_to_cpu(ondisk->snap_names_len); @@ -3298,13 +3080,85 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) snap_count = le32_to_cpu(ondisk->snap_count); } while (snap_count != want_count); - ret = rbd_header_from_disk(rbd_dev, ondisk); -out: + return ondisk; + +out_err: + kfree(ondisk); + + return ERR_PTR(ret); +} + +/* + * reload the ondisk the header + */ +static int rbd_read_header(struct rbd_device *rbd_dev, + struct rbd_image_header *header) +{ + struct rbd_image_header_ondisk *ondisk; + int ret; + + ondisk = rbd_dev_v1_header_read(rbd_dev); + if (IS_ERR(ondisk)) + return PTR_ERR(ondisk); + ret = rbd_header_from_disk(header, ondisk); kfree(ondisk); return ret; } +static void rbd_update_mapping_size(struct rbd_device *rbd_dev) +{ + if (rbd_dev->spec->snap_id != CEPH_NOSNAP) + return; + + if (rbd_dev->mapping.size != rbd_dev->header.image_size) { + sector_t size; + + rbd_dev->mapping.size = rbd_dev->header.image_size; + size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; + dout("setting size to %llu sectors", (unsigned long long)size); + set_capacity(rbd_dev->disk, size); + } +} + +/* + * only read the first part of the ondisk header, without the snaps info + */ +static int rbd_dev_v1_refresh(struct rbd_device *rbd_dev) +{ + int ret; + struct rbd_image_header h; + + ret = rbd_read_header(rbd_dev, &h); + if (ret < 0) + return ret; + + down_write(&rbd_dev->header_rwsem); + + /* Update image size, and check for resize of mapped image */ + rbd_dev->header.image_size = h.image_size; + rbd_update_mapping_size(rbd_dev); + + /* rbd_dev->header.object_prefix shouldn't change */ + kfree(rbd_dev->header.snap_sizes); + kfree(rbd_dev->header.snap_names); + /* osd requests may still refer to snapc */ + ceph_put_snap_context(rbd_dev->header.snapc); + + rbd_dev->header.image_size = h.image_size; + rbd_dev->header.snapc = h.snapc; + rbd_dev->header.snap_names = h.snap_names; + rbd_dev->header.snap_sizes = h.snap_sizes; + /* Free the extra copy of the object prefix */ + if (strcmp(rbd_dev->header.object_prefix, h.object_prefix)) + rbd_warn(rbd_dev, "object prefix changed (ignoring)"); + kfree(h.object_prefix); + + up_write(&rbd_dev->header_rwsem); + + return ret; +} + /* * Clear the rbd device's EXISTS flag if the snapshot it's mapped to * has disappeared from the (just updated) snapshot context. @@ -3326,29 +3180,26 @@ static void rbd_exists_validate(struct rbd_device *rbd_dev) static int rbd_dev_refresh(struct rbd_device *rbd_dev) { - u64 mapping_size; + u64 image_size; int ret; rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); - mapping_size = rbd_dev->mapping.size; + image_size = rbd_dev->header.image_size; mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); if (rbd_dev->image_format == 1) - ret = rbd_dev_v1_header_info(rbd_dev); + ret = rbd_dev_v1_refresh(rbd_dev); else - ret = rbd_dev_v2_header_info(rbd_dev); + ret = rbd_dev_v2_refresh(rbd_dev); /* If it's a mapped snapshot, validate its EXISTS flag */ rbd_exists_validate(rbd_dev); mutex_unlock(&ctl_mutex); - if (mapping_size != rbd_dev->mapping.size) { - sector_t size; - - size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; - dout("setting size to %llu sectors", (unsigned long long)size); - set_capacity(rbd_dev->disk, size); + if (ret) + rbd_warn(rbd_dev, "got notification but failed to " + " update snaps: %d\n", ret); + if (image_size != rbd_dev->header.image_size) revalidate_disk(rbd_dev->disk); - } return ret; } @@ -3552,8 +3403,6 @@ static ssize_t rbd_image_refresh(struct device *dev, int ret; ret = rbd_dev_refresh(rbd_dev); - if (ret) - rbd_warn(rbd_dev, ": manual header refresh error (%d)\n", ret); return ret < 0 ? ret : size; } @@ -3652,7 +3501,6 @@ static struct rbd_device *rbd_dev_create(struct rbd_client *rbdc, spin_lock_init(&rbd_dev->lock); rbd_dev->flags = 0; - atomic_set(&rbd_dev->parent_ref, 0); INIT_LIST_HEAD(&rbd_dev->node); init_rwsem(&rbd_dev->header_rwsem); @@ -3802,7 +3650,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) __le64 snapid; void *p; void *end; - u64 pool_id; char *image_id; u64 overlap; int ret; @@ -3833,37 +3680,18 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) p = reply_buf; end = reply_buf + ret; ret = -ERANGE; - ceph_decode_64_safe(&p, end, pool_id, out_err); - if (pool_id == CEPH_NOPOOL) { - /* - * Either the parent never existed, or we have - * record of it but the image got flattened so it no - * longer has a parent. When the parent of a - * layered image disappears we immediately set the - * overlap to 0. The effect of this is that all new - * requests will be treated as if the image had no - * parent. - */ - if (rbd_dev->parent_overlap) { - rbd_dev->parent_overlap = 0; - smp_mb(); - rbd_dev_parent_put(rbd_dev); - pr_info("%s: clone image has been flattened\n", - rbd_dev->disk->disk_name); - } - + ceph_decode_64_safe(&p, end, parent_spec->pool_id, out_err); + if (parent_spec->pool_id == CEPH_NOPOOL) goto out; /* No parent? No problem. */ - } /* The ceph file layout needs to fit pool id in 32 bits */ ret = -EIO; - if (pool_id > (u64)U32_MAX) { + if (parent_spec->pool_id > (u64)U32_MAX) { rbd_warn(NULL, "parent pool id too large (%llu > %u)\n", - (unsigned long long)pool_id, U32_MAX); + (unsigned long long)parent_spec->pool_id, U32_MAX); goto out_err; } - parent_spec->pool_id = pool_id; image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL); if (IS_ERR(image_id)) { @@ -3874,14 +3702,9 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err); ceph_decode_64_safe(&p, end, overlap, out_err); - if (overlap) { - rbd_spec_put(rbd_dev->parent_spec); - rbd_dev->parent_spec = parent_spec; - parent_spec = NULL; /* rbd_dev now owns this */ - rbd_dev->parent_overlap = overlap; - } else { - rbd_warn(rbd_dev, "ignoring parent of clone with overlap 0\n"); - } + rbd_dev->parent_overlap = overlap; + rbd_dev->parent_spec = parent_spec; + parent_spec = NULL; /* rbd_dev now owns this */ out: ret = 0; out_err: @@ -4179,7 +4002,6 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) for (i = 0; i < snap_count; i++) snapc->snaps[i] = ceph_decode_64(&p); - ceph_put_snap_context(rbd_dev->header.snapc); rbd_dev->header.snapc = snapc; dout(" snap context seq = %llu, snap_count = %u\n", @@ -4231,56 +4053,21 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, return snap_name; } -static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev) { - bool first_time = rbd_dev->header.object_prefix == NULL; int ret; down_write(&rbd_dev->header_rwsem); - if (first_time) { - ret = rbd_dev_v2_header_onetime(rbd_dev); - if (ret) - goto out; - } - - /* - * If the image supports layering, get the parent info. We - * need to probe the first time regardless. Thereafter we - * only need to if there's a parent, to see if it has - * disappeared due to the mapped image getting flattened. - */ - if (rbd_dev->header.features & RBD_FEATURE_LAYERING && - (first_time || rbd_dev->parent_spec)) { - bool warn; - - ret = rbd_dev_v2_parent_info(rbd_dev); - if (ret) - goto out; - - /* - * Print a warning if this is the initial probe and - * the image has a parent. Don't print it if the - * image now being probed is itself a parent. We - * can tell at this point because we won't know its - * pool name yet (just its pool id). - */ - warn = rbd_dev->parent_spec && rbd_dev->spec->pool_name; - if (first_time && warn) - rbd_warn(rbd_dev, "WARNING: kernel layering " - "is EXPERIMENTAL!"); - } - ret = rbd_dev_v2_image_size(rbd_dev); if (ret) goto out; - - if (rbd_dev->spec->snap_id == CEPH_NOSNAP) - if (rbd_dev->mapping.size != rbd_dev->header.image_size) - rbd_dev->mapping.size = rbd_dev->header.image_size; + rbd_update_mapping_size(rbd_dev); ret = rbd_dev_v2_snap_context(rbd_dev); dout("rbd_dev_v2_snap_context returned %d\n", ret); + if (ret) + goto out; out: up_write(&rbd_dev->header_rwsem); @@ -4703,10 +4490,10 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) { struct rbd_image_header *header; - /* Drop parent reference unless it's already been done (or none) */ - - if (rbd_dev->parent_overlap) - rbd_dev_parent_put(rbd_dev); + rbd_dev_remove_parent(rbd_dev); + rbd_spec_put(rbd_dev->parent_spec); + rbd_dev->parent_spec = NULL; + rbd_dev->parent_overlap = 0; /* Free dynamic fields from the header, then zero it out */ @@ -4718,22 +4505,72 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) memset(header, 0, sizeof (*header)); } -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) +static int rbd_dev_v1_probe(struct rbd_device *rbd_dev) { int ret; + /* Populate rbd image metadata */ + + ret = rbd_read_header(rbd_dev, &rbd_dev->header); + if (ret < 0) + goto out_err; + + /* Version 1 images have no parent (no layering) */ + + rbd_dev->parent_spec = NULL; + rbd_dev->parent_overlap = 0; + + dout("discovered version 1 image, header name is %s\n", + rbd_dev->header_name); + + return 0; + +out_err: + kfree(rbd_dev->header_name); + rbd_dev->header_name = NULL; + kfree(rbd_dev->spec->image_id); + rbd_dev->spec->image_id = NULL; + + return ret; +} + +static int rbd_dev_v2_probe(struct rbd_device *rbd_dev) +{ + int ret; + + ret = rbd_dev_v2_image_size(rbd_dev); + if (ret) + goto out_err; + + /* Get the object prefix (a.k.a. block_name) for the image */ + ret = rbd_dev_v2_object_prefix(rbd_dev); if (ret) goto out_err; - /* - * Get the and check features for the image. Currently the - * features are assumed to never change. - */ + /* Get the and check features for the image */ + ret = rbd_dev_v2_features(rbd_dev); if (ret) goto out_err; + /* If the image supports layering, get the parent info */ + + if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { + ret = rbd_dev_v2_parent_info(rbd_dev); + if (ret) + goto out_err; + + /* + * Don't print a warning for parent images. We can + * tell this point because we won't know its pool + * name yet (just its pool id). + */ + if (rbd_dev->spec->pool_name) + rbd_warn(rbd_dev, "WARNING: kernel layering " + "is EXPERIMENTAL!"); + } + /* If the image supports fancy striping, get its parameters */ if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { @@ -4741,11 +4578,28 @@ static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) if (ret < 0) goto out_err; } - /* No support for crypto and compression type format 2 images */ + + /* crypto and compression type aren't (yet) supported for v2 images */ + + rbd_dev->header.crypt_type = 0; + rbd_dev->header.comp_type = 0; + + /* Get the snapshot context, plus the header version */ + + ret = rbd_dev_v2_snap_context(rbd_dev); + if (ret) + goto out_err; + + dout("discovered version 2 image, header name is %s\n", + rbd_dev->header_name); return 0; out_err: - rbd_dev->header.features = 0; + rbd_dev->parent_overlap = 0; + rbd_spec_put(rbd_dev->parent_spec); + rbd_dev->parent_spec = NULL; + kfree(rbd_dev->header_name); + rbd_dev->header_name = NULL; kfree(rbd_dev->header.object_prefix); rbd_dev->header.object_prefix = NULL; @@ -4774,16 +4628,15 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev) if (!parent) goto out_err; - ret = rbd_dev_image_probe(parent, false); + ret = rbd_dev_image_probe(parent); if (ret < 0) goto out_err; rbd_dev->parent = parent; - atomic_set(&rbd_dev->parent_ref, 1); return 0; out_err: if (parent) { - rbd_dev_unparent(rbd_dev); + rbd_spec_put(rbd_dev->parent_spec); kfree(rbd_dev->header_name); rbd_dev_destroy(parent); } else { @@ -4798,6 +4651,10 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) { int ret; + ret = rbd_dev_mapping_set(rbd_dev); + if (ret) + return ret; + /* generate unique id: find highest unique id, add one */ rbd_dev_id_get(rbd_dev); @@ -4819,17 +4676,13 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) if (ret) goto err_out_blkdev; - ret = rbd_dev_mapping_set(rbd_dev); - if (ret) - goto err_out_disk; - set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); - ret = rbd_bus_add_dev(rbd_dev); if (ret) - goto err_out_mapping; + goto err_out_disk; /* Everything's ready. Announce the disk to the world. */ + set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); add_disk(rbd_dev->disk); @@ -4838,8 +4691,6 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev) return ret; -err_out_mapping: - rbd_dev_mapping_clear(rbd_dev); err_out_disk: rbd_free_disk(rbd_dev); err_out_blkdev: @@ -4880,7 +4731,12 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev) static void rbd_dev_image_release(struct rbd_device *rbd_dev) { + int ret; + rbd_dev_unprobe(rbd_dev); + ret = rbd_dev_header_watch_sync(rbd_dev, 0); + if (ret) + rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret); kfree(rbd_dev->header_name); rbd_dev->header_name = NULL; rbd_dev->image_format = 0; @@ -4892,11 +4748,10 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev) /* * Probe for the existence of the header object for the given rbd - * device. If this image is the one being mapped (i.e., not a - * parent), initiate a watch on its header object before using that - * object to get detailed information about the rbd image. + * device. For format 2 images this includes determining the image + * id. */ -static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping) +static int rbd_dev_image_probe(struct rbd_device *rbd_dev) { int ret; int tmp; @@ -4916,16 +4771,14 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping) if (ret) goto err_out_format; - if (mapping) { - ret = rbd_dev_header_watch_sync(rbd_dev, true); - if (ret) - goto out_header_name; - } + ret = rbd_dev_header_watch_sync(rbd_dev, 1); + if (ret) + goto out_header_name; if (rbd_dev->image_format == 1) - ret = rbd_dev_v1_header_info(rbd_dev); + ret = rbd_dev_v1_probe(rbd_dev); else - ret = rbd_dev_v2_header_info(rbd_dev); + ret = rbd_dev_v2_probe(rbd_dev); if (ret) goto err_out_watch; @@ -4934,22 +4787,15 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping) goto err_out_probe; ret = rbd_dev_probe_parent(rbd_dev); - if (ret) - goto err_out_probe; - - dout("discovered format %u image, header name is %s\n", - rbd_dev->image_format, rbd_dev->header_name); + if (!ret) + return 0; - return 0; err_out_probe: rbd_dev_unprobe(rbd_dev); err_out_watch: - if (mapping) { - tmp = rbd_dev_header_watch_sync(rbd_dev, false); - if (tmp) - rbd_warn(rbd_dev, "unable to tear down " - "watch request (%d)\n", tmp); - } + tmp = rbd_dev_header_watch_sync(rbd_dev, 0); + if (tmp) + rbd_warn(rbd_dev, "unable to tear down watch request\n"); out_header_name: kfree(rbd_dev->header_name); rbd_dev->header_name = NULL; @@ -4973,7 +4819,6 @@ static ssize_t rbd_add(struct bus_type *bus, struct rbd_spec *spec = NULL; struct rbd_client *rbdc; struct ceph_osd_client *osdc; - bool read_only; int rc = -ENOMEM; if (!try_module_get(THIS_MODULE)) @@ -4983,9 +4828,6 @@ static ssize_t rbd_add(struct bus_type *bus, rc = rbd_add_parse_args(buf, &ceph_opts, &rbd_opts, &spec); if (rc < 0) goto err_out_module; - read_only = rbd_opts->read_only; - kfree(rbd_opts); - rbd_opts = NULL; /* done with this */ rbdc = rbd_get_client(ceph_opts); if (IS_ERR(rbdc)) { @@ -5016,16 +4858,14 @@ static ssize_t rbd_add(struct bus_type *bus, rbdc = NULL; /* rbd_dev now owns this */ spec = NULL; /* rbd_dev now owns this */ - rc = rbd_dev_image_probe(rbd_dev, true); + rbd_dev->mapping.read_only = rbd_opts->read_only; + kfree(rbd_opts); + rbd_opts = NULL; /* done with this */ + + rc = rbd_dev_image_probe(rbd_dev); if (rc < 0) goto err_out_rbd_dev; - /* If we are mapping a snapshot it must be marked read-only */ - - if (rbd_dev->spec->snap_id != CEPH_NOSNAP) - read_only = true; - rbd_dev->mapping.read_only = read_only; - rc = rbd_dev_device_setup(rbd_dev); if (!rc) return count; @@ -5071,7 +4911,7 @@ static void rbd_dev_device_release(struct device *dev) rbd_free_disk(rbd_dev); clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); - rbd_dev_mapping_clear(rbd_dev); + rbd_dev_clear_mapping(rbd_dev); unregister_blkdev(rbd_dev->major, rbd_dev->name); rbd_dev->major = 0; rbd_dev_id_put(rbd_dev); @@ -5138,13 +4978,10 @@ static ssize_t rbd_remove(struct bus_type *bus, spin_unlock_irq(&rbd_dev->lock); if (ret < 0) goto done; + ret = count; rbd_bus_del_dev(rbd_dev); - ret = rbd_dev_header_watch_sync(rbd_dev, false); - if (ret) - rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret); rbd_dev_image_release(rbd_dev); module_put(THIS_MODULE); - ret = count; done: mutex_unlock(&ctl_mutex); diff --git a/trunk/drivers/char/hw_random/mxc-rnga.c b/trunk/drivers/char/hw_random/mxc-rnga.c index 19a12ac64a9e..4ca35e8a5d8c 100644 --- a/trunk/drivers/char/hw_random/mxc-rnga.c +++ b/trunk/drivers/char/hw_random/mxc-rnga.c @@ -167,6 +167,11 @@ static int __init mxc_rnga_probe(struct platform_device *pdev) clk_prepare_enable(mxc_rng->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + err = -ENOENT; + goto err_region; + } + mxc_rng->mem = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(mxc_rng->mem)) { err = PTR_ERR(mxc_rng->mem); @@ -184,6 +189,7 @@ static int __init mxc_rnga_probe(struct platform_device *pdev) return 0; err_ioremap: +err_region: clk_disable_unprepare(mxc_rng->clk); out: diff --git a/trunk/drivers/char/hw_random/omap-rng.c b/trunk/drivers/char/hw_random/omap-rng.c index d2903e772270..749dc16ca2cc 100644 --- a/trunk/drivers/char/hw_random/omap-rng.c +++ b/trunk/drivers/char/hw_random/omap-rng.c @@ -119,6 +119,11 @@ static int omap_rng_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!priv->mem_res) { + ret = -ENOENT; + goto err_ioremap; + } + priv->base = devm_ioremap_resource(&pdev->dev, priv->mem_res); if (IS_ERR(priv->base)) { ret = PTR_ERR(priv->base); diff --git a/trunk/drivers/char/ipmi/ipmi_bt_sm.c b/trunk/drivers/char/ipmi/ipmi_bt_sm.c index a22a7a502740..cdd4c09fda96 100644 --- a/trunk/drivers/char/ipmi/ipmi_bt_sm.c +++ b/trunk/drivers/char/ipmi/ipmi_bt_sm.c @@ -95,9 +95,9 @@ struct si_sm_data { enum bt_states state; unsigned char seq; /* BT sequence number */ struct si_sm_io *io; - unsigned char write_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */ + unsigned char write_data[IPMI_MAX_MSG_LENGTH]; int write_count; - unsigned char read_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */ + unsigned char read_data[IPMI_MAX_MSG_LENGTH]; int read_count; int truncated; long timeout; /* microseconds countdown */ diff --git a/trunk/drivers/char/ipmi/ipmi_devintf.c b/trunk/drivers/char/ipmi/ipmi_devintf.c index d5a5f020810a..9eb360ff8cab 100644 --- a/trunk/drivers/char/ipmi/ipmi_devintf.c +++ b/trunk/drivers/char/ipmi/ipmi_devintf.c @@ -837,25 +837,13 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, return ipmi_ioctl(filep, cmd, arg); } } - -static long unlocked_compat_ipmi_ioctl(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - int ret; - - mutex_lock(&ipmi_mutex); - ret = compat_ipmi_ioctl(filep, cmd, arg); - mutex_unlock(&ipmi_mutex); - - return ret; -} #endif static const struct file_operations ipmi_fops = { .owner = THIS_MODULE, .unlocked_ioctl = ipmi_unlocked_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = unlocked_compat_ipmi_ioctl, + .compat_ioctl = compat_ipmi_ioctl, #endif .open = ipmi_open, .release = ipmi_release, diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 4445fa164a2d..4d439d2fcfd6 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -2037,11 +2037,12 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; - entry->name = kstrdup(name, GFP_KERNEL); + entry->name = kmalloc(strlen(name)+1, GFP_KERNEL); if (!entry->name) { kfree(entry); return -ENOMEM; } + strcpy(entry->name, name); file = proc_create_data(name, 0, smi->proc_dir, proc_ops, data); if (!file) { diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index af4b23ffc5a6..313538abe63c 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -663,10 +663,8 @@ static void handle_transaction_done(struct smi_info *smi_info) /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) { - dev_warn(smi_info->dev, - "Couldn't get irq info: %x.\n", msg[2]); - dev_warn(smi_info->dev, - "Maybe ok, but ipmi might run very slowly.\n"); + dev_warn(smi_info->dev, "Could not enable interrupts" + ", failed get, using polled mode.\n"); smi_info->si_state = SI_NORMAL; } else { msg[0] = (IPMI_NETFN_APP_REQUEST << 2); @@ -687,12 +685,10 @@ static void handle_transaction_done(struct smi_info *smi_info) /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); - if (msg[2] != 0) { - dev_warn(smi_info->dev, - "Couldn't set irq info: %x.\n", msg[2]); - dev_warn(smi_info->dev, - "Maybe ok, but ipmi might run very slowly.\n"); - } else + if (msg[2] != 0) + dev_warn(smi_info->dev, "Could not enable interrupts" + ", failed set, using polled mode.\n"); + else smi_info->interrupt_disabled = 0; smi_info->si_state = SI_NORMAL; break; diff --git a/trunk/drivers/char/lp.c b/trunk/drivers/char/lp.c index 0913d79424d3..dafd9ac6428f 100644 --- a/trunk/drivers/char/lp.c +++ b/trunk/drivers/char/lp.c @@ -622,12 +622,9 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd, return -EFAULT; break; case LPGETSTATUS: - if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) - return -EINTR; lp_claim_parport_or_block (&lp_table[minor]); status = r_str(minor); lp_release_parport (&lp_table[minor]); - mutex_unlock(&lp_table[minor].port_mutex); if (copy_to_user(argp, &status, sizeof(int))) return -EFAULT; diff --git a/trunk/drivers/char/ttyprintk.c b/trunk/drivers/char/ttyprintk.c index d5d2e4a985aa..4945bd3d18d0 100644 --- a/trunk/drivers/char/ttyprintk.c +++ b/trunk/drivers/char/ttyprintk.c @@ -179,6 +179,7 @@ static int __init ttyprintk_init(void) { int ret = -ENOMEM; + tpk_port.port.ops = &null_ops; mutex_init(&tpk_port.port_write_mutex); ttyprintk_driver = tty_alloc_driver(1, @@ -189,7 +190,6 @@ static int __init ttyprintk_init(void) return PTR_ERR(ttyprintk_driver); tty_port_init(&tpk_port.port); - tpk_port.port.ops = &null_ops; ttyprintk_driver->driver_name = "ttyprintk"; ttyprintk_driver->name = "ttyprintk"; diff --git a/trunk/drivers/cpufreq/Kconfig b/trunk/drivers/cpufreq/Kconfig index 534fcb825153..a1488f58f6ca 100644 --- a/trunk/drivers/cpufreq/Kconfig +++ b/trunk/drivers/cpufreq/Kconfig @@ -47,7 +47,7 @@ config CPU_FREQ_STAT_DETAILS choice prompt "Default CPUFreq governor" - default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ + default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 default CPU_FREQ_DEFAULT_GOV_PERFORMANCE help This option sets which CPUFreq governor shall be loaded at diff --git a/trunk/drivers/cpufreq/Kconfig.arm b/trunk/drivers/cpufreq/Kconfig.arm index 6e57543fe0b9..f3af18b9acc5 100644 --- a/trunk/drivers/cpufreq/Kconfig.arm +++ b/trunk/drivers/cpufreq/Kconfig.arm @@ -3,17 +3,16 @@ # config ARM_BIG_LITTLE_CPUFREQ - tristate "Generic ARM big LITTLE CPUfreq driver" - depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK - help - This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. + tristate + depends on ARM_CPU_TOPOLOGY config ARM_DT_BL_CPUFREQ - tristate "Generic probing via DT for ARM big LITTLE CPUfreq driver" - depends on ARM_BIG_LITTLE_CPUFREQ && OF + tristate "Generic ARM big LITTLE CPUfreq driver probed via DT" + select ARM_BIG_LITTLE_CPUFREQ + depends on OF && HAVE_CLK help - This enables probing via DT for Generic CPUfreq driver for ARM - big.LITTLE platform. This gets frequency tables from DT. + This enables the Generic CPUfreq driver for ARM big.LITTLE platform. + This gets frequency tables from DT. config ARM_EXYNOS_CPUFREQ bool "SAMSUNG EXYNOS SoCs" diff --git a/trunk/drivers/cpufreq/arm_big_little.c b/trunk/drivers/cpufreq/arm_big_little.c index 5d7f53fcd6f5..dbdf677d2f36 100644 --- a/trunk/drivers/cpufreq/arm_big_little.c +++ b/trunk/drivers/cpufreq/arm_big_little.c @@ -40,6 +40,11 @@ static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS]; static atomic_t cluster_usage[MAX_CLUSTERS] = {ATOMIC_INIT(0), ATOMIC_INIT(0)}; +static int cpu_to_cluster(int cpu) +{ + return topology_physical_package_id(cpu); +} + static unsigned int bL_cpufreq_get(unsigned int cpu) { u32 cur_cluster = cpu_to_cluster(cpu); @@ -187,7 +192,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu)); - dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu); + dev_info(cpu_dev, "CPU %d initialized\n", policy->cpu); return 0; } diff --git a/trunk/drivers/cpufreq/arm_big_little.h b/trunk/drivers/cpufreq/arm_big_little.h index 79b2ce17884d..70f18fc12d4a 100644 --- a/trunk/drivers/cpufreq/arm_big_little.h +++ b/trunk/drivers/cpufreq/arm_big_little.h @@ -34,11 +34,6 @@ struct cpufreq_arm_bL_ops { int (*init_opp_table)(struct device *cpu_dev); }; -static inline int cpu_to_cluster(int cpu) -{ - return topology_physical_package_id(cpu); -} - int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops); void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops); diff --git a/trunk/drivers/cpufreq/arm_big_little_dt.c b/trunk/drivers/cpufreq/arm_big_little_dt.c index 173ed059d95f..44be3115375c 100644 --- a/trunk/drivers/cpufreq/arm_big_little_dt.c +++ b/trunk/drivers/cpufreq/arm_big_little_dt.c @@ -66,8 +66,8 @@ static int dt_get_transition_latency(struct device *cpu_dev) parent = of_find_node_by_path("/cpus"); if (!parent) { - pr_info("Failed to find OF /cpus. Use CPUFREQ_ETERNAL transition latency\n"); - return CPUFREQ_ETERNAL; + pr_err("failed to find OF /cpus\n"); + return -ENOENT; } for_each_child_of_node(parent, np) { @@ -78,11 +78,10 @@ static int dt_get_transition_latency(struct device *cpu_dev) of_node_put(np); of_node_put(parent); - return transition_latency; + return 0; } - pr_info("clock-latency isn't found, use CPUFREQ_ETERNAL transition latency\n"); - return CPUFREQ_ETERNAL; + return -ENODEV; } static struct cpufreq_arm_bL_ops dt_bL_ops = { diff --git a/trunk/drivers/cpufreq/cpufreq-cpu0.c b/trunk/drivers/cpufreq/cpufreq-cpu0.c index a64eb8b70444..3ab8294eab04 100644 --- a/trunk/drivers/cpufreq/cpufreq-cpu0.c +++ b/trunk/drivers/cpufreq/cpufreq-cpu0.c @@ -189,29 +189,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) if (!np) { pr_err("failed to find cpu0 node\n"); - ret = -ENOENT; - goto out_put_parent; + return -ENOENT; } cpu_dev = &pdev->dev; cpu_dev->of_node = np; - cpu_reg = devm_regulator_get(cpu_dev, "cpu0"); - if (IS_ERR(cpu_reg)) { - /* - * If cpu0 regulator supply node is present, but regulator is - * not yet registered, we should try defering probe. - */ - if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { - dev_err(cpu_dev, "cpu0 regulator not ready, retry\n"); - ret = -EPROBE_DEFER; - goto out_put_node; - } - pr_warn("failed to get cpu0 regulator: %ld\n", - PTR_ERR(cpu_reg)); - cpu_reg = NULL; - } - cpu_clk = devm_clk_get(cpu_dev, NULL); if (IS_ERR(cpu_clk)) { ret = PTR_ERR(cpu_clk); @@ -219,6 +202,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) goto out_put_node; } + cpu_reg = devm_regulator_get(cpu_dev, "cpu0"); + if (IS_ERR(cpu_reg)) { + pr_warn("failed to get cpu0 regulator\n"); + cpu_reg = NULL; + } + ret = of_init_opp_table(cpu_dev); if (ret) { pr_err("failed to init OPP table: %d\n", ret); @@ -275,8 +264,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) opp_free_cpufreq_table(cpu_dev, &freq_table); out_put_node: of_node_put(np); -out_put_parent: - of_node_put(parent); return ret; } diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 4b8c7f297d74..1b8a48eaf90f 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -1075,14 +1075,14 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif __func__, cpu_dev->id, cpu); } - if ((cpus == 1) && (cpufreq_driver->target)) - __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); - pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); cpufreq_cpu_put(data); /* If cpu is last user of policy, free policy */ if (cpus == 1) { + if (cpufreq_driver->target) + __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); + lock_policy_rwsem_read(cpu); kobj = &data->kobj; cmp = &data->kobj_unregister; @@ -1832,13 +1832,15 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, if (dev) { switch (action) { case CPU_ONLINE: + case CPU_ONLINE_FROZEN: cpufreq_add_dev(dev, NULL); break; case CPU_DOWN_PREPARE: - case CPU_UP_CANCELED_FROZEN: + case CPU_DOWN_PREPARE_FROZEN: __cpufreq_remove_dev(dev, NULL); break; case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: cpufreq_add_dev(dev, NULL); break; } diff --git a/trunk/drivers/cpufreq/cpufreq_governor.c b/trunk/drivers/cpufreq/cpufreq_governor.c index 5af40ad82d23..443442df113b 100644 --- a/trunk/drivers/cpufreq/cpufreq_governor.c +++ b/trunk/drivers/cpufreq/cpufreq_governor.c @@ -255,7 +255,6 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, if (have_governor_per_policy()) { WARN_ON(dbs_data); } else if (dbs_data) { - dbs_data->usage_count++; policy->governor_data = dbs_data; return 0; } @@ -267,7 +266,6 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, } dbs_data->cdata = cdata; - dbs_data->usage_count = 1; rc = cdata->init(dbs_data); if (rc) { pr_err("%s: POLICY_INIT: init() failed\n", __func__); @@ -296,8 +294,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, set_sampling_rate(dbs_data, max(dbs_data->min_sampling_rate, latency * LATENCY_MULTIPLIER)); - if ((cdata->governor == GOV_CONSERVATIVE) && - (!policy->governor->initialized)) { + if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; cpufreq_register_notifier(cs_ops->notifier_block, @@ -309,12 +306,12 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, return 0; case CPUFREQ_GOV_POLICY_EXIT: - if (!--dbs_data->usage_count) { + if ((policy->governor->initialized == 1) || + have_governor_per_policy()) { sysfs_remove_group(get_governor_parent_kobj(policy), get_sysfs_attr(dbs_data)); - if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) && - (policy->governor->initialized == 1)) { + if (dbs_data->cdata->governor == GOV_CONSERVATIVE) { struct cs_ops *cs_ops = dbs_data->cdata->gov_ops; cpufreq_unregister_notifier(cs_ops->notifier_block, diff --git a/trunk/drivers/cpufreq/cpufreq_governor.h b/trunk/drivers/cpufreq/cpufreq_governor.h index e16a96130cb3..8ac33538d0bd 100644 --- a/trunk/drivers/cpufreq/cpufreq_governor.h +++ b/trunk/drivers/cpufreq/cpufreq_governor.h @@ -211,7 +211,6 @@ struct common_dbs_data { struct dbs_data { struct common_dbs_data *cdata; unsigned int min_sampling_rate; - int usage_count; void *tuners; /* dbs_mutex protects dbs_enable in governor start/stop */ diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index 4b9bb5def6f1..b0ffef96bf77 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -547,6 +547,7 @@ static int od_init(struct dbs_data *dbs_data) tuners->io_is_busy = should_io_be_busy(); dbs_data->tuners = tuners; + pr_info("%s: tuners %p\n", __func__, tuners); mutex_init(&dbs_data->mutex); return 0; } diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c index fb65decffa28..bfd6273fd873 100644 --- a/trunk/drivers/cpufreq/cpufreq_stats.c +++ b/trunk/drivers/cpufreq/cpufreq_stats.c @@ -349,16 +349,15 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_ONLINE: + case CPU_ONLINE_FROZEN: cpufreq_update_policy(cpu); break; case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: cpufreq_stats_free_sysfs(cpu); break; case CPU_DEAD: - cpufreq_stats_free_table(cpu); - break; - case CPU_UP_CANCELED_FROZEN: - cpufreq_stats_free_sysfs(cpu); + case CPU_DEAD_FROZEN: cpufreq_stats_free_table(cpu); break; } diff --git a/trunk/drivers/cpufreq/intel_pstate.c b/trunk/drivers/cpufreq/intel_pstate.c index 9c36ace92a39..cc3a8e6c92be 100644 --- a/trunk/drivers/cpufreq/intel_pstate.c +++ b/trunk/drivers/cpufreq/intel_pstate.c @@ -48,7 +48,12 @@ static inline int32_t div_fp(int32_t x, int32_t y) } struct sample { + ktime_t start_time; + ktime_t end_time; int core_pct_busy; + int pstate_pct_busy; + u64 duration_us; + u64 idletime_us; u64 aperf; u64 mperf; int freq; @@ -81,9 +86,13 @@ struct cpudata { struct pstate_adjust_policy *pstate_policy; struct pstate_data pstate; struct _pid pid; + struct _pid idle_pid; int min_pstate_count; + int idle_mode; + ktime_t prev_sample; + u64 prev_idle_time_us; u64 prev_aperf; u64 prev_mperf; int sample_ptr; @@ -115,8 +124,6 @@ struct perf_limits { int min_perf_pct; int32_t max_perf; int32_t min_perf; - int max_policy_pct; - int max_sysfs_pct; }; static struct perf_limits limits = { @@ -125,8 +132,6 @@ static struct perf_limits limits = { .max_perf = int_tofp(1), .min_perf_pct = 0, .min_perf = 0, - .max_policy_pct = 100, - .max_sysfs_pct = 100, }; static inline void pid_reset(struct _pid *pid, int setpoint, int busy, @@ -197,6 +202,19 @@ static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu) 0); } +static inline void intel_pstate_idle_pid_reset(struct cpudata *cpu) +{ + pid_p_gain_set(&cpu->idle_pid, cpu->pstate_policy->p_gain_pct); + pid_d_gain_set(&cpu->idle_pid, cpu->pstate_policy->d_gain_pct); + pid_i_gain_set(&cpu->idle_pid, cpu->pstate_policy->i_gain_pct); + + pid_reset(&cpu->idle_pid, + 75, + 50, + cpu->pstate_policy->deadband, + 0); +} + static inline void intel_pstate_reset_all_pid(void) { unsigned int cpu; @@ -284,8 +302,7 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, if (ret != 1) return -EINVAL; - limits.max_sysfs_pct = clamp_t(int, input, 0 , 100); - limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); + limits.max_perf_pct = clamp_t(int, input, 0 , 100); limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); return count; } @@ -391,8 +408,9 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) if (pstate == cpu->pstate.current_pstate) return; +#ifndef MODULE trace_cpu_frequency(pstate * 100000, cpu->cpu); - +#endif cpu->pstate.current_pstate = pstate; wrmsrl(MSR_IA32_PERF_CTL, pstate << 8); @@ -432,26 +450,48 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu, struct sample *sample) { u64 core_pct; + sample->pstate_pct_busy = 100 - div64_u64( + sample->idletime_us * 100, + sample->duration_us); core_pct = div64_u64(sample->aperf * 100, sample->mperf); sample->freq = cpu->pstate.max_pstate * core_pct * 1000; - sample->core_pct_busy = core_pct; + sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct), + 100); } static inline void intel_pstate_sample(struct cpudata *cpu) { + ktime_t now; + u64 idle_time_us; u64 aperf, mperf; + now = ktime_get(); + idle_time_us = get_cpu_idle_time_us(cpu->cpu, NULL); + rdmsrl(MSR_IA32_APERF, aperf); rdmsrl(MSR_IA32_MPERF, mperf); - cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; - cpu->samples[cpu->sample_ptr].aperf = aperf; - cpu->samples[cpu->sample_ptr].mperf = mperf; - cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; - cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; - - intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); + /* for the first sample, don't actually record a sample, just + * set the baseline */ + if (cpu->prev_idle_time_us > 0) { + cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; + cpu->samples[cpu->sample_ptr].start_time = cpu->prev_sample; + cpu->samples[cpu->sample_ptr].end_time = now; + cpu->samples[cpu->sample_ptr].duration_us = + ktime_us_delta(now, cpu->prev_sample); + cpu->samples[cpu->sample_ptr].idletime_us = + idle_time_us - cpu->prev_idle_time_us; + + cpu->samples[cpu->sample_ptr].aperf = aperf; + cpu->samples[cpu->sample_ptr].mperf = mperf; + cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; + cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; + + intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); + } + cpu->prev_sample = now; + cpu->prev_idle_time_us = idle_time_us; cpu->prev_aperf = aperf; cpu->prev_mperf = mperf; } @@ -465,6 +505,16 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu) mod_timer_pinned(&cpu->timer, jiffies + delay); } +static inline void intel_pstate_idle_mode(struct cpudata *cpu) +{ + cpu->idle_mode = 1; +} + +static inline void intel_pstate_normal_mode(struct cpudata *cpu) +{ + cpu->idle_mode = 0; +} + static inline int intel_pstate_get_scaled_busy(struct cpudata *cpu) { int32_t busy_scaled; @@ -497,21 +547,50 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) intel_pstate_pstate_decrease(cpu, steps); } +static inline void intel_pstate_adjust_idle_pstate(struct cpudata *cpu) +{ + int busy_scaled; + struct _pid *pid; + int ctl = 0; + int steps; + + pid = &cpu->idle_pid; + + busy_scaled = intel_pstate_get_scaled_busy(cpu); + + ctl = pid_calc(pid, 100 - busy_scaled); + + steps = abs(ctl); + if (ctl < 0) + intel_pstate_pstate_decrease(cpu, steps); + else + intel_pstate_pstate_increase(cpu, steps); + + if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) + intel_pstate_normal_mode(cpu); +} + static void intel_pstate_timer_func(unsigned long __data) { struct cpudata *cpu = (struct cpudata *) __data; intel_pstate_sample(cpu); - intel_pstate_adjust_busy_pstate(cpu); + if (!cpu->idle_mode) + intel_pstate_adjust_busy_pstate(cpu); + else + intel_pstate_adjust_idle_pstate(cpu); + +#if defined(XPERF_FIX) if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) { cpu->min_pstate_count++; if (!(cpu->min_pstate_count % 5)) { intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); + intel_pstate_idle_mode(cpu); } } else cpu->min_pstate_count = 0; - +#endif intel_pstate_set_sample_time(cpu); } @@ -552,6 +631,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) (unsigned long)cpu; cpu->timer.expires = jiffies + HZ/100; intel_pstate_busy_pid_reset(cpu); + intel_pstate_idle_pid_reset(cpu); intel_pstate_sample(cpu); intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate); @@ -595,9 +675,8 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100); limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); - limits.max_policy_pct = policy->max * 100 / policy->cpuinfo.max_freq; - limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100); - limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); + limits.max_perf_pct = policy->max * 100 / policy->cpuinfo.max_freq; + limits.max_perf_pct = clamp_t(int, limits.max_perf_pct, 0 , 100); limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); return 0; @@ -709,9 +788,10 @@ static int __init intel_pstate_init(void) pr_info("Intel P-state driver initializing.\n"); - all_cpu_data = vzalloc(sizeof(void *) * num_possible_cpus()); + all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus()); if (!all_cpu_data) return -ENOMEM; + memset(all_cpu_data, 0, sizeof(void *) * num_possible_cpus()); rc = cpufreq_register_driver(&intel_pstate_driver); if (rc) diff --git a/trunk/drivers/cpufreq/kirkwood-cpufreq.c b/trunk/drivers/cpufreq/kirkwood-cpufreq.c index b2644af985ec..d36ea8dc96eb 100644 --- a/trunk/drivers/cpufreq/kirkwood-cpufreq.c +++ b/trunk/drivers/cpufreq/kirkwood-cpufreq.c @@ -171,6 +171,10 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev) priv.dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Cannot get memory resource\n"); + return -ENODEV; + } priv.base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv.base)) return PTR_ERR(priv.base); diff --git a/trunk/drivers/cpufreq/loongson2_cpufreq.c b/trunk/drivers/cpufreq/loongson2_cpufreq.c index d53912768946..84889573b566 100644 --- a/trunk/drivers/cpufreq/loongson2_cpufreq.c +++ b/trunk/drivers/cpufreq/loongson2_cpufreq.c @@ -18,7 +18,6 @@ #include #include -#include #include @@ -201,7 +200,6 @@ static void loongson2_cpu_wait(void) LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ spin_unlock_irqrestore(&loongson2_wait_lock, flags); - local_irq_enable(); } static int __init cpufreq_init(void) diff --git a/trunk/drivers/crypto/nx/nx-aes-cbc.c b/trunk/drivers/crypto/nx/nx-aes-cbc.c index 35d483f8db66..a76d4c4f29f5 100644 --- a/trunk/drivers/crypto/nx/nx-aes-cbc.c +++ b/trunk/drivers/crypto/nx/nx-aes-cbc.c @@ -126,7 +126,6 @@ struct crypto_alg nx_cbc_aes_alg = { .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct nx_crypto_ctx), .cra_type = &crypto_blkcipher_type, - .cra_alignmask = 0xf, .cra_module = THIS_MODULE, .cra_init = nx_crypto_ctx_aes_cbc_init, .cra_exit = nx_crypto_ctx_exit, diff --git a/trunk/drivers/crypto/nx/nx-aes-ecb.c b/trunk/drivers/crypto/nx/nx-aes-ecb.c index 7bbc9a81da21..ba5f1611336f 100644 --- a/trunk/drivers/crypto/nx/nx-aes-ecb.c +++ b/trunk/drivers/crypto/nx/nx-aes-ecb.c @@ -123,7 +123,6 @@ struct crypto_alg nx_ecb_aes_alg = { .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, .cra_blocksize = AES_BLOCK_SIZE, - .cra_alignmask = 0xf, .cra_ctxsize = sizeof(struct nx_crypto_ctx), .cra_type = &crypto_blkcipher_type, .cra_module = THIS_MODULE, diff --git a/trunk/drivers/crypto/nx/nx-aes-gcm.c b/trunk/drivers/crypto/nx/nx-aes-gcm.c index 6cca6c392b00..c8109edc5cfb 100644 --- a/trunk/drivers/crypto/nx/nx-aes-gcm.c +++ b/trunk/drivers/crypto/nx/nx-aes-gcm.c @@ -219,7 +219,7 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc) if (enc) NX_CPB_FDM(csbcpb) |= NX_FDM_ENDE_ENCRYPT; else - nbytes -= crypto_aead_authsize(crypto_aead_reqtfm(req)); + nbytes -= AES_BLOCK_SIZE; csbcpb->cpb.aes_gcm.bit_length_data = nbytes * 8; diff --git a/trunk/drivers/crypto/nx/nx-sha256.c b/trunk/drivers/crypto/nx/nx-sha256.c index 67024f2f0b78..9767315f8c0b 100644 --- a/trunk/drivers/crypto/nx/nx-sha256.c +++ b/trunk/drivers/crypto/nx/nx-sha256.c @@ -69,7 +69,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data, * 1: <= SHA256_BLOCK_SIZE: copy into state, return 0 * 2: > SHA256_BLOCK_SIZE: process X blocks, copy in leftover */ - if (len + sctx->count < SHA256_BLOCK_SIZE) { + if (len + sctx->count <= SHA256_BLOCK_SIZE) { memcpy(sctx->buf + sctx->count, data, len); sctx->count += len; goto out; @@ -110,8 +110,7 @@ static int nx_sha256_update(struct shash_desc *desc, const u8 *data, atomic_inc(&(nx_ctx->stats->sha256_ops)); /* copy the leftover back into the state struct */ - if (leftover) - memcpy(sctx->buf, data + len - leftover, leftover); + memcpy(sctx->buf, data + len - leftover, leftover); sctx->count = leftover; csbcpb->cpb.sha256.message_bit_length += (u64) @@ -131,7 +130,6 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out) struct nx_sg *in_sg, *out_sg; int rc; - if (NX_CPB_FDM(csbcpb) & NX_FDM_CONTINUATION) { /* we've hit the nx chip previously, now we're finalizing, * so copy over the partial digest */ @@ -164,7 +162,7 @@ static int nx_sha256_final(struct shash_desc *desc, u8 *out) atomic_inc(&(nx_ctx->stats->sha256_ops)); - atomic64_add(csbcpb->cpb.sha256.message_bit_length / 8, + atomic64_add(csbcpb->cpb.sha256.message_bit_length, &(nx_ctx->stats->sha256_bytes)); memcpy(out, csbcpb->cpb.sha256.message_digest, SHA256_DIGEST_SIZE); out: diff --git a/trunk/drivers/crypto/nx/nx-sha512.c b/trunk/drivers/crypto/nx/nx-sha512.c index 08eee1122349..3177b8c3d5f1 100644 --- a/trunk/drivers/crypto/nx/nx-sha512.c +++ b/trunk/drivers/crypto/nx/nx-sha512.c @@ -69,7 +69,7 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data, * 1: <= SHA512_BLOCK_SIZE: copy into state, return 0 * 2: > SHA512_BLOCK_SIZE: process X blocks, copy in leftover */ - if ((u64)len + sctx->count[0] < SHA512_BLOCK_SIZE) { + if ((u64)len + sctx->count[0] <= SHA512_BLOCK_SIZE) { memcpy(sctx->buf + sctx->count[0], data, len); sctx->count[0] += len; goto out; @@ -110,8 +110,7 @@ static int nx_sha512_update(struct shash_desc *desc, const u8 *data, atomic_inc(&(nx_ctx->stats->sha512_ops)); /* copy the leftover back into the state struct */ - if (leftover) - memcpy(sctx->buf, data + len - leftover, leftover); + memcpy(sctx->buf, data + len - leftover, leftover); sctx->count[0] = leftover; spbc_bits = csbcpb->cpb.sha512.spbc * 8; @@ -169,7 +168,7 @@ static int nx_sha512_final(struct shash_desc *desc, u8 *out) goto out; atomic_inc(&(nx_ctx->stats->sha512_ops)); - atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo / 8, + atomic64_add(csbcpb->cpb.sha512.message_bit_length_lo, &(nx_ctx->stats->sha512_bytes)); memcpy(out, csbcpb->cpb.sha512.message_digest, SHA512_DIGEST_SIZE); diff --git a/trunk/drivers/crypto/nx/nx.c b/trunk/drivers/crypto/nx/nx.c index bbdab6e5ccf0..c767f232e693 100644 --- a/trunk/drivers/crypto/nx/nx.c +++ b/trunk/drivers/crypto/nx/nx.c @@ -211,20 +211,44 @@ int nx_build_sg_lists(struct nx_crypto_ctx *nx_ctx, { struct nx_sg *nx_insg = nx_ctx->in_sg; struct nx_sg *nx_outsg = nx_ctx->out_sg; + struct blkcipher_walk walk; + int rc; + + blkcipher_walk_init(&walk, dst, src, nbytes); + rc = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); + if (rc) + goto out; if (iv) - memcpy(iv, desc->info, AES_BLOCK_SIZE); + memcpy(iv, walk.iv, AES_BLOCK_SIZE); - nx_insg = nx_walk_and_build(nx_insg, nx_ctx->ap->sglen, src, 0, nbytes); - nx_outsg = nx_walk_and_build(nx_outsg, nx_ctx->ap->sglen, dst, 0, nbytes); + while (walk.nbytes) { + nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr, + walk.nbytes, nx_ctx->ap->sglen); + nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr, + walk.nbytes, nx_ctx->ap->sglen); + + rc = blkcipher_walk_done(desc, &walk, 0); + if (rc) + break; + } + + if (walk.nbytes) { + nx_insg = nx_build_sg_list(nx_insg, walk.src.virt.addr, + walk.nbytes, nx_ctx->ap->sglen); + nx_outsg = nx_build_sg_list(nx_outsg, walk.dst.virt.addr, + walk.nbytes, nx_ctx->ap->sglen); + + rc = 0; + } /* these lengths should be negative, which will indicate to phyp that * the input and output parameters are scatterlists, not linear * buffers */ nx_ctx->op.inlen = (nx_ctx->in_sg - nx_insg) * sizeof(struct nx_sg); nx_ctx->op.outlen = (nx_ctx->out_sg - nx_outsg) * sizeof(struct nx_sg); - - return 0; +out: + return rc; } /** @@ -430,8 +454,6 @@ static int nx_register_algs(void) if (rc) goto out; - nx_driver.of.status = NX_OKAY; - rc = crypto_register_alg(&nx_ecb_aes_alg); if (rc) goto out; @@ -476,6 +498,8 @@ static int nx_register_algs(void) if (rc) goto out_unreg_s512; + nx_driver.of.status = NX_OKAY; + goto out; out_unreg_s512: diff --git a/trunk/drivers/dma/tegra20-apb-dma.c b/trunk/drivers/dma/tegra20-apb-dma.c index 33f59ecd256e..ce193409ebd3 100644 --- a/trunk/drivers/dma/tegra20-apb-dma.c +++ b/trunk/drivers/dma/tegra20-apb-dma.c @@ -1273,6 +1273,11 @@ static int tegra_dma_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tdma); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "No mem resource for DMA\n"); + return -EINVAL; + } + tdma->base_addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(tdma->base_addr)) return PTR_ERR(tdma->base_addr); diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index 573c449c49b9..87d567089f13 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -636,7 +636,7 @@ config GPIO_MAX7301 config GPIO_MCP23S08 tristate "Microchip MCP23xxx I/O expander" - depends on (SPI_MASTER && !I2C) || I2C + depends on SPI_MASTER || I2C help SPI/I2C driver for Microchip MCP23S08/MCP23S17/MCP23008/MCP23017 I/O expanders. diff --git a/trunk/drivers/gpio/gpio-langwell.c b/trunk/drivers/gpio/gpio-langwell.c index 62ef10a641c4..634c3d37f7b5 100644 --- a/trunk/drivers/gpio/gpio-langwell.c +++ b/trunk/drivers/gpio/gpio-langwell.c @@ -324,7 +324,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, resource_size_t start, len; struct lnw_gpio *lnw; u32 gpio_base; - u32 irq_base; int retval; int ngpio = id->driver_data; @@ -346,7 +345,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, retval = -EFAULT; goto err_ioremap; } - irq_base = *(u32 *)base; gpio_base = *((u32 *)base + 1); /* release the IO mapping, since we already get the info from bar1 */ iounmap(base); @@ -367,6 +365,13 @@ static int lnw_gpio_probe(struct pci_dev *pdev, goto err_ioremap; } + lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, + &lnw_gpio_irq_ops, lnw); + if (!lnw->domain) { + retval = -ENOMEM; + goto err_ioremap; + } + lnw->reg_base = base; lnw->chip.label = dev_name(&pdev->dev); lnw->chip.request = lnw_gpio_request; @@ -379,14 +384,6 @@ static int lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.ngpio = ngpio; lnw->chip.can_sleep = 0; lnw->pdev = pdev; - - lnw->domain = irq_domain_add_simple(pdev->dev.of_node, ngpio, irq_base, - &lnw_gpio_irq_ops, lnw); - if (!lnw->domain) { - retval = -ENOMEM; - goto err_ioremap; - } - pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); if (retval) { diff --git a/trunk/drivers/gpio/gpio-ml-ioh.c b/trunk/drivers/gpio/gpio-ml-ioh.c index 0966f2637ad2..b73366523fae 100644 --- a/trunk/drivers/gpio/gpio-ml-ioh.c +++ b/trunk/drivers/gpio/gpio-ml-ioh.c @@ -496,7 +496,8 @@ static int ioh_gpio_probe(struct pci_dev *pdev, err_gpiochip_add: while (--i >= 0) { chip--; - if (gpiochip_remove(&chip->gpio)) + ret = gpiochip_remove(&chip->gpio); + if (ret) dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); } kfree(chip_save); diff --git a/trunk/drivers/gpio/gpio-mvebu.c b/trunk/drivers/gpio/gpio-mvebu.c index 3a4816adc137..bf69a7eff370 100644 --- a/trunk/drivers/gpio/gpio-mvebu.c +++ b/trunk/drivers/gpio/gpio-mvebu.c @@ -619,6 +619,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev) * per-CPU registers */ if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(&pdev->dev, "Cannot get memory resource\n"); + return -ENODEV; + } + mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(mvchip->percpu_membase)) diff --git a/trunk/drivers/gpio/gpio-mxs.c b/trunk/drivers/gpio/gpio-mxs.c index f8e6af20dfbf..25000b0f8453 100644 --- a/trunk/drivers/gpio/gpio-mxs.c +++ b/trunk/drivers/gpio/gpio-mxs.c @@ -326,8 +326,7 @@ static int mxs_gpio_probe(struct platform_device *pdev) err = bgpio_init(&port->bgc, &pdev->dev, 4, port->base + PINCTRL_DIN(port), - port->base + PINCTRL_DOUT(port) + MXS_SET, - port->base + PINCTRL_DOUT(port) + MXS_CLR, + port->base + PINCTRL_DOUT(port), NULL, port->base + PINCTRL_DOE(port), NULL, 0); if (err) goto out_irqdesc_free; diff --git a/trunk/drivers/gpio/gpio-omap.c b/trunk/drivers/gpio/gpio-omap.c index d3f7d2db870f..2050891d9c65 100644 --- a/trunk/drivers/gpio/gpio-omap.c +++ b/trunk/drivers/gpio/gpio-omap.c @@ -69,7 +69,6 @@ struct gpio_bank { bool is_mpuio; bool dbck_flag; bool loses_context; - bool context_valid; int stride; u32 width; int context_loss_count; @@ -1129,10 +1128,6 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->loses_context = true; } else { bank->loses_context = pdata->loses_context; - - if (bank->loses_context) - bank->get_context_loss_count = - pdata->get_context_loss_count; } @@ -1183,6 +1178,9 @@ static int omap_gpio_probe(struct platform_device *pdev) omap_gpio_chip_init(bank); omap_gpio_show_rev(bank); + if (bank->loses_context) + bank->get_context_loss_count = pdata->get_context_loss_count; + pm_runtime_put(bank->dev); list_add_tail(&bank->node, &omap_gpio_list); @@ -1261,8 +1259,6 @@ static int omap_gpio_runtime_suspend(struct device *dev) return 0; } -static void omap_gpio_init_context(struct gpio_bank *p); - static int omap_gpio_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -1272,20 +1268,6 @@ static int omap_gpio_runtime_resume(struct device *dev) int c; spin_lock_irqsave(&bank->lock, flags); - - /* - * On the first resume during the probe, the context has not - * been initialised and so initialise it now. Also initialise - * the context loss count. - */ - if (bank->loses_context && !bank->context_valid) { - omap_gpio_init_context(bank); - - if (bank->get_context_loss_count) - bank->context_loss_count = - bank->get_context_loss_count(bank->dev); - } - _gpio_dbck_enable(bank); /* @@ -1402,29 +1384,6 @@ void omap2_gpio_resume_after_idle(void) } #if defined(CONFIG_PM_RUNTIME) -static void omap_gpio_init_context(struct gpio_bank *p) -{ - struct omap_gpio_reg_offs *regs = p->regs; - void __iomem *base = p->base; - - p->context.ctrl = __raw_readl(base + regs->ctrl); - p->context.oe = __raw_readl(base + regs->direction); - p->context.wake_en = __raw_readl(base + regs->wkup_en); - p->context.leveldetect0 = __raw_readl(base + regs->leveldetect0); - p->context.leveldetect1 = __raw_readl(base + regs->leveldetect1); - p->context.risingdetect = __raw_readl(base + regs->risingdetect); - p->context.fallingdetect = __raw_readl(base + regs->fallingdetect); - p->context.irqenable1 = __raw_readl(base + regs->irqenable); - p->context.irqenable2 = __raw_readl(base + regs->irqenable2); - - if (regs->set_dataout && p->regs->clr_dataout) - p->context.dataout = __raw_readl(base + regs->set_dataout); - else - p->context.dataout = __raw_readl(base + regs->dataout); - - p->context_valid = true; -} - static void omap_gpio_restore_context(struct gpio_bank *bank) { __raw_writel(bank->context.wake_en, @@ -1462,7 +1421,6 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) #else #define omap_gpio_runtime_suspend NULL #define omap_gpio_runtime_resume NULL -static void omap_gpio_init_context(struct gpio_bank *p) {} #endif static const struct dev_pm_ops gpio_pm_ops = { diff --git a/trunk/drivers/gpio/gpio-pch.c b/trunk/drivers/gpio/gpio-pch.c index 0fec097e838d..cdf599687cf7 100644 --- a/trunk/drivers/gpio/gpio-pch.c +++ b/trunk/drivers/gpio/gpio-pch.c @@ -424,7 +424,8 @@ static int pch_gpio_probe(struct pci_dev *pdev, err_request_irq: irq_free_descs(irq_base, gpio_pins[chip->ioh]); - if (gpiochip_remove(&chip->gpio)) + ret = gpiochip_remove(&chip->gpio); + if (ret) dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); err_gpiochip_add: diff --git a/trunk/drivers/gpio/gpio-sch.c b/trunk/drivers/gpio/gpio-sch.c index 5af65719b95d..1e4de16ceb41 100644 --- a/trunk/drivers/gpio/gpio-sch.c +++ b/trunk/drivers/gpio/gpio-sch.c @@ -272,8 +272,10 @@ static int sch_gpio_probe(struct platform_device *pdev) return 0; err_sch_gpio_resume: - if (gpiochip_remove(&sch_gpio_core)) - dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); + err = gpiochip_remove(&sch_gpio_core); + if (err) + dev_err(&pdev->dev, "%s failed, %d\n", + "gpiochip_remove()", err); err_sch_gpio_core: release_region(res->start, resource_size(res)); diff --git a/trunk/drivers/gpio/gpio-tegra.c b/trunk/drivers/gpio/gpio-tegra.c index 9a62672f1bed..da4cb5b0cb87 100644 --- a/trunk/drivers/gpio/gpio-tegra.c +++ b/trunk/drivers/gpio/gpio-tegra.c @@ -463,6 +463,11 @@ static int tegra_gpio_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Missing MEM resource\n"); + return -ENODEV; + } + regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(regs)) return PTR_ERR(regs); diff --git a/trunk/drivers/gpio/gpio-viperboard.c b/trunk/drivers/gpio/gpio-viperboard.c index 5ac2919197fe..095ab14cea4d 100644 --- a/trunk/drivers/gpio/gpio-viperboard.c +++ b/trunk/drivers/gpio/gpio-viperboard.c @@ -446,8 +446,7 @@ static int vprbrd_gpio_probe(struct platform_device *pdev) return ret; err_gpiob: - if (gpiochip_remove(&vb_gpio->gpioa)) - dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); + ret = gpiochip_remove(&vb_gpio->gpioa); err_gpioa: return ret; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c index 6652597586a1..bbfc3840080c 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -2005,6 +2005,11 @@ static int hdmi_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + DRM_ERROR("failed to find registers\n"); + return -ENOENT; + } + hdata->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hdata->regs)) return PTR_ERR(hdata->regs); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index a36e64e98ef3..955af122c3a6 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c @@ -138,6 +138,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; + device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; break; case 0xce: @@ -224,6 +225,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; + device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; break; case 0xc8: diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index 89bf459d584b..ddaeb5572903 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -47,7 +47,6 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) struct nouveau_gpuobj *cur; int i, p; - mutex_lock(&nv_subdev(priv)->mutex); cur = priv->playlist[priv->cur_playlist]; priv->cur_playlist = !priv->cur_playlist; @@ -61,7 +60,6 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) nv_wr32(priv, 0x0032f4, cur->addr >> 12); nv_wr32(priv, 0x0032ec, p); nv_wr32(priv, 0x002500, 0x00000101); - mutex_unlock(&nv_subdev(priv)->mutex); } static int diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 46dfa68c47bb..4d4a6b905370 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -71,7 +71,6 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) struct nouveau_gpuobj *cur; int i, p; - mutex_lock(&nv_subdev(priv)->mutex); cur = priv->playlist[priv->cur_playlist]; priv->cur_playlist = !priv->cur_playlist; @@ -88,7 +87,6 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3)); if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000)) nv_error(priv, "playlist update failed\n"); - mutex_unlock(&nv_subdev(priv)->mutex); } static int @@ -250,17 +248,9 @@ nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend) struct nvc0_fifo_priv *priv = (void *)object->engine; struct nvc0_fifo_chan *chan = (void *)object; u32 chid = chan->base.chid; - u32 mask, engine; nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); nvc0_fifo_playlist_update(priv); - mask = nv_rd32(priv, 0x0025a4); - for (engine = 0; mask && engine < 16; engine++) { - if (!(mask & (1 << engine))) - continue; - nv_mask(priv, 0x0025a8 + (engine * 4), 0x00000000, 0x00000000); - mask &= ~(1 << engine); - } nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); return nouveau_fifo_channel_fini(&chan->base, suspend); diff --git a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 56192a7242ae..9151919fb831 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -94,13 +94,11 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) u32 match = (engine << 16) | 0x00000001; int i, p; - mutex_lock(&nv_subdev(priv)->mutex); cur = engn->playlist[engn->cur_playlist]; if (unlikely(cur == NULL)) { int ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000, 0, &cur); if (ret) { - mutex_unlock(&nv_subdev(priv)->mutex); nv_error(priv, "playlist alloc failed\n"); return; } @@ -124,7 +122,6 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) nv_error(priv, "playlist %d update timeout\n", engine); - mutex_unlock(&nv_subdev(priv)->mutex); } static int diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index c434d398d16f..c300b5e7b670 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -1940,8 +1940,8 @@ init_zm_mask_add(struct nvbios_init *init) trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add); init->offset += 13; - data = init_rd32(init, addr); - data = (data & mask) | ((data + add) & ~mask); + data = init_rd32(init, addr) & mask; + data |= ((data + add) & ~mask); init_wr32(init, addr, data); } diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c index fb794e997fbc..e4940fb166e8 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c @@ -29,6 +29,7 @@ struct nvc0_ltcg_priv { struct nouveau_ltcg base; u32 part_nr; + u32 part_mask; u32 subp_nr; struct nouveau_mm tags; u32 num_tags; @@ -104,6 +105,8 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) /* wait until it's finished with clearing */ for (p = 0; p < priv->part_nr; ++p) { + if (!(priv->part_mask & (1 << p))) + continue; for (i = 0; i < priv->subp_nr; ++i) nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); } @@ -118,8 +121,6 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) int ret; nv_wr32(priv, 0x17e8d8, priv->part_nr); - if (nv_device(pfb)->card_type >= NV_E0) - nv_wr32(priv, 0x17e000, priv->part_nr); /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */ priv->num_tags = (pfb->ram.size >> 17) / 4; @@ -166,20 +167,16 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, { struct nvc0_ltcg_priv *priv; struct nouveau_fb *pfb = nouveau_fb(parent); - u32 parts, mask; - int ret, i; + int ret; ret = nouveau_ltcg_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; - parts = nv_rd32(priv, 0x022438); - mask = nv_rd32(priv, 0x022554); - for (i = 0; i < parts; i++) { - if (!(mask & (1 << i))) - priv->part_nr++; - } + priv->part_nr = nv_rd32(priv, 0x022438); + priv->part_mask = nv_rd32(priv, 0x022554); + priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index 383f4e6ea9d1..46c152ff0a80 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -453,32 +453,18 @@ nouveau_do_suspend(struct drm_device *dev) NV_INFO(drm, "evicting buffers...\n"); ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); - NV_INFO(drm, "waiting for kernel channels to go idle...\n"); - if (drm->cechan) { - ret = nouveau_channel_idle(drm->cechan); - if (ret) - return ret; - } - - if (drm->channel) { - ret = nouveau_channel_idle(drm->channel); - if (ret) - return ret; - } - - NV_INFO(drm, "suspending client object trees...\n"); if (drm->fence && nouveau_fence(drm)->suspend) { if (!nouveau_fence(drm)->suspend(drm)) return -ENOMEM; } + NV_INFO(drm, "suspending client object trees...\n"); list_for_each_entry(cli, &drm->clients, head) { ret = nouveau_client_fini(&cli->base, true); if (ret) goto fail_client; } - NV_INFO(drm, "suspending kernel object tree...\n"); ret = nouveau_client_fini(&drm->client.base, true); if (ret) goto fail_client; @@ -528,18 +514,17 @@ nouveau_do_resume(struct drm_device *dev) nouveau_agp_reset(drm); - NV_INFO(drm, "resuming kernel object tree...\n"); + NV_INFO(drm, "resuming client object trees...\n"); nouveau_client_init(&drm->client.base); nouveau_agp_init(drm); - NV_INFO(drm, "resuming client object trees...\n"); - if (drm->fence && nouveau_fence(drm)->resume) - nouveau_fence(drm)->resume(drm); - list_for_each_entry(cli, &drm->clients, head) { nouveau_client_init(&cli->base); } + if (drm->fence && nouveau_fence(drm)->resume) + nouveau_fence(drm)->resume(drm); + nouveau_run_vbios_init(dev); nouveau_pm_resume(dev); diff --git a/trunk/drivers/gpu/drm/qxl/qxl_cmd.c b/trunk/drivers/gpu/drm/qxl/qxl_cmd.c index f86771481317..08b0823c93d5 100644 --- a/trunk/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/trunk/drivers/gpu/drm/qxl/qxl_cmd.c @@ -277,7 +277,7 @@ int qxl_alloc_bo_reserved(struct qxl_device *qdev, unsigned long size, return 0; } -static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, bool intr) +static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port) { int irq_num; long addr = qdev->io_base + port; @@ -285,29 +285,20 @@ static int wait_for_io_cmd_user(struct qxl_device *qdev, uint8_t val, long port, mutex_lock(&qdev->async_io_mutex); irq_num = atomic_read(&qdev->irq_received_io_cmd); + + if (qdev->last_sent_io_cmd > irq_num) { - if (intr) - ret = wait_event_interruptible_timeout(qdev->io_cmd_event, - atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); - else - ret = wait_event_timeout(qdev->io_cmd_event, - atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); - /* 0 is timeout, just bail the "hw" has gone away */ - if (ret <= 0) + ret = wait_event_interruptible(qdev->io_cmd_event, + atomic_read(&qdev->irq_received_io_cmd) > irq_num); + if (ret) goto out; irq_num = atomic_read(&qdev->irq_received_io_cmd); } outb(val, addr); qdev->last_sent_io_cmd = irq_num + 1; - if (intr) - ret = wait_event_interruptible_timeout(qdev->io_cmd_event, - atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); - else - ret = wait_event_timeout(qdev->io_cmd_event, - atomic_read(&qdev->irq_received_io_cmd) > irq_num, 5*HZ); + ret = wait_event_interruptible(qdev->io_cmd_event, + atomic_read(&qdev->irq_received_io_cmd) > irq_num); out: - if (ret > 0) - ret = 0; mutex_unlock(&qdev->async_io_mutex); return ret; } @@ -317,7 +308,7 @@ static void wait_for_io_cmd(struct qxl_device *qdev, uint8_t val, long port) int ret; restart: - ret = wait_for_io_cmd_user(qdev, val, port, false); + ret = wait_for_io_cmd_user(qdev, val, port); if (ret == -ERESTARTSYS) goto restart; } @@ -349,7 +340,7 @@ int qxl_io_update_area(struct qxl_device *qdev, struct qxl_bo *surf, mutex_lock(&qdev->update_area_mutex); qdev->ram_header->update_area = *area; qdev->ram_header->update_surface = surface_id; - ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC, true); + ret = wait_for_io_cmd_user(qdev, 0, QXL_IO_UPDATE_AREA_ASYNC); mutex_unlock(&qdev->update_area_mutex); return ret; } diff --git a/trunk/drivers/gpu/drm/qxl/qxl_display.c b/trunk/drivers/gpu/drm/qxl/qxl_display.c index 823d29e926ec..fcfd4436ceed 100644 --- a/trunk/drivers/gpu/drm/qxl/qxl_display.c +++ b/trunk/drivers/gpu/drm/qxl/qxl_display.c @@ -428,10 +428,10 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, int inc = 1; qobj = gem_to_qxl_bo(qxl_fb->obj); - /* if we aren't primary surface ignore this */ - if (!qobj->is_primary) - return 0; - + if (qxl_fb != qdev->active_user_framebuffer) { + DRM_INFO("%s: qxl_fb 0x%p != qdev->active_user_framebuffer 0x%p\n", + __func__, qxl_fb, qdev->active_user_framebuffer); + } if (!num_clips) { num_clips = 1; clips = &norect; @@ -604,6 +604,7 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, mode->hdisplay, mode->vdisplay); } + qdev->mode_set = true; return 0; } @@ -892,6 +893,7 @@ qxl_user_framebuffer_create(struct drm_device *dev, { struct drm_gem_object *obj; struct qxl_framebuffer *qxl_fb; + struct qxl_device *qdev = dev->dev_private; int ret; obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); @@ -907,6 +909,13 @@ qxl_user_framebuffer_create(struct drm_device *dev, return NULL; } + if (qdev->active_user_framebuffer) { + DRM_INFO("%s: active_user_framebuffer %p -> %p\n", + __func__, + qdev->active_user_framebuffer, qxl_fb); + } + qdev->active_user_framebuffer = qxl_fb; + return &qxl_fb->base; } diff --git a/trunk/drivers/gpu/drm/qxl/qxl_drv.h b/trunk/drivers/gpu/drm/qxl/qxl_drv.h index 43d06ab28a21..52b582c211da 100644 --- a/trunk/drivers/gpu/drm/qxl/qxl_drv.h +++ b/trunk/drivers/gpu/drm/qxl/qxl_drv.h @@ -255,6 +255,12 @@ struct qxl_device { struct qxl_gem gem; struct qxl_mode_info mode_info; + /* + * last created framebuffer with fb_create + * only used by debugfs dumbppm + */ + struct qxl_framebuffer *active_user_framebuffer; + struct fb_info *fbdev_info; struct qxl_framebuffer *fbdev_qfb; void *ram_physical; @@ -264,6 +270,7 @@ struct qxl_device { struct qxl_ring *cursor_ring; struct qxl_ram_header *ram_header; + bool mode_set; bool primary_created; diff --git a/trunk/drivers/gpu/drm/qxl/qxl_ioctl.c b/trunk/drivers/gpu/drm/qxl/qxl_ioctl.c index 6db7370373ea..04b64f9cbfdb 100644 --- a/trunk/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/trunk/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -294,7 +294,6 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, goto out; if (!qobj->pin_count) { - qxl_ttm_placement_from_domain(qobj, qobj->type); ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, true, false); if (unlikely(ret)) diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index d5df8fd10217..6d6fdb3ba0d0 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1811,9 +1811,12 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, static void atombios_crtc_prepare(struct drm_crtc *crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct radeon_device *rdev = dev->dev_private; + radeon_crtc->in_mode_set = true; + /* disable crtc pair power gating before programming */ if (ASIC_IS_DCE6(rdev)) atombios_powergate_crtc(crtc, ATOM_DISABLE); @@ -1824,8 +1827,11 @@ static void atombios_crtc_prepare(struct drm_crtc *crtc) static void atombios_crtc_commit(struct drm_crtc *crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); atombios_lock_crtc(crtc, ATOM_DISABLE); + radeon_crtc->in_mode_set = false; } static void atombios_crtc_disable(struct drm_crtc *crtc) diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 8f9e2d31b255..105bafb6c29d 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -2343,13 +2343,11 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav u32 crtc_enabled, tmp, frame_count, blackout; int i, j; - if (!ASIC_IS_NODCE(rdev)) { - save->vga_render_control = RREG32(VGA_RENDER_CONTROL); - save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); + save->vga_render_control = RREG32(VGA_RENDER_CONTROL); + save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); - /* disable VGA render */ - WREG32(VGA_RENDER_CONTROL, 0); - } + /* disable VGA render */ + WREG32(VGA_RENDER_CONTROL, 0); /* blank the display controllers */ for (i = 0; i < rdev->num_crtc; i++) { crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN; @@ -2440,11 +2438,8 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], (u32)rdev->mc.vram_start); } - - if (!ASIC_IS_NODCE(rdev)) { - WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); - } + WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); /* unlock regs and wait for update */ for (i = 0; i < rdev->num_crtc; i++) { @@ -2504,12 +2499,10 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s } } } - if (!ASIC_IS_NODCE(rdev)) { - /* Unlock vga access */ - WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); - mdelay(1); - WREG32(VGA_RENDER_CONTROL, save->vga_render_control); - } + /* Unlock vga access */ + WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); + mdelay(1); + WREG32(VGA_RENDER_CONTROL, save->vga_render_control); } void evergreen_mc_program(struct radeon_device *rdev) @@ -3412,8 +3405,8 @@ int evergreen_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); } else { /* size in MB on evergreen/cayman/tn */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; + rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; } rdev->mc.visible_vram_size = rdev->mc.aper_size; r700_vram_gtt_location(rdev, &rdev->mc); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c b/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c index ed7c8a768092..b4ab8ceb1654 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -154,18 +154,19 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - u32 base_rate = 24000; + u32 base_rate = 48000; if (!dig || !dig->afmt) return; + /* XXX: properly calculate this */ /* XXX two dtos; generally use dto0 for hdmi */ /* Express [24MHz / target pixel clock] as an exact rational * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator */ - WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); - WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); + WREG32(DCCG_AUDIO_DTO0_PHASE, (base_rate*50) & 0xffffff); + WREG32(DCCG_AUDIO_DTO0_MODULE, (clock*100) & 0xffffff); WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); } diff --git a/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c b/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c index 60170ea5e3a2..865e2c9980db 100644 --- a/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/trunk/drivers/gpu/drm/radeon/r300_cmdbuf.c @@ -75,7 +75,7 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); for (i = 0; i < nr; ++i) { - if (DRM_COPY_FROM_USER + if (DRM_COPY_FROM_USER_UNCHECKED (&box, &cmdbuf->boxes[n + i], sizeof(box))) { DRM_ERROR("copy cliprect faulted\n"); return -EFAULT; diff --git a/trunk/drivers/gpu/drm/radeon/r600_hdmi.c b/trunk/drivers/gpu/drm/radeon/r600_hdmi.c index 456750a0daa5..47f180a79352 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/trunk/drivers/gpu/drm/radeon/r600_hdmi.c @@ -232,7 +232,7 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - u32 base_rate = 24000; + u32 base_rate = 48000; if (!dig || !dig->afmt) return; @@ -240,6 +240,7 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. * doesn't matter which one you use. Just use the first one. */ + /* XXX: properly calculate this */ /* XXX two dtos; generally use dto0 for hdmi */ /* Express [24MHz / target pixel clock] as an exact rational * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE @@ -249,13 +250,13 @@ void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) /* according to the reg specs, this should DCE3.2 only, but in * practice it seems to cover DCE3.0 as well. */ - WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); + WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 50); WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ } else { /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ - WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | - AUDIO_DTO_MODULE(clock / 10)); + WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate * 50) | + AUDIO_DTO_MODULE(clock * 100)); } } diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 142ce6cc69f5..1442ce765d48 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -1694,7 +1694,6 @@ struct radeon_device { int num_crtc; /* number of crtcs */ struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ bool audio_enabled; - bool has_uvd; struct r600_audio audio_status; /* audio stuff */ struct notifier_block acpi_nb; /* only one userspace can use Hyperz features or CMASK at a time */ @@ -1839,7 +1838,6 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); #define ASIC_IS_DCE61(rdev) ((rdev->family >= CHIP_ARUBA) && \ (rdev->flags & RADEON_IS_IGP)) #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND)) -#define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN)) /* * BIOS helpers. diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c index 06b8c19ab19e..6417132c50cf 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c @@ -1935,8 +1935,6 @@ int radeon_asic_init(struct radeon_device *rdev) else rdev->num_crtc = 2; - rdev->has_uvd = false; - switch (rdev->family) { case CHIP_R100: case CHIP_RV100: @@ -2001,22 +1999,16 @@ int radeon_asic_init(struct radeon_device *rdev) case CHIP_RV635: case CHIP_RV670: rdev->asic = &r600_asic; - if (rdev->family == CHIP_R600) - rdev->has_uvd = false; - else - rdev->has_uvd = true; break; case CHIP_RS780: case CHIP_RS880: rdev->asic = &rs780_asic; - rdev->has_uvd = true; break; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: rdev->asic = &rv770_asic; - rdev->has_uvd = true; break; case CHIP_CEDAR: case CHIP_REDWOOD: @@ -2029,13 +2021,11 @@ int radeon_asic_init(struct radeon_device *rdev) else rdev->num_crtc = 6; rdev->asic = &evergreen_asic; - rdev->has_uvd = true; break; case CHIP_PALM: case CHIP_SUMO: case CHIP_SUMO2: rdev->asic = &sumo_asic; - rdev->has_uvd = true; break; case CHIP_BARTS: case CHIP_TURKS: @@ -2046,37 +2036,27 @@ int radeon_asic_init(struct radeon_device *rdev) else rdev->num_crtc = 6; rdev->asic = &btc_asic; - rdev->has_uvd = true; break; case CHIP_CAYMAN: rdev->asic = &cayman_asic; /* set num crtcs */ rdev->num_crtc = 6; - rdev->has_uvd = true; break; case CHIP_ARUBA: rdev->asic = &trinity_asic; /* set num crtcs */ rdev->num_crtc = 4; - rdev->has_uvd = true; break; case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_VERDE: case CHIP_OLAND: - case CHIP_HAINAN: rdev->asic = &si_asic; /* set num crtcs */ - if (rdev->family == CHIP_HAINAN) - rdev->num_crtc = 0; - else if (rdev->family == CHIP_OLAND) + if (rdev->family == CHIP_OLAND) rdev->num_crtc = 2; else rdev->num_crtc = 6; - if (rdev->family == CHIP_HAINAN) - rdev->has_uvd = false; - else - rdev->has_uvd = true; break; default: /* FIXME: not supported yet */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index 061b227dae0c..fa3c56fba294 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -244,28 +244,24 @@ static bool ni_read_disabled_bios(struct radeon_device *rdev) /* enable the rom */ WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS)); - if (!ASIC_IS_NODCE(rdev)) { - /* Disable VGA mode */ - WREG32(AVIVO_D1VGA_CONTROL, - (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_D2VGA_CONTROL, - (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | - AVIVO_DVGA_CONTROL_TIMING_SELECT))); - WREG32(AVIVO_VGA_RENDER_CONTROL, - (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); - } + /* Disable VGA mode */ + WREG32(AVIVO_D1VGA_CONTROL, + (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | + AVIVO_DVGA_CONTROL_TIMING_SELECT))); + WREG32(AVIVO_D2VGA_CONTROL, + (d2vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE | + AVIVO_DVGA_CONTROL_TIMING_SELECT))); + WREG32(AVIVO_VGA_RENDER_CONTROL, + (vga_render_control & ~AVIVO_VGA_VSTATUS_CNTL_MASK)); WREG32(R600_ROM_CNTL, rom_cntl | R600_SCK_OVERWRITE); r = radeon_read_bios(rdev); /* restore regs */ WREG32(R600_BUS_CNTL, bus_cntl); - if (!ASIC_IS_NODCE(rdev)) { - WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); - WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); - WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); - } + WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); + WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); + WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); WREG32(R600_ROM_CNTL, rom_cntl); return r; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index c2c59fb1ea01..a8f608903989 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -94,7 +94,6 @@ static const char radeon_family_name[][16] = { "PITCAIRN", "VERDE", "OLAND", - "HAINAN", "LAST", }; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 094e7e5ea39e..d33f484ace48 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -147,7 +147,7 @@ static inline void radeon_unregister_atpx_handler(void) {} #endif int radeon_no_wb; -int radeon_modeset = -1; +int radeon_modeset = 1; int radeon_dynclks = -1; int radeon_r4xx_atom = 0; int radeon_agpmode = 0; @@ -456,16 +456,6 @@ static struct pci_driver radeon_kms_pci_driver = { static int __init radeon_init(void) { -#ifdef CONFIG_VGA_CONSOLE - if (vgacon_text_force() && radeon_modeset == -1) { - DRM_INFO("VGACON disable radeon kernel modesetting.\n"); - radeon_modeset = 0; - } -#endif - /* set to modesetting by default if not nomodeset */ - if (radeon_modeset == -1) - radeon_modeset = 1; - if (radeon_modeset == 1) { DRM_INFO("radeon kernel modesetting enabled.\n"); driver = &kms_driver; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_family.h b/trunk/drivers/gpu/drm/radeon/radeon_family.h index 36e9803b077d..2d91123f2759 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_family.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_family.h @@ -92,7 +92,6 @@ enum radeon_family { CHIP_PITCAIRN, CHIP_VERDE, CHIP_OLAND, - CHIP_HAINAN, CHIP_LAST, }; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 7cb178a34a0f..6857cb4efb76 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -1031,9 +1031,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, static void radeon_crtc_prepare(struct drm_crtc *crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct drm_crtc *crtci; + radeon_crtc->in_mode_set = true; /* * The hardware wedges sometimes if you reconfigure one CRTC * whilst another is running (see fdo bug #24611). @@ -1044,6 +1046,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) static void radeon_crtc_commit(struct drm_crtc *crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; struct drm_crtc *crtci; @@ -1054,6 +1057,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) if (crtci->enabled) radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); } + radeon_crtc->in_mode_set = false; } static const struct drm_crtc_helper_funcs legacy_helper_funcs = { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index 69ad4fe224c1..44e579e75fd0 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -302,6 +302,7 @@ struct radeon_crtc { u16 lut_r[256], lut_g[256], lut_b[256]; bool enabled; bool can_tile; + bool in_mode_set; uint32_t crtc_offset; struct drm_gem_object *cursor_bo; uint64_t cursor_addr; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c index 6c0ce8915fac..93f760e27a92 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c @@ -726,7 +726,7 @@ int radeon_ttm_init(struct radeon_device *rdev) return r; } DRM_INFO("radeon: %uM of VRAM memory ready\n", - (unsigned) (rdev->mc.real_vram_size / (1024 * 1024))); + (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, rdev->mc.gtt_size >> PAGE_SHIFT); if (r) { diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 5ffade69af25..f0b6c2f87c4d 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -60,11 +60,6 @@ MODULE_FIRMWARE("radeon/OLAND_me.bin"); MODULE_FIRMWARE("radeon/OLAND_ce.bin"); MODULE_FIRMWARE("radeon/OLAND_mc.bin"); MODULE_FIRMWARE("radeon/OLAND_rlc.bin"); -MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); -MODULE_FIRMWARE("radeon/HAINAN_me.bin"); -MODULE_FIRMWARE("radeon/HAINAN_ce.bin"); -MODULE_FIRMWARE("radeon/HAINAN_mc.bin"); -MODULE_FIRMWARE("radeon/HAINAN_rlc.bin"); extern int r600_ih_ring_alloc(struct radeon_device *rdev); extern void r600_ih_ring_fini(struct radeon_device *rdev); @@ -270,40 +265,6 @@ static const u32 oland_golden_registers[] = 0x15c0, 0x000c0fc0, 0x000c0400 }; -static const u32 hainan_golden_registers[] = -{ - 0x9a10, 0x00010000, 0x00018208, - 0x9830, 0xffffffff, 0x00000000, - 0x9834, 0xf00fffff, 0x00000400, - 0x9838, 0x0002021c, 0x00020200, - 0xd0c0, 0xff000fff, 0x00000100, - 0xd030, 0x000300c0, 0x00800040, - 0xd8c0, 0xff000fff, 0x00000100, - 0xd830, 0x000300c0, 0x00800040, - 0x2ae4, 0x00073ffe, 0x000022a2, - 0x240c, 0x000007ff, 0x00000000, - 0x8a14, 0xf000001f, 0x00000007, - 0x8b24, 0xffffffff, 0x00ffffff, - 0x8b10, 0x0000ff0f, 0x00000000, - 0x28a4c, 0x07ffffff, 0x4e000000, - 0x28350, 0x3f3f3fff, 0x00000000, - 0x30, 0x000000ff, 0x0040, - 0x34, 0x00000040, 0x00004040, - 0x9100, 0x03e00000, 0x03600000, - 0x9060, 0x0000007f, 0x00000020, - 0x9508, 0x00010000, 0x00010000, - 0xac14, 0x000003ff, 0x000000f1, - 0xac10, 0xffffffff, 0x00000000, - 0xac0c, 0xffffffff, 0x00003210, - 0x88d4, 0x0000001f, 0x00000010, - 0x15c0, 0x000c0fc0, 0x000c0400 -}; - -static const u32 hainan_golden_registers2[] = -{ - 0x98f8, 0xffffffff, 0x02010001 -}; - static const u32 tahiti_mgcg_cgcg_init[] = { 0xc400, 0xffffffff, 0xfffffffc, @@ -712,83 +673,6 @@ static const u32 oland_mgcg_cgcg_init[] = 0xd8c0, 0xfffffff0, 0x00000100 }; -static const u32 hainan_mgcg_cgcg_init[] = -{ - 0xc400, 0xffffffff, 0xfffffffc, - 0x802c, 0xffffffff, 0xe0000000, - 0x9a60, 0xffffffff, 0x00000100, - 0x92a4, 0xffffffff, 0x00000100, - 0xc164, 0xffffffff, 0x00000100, - 0x9774, 0xffffffff, 0x00000100, - 0x8984, 0xffffffff, 0x06000100, - 0x8a18, 0xffffffff, 0x00000100, - 0x92a0, 0xffffffff, 0x00000100, - 0xc380, 0xffffffff, 0x00000100, - 0x8b28, 0xffffffff, 0x00000100, - 0x9144, 0xffffffff, 0x00000100, - 0x8d88, 0xffffffff, 0x00000100, - 0x8d8c, 0xffffffff, 0x00000100, - 0x9030, 0xffffffff, 0x00000100, - 0x9034, 0xffffffff, 0x00000100, - 0x9038, 0xffffffff, 0x00000100, - 0x903c, 0xffffffff, 0x00000100, - 0xad80, 0xffffffff, 0x00000100, - 0xac54, 0xffffffff, 0x00000100, - 0x897c, 0xffffffff, 0x06000100, - 0x9868, 0xffffffff, 0x00000100, - 0x9510, 0xffffffff, 0x00000100, - 0xaf04, 0xffffffff, 0x00000100, - 0xae04, 0xffffffff, 0x00000100, - 0x949c, 0xffffffff, 0x00000100, - 0x802c, 0xffffffff, 0xe0000000, - 0x9160, 0xffffffff, 0x00010000, - 0x9164, 0xffffffff, 0x00030002, - 0x9168, 0xffffffff, 0x00040007, - 0x916c, 0xffffffff, 0x00060005, - 0x9170, 0xffffffff, 0x00090008, - 0x9174, 0xffffffff, 0x00020001, - 0x9178, 0xffffffff, 0x00040003, - 0x917c, 0xffffffff, 0x00000007, - 0x9180, 0xffffffff, 0x00060005, - 0x9184, 0xffffffff, 0x00090008, - 0x9188, 0xffffffff, 0x00030002, - 0x918c, 0xffffffff, 0x00050004, - 0x9190, 0xffffffff, 0x00000008, - 0x9194, 0xffffffff, 0x00070006, - 0x9198, 0xffffffff, 0x000a0009, - 0x919c, 0xffffffff, 0x00040003, - 0x91a0, 0xffffffff, 0x00060005, - 0x91a4, 0xffffffff, 0x00000009, - 0x91a8, 0xffffffff, 0x00080007, - 0x91ac, 0xffffffff, 0x000b000a, - 0x91b0, 0xffffffff, 0x00050004, - 0x91b4, 0xffffffff, 0x00070006, - 0x91b8, 0xffffffff, 0x0008000b, - 0x91bc, 0xffffffff, 0x000a0009, - 0x91c0, 0xffffffff, 0x000d000c, - 0x91c4, 0xffffffff, 0x00060005, - 0x91c8, 0xffffffff, 0x00080007, - 0x91cc, 0xffffffff, 0x0000000b, - 0x91d0, 0xffffffff, 0x000a0009, - 0x91d4, 0xffffffff, 0x000d000c, - 0x9150, 0xffffffff, 0x96940200, - 0x8708, 0xffffffff, 0x00900100, - 0xc478, 0xffffffff, 0x00000080, - 0xc404, 0xffffffff, 0x0020003f, - 0x30, 0xffffffff, 0x0000001c, - 0x34, 0x000f0000, 0x000f0000, - 0x160c, 0xffffffff, 0x00000100, - 0x1024, 0xffffffff, 0x00000100, - 0x20a8, 0xffffffff, 0x00000104, - 0x264c, 0x000c0000, 0x000c0000, - 0x2648, 0x000c0000, 0x000c0000, - 0x2f50, 0x00000001, 0x00000001, - 0x30cc, 0xc0000fff, 0x00000104, - 0xc1e4, 0x00000001, 0x00000001, - 0xd0c0, 0xfffffff0, 0x00000100, - 0xd8c0, 0xfffffff0, 0x00000100 -}; - static u32 verde_pg_init[] = { 0x353c, 0xffffffff, 0x40000, @@ -969,17 +853,6 @@ static void si_init_golden_registers(struct radeon_device *rdev) oland_mgcg_cgcg_init, (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init)); break; - case CHIP_HAINAN: - radeon_program_register_sequence(rdev, - hainan_golden_registers, - (const u32)ARRAY_SIZE(hainan_golden_registers)); - radeon_program_register_sequence(rdev, - hainan_golden_registers2, - (const u32)ARRAY_SIZE(hainan_golden_registers2)); - radeon_program_register_sequence(rdev, - hainan_mgcg_cgcg_init, - (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init)); - break; default: break; } @@ -1189,45 +1062,6 @@ static const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { {0x0000009f, 0x00a17730} }; -static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { - {0x0000006f, 0x03044000}, - {0x00000070, 0x0480c018}, - {0x00000071, 0x00000040}, - {0x00000072, 0x01000000}, - {0x00000074, 0x000000ff}, - {0x00000075, 0x00143400}, - {0x00000076, 0x08ec0800}, - {0x00000077, 0x040000cc}, - {0x00000079, 0x00000000}, - {0x0000007a, 0x21000409}, - {0x0000007c, 0x00000000}, - {0x0000007d, 0xe8000000}, - {0x0000007e, 0x044408a8}, - {0x0000007f, 0x00000003}, - {0x00000080, 0x00000000}, - {0x00000081, 0x01000000}, - {0x00000082, 0x02000000}, - {0x00000083, 0x00000000}, - {0x00000084, 0xe3f3e4f4}, - {0x00000085, 0x00052024}, - {0x00000087, 0x00000000}, - {0x00000088, 0x66036603}, - {0x00000089, 0x01000000}, - {0x0000008b, 0x1c0a0000}, - {0x0000008c, 0xff010000}, - {0x0000008e, 0xffffefff}, - {0x0000008f, 0xfff3efff}, - {0x00000090, 0xfff3efbf}, - {0x00000094, 0x00101101}, - {0x00000095, 0x00000fff}, - {0x00000096, 0x00116fff}, - {0x00000097, 0x60010000}, - {0x00000098, 0x10010000}, - {0x00000099, 0x00006000}, - {0x0000009a, 0x00001000}, - {0x0000009f, 0x00a07730} -}; - /* ucode loading */ static int si_mc_load_microcode(struct radeon_device *rdev) { @@ -1261,11 +1095,6 @@ static int si_mc_load_microcode(struct radeon_device *rdev) ucode_size = OLAND_MC_UCODE_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE; break; - case CHIP_HAINAN: - io_mc_regs = (u32 *)&hainan_io_mc_regs; - ucode_size = OLAND_MC_UCODE_SIZE; - regs_size = TAHITI_IO_MC_REGS_SIZE; - break; } running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; @@ -1369,15 +1198,6 @@ static int si_init_microcode(struct radeon_device *rdev) rlc_req_size = SI_RLC_UCODE_SIZE * 4; mc_req_size = OLAND_MC_UCODE_SIZE * 4; break; - case CHIP_HAINAN: - chip_name = "HAINAN"; - rlc_chip_name = "HAINAN"; - pfp_req_size = SI_PFP_UCODE_SIZE * 4; - me_req_size = SI_PM4_UCODE_SIZE * 4; - ce_req_size = SI_CE_UCODE_SIZE * 4; - rlc_req_size = SI_RLC_UCODE_SIZE * 4; - mc_req_size = OLAND_MC_UCODE_SIZE * 4; - break; default: BUG(); } @@ -2183,8 +2003,7 @@ static void si_tiling_mode_table_init(struct radeon_device *rdev) WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden); } } else if ((rdev->family == CHIP_VERDE) || - (rdev->family == CHIP_OLAND) || - (rdev->family == CHIP_HAINAN)) { + (rdev->family == CHIP_OLAND)) { for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { switch (reg_offset) { case 0: /* non-AA compressed depth or any compressed stencil */ @@ -2647,23 +2466,6 @@ static void si_gpu_init(struct radeon_device *rdev) rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; break; - case CHIP_HAINAN: - rdev->config.si.max_shader_engines = 1; - rdev->config.si.max_tile_pipes = 4; - rdev->config.si.max_cu_per_sh = 5; - rdev->config.si.max_sh_per_se = 1; - rdev->config.si.max_backends_per_se = 1; - rdev->config.si.max_texture_channel_caches = 2; - rdev->config.si.max_gprs = 256; - rdev->config.si.max_gs_threads = 16; - rdev->config.si.max_hw_contexts = 8; - - rdev->config.si.sc_prim_fifo_size_frontend = 0x20; - rdev->config.si.sc_prim_fifo_size_backend = 0x40; - rdev->config.si.sc_hiz_tile_fifo_size = 0x30; - rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN; - break; } /* Initialize HDP */ @@ -2757,11 +2559,9 @@ static void si_gpu_init(struct radeon_device *rdev) WREG32(HDP_ADDR_CONFIG, gb_addr_config); WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); - if (rdev->has_uvd) { - WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); - WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); - WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); - } + WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); + WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); + WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); si_tiling_mode_table_init(rdev); @@ -3504,9 +3304,8 @@ static void si_mc_program(struct radeon_device *rdev) if (radeon_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } - if (!ASIC_IS_NODCE(rdev)) - /* Lockout access through VGA aperture*/ - WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); + /* Lockout access through VGA aperture*/ + WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); /* Update configuration */ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); @@ -3528,11 +3327,9 @@ static void si_mc_program(struct radeon_device *rdev) dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); } evergreen_mc_resume(rdev, &save); - if (!ASIC_IS_NODCE(rdev)) { - /* we need to own VRAM, so turn off the VGA renderer here - * to stop it overwriting our objects */ - rv515_vga_render_disable(rdev); - } + /* we need to own VRAM, so turn off the VGA renderer here + * to stop it overwriting our objects */ + rv515_vga_render_disable(rdev); } static void si_vram_gtt_location(struct radeon_device *rdev, @@ -3600,8 +3397,8 @@ static int si_mc_init(struct radeon_device *rdev) rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* size in MB on si */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; + rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; rdev->mc.visible_vram_size = rdev->mc.aper_size; si_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); @@ -4454,10 +4251,8 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp); WREG32(GRBM_INT_CNTL, 0); - if (rdev->num_crtc >= 2) { - WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - } + WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); if (rdev->num_crtc >= 4) { WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); @@ -4467,10 +4262,8 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); } - if (rdev->num_crtc >= 2) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - } + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); if (rdev->num_crtc >= 4) { WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); @@ -4480,22 +4273,21 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); } - if (!ASIC_IS_NODCE(rdev)) { - WREG32(DACA_AUTODETECT_INT_CONTROL, 0); + WREG32(DACA_AUTODETECT_INT_CONTROL, 0); + + tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; + WREG32(DC_HPD1_INT_CONTROL, tmp); + tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; + WREG32(DC_HPD2_INT_CONTROL, tmp); + tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; + WREG32(DC_HPD3_INT_CONTROL, tmp); + tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; + WREG32(DC_HPD4_INT_CONTROL, tmp); + tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; + WREG32(DC_HPD5_INT_CONTROL, tmp); + tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; + WREG32(DC_HPD6_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD1_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD2_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD3_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD4_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD5_INT_CONTROL, tmp); - tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; - WREG32(DC_HPD6_INT_CONTROL, tmp); - } } static int si_irq_init(struct radeon_device *rdev) @@ -4574,7 +4366,7 @@ int si_irq_set(struct radeon_device *rdev) u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; - u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0; + u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; u32 grbm_int_cntl = 0; u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; u32 dma_cntl, dma_cntl1; @@ -4591,14 +4383,12 @@ int si_irq_set(struct radeon_device *rdev) return 0; } - if (!ASIC_IS_NODCE(rdev)) { - hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; - hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; - } + hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; + hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; + hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; + hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; + hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; + hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; @@ -4689,10 +4479,8 @@ int si_irq_set(struct radeon_device *rdev) WREG32(GRBM_INT_CNTL, grbm_int_cntl); - if (rdev->num_crtc >= 2) { - WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); - WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); - } + WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); + WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); if (rdev->num_crtc >= 4) { WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); @@ -4702,10 +4490,8 @@ int si_irq_set(struct radeon_device *rdev) WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); } - if (rdev->num_crtc >= 2) { - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); - } + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); if (rdev->num_crtc >= 4) { WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); @@ -4715,14 +4501,12 @@ int si_irq_set(struct radeon_device *rdev) WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); } - if (!ASIC_IS_NODCE(rdev)) { - WREG32(DC_HPD1_INT_CONTROL, hpd1); - WREG32(DC_HPD2_INT_CONTROL, hpd2); - WREG32(DC_HPD3_INT_CONTROL, hpd3); - WREG32(DC_HPD4_INT_CONTROL, hpd4); - WREG32(DC_HPD5_INT_CONTROL, hpd5); - WREG32(DC_HPD6_INT_CONTROL, hpd6); - } + WREG32(DC_HPD1_INT_CONTROL, hpd1); + WREG32(DC_HPD2_INT_CONTROL, hpd2); + WREG32(DC_HPD3_INT_CONTROL, hpd3); + WREG32(DC_HPD4_INT_CONTROL, hpd4); + WREG32(DC_HPD5_INT_CONTROL, hpd5); + WREG32(DC_HPD6_INT_CONTROL, hpd6); return 0; } @@ -4731,9 +4515,6 @@ static inline void si_irq_ack(struct radeon_device *rdev) { u32 tmp; - if (ASIC_IS_NODCE(rdev)) - return; - rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); @@ -5337,17 +5118,15 @@ static int si_startup(struct radeon_device *rdev) return r; } - if (rdev->has_uvd) { - r = rv770_uvd_resume(rdev); - if (!r) { - r = radeon_fence_driver_start_ring(rdev, - R600_RING_TYPE_UVD_INDEX); - if (r) - dev_err(rdev->dev, "UVD fences init error (%d).\n", r); - } + r = rv770_uvd_resume(rdev); + if (!r) { + r = radeon_fence_driver_start_ring(rdev, + R600_RING_TYPE_UVD_INDEX); if (r) - rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + dev_err(rdev->dev, "UVD fences init error (%d).\n", r); } + if (r) + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; /* Enable IRQ */ r = si_irq_init(rdev); @@ -5406,18 +5185,16 @@ static int si_startup(struct radeon_device *rdev) if (r) return r; - if (rdev->has_uvd) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - if (ring->ring_size) { - r = radeon_ring_init(rdev, ring, ring->ring_size, - R600_WB_UVD_RPTR_OFFSET, - UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, - 0, 0xfffff, RADEON_CP_PACKET2); - if (!r) - r = r600_uvd_init(rdev); - if (r) - DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); - } + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + if (ring->ring_size) { + r = radeon_ring_init(rdev, ring, ring->ring_size, + R600_WB_UVD_RPTR_OFFSET, + UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, + 0, 0xfffff, RADEON_CP_PACKET2); + if (!r) + r = r600_uvd_init(rdev); + if (r) + DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); } r = radeon_ib_pool_init(rdev); @@ -5466,10 +5243,8 @@ int si_suspend(struct radeon_device *rdev) radeon_vm_manager_fini(rdev); si_cp_enable(rdev, false); cayman_dma_stop(rdev); - if (rdev->has_uvd) { - r600_uvd_rbc_stop(rdev); - radeon_uvd_suspend(rdev); - } + r600_uvd_rbc_stop(rdev); + radeon_uvd_suspend(rdev); si_irq_suspend(rdev); radeon_wb_disable(rdev); si_pcie_gart_disable(rdev); @@ -5557,13 +5332,11 @@ int si_init(struct radeon_device *rdev) ring->ring_obj = NULL; r600_ring_init(rdev, ring, 64 * 1024); - if (rdev->has_uvd) { - r = radeon_uvd_init(rdev); - if (!r) { - ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; - ring->ring_obj = NULL; - r600_ring_init(rdev, ring, 4096); - } + r = radeon_uvd_init(rdev); + if (!r) { + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + ring->ring_obj = NULL; + r600_ring_init(rdev, ring, 4096); } rdev->ih.ring_obj = NULL; @@ -5611,8 +5384,7 @@ void si_fini(struct radeon_device *rdev) radeon_vm_manager_fini(rdev); radeon_ib_pool_fini(rdev); radeon_irq_kms_fini(rdev); - if (rdev->has_uvd) - radeon_uvd_fini(rdev); + radeon_uvd_fini(rdev); si_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/sid.h b/trunk/drivers/gpu/drm/radeon/sid.h index 8f2d7d4f9b28..222877ba6cf5 100644 --- a/trunk/drivers/gpu/drm/radeon/sid.h +++ b/trunk/drivers/gpu/drm/radeon/sid.h @@ -28,7 +28,6 @@ #define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003 #define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002 -#define HAINAN_GB_ADDR_CONFIG_GOLDEN 0x02010001 /* discrete uvd clocks */ #define CG_UPLL_FUNC_CNTL 0x634 diff --git a/trunk/drivers/gpu/host1x/drm/dc.c b/trunk/drivers/gpu/host1x/drm/dc.c index 8c04943f82e3..1e2060324f02 100644 --- a/trunk/drivers/gpu/host1x/drm/dc.c +++ b/trunk/drivers/gpu/host1x/drm/dc.c @@ -1128,6 +1128,11 @@ static int tegra_dc_probe(struct platform_device *pdev) return err; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "failed to get registers\n"); + return -ENXIO; + } + dc->regs = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(dc->regs)) return PTR_ERR(dc->regs); diff --git a/trunk/drivers/hv/channel_mgmt.c b/trunk/drivers/hv/channel_mgmt.c index 21ef68934a20..bad8128b283a 100644 --- a/trunk/drivers/hv/channel_mgmt.c +++ b/trunk/drivers/hv/channel_mgmt.c @@ -329,7 +329,7 @@ static u32 get_vp_index(uuid_le *type_guid) return 0; } cur_cpu = (++next_vp % max_cpus); - return hv_context.vp_index[cur_cpu]; + return cur_cpu; } /* diff --git a/trunk/drivers/hwmon/abituguru.c b/trunk/drivers/hwmon/abituguru.c index 2ebd6ce46108..df0b69987914 100644 --- a/trunk/drivers/hwmon/abituguru.c +++ b/trunk/drivers/hwmon/abituguru.c @@ -1414,18 +1414,14 @@ static int abituguru_probe(struct platform_device *pdev) pr_info("found Abit uGuru\n"); /* Register sysfs hooks */ - for (i = 0; i < sysfs_attr_i; i++) { - res = device_create_file(&pdev->dev, - &data->sysfs_attr[i].dev_attr); - if (res) + for (i = 0; i < sysfs_attr_i; i++) + if (device_create_file(&pdev->dev, + &data->sysfs_attr[i].dev_attr)) goto abituguru_probe_error; - } - for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) { - res = device_create_file(&pdev->dev, - &abituguru_sysfs_attr[i].dev_attr); - if (res) + for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) + if (device_create_file(&pdev->dev, + &abituguru_sysfs_attr[i].dev_attr)) goto abituguru_probe_error; - } data->hwmon_dev = hwmon_device_register(&pdev->dev); if (!IS_ERR(data->hwmon_dev)) diff --git a/trunk/drivers/hwmon/iio_hwmon.c b/trunk/drivers/hwmon/iio_hwmon.c index 52b77afebde1..aafa4531b961 100644 --- a/trunk/drivers/hwmon/iio_hwmon.c +++ b/trunk/drivers/hwmon/iio_hwmon.c @@ -84,10 +84,8 @@ static int iio_hwmon_probe(struct platform_device *pdev) return PTR_ERR(channels); st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_release_channels; - } + if (st == NULL) + return -ENOMEM; st->channels = channels; @@ -161,7 +159,7 @@ static int iio_hwmon_probe(struct platform_device *pdev) error_remove_group: sysfs_remove_group(&dev->kobj, &st->attr_group); error_release_channels: - iio_channel_release_all(channels); + iio_channel_release_all(st->channels); return ret; } diff --git a/trunk/drivers/hwmon/nct6775.c b/trunk/drivers/hwmon/nct6775.c index 04638aee9039..f43f5e571db9 100644 --- a/trunk/drivers/hwmon/nct6775.c +++ b/trunk/drivers/hwmon/nct6775.c @@ -3705,10 +3705,8 @@ static int nct6775_probe(struct platform_device *pdev) data->have_temp |= 1 << i; data->have_temp_fixed |= 1 << i; data->reg_temp[0][i] = reg_temp_alternate[i]; - if (i < num_reg_temp) { - data->reg_temp[1][i] = reg_temp_over[i]; - data->reg_temp[2][i] = reg_temp_hyst[i]; - } + data->reg_temp[1][i] = reg_temp_over[i]; + data->reg_temp[2][i] = reg_temp_hyst[i]; data->temp_src[i] = i + 1; continue; } diff --git a/trunk/drivers/hwmon/tmp401.c b/trunk/drivers/hwmon/tmp401.c index dfe6d9527efb..a478454f690f 100644 --- a/trunk/drivers/hwmon/tmp401.c +++ b/trunk/drivers/hwmon/tmp401.c @@ -240,7 +240,7 @@ static struct tmp401_data *tmp401_update_device(struct device *dev) mutex_lock(&data->update_lock); next_update = data->last_updated + - msecs_to_jiffies(data->update_interval); + msecs_to_jiffies(data->update_interval) + 1; if (time_after(jiffies, next_update) || !data->valid) { if (data->kind != tmp432) { /* diff --git a/trunk/drivers/i2c/busses/i2c-designware-core.c b/trunk/drivers/i2c/busses/i2c-designware-core.c index c41ca6354fc5..21fbb340ad66 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-core.c +++ b/trunk/drivers/i2c/busses/i2c-designware-core.c @@ -383,8 +383,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) /* Enable the adapter */ __i2c_dw_enable(dev, true); - /* Clear and enable interrupts */ - i2c_dw_clear_int(dev); + /* Enable interrupts */ dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); } @@ -449,14 +448,8 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) cmd |= BIT(9); if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { - - /* avoid rx buffer overrun */ - if (rx_limit - dev->rx_outstanding <= 0) - break; - dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD); rx_limit--; - dev->rx_outstanding++; } else dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD); tx_limit--; buf_len--; @@ -509,10 +502,8 @@ i2c_dw_read(struct dw_i2c_dev *dev) rx_valid = dw_readl(dev, DW_IC_RXFLR); - for (; len > 0 && rx_valid > 0; len--, rx_valid--) { + for (; len > 0 && rx_valid > 0; len--, rx_valid--) *buf++ = dw_readl(dev, DW_IC_DATA_CMD); - dev->rx_outstanding--; - } if (len > 0) { dev->status |= STATUS_READ_IN_PROGRESS; @@ -570,7 +561,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev->msg_err = 0; dev->status = STATUS_IDLE; dev->abort_source = 0; - dev->rx_outstanding = 0; ret = i2c_dw_wait_bus_not_busy(dev); if (ret < 0) diff --git a/trunk/drivers/i2c/busses/i2c-designware-core.h b/trunk/drivers/i2c/busses/i2c-designware-core.h index e761ad18dd61..9c1840ee09c7 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-core.h +++ b/trunk/drivers/i2c/busses/i2c-designware-core.h @@ -60,7 +60,6 @@ * @adapter: i2c subsystem adapter node * @tx_fifo_depth: depth of the hardware tx fifo * @rx_fifo_depth: depth of the hardware rx fifo - * @rx_outstanding: current master-rx elements in tx fifo */ struct dw_i2c_dev { struct device *dev; @@ -89,7 +88,6 @@ struct dw_i2c_dev { u32 master_cfg; unsigned int tx_fifo_depth; unsigned int rx_fifo_depth; - int rx_outstanding; }; #define ACCESS_SWAP 0x00000001 diff --git a/trunk/drivers/i2c/busses/i2c-designware-platdrv.c b/trunk/drivers/i2c/busses/i2c-designware-platdrv.c index 35b70a1edf57..8ec91335d95a 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/trunk/drivers/i2c/busses/i2c-designware-platdrv.c @@ -69,7 +69,6 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev) static const struct acpi_device_id dw_i2c_acpi_match[] = { { "INT33C2", 0 }, { "INT33C3", 0 }, - { "80860F41", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 3a6903f63913..e1cf2e0e1f23 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -231,11 +231,7 @@ static const char *i801_feature_names[] = { static unsigned int disable_features; module_param(disable_features, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n" - "\t\t 0x01 disable SMBus PEC\n" - "\t\t 0x02 disable the block buffer\n" - "\t\t 0x08 disable the I2C block read functionality\n" - "\t\t 0x10 don't use interrupts "); +MODULE_PARM_DESC(disable_features, "Disable selected driver features"); /* Make sure the SMBus host is ready to start transmitting. Return 0 if it is, -EBUSY if it is not. */ diff --git a/trunk/drivers/i2c/busses/i2c-mv64xxx.c b/trunk/drivers/i2c/busses/i2c-mv64xxx.c index 1a3abd6a0bfc..3bbd65d35a5e 100644 --- a/trunk/drivers/i2c/busses/i2c-mv64xxx.c +++ b/trunk/drivers/i2c/busses/i2c-mv64xxx.c @@ -252,7 +252,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) writel(drv_data->cntl_bits, drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); drv_data->block = 0; - wake_up(&drv_data->waitq); + wake_up_interruptible(&drv_data->waitq); break; case MV64XXX_I2C_ACTION_CONTINUE: @@ -300,7 +300,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); drv_data->block = 0; - wake_up(&drv_data->waitq); + wake_up_interruptible(&drv_data->waitq); break; case MV64XXX_I2C_ACTION_INVALID: @@ -315,7 +315,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); drv_data->block = 0; - wake_up(&drv_data->waitq); + wake_up_interruptible(&drv_data->waitq); break; } } @@ -381,7 +381,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) unsigned long flags; char abort = 0; - time_left = wait_event_timeout(drv_data->waitq, + time_left = wait_event_interruptible_timeout(drv_data->waitq, !drv_data->block, drv_data->adapter.timeout); spin_lock_irqsave(&drv_data->lock, flags); diff --git a/trunk/drivers/i2c/busses/i2c-s3c2410.c b/trunk/drivers/i2c/busses/i2c-s3c2410.c index cab1c91b75a3..6e8ee92ab553 100644 --- a/trunk/drivers/i2c/busses/i2c-s3c2410.c +++ b/trunk/drivers/i2c/busses/i2c-s3c2410.c @@ -1082,6 +1082,11 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) /* map the registers */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "cannot find IO resource\n"); + return -ENOENT; + } + i2c->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(i2c->regs)) diff --git a/trunk/drivers/i2c/busses/i2c-sirf.c b/trunk/drivers/i2c/busses/i2c-sirf.c index a63c7d506836..5a7ad240bd26 100644 --- a/trunk/drivers/i2c/busses/i2c-sirf.c +++ b/trunk/drivers/i2c/busses/i2c-sirf.c @@ -303,6 +303,12 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev) adap->class = I2C_CLASS_HWMON; mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem_res == NULL) { + dev_err(&pdev->dev, "Unable to get MEM resource\n"); + err = -EINVAL; + goto out; + } + siic->base = devm_ioremap_resource(&pdev->dev, mem_res); if (IS_ERR(siic->base)) { err = PTR_ERR(siic->base); diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index 9aa1b60f7fdd..b60ff90adc39 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -714,6 +714,11 @@ static int tegra_i2c_probe(struct platform_device *pdev) int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no mem resource\n"); + return -EINVAL; + } + base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index 48e31ed69dbf..6b63cc7eb71e 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -892,8 +892,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device); -static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, S_IWUSR, NULL, - i2c_sysfs_delete_device); +static DEVICE_ATTR(delete_device, S_IWUSR, NULL, i2c_sysfs_delete_device); static struct attribute *i2c_adapter_attrs[] = { &dev_attr_name.attr, diff --git a/trunk/drivers/iio/adc/exynos_adc.c b/trunk/drivers/iio/adc/exynos_adc.c index b3d03d335948..9f3a8ef1fb3e 100644 --- a/trunk/drivers/iio/adc/exynos_adc.c +++ b/trunk/drivers/iio/adc/exynos_adc.c @@ -390,8 +390,8 @@ static int exynos_adc_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int exynos_adc_suspend(struct device *dev) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct exynos_adc *info = iio_priv(indio_dev); + struct platform_device *pdev = to_platform_device(dev); + struct exynos_adc *info = platform_get_drvdata(pdev); u32 con; if (info->version == ADC_V2) { @@ -413,8 +413,8 @@ static int exynos_adc_suspend(struct device *dev) static int exynos_adc_resume(struct device *dev) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct exynos_adc *info = iio_priv(indio_dev); + struct platform_device *pdev = to_platform_device(dev); + struct exynos_adc *info = platform_get_drvdata(pdev); int ret; ret = regulator_enable(info->vdd); diff --git a/trunk/drivers/iio/common/st_sensors/st_sensors_core.c b/trunk/drivers/iio/common/st_sensors/st_sensors_core.c index ed9bc8ae9330..bd33473f8e38 100644 --- a/trunk/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/trunk/drivers/iio/common/st_sensors/st_sensors_core.c @@ -312,8 +312,6 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev, goto read_error; *val = *val >> ch->scan_type.shift; - - err = st_sensors_set_enable(indio_dev, false); } mutex_unlock(&indio_dev->mlock); diff --git a/trunk/drivers/iio/dac/Kconfig b/trunk/drivers/iio/dac/Kconfig index b61160bd935e..f4a6f0838327 100644 --- a/trunk/drivers/iio/dac/Kconfig +++ b/trunk/drivers/iio/dac/Kconfig @@ -5,7 +5,7 @@ menu "Digital to analog converters" config AD5064 tristate "Analog Devices AD5064 and similar multi-channel DAC driver" - depends on (SPI_MASTER && I2C!=m) || I2C + depends on (SPI_MASTER || I2C) help Say yes here to build support for Analog Devices AD5024, AD5025, AD5044, AD5045, AD5064, AD5064-1, AD5065, AD5628, AD5629R, AD5648, AD5666, AD5668, @@ -27,7 +27,7 @@ config AD5360 config AD5380 tristate "Analog Devices AD5380/81/82/83/84/90/91/92 DAC driver" - depends on (SPI_MASTER && I2C!=m) || I2C + depends on (SPI_MASTER || I2C) select REGMAP_I2C if I2C select REGMAP_SPI if SPI_MASTER help @@ -57,7 +57,7 @@ config AD5624R_SPI config AD5446 tristate "Analog Devices AD5446 and similar single channel DACs driver" - depends on (SPI_MASTER && I2C!=m) || I2C + depends on (SPI_MASTER || I2C) help Say yes here to build support for Analog Devices AD5300, AD5301, AD5310, AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index 5c68e4486845..0bfd8cf25200 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -342,10 +342,10 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) | ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12); - switch (wacom->id[idx]) { + switch (wacom->id[idx] & 0xfffff) { case 0x812: /* Inking pen */ case 0x801: /* Intuos3 Inking pen */ - case 0x120802: /* Intuos4/5 Inking Pen */ + case 0x20802: /* Intuos4 Inking Pen */ case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL; break; @@ -356,13 +356,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x823: /* Intuos3 Grip Pen */ case 0x813: /* Intuos3 Classic Pen */ case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4/5 13HD/24HD General Pen */ - case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ + case 0x802: /* Intuos4 General Pen */ + case 0x804: /* Intuos4 Marker Pen */ + case 0x40802: /* Intuos4 Classic Pen */ + case 0x18802: /* DTH2242 Grip Pen */ case 0x022: - case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */ - case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ - case 0x160802: /* Cintiq 13HD Pro Pen */ - case 0x180802: /* DTH2242 Pen */ wacom->tool[idx] = BTN_TOOL_PEN; break; @@ -393,14 +391,10 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x82b: /* Intuos3 Grip Pen Eraser */ case 0x81b: /* Intuos3 Classic Pen Eraser */ case 0x91b: /* Intuos3 Airbrush Eraser */ - case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */ - case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */ - case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ - case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */ - case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */ - case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ - case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ - case 0x18080a: /* DTH2242 Eraser */ + case 0x80c: /* Intuos4 Marker Pen Eraser */ + case 0x80a: /* Intuos4 General Pen Eraser */ + case 0x4080a: /* Intuos4 Classic Pen Eraser */ + case 0x90a: /* Intuos4 Airbrush Eraser */ wacom->tool[idx] = BTN_TOOL_RUBBER; break; @@ -408,8 +402,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x912: case 0x112: case 0x913: /* Intuos3 Airbrush */ - case 0x902: /* Intuos4/5 13HD/24HD Airbrush */ - case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */ + case 0x902: /* Intuos4 Airbrush */ wacom->tool[idx] = BTN_TOOL_AIRBRUSH; break; @@ -540,8 +533,10 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, BTN_8, (data[3] & 0x80)); } if (data[1] | (data[2] & 0x01) | data[3]) { + input_report_key(input, wacom->tool[1], 1); input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); } else { + input_report_key(input, wacom->tool[1], 0); input_report_abs(input, ABS_MISC, 0); } } else if (features->type == DTK) { @@ -551,26 +546,6 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, BTN_3, (data[6] & 0x08)); input_report_key(input, BTN_4, (data[6] & 0x10)); input_report_key(input, BTN_5, (data[6] & 0x20)); - if (data[6] & 0x3f) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } - } else if (features->type == WACOM_13HD) { - input_report_key(input, BTN_0, (data[3] & 0x01)); - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - input_report_key(input, BTN_5, (data[4] & 0x10)); - input_report_key(input, BTN_6, (data[4] & 0x20)); - input_report_key(input, BTN_7, (data[4] & 0x40)); - input_report_key(input, BTN_8, (data[4] & 0x80)); - if ((data[3] & 0x01) | data[4]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } } else if (features->type == WACOM_24HD) { input_report_key(input, BTN_0, (data[6] & 0x01)); input_report_key(input, BTN_1, (data[6] & 0x02)); @@ -615,8 +590,10 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) } if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) { + input_report_key(input, wacom->tool[1], 1); input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); } else { + input_report_key(input, wacom->tool[1], 0); input_report_abs(input, ABS_MISC, 0); } } else if (features->type >= INTUOS5S && features->type <= INTUOS5L) { @@ -641,8 +618,10 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) } if (data[2] | (data[3] & 0x01) | data[4] | data[5]) { + input_report_key(input, wacom->tool[1], 1); input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); } else { + input_report_key(input, wacom->tool[1], 0); input_report_abs(input, ABS_MISC, 0); } } else { @@ -689,8 +668,10 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | data[2] | (data[3] & 0x1f) | data[4] | data[8] | (data[7] & 0x01)) { + input_report_key(input, wacom->tool[1], 1); input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); } else { + input_report_key(input, wacom->tool[1], 0); input_report_abs(input, ABS_MISC, 0); } } @@ -1320,7 +1301,6 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case INTUOS4L: case CINTIQ: case WACOM_BEE: - case WACOM_13HD: case WACOM_21UX2: case WACOM_22HD: case WACOM_24HD: @@ -1550,15 +1530,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(KEY_PROG1, input_dev->keybit); __set_bit(KEY_PROG2, input_dev->keybit); __set_bit(KEY_PROG3, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); /* fall through */ case DTK: for (i = 0; i < 6; i++) __set_bit(BTN_0 + i, input_dev->keybit); + input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); + input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); wacom_setup_cintiq(wacom_wac); @@ -1599,15 +1579,6 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, wacom_setup_cintiq(wacom_wac); break; - case WACOM_13HD: - for (i = 0; i < 9; i++) - __set_bit(BTN_0 + i, input_dev->keybit); - - input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - wacom_setup_cintiq(wacom_wac); - break; - case INTUOS3: case INTUOS3L: __set_bit(BTN_4, input_dev->keybit); @@ -1979,9 +1950,6 @@ static const struct wacom_features wacom_features_0xC5 = static const struct wacom_features wacom_features_0xC6 = { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0x304 = - { "Wacom Cintiq 13HD", WACOM_PKGLEN_INTUOS, 59552, 33848, 1023, - 63, WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xC7 = { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -1991,9 +1959,6 @@ static const struct wacom_features wacom_features_0xCE = static const struct wacom_features wacom_features_0xF0 = { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; -static const struct wacom_features wacom_features_0x57 = - { "Wacom DTK2241", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, - 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES}; static const struct wacom_features wacom_features_0x59 = /* Pen */ { "Wacom DTH2242", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, @@ -2007,12 +1972,6 @@ static const struct wacom_features wacom_features_0xCC = static const struct wacom_features wacom_features_0xFA = { "Wacom Cintiq 22HD", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, 63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; -static const struct wacom_features wacom_features_0x5B = - { "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, - 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e }; -static const struct wacom_features wacom_features_0x5E = - { "Wacom Cintiq 22HDT", .type = WACOM_24HDT, - .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10 }; static const struct wacom_features wacom_features_0x90 = { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -2184,11 +2143,8 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x43) }, { USB_DEVICE_WACOM(0x44) }, { USB_DEVICE_WACOM(0x45) }, - { USB_DEVICE_WACOM(0x57) }, { USB_DEVICE_WACOM(0x59) }, { USB_DEVICE_DETAILED(0x5D, USB_CLASS_HID, 0, 0) }, - { USB_DEVICE_WACOM(0x5B) }, - { USB_DEVICE_DETAILED(0x5E, USB_CLASS_HID, 0, 0) }, { USB_DEVICE_WACOM(0xB0) }, { USB_DEVICE_WACOM(0xB1) }, { USB_DEVICE_WACOM(0xB2) }, @@ -2249,7 +2205,6 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x100) }, { USB_DEVICE_WACOM(0x101) }, { USB_DEVICE_WACOM(0x10D) }, - { USB_DEVICE_WACOM(0x304) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, diff --git a/trunk/drivers/input/tablet/wacom_wac.h b/trunk/drivers/input/tablet/wacom_wac.h index dfc9e08e7f70..5f9a7721e16c 100644 --- a/trunk/drivers/input/tablet/wacom_wac.h +++ b/trunk/drivers/input/tablet/wacom_wac.h @@ -82,7 +82,6 @@ enum { WACOM_24HD, CINTIQ, WACOM_BEE, - WACOM_13HD, WACOM_MO, WIRELESS, BAMBOO_PT, diff --git a/trunk/drivers/input/touchscreen/egalax_ts.c b/trunk/drivers/input/touchscreen/egalax_ts.c index 39f3df8670c3..17c9097f3b5d 100644 --- a/trunk/drivers/input/touchscreen/egalax_ts.c +++ b/trunk/drivers/input/touchscreen/egalax_ts.c @@ -216,7 +216,7 @@ static int egalax_ts_probe(struct i2c_client *client, input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0); input_set_abs_params(input_dev, - ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0); + ABS_MT_POSITION_X, 0, EGALAX_MAX_Y, 0, 0); input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0); input_set_drvdata(input_dev, ts); diff --git a/trunk/drivers/leds/leds-gpio.c b/trunk/drivers/leds/leds-gpio.c index b02b679abf31..a0d931bcb37c 100644 --- a/trunk/drivers/leds/leds-gpio.c +++ b/trunk/drivers/leds/leds-gpio.c @@ -107,10 +107,6 @@ static int create_gpio_led(const struct gpio_led *template, return 0; } - ret = devm_gpio_request(parent, template->gpio, template->name); - if (ret < 0) - return ret; - led_dat->cdev.name = template->name; led_dat->cdev.default_trigger = template->default_trigger; led_dat->gpio = template->gpio; @@ -130,7 +126,10 @@ static int create_gpio_led(const struct gpio_led *template, if (!template->retain_state_suspended) led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; - ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); + ret = devm_gpio_request_one(parent, template->gpio, + (led_dat->active_low ^ state) ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, + template->name); if (ret < 0) return ret; diff --git a/trunk/drivers/md/dm-thin.c b/trunk/drivers/md/dm-thin.c index 88f2f802d528..759cffc45cab 100644 --- a/trunk/drivers/md/dm-thin.c +++ b/trunk/drivers/md/dm-thin.c @@ -2188,7 +2188,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit) *need_commit = false; - metadata_dev_size = get_metadata_dev_size_in_blocks(pool->md_dev); + metadata_dev_size = get_metadata_dev_size(pool->md_dev); r = dm_pool_get_metadata_dev_size(pool->pmd, &sb_metadata_dev_size); if (r) { @@ -2197,7 +2197,7 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit) } if (metadata_dev_size < sb_metadata_dev_size) { - DMERR("metadata device (%llu blocks) too small: expected %llu", + DMERR("metadata device (%llu sectors) too small: expected %llu", metadata_dev_size, sb_metadata_dev_size); return -EINVAL; diff --git a/trunk/drivers/memory/emif.c b/trunk/drivers/memory/emif.c index 04644e7b42b1..cadf1cc19aaf 100644 --- a/trunk/drivers/memory/emif.c +++ b/trunk/drivers/memory/emif.c @@ -1560,6 +1560,12 @@ static int __init_or_module emif_probe(struct platform_device *pdev) platform_set_drvdata(pdev, emif); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(emif->dev, "%s: error getting memory resource\n", + __func__); + goto error; + } + emif->base = devm_ioremap_resource(emif->dev, res); if (IS_ERR(emif->base)) goto error; diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index d54e985748b7..d9aed1593e5d 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -579,7 +579,7 @@ config AB8500_CORE config AB8500_DEBUG bool "Enable debug info via debugfs" - depends on AB8500_GPADC && DEBUG_FS + depends on AB8500_CORE && DEBUG_FS default y if DEBUG_FS help Select this option if you want debug information using the debug @@ -818,7 +818,6 @@ config MFD_TPS65910 config MFD_TPS65912 bool "TI TPS65912 Power Management chip" depends on GPIOLIB - select MFD_CORE help If you say yes here you get support for the TPS65912 series of PM chips. diff --git a/trunk/drivers/mfd/ab8500-core.c b/trunk/drivers/mfd/ab8500-core.c index 258b367e3989..8e8a016effe9 100644 --- a/trunk/drivers/mfd/ab8500-core.c +++ b/trunk/drivers/mfd/ab8500-core.c @@ -867,15 +867,6 @@ static struct resource ab8500_chargalg_resources[] = {}; #ifdef CONFIG_DEBUG_FS static struct resource ab8500_debug_resources[] = { - { - .name = "IRQ_AB8500", - /* - * Number will be filled in. NOTE: this is deliberately - * not flagged as an IRQ in ordet to avoid remapping using - * the irqdomain in the MFD core, so that this IRQ passes - * unremapped to the debug code. - */ - }, { .name = "IRQ_FIRST", .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, @@ -1060,7 +1051,6 @@ static struct mfd_cell ab8500_devs[] = { }, { .name = "ab8500-gpadc", - .of_compatible = "stericsson,ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), .resources = ab8500_gpadc_resources, }, @@ -1107,7 +1097,7 @@ static struct mfd_cell ab8500_devs[] = { .of_compatible = "stericsson,ab8500-denc", }, { - .name = "pinctrl-ab8500", + .name = "ab8500-gpio", .of_compatible = "stericsson,ab8500-gpio", }, { @@ -1218,7 +1208,6 @@ static struct mfd_cell ab8505_devs[] = { }, { .name = "ab8500-gpadc", - .of_compatible = "stericsson,ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), .resources = ab8505_gpadc_resources, }, @@ -1245,7 +1234,7 @@ static struct mfd_cell ab8505_devs[] = { .name = "ab8500-leds", }, { - .name = "pinctrl-ab8505", + .name = "ab8500-gpio", }, { .name = "ab8500-usb", @@ -1282,7 +1271,6 @@ static struct mfd_cell ab8540_devs[] = { }, { .name = "ab8500-gpadc", - .of_compatible = "stericsson,ab8500-gpadc", .num_resources = ARRAY_SIZE(ab8505_gpadc_resources), .resources = ab8505_gpadc_resources, }, @@ -1314,7 +1302,7 @@ static struct mfd_cell ab8540_devs[] = { .resources = ab8500_temp_resources, }, { - .name = "pinctrl-ab8540", + .name = "ab8500-gpio", }, { .name = "ab8540-usb", @@ -1724,12 +1712,6 @@ static int ab8500_probe(struct platform_device *pdev) if (ret) return ret; -#if CONFIG_DEBUG_FS - /* Pass to debugfs */ - ab8500_debug_resources[0].start = ab8500->irq; - ab8500_debug_resources[0].end = ab8500->irq; -#endif - if (is_ab9540(ab8500)) ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, ARRAY_SIZE(ab9540_devs), NULL, diff --git a/trunk/drivers/mfd/ab8500-debugfs.c b/trunk/drivers/mfd/ab8500-debugfs.c index 37b7ce4c7c3b..b88bbbc15f1e 100644 --- a/trunk/drivers/mfd/ab8500-debugfs.c +++ b/trunk/drivers/mfd/ab8500-debugfs.c @@ -91,10 +91,12 @@ #include #endif +/* TODO: this file should not reference IRQ_DB8500_AB8500! */ +#include + static u32 debug_bank; static u32 debug_address; -static int irq_ab8500; static int irq_first; static int irq_last; static u32 *irq_count; @@ -1587,7 +1589,7 @@ void ab8500_debug_register_interrupt(int line) { if (line < num_interrupt_lines) { num_interrupts[line]++; - if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500)) + if (suspend_test_wake_cause_interrupt_is_mine(IRQ_DB8500_AB8500)) num_wake_interrupts[line]++; } } @@ -2939,7 +2941,6 @@ static int ab8500_debug_probe(struct platform_device *plf) struct dentry *file; int ret = -ENOMEM; struct ab8500 *ab8500; - struct resource *res; debug_bank = AB8500_MISC; debug_address = AB8500_REV_REG & 0x00FF; @@ -2958,15 +2959,6 @@ static int ab8500_debug_probe(struct platform_device *plf) if (!event_name) goto out_freedev_attr; - res = platform_get_resource_byname(plf, 0, "IRQ_AB8500"); - if (!res) { - dev_err(&plf->dev, "AB8500 irq not found, err %d\n", - irq_first); - ret = -ENXIO; - goto out_freeevent_name; - } - irq_ab8500 = res->start; - irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); if (irq_first < 0) { dev_err(&plf->dev, "First irq not found, err %d\n", diff --git a/trunk/drivers/mfd/ab8500-gpadc.c b/trunk/drivers/mfd/ab8500-gpadc.c index 13f7866de46e..5e65b28a5d09 100644 --- a/trunk/drivers/mfd/ab8500-gpadc.c +++ b/trunk/drivers/mfd/ab8500-gpadc.c @@ -907,17 +907,14 @@ static int ab8500_gpadc_suspend(struct device *dev) static int ab8500_gpadc_resume(struct device *dev) { struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); - int ret; - ret = regulator_enable(gpadc->regu); - if (ret) - dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret); + regulator_enable(gpadc->regu); pm_runtime_mark_last_busy(gpadc->dev); pm_runtime_put_autosuspend(gpadc->dev); mutex_unlock(&gpadc->ab8500_gpadc_lock); - return ret; + return 0; } static int ab8500_gpadc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/mfd/ab8500-sysctrl.c b/trunk/drivers/mfd/ab8500-sysctrl.c index 8e0dae59844d..fbca1ced49fa 100644 --- a/trunk/drivers/mfd/ab8500-sysctrl.c +++ b/trunk/drivers/mfd/ab8500-sysctrl.c @@ -23,7 +23,7 @@ static struct device *sysctrl_dev; -static void ab8500_power_off(void) +void ab8500_power_off(void) { sigset_t old; sigset_t all; @@ -104,7 +104,7 @@ void ab8500_restart(char mode, const char *cmd) plat = dev_get_platdata(sysctrl_dev->parent); pdata = plat->sysctrl; - if (pdata && pdata->reboot_reason_code) + if (pdata->reboot_reason_code) reason = pdata->reboot_reason_code(cmd); else pr_warn("[%s] No reboot reason set. Default reason %d\n", @@ -188,15 +188,14 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev) plat = dev_get_platdata(pdev->dev.parent); - if (!plat) + if (!(plat && plat->sysctrl)) return -EINVAL; - sysctrl_dev = &pdev->dev; - - if (!pm_power_off) + if (plat->pm_power_off) pm_power_off = ab8500_power_off; pdata = plat->sysctrl; + if (pdata) { int last, ret, i, j; @@ -227,10 +226,6 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev) static int ab8500_sysctrl_remove(struct platform_device *pdev) { sysctrl_dev = NULL; - - if (pm_power_off == ab8500_power_off) - pm_power_off = NULL; - return 0; } diff --git a/trunk/drivers/mfd/abx500-core.c b/trunk/drivers/mfd/abx500-core.c index 3714acb61458..9818afba2515 100644 --- a/trunk/drivers/mfd/abx500-core.c +++ b/trunk/drivers/mfd/abx500-core.c @@ -156,7 +156,7 @@ EXPORT_SYMBOL(abx500_startup_irq_enabled); void abx500_dump_all_banks(void) { struct abx500_ops *ops; - struct device dummy_child = {NULL}; + struct device dummy_child = {0}; struct abx500_device_entry *dev_entry; list_for_each_entry(dev_entry, &abx500_list, list) { diff --git a/trunk/drivers/mfd/cros_ec_spi.c b/trunk/drivers/mfd/cros_ec_spi.c index 367ccb58ecb1..19193cf1e7a1 100644 --- a/trunk/drivers/mfd/cros_ec_spi.c +++ b/trunk/drivers/mfd/cros_ec_spi.c @@ -120,7 +120,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) { if (*ptr == EC_MSG_HEADER) { - dev_dbg(ec_dev->dev, "msg found at %zd\n", + dev_dbg(ec_dev->dev, "msg found at %ld\n", ptr - ec_dev->din); break; } @@ -154,7 +154,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, * maximum-supported transfer size. */ todo = min(need_len, 256); - dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", + dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%ld\n", todo, need_len, ptr - ec_dev->din); memset(&trans, '\0', sizeof(trans)); @@ -178,7 +178,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, need_len -= todo; } - dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din); + dev_dbg(ec_dev->dev, "loop done, ptr=%ld\n", ptr - ec_dev->din); return 0; } diff --git a/trunk/drivers/mfd/db8500-prcmu.c b/trunk/drivers/mfd/db8500-prcmu.c index 66f80973596b..319b8abe742b 100644 --- a/trunk/drivers/mfd/db8500-prcmu.c +++ b/trunk/drivers/mfd/db8500-prcmu.c @@ -1613,8 +1613,6 @@ static unsigned long dsiclk_rate(u8 n) if (divsel == PRCM_DSI_PLLOUT_SEL_OFF) divsel = dsiclk[n].divsel; - else - dsiclk[n].divsel = divsel; switch (divsel) { case PRCM_DSI_PLLOUT_SEL_PHI_4: @@ -3097,7 +3095,6 @@ static struct mfd_cell db8500_prcmu_devs[] = { .num_resources = ARRAY_SIZE(db8500_thsens_resources), .resources = db8500_thsens_resources, .platform_data = &db8500_thsens_data, - .pdata_size = sizeof(db8500_thsens_data), }, }; diff --git a/trunk/drivers/mfd/intel_msic.c b/trunk/drivers/mfd/intel_msic.c index d8d5137f9717..5be3b5e13855 100644 --- a/trunk/drivers/mfd/intel_msic.c +++ b/trunk/drivers/mfd/intel_msic.c @@ -414,6 +414,11 @@ static int intel_msic_probe(struct platform_device *pdev) * the clients via intel_msic_irq_read(). */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get SRAM iomem resource\n"); + return -ENODEV; + } + msic->irq_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(msic->irq_base)) return PTR_ERR(msic->irq_base); diff --git a/trunk/drivers/mfd/si476x-cmd.c b/trunk/drivers/mfd/si476x-cmd.c index 6f1ef63086c9..de48b4e88450 100644 --- a/trunk/drivers/mfd/si476x-cmd.c +++ b/trunk/drivers/mfd/si476x-cmd.c @@ -29,8 +29,6 @@ #include -#include - #define msb(x) ((u8)((u16) x >> 8)) #define lsb(x) ((u8)((u16) x & 0x00FF)) @@ -152,7 +150,7 @@ enum si476x_acf_status_report_bits { SI476X_ACF_SOFTMUTE_INT = (1 << 0), SI476X_ACF_SMUTE = (1 << 0), - SI476X_ACF_SMATTN = 0x1f, + SI476X_ACF_SMATTN = 0b11111, SI476X_ACF_PILOT = (1 << 7), SI476X_ACF_STBLEND = ~SI476X_ACF_PILOT, }; @@ -485,7 +483,7 @@ int si476x_core_cmd_get_property(struct si476x_core *core, u16 property) if (err < 0) return err; else - return get_unaligned_be16(resp + 2); + return be16_to_cpup((__be16 *)(resp + 2)); } EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property); @@ -774,18 +772,18 @@ int si476x_core_cmd_am_rsq_status(struct si476x_core *core, if (!report) return err; - report->snrhint = 0x08 & resp[1]; - report->snrlint = 0x04 & resp[1]; - report->rssihint = 0x02 & resp[1]; - report->rssilint = 0x01 & resp[1]; + report->snrhint = 0b00001000 & resp[1]; + report->snrlint = 0b00000100 & resp[1]; + report->rssihint = 0b00000010 & resp[1]; + report->rssilint = 0b00000001 & resp[1]; - report->bltf = 0x80 & resp[2]; - report->snr_ready = 0x20 & resp[2]; - report->rssiready = 0x08 & resp[2]; - report->afcrl = 0x02 & resp[2]; - report->valid = 0x01 & resp[2]; + report->bltf = 0b10000000 & resp[2]; + report->snr_ready = 0b00100000 & resp[2]; + report->rssiready = 0b00001000 & resp[2]; + report->afcrl = 0b00000010 & resp[2]; + report->valid = 0b00000001 & resp[2]; - report->readfreq = get_unaligned_be16(resp + 3); + report->readfreq = be16_to_cpup((__be16 *)(resp + 3)); report->freqoff = resp[5]; report->rssi = resp[6]; report->snr = resp[7]; @@ -933,26 +931,26 @@ int si476x_core_cmd_fm_rds_status(struct si476x_core *core, if (err < 0 || report == NULL) return err; - report->rdstpptyint = 0x10 & resp[1]; - report->rdspiint = 0x08 & resp[1]; - report->rdssyncint = 0x02 & resp[1]; - report->rdsfifoint = 0x01 & resp[1]; + report->rdstpptyint = 0b00010000 & resp[1]; + report->rdspiint = 0b00001000 & resp[1]; + report->rdssyncint = 0b00000010 & resp[1]; + report->rdsfifoint = 0b00000001 & resp[1]; - report->tpptyvalid = 0x10 & resp[2]; - report->pivalid = 0x08 & resp[2]; - report->rdssync = 0x02 & resp[2]; - report->rdsfifolost = 0x01 & resp[2]; + report->tpptyvalid = 0b00010000 & resp[2]; + report->pivalid = 0b00001000 & resp[2]; + report->rdssync = 0b00000010 & resp[2]; + report->rdsfifolost = 0b00000001 & resp[2]; - report->tp = 0x20 & resp[3]; - report->pty = 0x1f & resp[3]; + report->tp = 0b00100000 & resp[3]; + report->pty = 0b00011111 & resp[3]; - report->pi = get_unaligned_be16(resp + 4); + report->pi = be16_to_cpup((__be16 *)(resp + 4)); report->rdsfifoused = resp[6]; - report->ble[V4L2_RDS_BLOCK_A] = 0xc0 & resp[7]; - report->ble[V4L2_RDS_BLOCK_B] = 0x30 & resp[7]; - report->ble[V4L2_RDS_BLOCK_C] = 0x0c & resp[7]; - report->ble[V4L2_RDS_BLOCK_D] = 0x03 & resp[7]; + report->ble[V4L2_RDS_BLOCK_A] = 0b11000000 & resp[7]; + report->ble[V4L2_RDS_BLOCK_B] = 0b00110000 & resp[7]; + report->ble[V4L2_RDS_BLOCK_C] = 0b00001100 & resp[7]; + report->ble[V4L2_RDS_BLOCK_D] = 0b00000011 & resp[7]; report->rds[V4L2_RDS_BLOCK_A].block = V4L2_RDS_BLOCK_A; report->rds[V4L2_RDS_BLOCK_A].msb = resp[8]; @@ -993,9 +991,9 @@ int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *core, SI476X_DEFAULT_TIMEOUT); if (!err) { - report->expected = get_unaligned_be16(resp + 2); - report->received = get_unaligned_be16(resp + 4); - report->uncorrectable = get_unaligned_be16(resp + 6); + report->expected = be16_to_cpup((__be16 *)(resp + 2)); + report->received = be16_to_cpup((__be16 *)(resp + 4)); + report->uncorrectable = be16_to_cpup((__be16 *)(resp + 6)); } return err; @@ -1007,7 +1005,7 @@ int si476x_core_cmd_fm_phase_diversity(struct si476x_core *core, { u8 resp[CMD_FM_PHASE_DIVERSITY_NRESP]; const u8 args[CMD_FM_PHASE_DIVERSITY_NARGS] = { - mode & 0x07, + mode & 0b111, }; return si476x_core_send_command(core, CMD_FM_PHASE_DIVERSITY, @@ -1164,7 +1162,7 @@ static int si476x_core_cmd_am_tune_freq_a20(struct si476x_core *core, const int am_freq = tuneargs->freq; u8 resp[CMD_AM_TUNE_FREQ_NRESP]; const u8 args[CMD_AM_TUNE_FREQ_NARGS] = { - (tuneargs->zifsr << 6) | (tuneargs->injside & 0x03), + (tuneargs->zifsr << 6) | (tuneargs->injside & 0b11), msb(am_freq), lsb(am_freq), }; @@ -1199,20 +1197,20 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core, if (err < 0 || report == NULL) return err; - report->multhint = 0x80 & resp[1]; - report->multlint = 0x40 & resp[1]; - report->snrhint = 0x08 & resp[1]; - report->snrlint = 0x04 & resp[1]; - report->rssihint = 0x02 & resp[1]; - report->rssilint = 0x01 & resp[1]; + report->multhint = 0b10000000 & resp[1]; + report->multlint = 0b01000000 & resp[1]; + report->snrhint = 0b00001000 & resp[1]; + report->snrlint = 0b00000100 & resp[1]; + report->rssihint = 0b00000010 & resp[1]; + report->rssilint = 0b00000001 & resp[1]; - report->bltf = 0x80 & resp[2]; - report->snr_ready = 0x20 & resp[2]; - report->rssiready = 0x08 & resp[2]; - report->afcrl = 0x02 & resp[2]; - report->valid = 0x01 & resp[2]; + report->bltf = 0b10000000 & resp[2]; + report->snr_ready = 0b00100000 & resp[2]; + report->rssiready = 0b00001000 & resp[2]; + report->afcrl = 0b00000010 & resp[2]; + report->valid = 0b00000001 & resp[2]; - report->readfreq = get_unaligned_be16(resp + 3); + report->readfreq = be16_to_cpup((__be16 *)(resp + 3)); report->freqoff = resp[5]; report->rssi = resp[6]; report->snr = resp[7]; @@ -1220,7 +1218,7 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core, report->hassi = resp[10]; report->mult = resp[11]; report->dev = resp[12]; - report->readantcap = get_unaligned_be16(resp + 13); + report->readantcap = be16_to_cpup((__be16 *)(resp + 13)); report->assi = resp[15]; report->usn = resp[16]; @@ -1253,20 +1251,20 @@ static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core, if (err < 0 || report == NULL) return err; - report->multhint = 0x80 & resp[1]; - report->multlint = 0x40 & resp[1]; - report->snrhint = 0x08 & resp[1]; - report->snrlint = 0x04 & resp[1]; - report->rssihint = 0x02 & resp[1]; - report->rssilint = 0x01 & resp[1]; + report->multhint = 0b10000000 & resp[1]; + report->multlint = 0b01000000 & resp[1]; + report->snrhint = 0b00001000 & resp[1]; + report->snrlint = 0b00000100 & resp[1]; + report->rssihint = 0b00000010 & resp[1]; + report->rssilint = 0b00000001 & resp[1]; - report->bltf = 0x80 & resp[2]; - report->snr_ready = 0x20 & resp[2]; - report->rssiready = 0x08 & resp[2]; - report->afcrl = 0x02 & resp[2]; - report->valid = 0x01 & resp[2]; + report->bltf = 0b10000000 & resp[2]; + report->snr_ready = 0b00100000 & resp[2]; + report->rssiready = 0b00001000 & resp[2]; + report->afcrl = 0b00000010 & resp[2]; + report->valid = 0b00000001 & resp[2]; - report->readfreq = get_unaligned_be16(resp + 3); + report->readfreq = be16_to_cpup((__be16 *)(resp + 3)); report->freqoff = resp[5]; report->rssi = resp[6]; report->snr = resp[7]; @@ -1274,7 +1272,7 @@ static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core, report->hassi = resp[10]; report->mult = resp[11]; report->dev = resp[12]; - report->readantcap = get_unaligned_be16(resp + 13); + report->readantcap = be16_to_cpup((__be16 *)(resp + 13)); report->assi = resp[15]; report->usn = resp[16]; @@ -1308,21 +1306,21 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core, if (err < 0 || report == NULL) return err; - report->multhint = 0x80 & resp[1]; - report->multlint = 0x40 & resp[1]; - report->snrhint = 0x08 & resp[1]; - report->snrlint = 0x04 & resp[1]; - report->rssihint = 0x02 & resp[1]; - report->rssilint = 0x01 & resp[1]; - - report->bltf = 0x80 & resp[2]; - report->snr_ready = 0x20 & resp[2]; - report->rssiready = 0x08 & resp[2]; - report->injside = 0x04 & resp[2]; - report->afcrl = 0x02 & resp[2]; - report->valid = 0x01 & resp[2]; - - report->readfreq = get_unaligned_be16(resp + 3); + report->multhint = 0b10000000 & resp[1]; + report->multlint = 0b01000000 & resp[1]; + report->snrhint = 0b00001000 & resp[1]; + report->snrlint = 0b00000100 & resp[1]; + report->rssihint = 0b00000010 & resp[1]; + report->rssilint = 0b00000001 & resp[1]; + + report->bltf = 0b10000000 & resp[2]; + report->snr_ready = 0b00100000 & resp[2]; + report->rssiready = 0b00001000 & resp[2]; + report->injside = 0b00000100 & resp[2]; + report->afcrl = 0b00000010 & resp[2]; + report->valid = 0b00000001 & resp[2]; + + report->readfreq = be16_to_cpup((__be16 *)(resp + 3)); report->freqoff = resp[5]; report->rssi = resp[6]; report->snr = resp[7]; @@ -1331,7 +1329,7 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core, report->hassi = resp[10]; report->mult = resp[11]; report->dev = resp[12]; - report->readantcap = get_unaligned_be16(resp + 13); + report->readantcap = be16_to_cpup((__be16 *)(resp + 13)); report->assi = resp[15]; report->usn = resp[16]; @@ -1339,7 +1337,7 @@ static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core, report->rdsdev = resp[18]; report->assidev = resp[19]; report->strongdev = resp[20]; - report->rdspi = get_unaligned_be16(resp + 21); + report->rdspi = be16_to_cpup((__be16 *)(resp + 21)); return err; } diff --git a/trunk/drivers/misc/atmel-ssc.c b/trunk/drivers/misc/atmel-ssc.c index 1abd5ad59925..c09c28f92055 100644 --- a/trunk/drivers/misc/atmel-ssc.c +++ b/trunk/drivers/misc/atmel-ssc.c @@ -154,6 +154,11 @@ static int ssc_probe(struct platform_device *pdev) ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_dbg(&pdev->dev, "no mmio resource defined\n"); + return -ENXIO; + } + ssc->regs = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(ssc->regs)) return PTR_ERR(ssc->regs); diff --git a/trunk/drivers/misc/dummy-irq.c b/trunk/drivers/misc/dummy-irq.c index c37eeedfe215..7014167e2c61 100644 --- a/trunk/drivers/misc/dummy-irq.c +++ b/trunk/drivers/misc/dummy-irq.c @@ -19,7 +19,7 @@ #include #include -static int irq = -1; +static int irq; static irqreturn_t dummy_interrupt(int irq, void *dev_id) { @@ -36,10 +36,6 @@ static irqreturn_t dummy_interrupt(int irq, void *dev_id) static int __init dummy_irq_init(void) { - if (irq < 0) { - printk(KERN_ERR "dummy-irq: no IRQ given. Use irq=N\n"); - return -EIO; - } if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) { printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq); return -EIO; diff --git a/trunk/drivers/misc/mei/bus.c b/trunk/drivers/misc/mei/bus.c index 9ecd49a7be1b..1e935eacaa7f 100644 --- a/trunk/drivers/misc/mei/bus.c +++ b/trunk/drivers/misc/mei/bus.c @@ -496,8 +496,6 @@ int mei_cl_disable_device(struct mei_cl_device *device) } } - device->event_cb = NULL; - mutex_unlock(&dev->device_lock); if (!device->ops || !device->ops->disable) diff --git a/trunk/drivers/misc/mei/main.c b/trunk/drivers/misc/mei/main.c index 053139f61086..7c44c8dbae42 100644 --- a/trunk/drivers/misc/mei/main.c +++ b/trunk/drivers/misc/mei/main.c @@ -489,16 +489,11 @@ static int mei_ioctl_connect_client(struct file *file, /* find ME client we're trying to connect to */ i = mei_me_cl_by_uuid(dev, &data->in_client_uuid); - if (i < 0 || dev->me_clients[i].props.fixed_address) { - dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n", - &data->in_client_uuid); - rets = -ENODEV; - goto end; + if (i >= 0 && !dev->me_clients[i].props.fixed_address) { + cl->me_client_id = dev->me_clients[i].client_id; + cl->state = MEI_FILE_CONNECTING; } - cl->me_client_id = dev->me_clients[i].client_id; - cl->state = MEI_FILE_CONNECTING; - dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", cl->me_client_id); dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", @@ -532,6 +527,11 @@ static int mei_ioctl_connect_client(struct file *file, goto end; } + if (cl->state != MEI_FILE_CONNECTING) { + rets = -ENODEV; + goto end; + } + /* prepare the output buffer */ client = &data->out_client_properties; @@ -543,6 +543,7 @@ static int mei_ioctl_connect_client(struct file *file, rets = mei_cl_connect(cl, file); end: + dev_dbg(&dev->pdev->dev, "free connect cb memory."); return rets; } diff --git a/trunk/drivers/misc/vmw_vmci/Kconfig b/trunk/drivers/misc/vmw_vmci/Kconfig index 39c2ecadb273..ea98f7e9ccd1 100644 --- a/trunk/drivers/misc/vmw_vmci/Kconfig +++ b/trunk/drivers/misc/vmw_vmci/Kconfig @@ -4,7 +4,7 @@ config VMWARE_VMCI tristate "VMware VMCI Driver" - depends on X86 && PCI + depends on X86 && PCI && NET help This is VMware's Virtual Machine Communication Interface. It enables high-speed communication between host and guest in a virtual diff --git a/trunk/drivers/misc/vmw_vmci/vmci_queue_pair.c b/trunk/drivers/misc/vmw_vmci/vmci_queue_pair.c index 8ff2e5ee8fb8..d94245dbd765 100644 --- a/trunk/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/trunk/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/mmc/host/mmci.c b/trunk/drivers/mmc/host/mmci.c index f4f3038c1df0..375c109607ff 100644 --- a/trunk/drivers/mmc/host/mmci.c +++ b/trunk/drivers/mmc/host/mmci.c @@ -1130,7 +1130,6 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct variant_data *variant = host->variant; u32 pwr = 0; unsigned long flags; - int ret; pm_runtime_get_sync(mmc_dev(mmc)); @@ -1162,12 +1161,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; case MMC_POWER_ON: if (!IS_ERR(mmc->supply.vqmmc) && - !regulator_is_enabled(mmc->supply.vqmmc)) { - ret = regulator_enable(mmc->supply.vqmmc); - if (ret < 0) - dev_err(mmc_dev(mmc), - "failed to enable vqmmc regulator\n"); - } + !regulator_is_enabled(mmc->supply.vqmmc)) + regulator_enable(mmc->supply.vqmmc); pwr |= MCI_PWR_ON; break; diff --git a/trunk/drivers/mtd/nand/lpc32xx_mlc.c b/trunk/drivers/mtd/nand/lpc32xx_mlc.c index fd1df5e13ae4..a94facb46e5c 100644 --- a/trunk/drivers/mtd/nand/lpc32xx_mlc.c +++ b/trunk/drivers/mtd/nand/lpc32xx_mlc.c @@ -672,6 +672,11 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) } rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (rc == NULL) { + dev_err(&pdev->dev, "No memory resource found for device!\r\n"); + return -ENXIO; + } + host->io_base = devm_ioremap_resource(&pdev->dev, rc); if (IS_ERR(host->io_base)) return PTR_ERR(host->io_base); diff --git a/trunk/drivers/net/ethernet/apple/bmac.c b/trunk/drivers/net/ethernet/apple/bmac.c index f36bbd6d5085..8848190e403d 100644 --- a/trunk/drivers/net/ethernet/apple/bmac.c +++ b/trunk/drivers/net/ethernet/apple/bmac.c @@ -1016,7 +1016,6 @@ static void bmac_set_multicast(struct net_device *dev) static void bmac_set_multicast(struct net_device *dev) { struct netdev_hw_addr *ha; - int i; unsigned short rx_cfg; u32 crc; diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c index a236ecd27cf3..fd7b547698ab 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -2976,17 +2976,22 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count, for (i = 0; i < desc_count; i++) { desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; if (((void *)desc + desc->desc_len) > - (void *)(buf + max_buf_size)) - return NULL; + (void *)(buf + max_buf_size)) { + desc = NULL; + break; + } if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) - return desc; + break; desc = (void *)desc + desc->desc_len; } - return NULL; + if (!desc || i == MAX_RESOURCE_DESC) + return NULL; + + return desc; } /* Uses Mbox */ diff --git a/trunk/drivers/net/ethernet/korina.c b/trunk/drivers/net/ethernet/korina.c index 5409fe876a44..907e94a3fb06 100644 --- a/trunk/drivers/net/ethernet/korina.c +++ b/trunk/drivers/net/ethernet/korina.c @@ -483,7 +483,6 @@ static void korina_multicast_list(struct net_device *dev) unsigned long flags; struct netdev_hw_addr *ha; u32 recognise = ETH_ARC_AB; /* always accept broadcasts */ - int i; /* Set promiscuous mode */ if (dev->flags & IFF_PROMISC) diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c index f87cc216045b..50235d201592 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -4717,7 +4717,6 @@ static int qlge_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "net device registration failed.\n"); ql_release_all(pdev); pci_disable_device(pdev); - free_netdev(ndev); return err; } /* Start up the timer to trigger EEH if diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.c b/trunk/drivers/net/ethernet/renesas/sh_eth.c index 42e9dd05c936..33dc6f2418f2 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.c +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.c @@ -2745,6 +2745,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev) if (mdp->cd->tsu) { struct resource *rtsu; rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!rtsu) { + dev_err(&pdev->dev, "Not found TSU resource\n"); + ret = -ENODEV; + goto out_release; + } mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu); if (IS_ERR(mdp->tsu_addr)) { ret = PTR_ERR(mdp->tsu_addr); diff --git a/trunk/drivers/net/ethernet/sun/sunbmac.c b/trunk/drivers/net/ethernet/sun/sunbmac.c index 054975939a18..85d3b6bec160 100644 --- a/trunk/drivers/net/ethernet/sun/sunbmac.c +++ b/trunk/drivers/net/ethernet/sun/sunbmac.c @@ -995,7 +995,6 @@ static void bigmac_set_multicast(struct net_device *dev) struct bigmac *bp = netdev_priv(dev); void __iomem *bregs = bp->bregs; struct netdev_hw_addr *ha; - int i; u32 tmp, crc; /* Disable the receiver. The bit self-clears when diff --git a/trunk/drivers/net/ntb_netdev.c b/trunk/drivers/net/ntb_netdev.c index f3cdf64997d6..ed947dd76fbd 100644 --- a/trunk/drivers/net/ntb_netdev.c +++ b/trunk/drivers/net/ntb_netdev.c @@ -375,8 +375,6 @@ static void ntb_netdev_remove(struct pci_dev *pdev) if (dev == NULL) return; - list_del(&dev->list); - ndev = dev->ndev; unregister_netdev(ndev); diff --git a/trunk/drivers/net/phy/phy.c b/trunk/drivers/net/phy/phy.c index 38f0b312ff85..c14f14741b3f 100644 --- a/trunk/drivers/net/phy/phy.c +++ b/trunk/drivers/net/phy/phy.c @@ -1044,7 +1044,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); idx = phy_find_setting(phydev->speed, phydev->duplex); - if (!(lp & adv & settings[idx].setting)) + if ((lp & adv & settings[idx].setting)) goto eee_exit; if (clk_stop_enable) { diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 89776c592151..f042b0373e5d 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -1585,10 +1585,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) else return -EINVAL; - if (!!(ifr->ifr_flags & IFF_MULTI_QUEUE) != - !!(tun->flags & TUN_TAP_MQ)) - return -EINVAL; - if (tun_not_capable(tun)) return -EPERM; err = security_tun_dev_open(tun->security); diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 06ee82f557d4..f95cb032394b 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -1477,7 +1477,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) /* usbnet already took usb runtime pm, so have to enable the feature * for usb interface, otherwise usb_autopm_get_interface may return - * failure if RUNTIME_PM is enabled. + * failure if USB_SUSPEND(RUNTIME_PM) is enabled. */ if (!driver->supports_autosuspend) { driver->supports_autosuspend = 1; diff --git a/trunk/drivers/ntb/ntb_hw.c b/trunk/drivers/ntb/ntb_hw.c index 2dacd19e1b8a..f802e7c92356 100644 --- a/trunk/drivers/ntb/ntb_hw.c +++ b/trunk/drivers/ntb/ntb_hw.c @@ -345,7 +345,7 @@ int ntb_read_remote_spad(struct ntb_device *ndev, unsigned int idx, u32 *val) */ void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw) { - if (mw >= NTB_NUM_MW) + if (mw > NTB_NUM_MW) return NULL; return ndev->mw[mw].vbase; @@ -362,7 +362,7 @@ void __iomem *ntb_get_mw_vbase(struct ntb_device *ndev, unsigned int mw) */ resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw) { - if (mw >= NTB_NUM_MW) + if (mw > NTB_NUM_MW) return 0; return ndev->mw[mw].bar_sz; @@ -380,7 +380,7 @@ resource_size_t ntb_get_mw_size(struct ntb_device *ndev, unsigned int mw) */ void ntb_set_mw_addr(struct ntb_device *ndev, unsigned int mw, u64 addr) { - if (mw >= NTB_NUM_MW) + if (mw > NTB_NUM_MW) return; dev_dbg(&ndev->pdev->dev, "Writing addr %Lx to BAR %d\n", addr, @@ -1027,8 +1027,8 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ndev->mw[i].vbase = ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)), ndev->mw[i].bar_sz); - dev_info(&pdev->dev, "MW %d size %llu\n", i, - pci_resource_len(pdev, MW_TO_BAR(i))); + dev_info(&pdev->dev, "MW %d size %d\n", i, + (u32) pci_resource_len(pdev, MW_TO_BAR(i))); if (!ndev->mw[i].vbase) { dev_warn(&pdev->dev, "Cannot remap BAR %d\n", MW_TO_BAR(i)); diff --git a/trunk/drivers/ntb/ntb_transport.c b/trunk/drivers/ntb/ntb_transport.c index f8d7081ee301..e0bdfd7f9930 100644 --- a/trunk/drivers/ntb/ntb_transport.c +++ b/trunk/drivers/ntb/ntb_transport.c @@ -58,7 +58,7 @@ #include #include "ntb_hw.h" -#define NTB_TRANSPORT_VERSION 3 +#define NTB_TRANSPORT_VERSION 2 static unsigned int transport_mtu = 0x401E; module_param(transport_mtu, uint, 0644); @@ -173,13 +173,10 @@ struct ntb_payload_header { enum { VERSION = 0, - QP_LINKS, + MW0_SZ, + MW1_SZ, NUM_QPS, - NUM_MWS, - MW0_SZ_HIGH, - MW0_SZ_LOW, - MW1_SZ_HIGH, - MW1_SZ_LOW, + QP_LINKS, MAX_SPAD, }; @@ -300,7 +297,7 @@ int ntb_register_client_dev(char *device_name) { struct ntb_transport_client_dev *client_dev; struct ntb_transport *nt; - int rc, i = 0; + int rc; if (list_empty(&ntb_transport_list)) return -ENODEV; @@ -318,7 +315,7 @@ int ntb_register_client_dev(char *device_name) dev = &client_dev->dev; /* setup and register client devices */ - dev_set_name(dev, "%s%d", device_name, i); + dev_set_name(dev, "%s", device_name); dev->bus = &ntb_bus_type; dev->release = ntb_client_release; dev->parent = &ntb_query_pdev(nt->ndev)->dev; @@ -330,7 +327,6 @@ int ntb_register_client_dev(char *device_name) } list_add_tail(&client_dev->entry, &nt->client_devs); - i++; } return 0; @@ -490,13 +486,12 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt, (qp_num / NTB_NUM_MW * rx_size); rx_size -= sizeof(struct ntb_rx_info); - qp->rx_buff = qp->remote_rx_info + 1; - /* Due to housekeeping, there must be atleast 2 buffs */ - qp->rx_max_frame = min(transport_mtu, rx_size / 2); + qp->rx_buff = qp->remote_rx_info + sizeof(struct ntb_rx_info); + qp->rx_max_frame = min(transport_mtu, rx_size); qp->rx_max_entry = rx_size / qp->rx_max_frame; qp->rx_index = 0; - qp->remote_rx_info->entry = qp->rx_max_entry - 1; + qp->remote_rx_info->entry = qp->rx_max_entry; /* setup the hdr offsets with 0's */ for (i = 0; i < qp->rx_max_entry; i++) { @@ -507,19 +502,6 @@ static void ntb_transport_setup_qp_mw(struct ntb_transport *nt, qp->rx_pkts = 0; qp->tx_pkts = 0; - qp->tx_index = 0; -} - -static void ntb_free_mw(struct ntb_transport *nt, int num_mw) -{ - struct ntb_transport_mw *mw = &nt->mw[num_mw]; - struct pci_dev *pdev = ntb_query_pdev(nt->ndev); - - if (!mw->virt_addr) - return; - - dma_free_coherent(&pdev->dev, mw->size, mw->virt_addr, mw->dma_addr); - mw->virt_addr = NULL; } static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size) @@ -527,20 +509,12 @@ static int ntb_set_mw(struct ntb_transport *nt, int num_mw, unsigned int size) struct ntb_transport_mw *mw = &nt->mw[num_mw]; struct pci_dev *pdev = ntb_query_pdev(nt->ndev); - /* No need to re-setup */ - if (mw->size == ALIGN(size, 4096)) - return 0; - - if (mw->size != 0) - ntb_free_mw(nt, num_mw); - /* Alloc memory for receiving data. Must be 4k aligned */ mw->size = ALIGN(size, 4096); mw->virt_addr = dma_alloc_coherent(&pdev->dev, mw->size, &mw->dma_addr, GFP_KERNEL); if (!mw->virt_addr) { - mw->size = 0; dev_err(&pdev->dev, "Unable to allocate MW buffer of size %d\n", (int) mw->size); return -ENOMEM; @@ -630,31 +604,25 @@ static void ntb_transport_link_work(struct work_struct *work) u32 val; int rc, i; - /* send the local info, in the opposite order of the way we read it */ - for (i = 0; i < NTB_NUM_MW; i++) { - rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), - ntb_get_mw_size(ndev, i) >> 32); - if (rc) { - dev_err(&pdev->dev, "Error writing %u to remote spad %d\n", - (u32)(ntb_get_mw_size(ndev, i) >> 32), - MW0_SZ_HIGH + (i * 2)); - goto out; - } + /* send the local info */ + rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION); + if (rc) { + dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", + 0, VERSION); + goto out; + } - rc = ntb_write_remote_spad(ndev, MW0_SZ_LOW + (i * 2), - (u32) ntb_get_mw_size(ndev, i)); - if (rc) { - dev_err(&pdev->dev, "Error writing %u to remote spad %d\n", - (u32) ntb_get_mw_size(ndev, i), - MW0_SZ_LOW + (i * 2)); - goto out; - } + rc = ntb_write_remote_spad(ndev, MW0_SZ, ntb_get_mw_size(ndev, 0)); + if (rc) { + dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", + (u32) ntb_get_mw_size(ndev, 0), MW0_SZ); + goto out; } - rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW); + rc = ntb_write_remote_spad(ndev, MW1_SZ, ntb_get_mw_size(ndev, 1)); if (rc) { dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", - NTB_NUM_MW, NUM_MWS); + (u32) ntb_get_mw_size(ndev, 1), MW1_SZ); goto out; } @@ -665,10 +633,16 @@ static void ntb_transport_link_work(struct work_struct *work) goto out; } - rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION); + rc = ntb_read_local_spad(nt->ndev, QP_LINKS, &val); + if (rc) { + dev_err(&pdev->dev, "Error reading spad %d\n", QP_LINKS); + goto out; + } + + rc = ntb_write_remote_spad(ndev, QP_LINKS, val); if (rc) { dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", - NTB_TRANSPORT_VERSION, VERSION); + val, QP_LINKS); goto out; } @@ -693,43 +667,33 @@ static void ntb_transport_link_work(struct work_struct *work) goto out; dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val); - rc = ntb_read_remote_spad(ndev, NUM_MWS, &val); + rc = ntb_read_remote_spad(ndev, MW0_SZ, &val); if (rc) { - dev_err(&pdev->dev, "Error reading remote spad %d\n", NUM_MWS); + dev_err(&pdev->dev, "Error reading remote spad %d\n", MW0_SZ); goto out; } - if (val != NTB_NUM_MW) + if (!val) goto out; - dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val); - - for (i = 0; i < NTB_NUM_MW; i++) { - u64 val64; + dev_dbg(&pdev->dev, "Remote MW0 size = %d\n", val); - rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val); - if (rc) { - dev_err(&pdev->dev, "Error reading remote spad %d\n", - MW0_SZ_HIGH + (i * 2)); - goto out1; - } - - val64 = (u64) val << 32; - - rc = ntb_read_remote_spad(ndev, MW0_SZ_LOW + (i * 2), &val); - if (rc) { - dev_err(&pdev->dev, "Error reading remote spad %d\n", - MW0_SZ_LOW + (i * 2)); - goto out1; - } + rc = ntb_set_mw(nt, 0, val); + if (rc) + goto out; - val64 |= val; + rc = ntb_read_remote_spad(ndev, MW1_SZ, &val); + if (rc) { + dev_err(&pdev->dev, "Error reading remote spad %d\n", MW1_SZ); + goto out; + } - dev_dbg(&pdev->dev, "Remote MW%d size = %llu\n", i, val64); + if (!val) + goto out; + dev_dbg(&pdev->dev, "Remote MW1 size = %d\n", val); - rc = ntb_set_mw(nt, i, val64); - if (rc) - goto out1; - } + rc = ntb_set_mw(nt, 1, val); + if (rc) + goto out; nt->transport_link = NTB_LINK_UP; @@ -744,9 +708,6 @@ static void ntb_transport_link_work(struct work_struct *work) return; -out1: - for (i = 0; i < NTB_NUM_MW; i++) - ntb_free_mw(nt, i); out: if (ntb_hw_link_status(ndev)) schedule_delayed_work(&nt->link_work, @@ -819,10 +780,10 @@ static void ntb_transport_init_queue(struct ntb_transport *nt, (qp_num / NTB_NUM_MW * tx_size); tx_size -= sizeof(struct ntb_rx_info); - qp->tx_mw = qp->rx_info + 1; - /* Due to housekeeping, there must be atleast 2 buffs */ - qp->tx_max_frame = min(transport_mtu, tx_size / 2); + qp->tx_mw = qp->rx_info + sizeof(struct ntb_rx_info); + qp->tx_max_frame = min(transport_mtu, tx_size); qp->tx_max_entry = tx_size / qp->tx_max_frame; + qp->tx_index = 0; if (nt->debugfs_dir) { char debugfs_name[4]; @@ -936,7 +897,10 @@ void ntb_transport_free(void *transport) pdev = ntb_query_pdev(nt->ndev); for (i = 0; i < NTB_NUM_MW; i++) - ntb_free_mw(nt, i); + if (nt->mw[i].virt_addr) + dma_free_coherent(&pdev->dev, nt->mw[i].size, + nt->mw[i].virt_addr, + nt->mw[i].dma_addr); kfree(nt->qps); ntb_unregister_transport(nt->ndev); @@ -1035,16 +999,11 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp) static void ntb_transport_rx(unsigned long data) { struct ntb_transport_qp *qp = (struct ntb_transport_qp *)data; - int rc, i; + int rc; - /* Limit the number of packets processed in a single interrupt to - * provide fairness to others - */ - for (i = 0; i < qp->rx_max_entry; i++) { + do { rc = ntb_process_rxc(qp); - if (rc) - break; - } + } while (!rc); } static void ntb_transport_rxc_db(void *data, int db_num) @@ -1251,14 +1210,12 @@ EXPORT_SYMBOL_GPL(ntb_transport_create_queue); */ void ntb_transport_free_queue(struct ntb_transport_qp *qp) { - struct pci_dev *pdev; + struct pci_dev *pdev = ntb_query_pdev(qp->ndev); struct ntb_queue_entry *entry; if (!qp) return; - pdev = ntb_query_pdev(qp->ndev); - cancel_delayed_work_sync(&qp->link_work); ntb_unregister_db_callback(qp->ndev, qp->qp_num); @@ -1414,13 +1371,12 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_up); */ void ntb_transport_link_down(struct ntb_transport_qp *qp) { - struct pci_dev *pdev; + struct pci_dev *pdev = ntb_query_pdev(qp->ndev); int rc, val; if (!qp) return; - pdev = ntb_query_pdev(qp->ndev); qp->client_ready = NTB_LINK_DOWN; rc = ntb_read_local_spad(qp->ndev, QP_LINKS, &val); @@ -1452,9 +1408,6 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_down); */ bool ntb_transport_link_query(struct ntb_transport_qp *qp) { - if (!qp) - return false; - return qp->qp_link == NTB_LINK_UP; } EXPORT_SYMBOL_GPL(ntb_transport_link_query); @@ -1469,9 +1422,6 @@ EXPORT_SYMBOL_GPL(ntb_transport_link_query); */ unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp) { - if (!qp) - return 0; - return qp->qp_num; } EXPORT_SYMBOL_GPL(ntb_transport_qp_num); @@ -1486,9 +1436,6 @@ EXPORT_SYMBOL_GPL(ntb_transport_qp_num); */ unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp) { - if (!qp) - return 0; - return qp->tx_max_frame - sizeof(struct ntb_payload_header); } EXPORT_SYMBOL_GPL(ntb_transport_max_size); diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index f53b992f060a..c76d16c972cc 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -1208,11 +1208,11 @@ static int __of_parse_phandle_with_args(const struct device_node *np, out_args->args_count = count; for (i = 0; i < count; i++) out_args->args[i] = be32_to_cpup(list++); - } else { - of_node_put(node); } /* Found it! return success */ + if (node) + of_node_put(node); return 0; } diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 716aa93fff76..96fed19c6d90 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -950,20 +950,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK ; } -void acpiphp_check_host_bridge(acpi_handle handle) -{ - struct acpiphp_bridge *bridge; - - bridge = acpiphp_handle_to_bridge(handle); - if (bridge) { - acpiphp_check_bridge(bridge); - put_bridge(bridge); - } - - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, - ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); -} - static void _handle_hotplug_event_bridge(struct work_struct *work) { struct acpiphp_bridge *bridge; diff --git a/trunk/drivers/pinctrl/pinctrl-abx500.c b/trunk/drivers/pinctrl/pinctrl-abx500.c index 6d4532702f80..aa17f7580f61 100644 --- a/trunk/drivers/pinctrl/pinctrl-abx500.c +++ b/trunk/drivers/pinctrl/pinctrl-abx500.c @@ -851,12 +851,23 @@ static int abx500_gpio_probe(struct platform_device *pdev) if (abx500_pdata) pdata = abx500_pdata->gpio; + if (!pdata) { + if (np) { + const struct of_device_id *match; - if (!(pdata || np)) { - dev_err(&pdev->dev, "gpio dt and platform data missing\n"); - return -ENODEV; + match = of_match_device(abx500_gpio_match, &pdev->dev); + if (!match) + return -ENODEV; + id = (unsigned long)match->data; + } else { + dev_err(&pdev->dev, "gpio dt and platform data missing\n"); + return -ENODEV; + } } + if (platid) + id = platid->driver_data; + pct = devm_kzalloc(&pdev->dev, sizeof(struct abx500_pinctrl), GFP_KERNEL); if (pct == NULL) { @@ -871,16 +882,6 @@ static int abx500_gpio_probe(struct platform_device *pdev) pct->chip.dev = &pdev->dev; pct->chip.base = (np) ? -1 : pdata->gpio_base; - if (platid) - id = platid->driver_data; - else if (np) { - const struct of_device_id *match; - - match = of_match_device(abx500_gpio_match, &pdev->dev); - if (match) - id = (unsigned long)match->data; - } - /* initialize the lock */ mutex_init(&pct->lock); @@ -899,7 +900,8 @@ static int abx500_gpio_probe(struct platform_device *pdev) abx500_pinctrl_ab8505_init(&pct->soc); break; default: - dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n", id); + dev_err(&pdev->dev, "Unsupported pinctrl sub driver (%d)\n", + (int) platid->driver_data); mutex_destroy(&pct->lock); return -EINVAL; } diff --git a/trunk/drivers/pinctrl/pinctrl-coh901.c b/trunk/drivers/pinctrl/pinctrl-coh901.c index a67af419f531..edde3acc4186 100644 --- a/trunk/drivers/pinctrl/pinctrl-coh901.c +++ b/trunk/drivers/pinctrl/pinctrl-coh901.c @@ -713,6 +713,11 @@ static int __init u300_gpio_probe(struct platform_device *pdev) gpio->dev = &pdev->dev; memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!memres) { + dev_err(gpio->dev, "could not get GPIO memory resource\n"); + return -ENODEV; + } + gpio->base = devm_ioremap_resource(&pdev->dev, memres); if (IS_ERR(gpio->base)) return PTR_ERR(gpio->base); diff --git a/trunk/drivers/pinctrl/pinctrl-exynos5440.c b/trunk/drivers/pinctrl/pinctrl-exynos5440.c index 32a48f44f574..6038503ed929 100644 --- a/trunk/drivers/pinctrl/pinctrl-exynos5440.c +++ b/trunk/drivers/pinctrl/pinctrl-exynos5440.c @@ -1000,6 +1000,11 @@ static int exynos5440_pinctrl_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "cannot find IO resource\n"); + return -ENOENT; + } + priv->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->reg_base)) return PTR_ERR(priv->reg_base); diff --git a/trunk/drivers/pinctrl/pinctrl-lantiq.c b/trunk/drivers/pinctrl/pinctrl-lantiq.c index d22ca252b80d..615c5002b757 100644 --- a/trunk/drivers/pinctrl/pinctrl-lantiq.c +++ b/trunk/drivers/pinctrl/pinctrl-lantiq.c @@ -52,8 +52,7 @@ static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, int i; for (i = 0; i < num_maps; i++) - if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN || - map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) + if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN) kfree(map[i].data.configs.configs); kfree(map); } diff --git a/trunk/drivers/pinctrl/pinctrl-samsung.c b/trunk/drivers/pinctrl/pinctrl-samsung.c index 055d0162098b..976366899f68 100644 --- a/trunk/drivers/pinctrl/pinctrl-samsung.c +++ b/trunk/drivers/pinctrl/pinctrl-samsung.c @@ -932,6 +932,11 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) drvdata->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "cannot find IO resource\n"); + return -ENOENT; + } + drvdata->virt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(drvdata->virt_base)) return PTR_ERR(drvdata->virt_base); diff --git a/trunk/drivers/pinctrl/pinctrl-single.c b/trunk/drivers/pinctrl/pinctrl-single.c index b9fa04618601..5f2d2bfd356e 100644 --- a/trunk/drivers/pinctrl/pinctrl-single.c +++ b/trunk/drivers/pinctrl/pinctrl-single.c @@ -1166,8 +1166,7 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, (*map)->data.mux.function = np->name; if (pcs->is_pinconf) { - res = pcs_parse_pinconf(pcs, np, function, map); - if (res) + if (pcs_parse_pinconf(pcs, np, function, map)) goto free_pingroups; *num_maps = 2; } else { diff --git a/trunk/drivers/pinctrl/pinctrl-xway.c b/trunk/drivers/pinctrl/pinctrl-xway.c index e92132c76a6b..f2977cff8366 100644 --- a/trunk/drivers/pinctrl/pinctrl-xway.c +++ b/trunk/drivers/pinctrl/pinctrl-xway.c @@ -716,6 +716,10 @@ static int pinmux_xway_probe(struct platform_device *pdev) /* get and remap our register range */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get resource\n"); + return -ENOENT; + } xway_info.membase[0] = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(xway_info.membase[0])) return PTR_ERR(xway_info.membase[0]); diff --git a/trunk/drivers/pinctrl/vt8500/pinctrl-wm8750.c b/trunk/drivers/pinctrl/vt8500/pinctrl-wm8750.c index de43262398db..b964cc550568 100644 --- a/trunk/drivers/pinctrl/vt8500/pinctrl-wm8750.c +++ b/trunk/drivers/pinctrl/vt8500/pinctrl-wm8750.c @@ -53,7 +53,7 @@ static const struct wmt_pinctrl_bank_registers wm8750_banks[] = { #define WMT_PIN_EXTGPIO6 WMT_PIN(0, 6) #define WMT_PIN_EXTGPIO7 WMT_PIN(0, 7) #define WMT_PIN_WAKEUP0 WMT_PIN(0, 16) -#define WMT_PIN_WAKEUP1 WMT_PIN(0, 17) +#define WMT_PIN_WAKEUP1 WMT_PIN(0, 16) #define WMT_PIN_SD0CD WMT_PIN(0, 28) #define WMT_PIN_VDOUT0 WMT_PIN(1, 0) #define WMT_PIN_VDOUT1 WMT_PIN(1, 1) diff --git a/trunk/drivers/ptp/ptp_pch.c b/trunk/drivers/ptp/ptp_pch.c index 71a2559278d7..bea94510ad2d 100644 --- a/trunk/drivers/ptp/ptp_pch.c +++ b/trunk/drivers/ptp/ptp_pch.c @@ -628,10 +628,9 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id) chip->caps = ptp_pch_caps; chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev); - if (IS_ERR(chip->ptp_clock)) { - ret = PTR_ERR(chip->ptp_clock); - goto err_ptp_clock_reg; - } + + if (IS_ERR(chip->ptp_clock)) + return PTR_ERR(chip->ptp_clock); spin_lock_init(&chip->register_lock); @@ -670,7 +669,6 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_req_irq: ptp_clock_unregister(chip->ptp_clock); -err_ptp_clock_reg: iounmap(chip->regs); chip->regs = NULL; diff --git a/trunk/drivers/pwm/pwm-imx.c b/trunk/drivers/pwm/pwm-imx.c index c938bae18812..ec287989eafc 100644 --- a/trunk/drivers/pwm/pwm-imx.c +++ b/trunk/drivers/pwm/pwm-imx.c @@ -265,6 +265,11 @@ static int imx_pwm_probe(struct platform_device *pdev) imx->chip.npwm = 1; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + imx->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); diff --git a/trunk/drivers/pwm/pwm-puv3.c b/trunk/drivers/pwm/pwm-puv3.c index ed6007b27585..d1eb499fb15d 100644 --- a/trunk/drivers/pwm/pwm-puv3.c +++ b/trunk/drivers/pwm/pwm-puv3.c @@ -117,6 +117,11 @@ static int pwm_probe(struct platform_device *pdev) return PTR_ERR(puv3->clk); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + puv3->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(puv3->base)) return PTR_ERR(puv3->base); diff --git a/trunk/drivers/pwm/pwm-pxa.c b/trunk/drivers/pwm/pwm-pxa.c index dc9717551d39..dee6ab552a0a 100644 --- a/trunk/drivers/pwm/pwm-pxa.c +++ b/trunk/drivers/pwm/pwm-pxa.c @@ -147,6 +147,11 @@ static int pwm_probe(struct platform_device *pdev) pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(pwm->mmio_base)) return PTR_ERR(pwm->mmio_base); diff --git a/trunk/drivers/pwm/pwm-tegra.c b/trunk/drivers/pwm/pwm-tegra.c index a5402933001f..3d75f4a88f98 100644 --- a/trunk/drivers/pwm/pwm-tegra.c +++ b/trunk/drivers/pwm/pwm-tegra.c @@ -181,6 +181,11 @@ static int tegra_pwm_probe(struct platform_device *pdev) pwm->dev = &pdev->dev; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no memory resources defined\n"); + return -ENODEV; + } + pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(pwm->mmio_base)) return PTR_ERR(pwm->mmio_base); diff --git a/trunk/drivers/pwm/pwm-tiecap.c b/trunk/drivers/pwm/pwm-tiecap.c index 72ca42dfa733..0d65fb2e02c7 100644 --- a/trunk/drivers/pwm/pwm-tiecap.c +++ b/trunk/drivers/pwm/pwm-tiecap.c @@ -240,6 +240,11 @@ static int ecap_pwm_probe(struct platform_device *pdev) pc->chip.npwm = 1; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(pc->mmio_base)) return PTR_ERR(pc->mmio_base); diff --git a/trunk/drivers/pwm/pwm-tiehrpwm.c b/trunk/drivers/pwm/pwm-tiehrpwm.c index 48a485c2e422..6a217596942f 100644 --- a/trunk/drivers/pwm/pwm-tiehrpwm.c +++ b/trunk/drivers/pwm/pwm-tiehrpwm.c @@ -471,6 +471,11 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) pc->chip.npwm = NUM_PWM_CHANNEL; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(pc->mmio_base)) return PTR_ERR(pc->mmio_base); diff --git a/trunk/drivers/pwm/pwm-tipwmss.c b/trunk/drivers/pwm/pwm-tipwmss.c index 3b119bc2c3c6..c9c3d3a1e0eb 100644 --- a/trunk/drivers/pwm/pwm-tipwmss.c +++ b/trunk/drivers/pwm/pwm-tipwmss.c @@ -70,6 +70,11 @@ static int pwmss_probe(struct platform_device *pdev) mutex_init(&info->pwmss_lock); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + info->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(info->mmio_base)) return PTR_ERR(info->mmio_base); diff --git a/trunk/drivers/pwm/pwm-vt8500.c b/trunk/drivers/pwm/pwm-vt8500.c index 323125abf3f4..69effd19afc7 100644 --- a/trunk/drivers/pwm/pwm-vt8500.c +++ b/trunk/drivers/pwm/pwm-vt8500.c @@ -230,6 +230,11 @@ static int vt8500_pwm_probe(struct platform_device *pdev) } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + chip->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(chip->base)) return PTR_ERR(chip->base); diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index b9838130a7b0..0c81915b1997 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -20,6 +20,7 @@ if RTC_CLASS config RTC_HCTOSYS bool "Set system time from RTC on startup and resume" default y + depends on !ALWAYS_USE_PERSISTENT_CLOCK help If you say yes here, the system time (wall clock) will be set using the value read from a specified RTC device. This is useful to avoid @@ -28,6 +29,7 @@ config RTC_HCTOSYS config RTC_SYSTOHC bool "Set the RTC time based on NTP synchronization" default y + depends on !ALWAYS_USE_PERSISTENT_CLOCK help If you say yes here, the system time (wall clock) will be stored in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 diff --git a/trunk/drivers/rtc/rtc-nuc900.c b/trunk/drivers/rtc/rtc-nuc900.c index d592e2fe43f7..f5dfb6e5e7d9 100644 --- a/trunk/drivers/rtc/rtc-nuc900.c +++ b/trunk/drivers/rtc/rtc-nuc900.c @@ -234,6 +234,11 @@ static int __init nuc900_rtc_probe(struct platform_device *pdev) return -ENOMEM; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "platform_get_resource failed\n"); + return -ENXIO; + } + nuc900_rtc->rtc_reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(nuc900_rtc->rtc_reg)) return PTR_ERR(nuc900_rtc->rtc_reg); diff --git a/trunk/drivers/rtc/rtc-omap.c b/trunk/drivers/rtc/rtc-omap.c index b0ba3fc991ea..4e1bdb832e37 100644 --- a/trunk/drivers/rtc/rtc-omap.c +++ b/trunk/drivers/rtc/rtc-omap.c @@ -347,6 +347,11 @@ static int __init omap_rtc_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + pr_debug("%s: RTC resource data missing\n", pdev->name); + return -ENOENT; + } + rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rtc_base)) return PTR_ERR(rtc_base); diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 0b495e8b8e66..14040b22888d 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -477,6 +477,11 @@ static int s3c_rtc_probe(struct platform_device *pdev) /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "failed to get memory region resource\n"); + return -ENOENT; + } + s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(s3c_rtc_base)) return PTR_ERR(s3c_rtc_base); diff --git a/trunk/drivers/rtc/rtc-tegra.c b/trunk/drivers/rtc/rtc-tegra.c index 76af92ad5a8a..a34315d25478 100644 --- a/trunk/drivers/rtc/rtc-tegra.c +++ b/trunk/drivers/rtc/rtc-tegra.c @@ -322,6 +322,12 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, + "Unable to allocate resources for device.\n"); + return -EBUSY; + } + info->rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(info->rtc_base)) return PTR_ERR(info->rtc_base); diff --git a/trunk/drivers/s390/block/xpram.c b/trunk/drivers/s390/block/xpram.c index 464dd29d06c0..690c3338a8ae 100644 --- a/trunk/drivers/s390/block/xpram.c +++ b/trunk/drivers/s390/block/xpram.c @@ -343,7 +343,6 @@ static int __init xpram_setup_blkdev(void) put_disk(xpram_disks[i]); goto out; } - queue_flag_set_unlocked(QUEUE_FLAG_NONROT, xpram_queues[i]); blk_queue_make_request(xpram_queues[i], xpram_make_request); blk_queue_logical_block_size(xpram_queues[i], 4096); } diff --git a/trunk/drivers/s390/cio/chp.c b/trunk/drivers/s390/cio/chp.c index 6c440d4349d4..21fabc6d5a9c 100644 --- a/trunk/drivers/s390/cio/chp.c +++ b/trunk/drivers/s390/cio/chp.c @@ -352,48 +352,12 @@ static ssize_t chp_shared_show(struct device *dev, static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL); -static ssize_t chp_chid_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct channel_path *chp = to_channelpath(dev); - ssize_t rc; - - mutex_lock(&chp->lock); - if (chp->desc_fmt1.flags & 0x10) - rc = sprintf(buf, "%04x\n", chp->desc_fmt1.chid); - else - rc = 0; - mutex_unlock(&chp->lock); - - return rc; -} -static DEVICE_ATTR(chid, 0444, chp_chid_show, NULL); - -static ssize_t chp_chid_external_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct channel_path *chp = to_channelpath(dev); - ssize_t rc; - - mutex_lock(&chp->lock); - if (chp->desc_fmt1.flags & 0x10) - rc = sprintf(buf, "%x\n", chp->desc_fmt1.flags & 0x8 ? 1 : 0); - else - rc = 0; - mutex_unlock(&chp->lock); - - return rc; -} -static DEVICE_ATTR(chid_external, 0444, chp_chid_external_show, NULL); - static struct attribute *chp_attrs[] = { &dev_attr_status.attr, &dev_attr_configure.attr, &dev_attr_type.attr, &dev_attr_cmg.attr, &dev_attr_shared.attr, - &dev_attr_chid.attr, - &dev_attr_chid_external.attr, NULL, }; static struct attribute_group chp_attr_group = { diff --git a/trunk/drivers/s390/cio/chsc.h b/trunk/drivers/s390/cio/chsc.h index e7ef2a683b8f..349d5fc47196 100644 --- a/trunk/drivers/s390/cio/chsc.h +++ b/trunk/drivers/s390/cio/chsc.h @@ -43,9 +43,7 @@ struct channel_path_desc_fmt1 { u8 chpid; u32:24; u8 chpp; - u32 unused[2]; - u16 chid; - u32:16; + u32 unused[3]; u16 mdc; u16:13; u8 r:1; diff --git a/trunk/drivers/spi/spi-tegra20-sflash.c b/trunk/drivers/spi/spi-tegra20-sflash.c index 09df8e22dba0..d65c000efe35 100644 --- a/trunk/drivers/spi/spi-tegra20-sflash.c +++ b/trunk/drivers/spi/spi-tegra20-sflash.c @@ -489,6 +489,11 @@ static int tegra_sflash_probe(struct platform_device *pdev) tegra_sflash_parse_dt(tsd); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "No IO memory resource\n"); + ret = -ENODEV; + goto exit_free_master; + } tsd->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(tsd->base)) { ret = PTR_ERR(tsd->base); diff --git a/trunk/drivers/staging/Kconfig b/trunk/drivers/staging/Kconfig index aefe820a8005..4e8a1794f50a 100644 --- a/trunk/drivers/staging/Kconfig +++ b/trunk/drivers/staging/Kconfig @@ -72,10 +72,10 @@ source "drivers/staging/sep/Kconfig" source "drivers/staging/iio/Kconfig" -source "drivers/staging/zsmalloc/Kconfig" - source "drivers/staging/zram/Kconfig" +source "drivers/staging/zsmalloc/Kconfig" + source "drivers/staging/wlags49_h2/Kconfig" source "drivers/staging/wlags49_h25/Kconfig" diff --git a/trunk/drivers/staging/android/logger.c b/trunk/drivers/staging/android/logger.c index 9bd874789ce5..b040200a5a55 100644 --- a/trunk/drivers/staging/android/logger.c +++ b/trunk/drivers/staging/android/logger.c @@ -242,7 +242,7 @@ static ssize_t do_read_log_to_user(struct logger_log *log, * 'log->buffer' which contains the first entry readable by 'euid' */ static size_t get_next_entry_by_uid(struct logger_log *log, - size_t off, kuid_t euid) + size_t off, uid_t euid) { while (off != log->w_off) { struct logger_entry *entry; @@ -251,7 +251,7 @@ static size_t get_next_entry_by_uid(struct logger_log *log, entry = get_entry_header(log, off, &scratch); - if (uid_eq(entry->euid, euid)) + if (entry->euid == euid) return off; next_len = sizeof(struct logger_entry) + entry->len; diff --git a/trunk/drivers/staging/android/logger.h b/trunk/drivers/staging/android/logger.h index 70af7d805dff..cc6bbd99c8e0 100644 --- a/trunk/drivers/staging/android/logger.h +++ b/trunk/drivers/staging/android/logger.h @@ -66,7 +66,7 @@ struct logger_entry { __s32 tid; __s32 sec; __s32 nsec; - kuid_t euid; + uid_t euid; char msg[0]; }; diff --git a/trunk/drivers/staging/comedi/Kconfig b/trunk/drivers/staging/comedi/Kconfig index 87e852a0ef49..7871579bb83d 100644 --- a/trunk/drivers/staging/comedi/Kconfig +++ b/trunk/drivers/staging/comedi/Kconfig @@ -981,7 +981,6 @@ config COMEDI_ME_DAQ config COMEDI_NI_6527 tristate "NI 6527 support" - depends on HAS_DMA select COMEDI_MITE ---help--- Enable support for the National Instruments 6527 PCI card @@ -991,7 +990,6 @@ config COMEDI_NI_6527 config COMEDI_NI_65XX tristate "NI 65xx static dio PCI card support" - depends on HAS_DMA select COMEDI_MITE ---help--- Enable support for National Instruments 65xx static dio boards. @@ -1005,7 +1003,6 @@ config COMEDI_NI_65XX config COMEDI_NI_660X tristate "NI 660x counter/timer PCI card support" - depends on HAS_DMA select COMEDI_NI_TIOCMD ---help--- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, @@ -1016,7 +1013,6 @@ config COMEDI_NI_660X config COMEDI_NI_670X tristate "NI 670x PCI card support" - depends on HAS_DMA select COMEDI_MITE ---help--- Enable support for National Instruments PCI-6703 and PCI-6704 @@ -1026,7 +1022,6 @@ config COMEDI_NI_670X config COMEDI_NI_LABPC_PCI tristate "NI Lab-PC PCI-1200 support" - depends on HAS_DMA select COMEDI_NI_LABPC select COMEDI_MITE ---help--- @@ -1037,7 +1032,6 @@ config COMEDI_NI_LABPC_PCI config COMEDI_NI_PCIDIO tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support" - depends on HAS_DMA select COMEDI_MITE select COMEDI_8255 ---help--- @@ -1049,7 +1043,6 @@ config COMEDI_NI_PCIDIO config COMEDI_NI_PCIMIO tristate "NI PCI-MIO-E series and M series support" - depends on HAS_DMA select COMEDI_NI_TIOCMD select COMEDI_8255 select COMEDI_FC @@ -1102,12 +1095,10 @@ config COMEDI_SSV_DNP called ssv_dnp. config COMEDI_MITE - depends on HAS_DMA tristate config COMEDI_NI_TIOCMD tristate - depends on HAS_DMA select COMEDI_NI_TIO select COMEDI_MITE diff --git a/trunk/drivers/staging/comedi/comedi_buf.c b/trunk/drivers/staging/comedi/comedi_buf.c index d4be0e68509b..ca709901fb3e 100644 --- a/trunk/drivers/staging/comedi/comedi_buf.c +++ b/trunk/drivers/staging/comedi/comedi_buf.c @@ -51,12 +51,10 @@ static void __comedi_buf_free(struct comedi_device *dev, clear_bit(PG_reserved, &(virt_to_page(buf->virt_addr)->flags)); if (s->async_dma_dir != DMA_NONE) { -#ifdef CONFIG_HAS_DMA dma_free_coherent(dev->hw_dev, PAGE_SIZE, buf->virt_addr, buf->dma_addr); -#endif } else { free_page((unsigned long)buf->virt_addr); } @@ -76,12 +74,6 @@ static void __comedi_buf_alloc(struct comedi_device *dev, struct comedi_buf_page *buf; unsigned i; - if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) { - dev_err(dev->class_dev, - "dma buffer allocation not supported\n"); - return; - } - async->buf_page_list = vzalloc(sizeof(*buf) * n_pages); if (async->buf_page_list) pages = vmalloc(sizeof(struct page *) * n_pages); @@ -92,15 +84,11 @@ static void __comedi_buf_alloc(struct comedi_device *dev, for (i = 0; i < n_pages; i++) { buf = &async->buf_page_list[i]; if (s->async_dma_dir != DMA_NONE) -#ifdef CONFIG_HAS_DMA buf->virt_addr = dma_alloc_coherent(dev->hw_dev, PAGE_SIZE, &buf->dma_addr, GFP_KERNEL | __GFP_COMP); -#else - break; -#endif else buf->virt_addr = (void *)get_zeroed_page(GFP_KERNEL); if (!buf->virt_addr) diff --git a/trunk/drivers/staging/comedi/comedi_fops.c b/trunk/drivers/staging/comedi/comedi_fops.c index 924c54c9c31f..00f2547024ec 100644 --- a/trunk/drivers/staging/comedi/comedi_fops.c +++ b/trunk/drivers/staging/comedi/comedi_fops.c @@ -246,6 +246,9 @@ static int resize_async_buffer(struct comedi_device *dev, return -EBUSY; } + if (!async->prealloc_buf) + return -EINVAL; + /* make sure buffer is an integral number of pages * (we round up) */ new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; diff --git a/trunk/drivers/staging/comedi/drivers/ni_labpc.c b/trunk/drivers/staging/comedi/drivers/ni_labpc.c index 77a7bb632580..3d978f34d212 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_labpc.c +++ b/trunk/drivers/staging/comedi/drivers/ni_labpc.c @@ -976,7 +976,8 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* clear flip-flop to make sure 2-byte registers for * count and address get set correctly */ clear_dma_ff(devpriv->dma_chan); - set_dma_addr(devpriv->dma_chan, devpriv->dma_addr); + set_dma_addr(devpriv->dma_chan, + virt_to_bus(devpriv->dma_buffer)); /* set appropriate size of transfer */ devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd); if (cmd->stop_src == TRIG_COUNT && @@ -1088,7 +1089,7 @@ static void labpc_drain_dma(struct comedi_device *dev) devpriv->count -= num_points; /* set address and count for next transfer */ - set_dma_addr(devpriv->dma_chan, devpriv->dma_addr); + set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer)); set_dma_count(devpriv->dma_chan, leftover * sample_size); release_dma_lock(flags); @@ -1740,9 +1741,6 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long dma_flags; devpriv->dma_chan = dma_chan; - devpriv->dma_addr = - virt_to_bus(devpriv->dma_buffer); - dma_flags = claim_dma_lock(); disable_dma(devpriv->dma_chan); set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); diff --git a/trunk/drivers/staging/comedi/drivers/ni_labpc.h b/trunk/drivers/staging/comedi/drivers/ni_labpc.h index 4b691f5a9965..615f16f271c0 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_labpc.h +++ b/trunk/drivers/staging/comedi/drivers/ni_labpc.h @@ -82,7 +82,6 @@ struct labpc_private { unsigned int divisor_b1; unsigned int dma_chan; /* dma channel to use */ u16 *dma_buffer; /* buffer ai will dma into */ - phys_addr_t dma_addr; /* transfer size in bytes for current transfer */ unsigned int dma_transfer_size; /* we are using dma/fifo-half-full/etc. */ diff --git a/trunk/drivers/staging/comedi/drivers/ni_mio_common.c b/trunk/drivers/staging/comedi/drivers/ni_mio_common.c index 8c5dee9b3b05..a46d579016d9 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/trunk/drivers/staging/comedi/drivers/ni_mio_common.c @@ -310,11 +310,9 @@ static int ni_gpct_insn_read(struct comedi_device *dev, static int ni_gpct_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -#ifdef PCIDMA static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s); static int ni_gpct_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); -#endif static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static void handle_gpct_interrupt(struct comedi_device *dev, @@ -4619,7 +4617,9 @@ static int ni_E_init(struct comedi_device *dev) for (j = 0; j < NUM_GPCT; ++j) { s = &dev->subdevices[NI_GPCT_SUBDEV(j)]; s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ + /* | SDF_CMD_WRITE */ ; s->n_chan = 3; if (board->reg_type & ni_reg_m_series_mask) s->maxdata = 0xffffffff; @@ -4628,14 +4628,11 @@ static int ni_E_init(struct comedi_device *dev) s->insn_read = &ni_gpct_insn_read; s->insn_write = &ni_gpct_insn_write; s->insn_config = &ni_gpct_insn_config; -#ifdef PCIDMA - s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */; s->do_cmd = &ni_gpct_cmd; s->len_chanlist = 1; s->do_cmdtest = &ni_gpct_cmdtest; s->cancel = &ni_gpct_cancel; s->async_dma_dir = DMA_BIDIRECTIONAL; -#endif s->private = &devpriv->counter_dev->counters[j]; devpriv->counter_dev->counters[j].chip_index = 0; @@ -5219,10 +5216,10 @@ static int ni_gpct_insn_write(struct comedi_device *dev, return ni_tio_winsn(counter, insn, data); } -#ifdef PCIDMA static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { int retval; +#ifdef PCIDMA struct ni_gpct *counter = s->private; /* const struct comedi_cmd *cmd = &s->async->cmd; */ @@ -5236,20 +5233,23 @@ static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL); ni_e_series_enable_second_irq(dev, counter->counter_index, 1); retval = ni_tio_cmd(counter, s->async); +#else + retval = -ENOTSUPP; +#endif return retval; } -#endif -#ifdef PCIDMA static int ni_gpct_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { +#ifdef PCIDMA struct ni_gpct *counter = s->private; return ni_tio_cmdtest(counter, cmd); +#else return -ENOTSUPP; -} #endif +} static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { diff --git a/trunk/drivers/staging/dwc2/Kconfig b/trunk/drivers/staging/dwc2/Kconfig index d15d9d58e5ac..f0b4739c65a1 100644 --- a/trunk/drivers/staging/dwc2/Kconfig +++ b/trunk/drivers/staging/dwc2/Kconfig @@ -2,6 +2,7 @@ config USB_DWC2 tristate "DesignWare USB2 DRD Core Support" depends on USB depends on VIRT_TO_BUS + select USB_OTG_UTILS help Say Y or M here if your system has a Dual Role HighSpeed USB controller based on the DesignWare HSOTG IP Core. @@ -38,7 +39,6 @@ config USB_DWC2_TRACK_MISSED_SOFS bool "Enable Missed SOF Tracking" help Say Y here to enable logging of missed SOF events to the dmesg log. - WARNING: This feature is still experimental. If in doubt, say N. config USB_DWC2_DEBUG_PERIODIC diff --git a/trunk/drivers/staging/dwc2/hcd_intr.c b/trunk/drivers/staging/dwc2/hcd_intr.c index e24062f0a49e..6e5dbed6ccec 100644 --- a/trunk/drivers/staging/dwc2/hcd_intr.c +++ b/trunk/drivers/staging/dwc2/hcd_intr.c @@ -56,6 +56,8 @@ static void dwc2_track_missed_sofs(struct dwc2_hsotg *hsotg) { #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS +#warning Compiling code to track missed SOFs + u16 curr_frame_number = hsotg->frame_number; if (hsotg->frame_num_idx < FRAME_NUM_ARRAY_SIZE) { diff --git a/trunk/drivers/staging/dwc2/platform.c b/trunk/drivers/staging/dwc2/platform.c index 44cce2fa6361..1f3d581a1078 100644 --- a/trunk/drivers/staging/dwc2/platform.c +++ b/trunk/drivers/staging/dwc2/platform.c @@ -95,14 +95,6 @@ static int dwc2_driver_probe(struct platform_device *dev) hsotg->dev = &dev->dev; - /* - * Use reasonable defaults so platforms don't have to provide these. - */ - if (!dev->dev.dma_mask) - dev->dev.dma_mask = &dev->dev.coherent_dma_mask; - if (!dev->dev.coherent_dma_mask) - dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - irq = platform_get_irq(dev, 0); if (irq < 0) { dev_err(&dev->dev, "missing IRQ resource\n"); @@ -110,6 +102,11 @@ static int dwc2_driver_probe(struct platform_device *dev) } res = platform_get_resource(dev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&dev->dev, "missing memory base resource\n"); + return -EINVAL; + } + hsotg->regs = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(hsotg->regs)) return PTR_ERR(hsotg->regs); diff --git a/trunk/drivers/staging/gdm72xx/Kconfig b/trunk/drivers/staging/gdm72xx/Kconfig index 69059138de4a..3c18efe31365 100644 --- a/trunk/drivers/staging/gdm72xx/Kconfig +++ b/trunk/drivers/staging/gdm72xx/Kconfig @@ -39,7 +39,7 @@ if WIMAX_GDM72XX_USB config WIMAX_GDM72XX_USB_PM bool "Enable power managerment support" - depends on PM_RUNTIME + depends on USB_SUSPEND endif # WIMAX_GDM72XX_USB diff --git a/trunk/drivers/staging/iio/adc/mxs-lradc.c b/trunk/drivers/staging/iio/adc/mxs-lradc.c index 163c638e4095..2856b8fd44ad 100644 --- a/trunk/drivers/staging/iio/adc/mxs-lradc.c +++ b/trunk/drivers/staging/iio/adc/mxs-lradc.c @@ -690,6 +690,7 @@ static void mxs_lradc_trigger_remove(struct iio_dev *iio) static int mxs_lradc_buffer_preenable(struct iio_dev *iio) { struct mxs_lradc *lradc = iio_priv(iio); + struct iio_buffer *buffer = iio->buffer; int ret = 0, chan, ofs = 0; unsigned long enable = 0; uint32_t ctrl4_set = 0; @@ -697,7 +698,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio) uint32_t ctrl1_irq = 0; const uint32_t chan_value = LRADC_CH_ACCUMULATE | ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); - const int len = bitmap_weight(iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS); + const int len = bitmap_weight(buffer->scan_mask, LRADC_MAX_TOTAL_CHANS); if (!len) return -EINVAL; @@ -724,7 +725,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio) lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); - for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { + for_each_set_bit(chan, buffer->scan_mask, LRADC_MAX_TOTAL_CHANS) { ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs); ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs); ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs); diff --git a/trunk/drivers/staging/iio/light/tsl2x7x_core.c b/trunk/drivers/staging/iio/light/tsl2x7x_core.c index c99f890cc6c6..d060f2572512 100644 --- a/trunk/drivers/staging/iio/light/tsl2x7x_core.c +++ b/trunk/drivers/staging/iio/light/tsl2x7x_core.c @@ -1869,7 +1869,6 @@ static int tsl2x7x_probe(struct i2c_client *clientp, dev_info(&chip->client->dev, "%s: i2c device found does not match expected id\n", __func__); - ret = -EINVAL; goto fail1; } @@ -1908,7 +1907,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp, if (ret) { dev_err(&clientp->dev, "%s: irq request failed", __func__); - goto fail1; + goto fail2; } } @@ -1921,17 +1920,17 @@ static int tsl2x7x_probe(struct i2c_client *clientp, if (ret) { dev_err(&clientp->dev, "%s: iio registration failed\n", __func__); - goto fail2; + goto fail1; } dev_info(&clientp->dev, "%s Light sensor found.\n", id->name); return 0; -fail2: +fail1: if (clientp->irq) free_irq(clientp->irq, indio_dev); -fail1: +fail2: iio_device_free(indio_dev); return ret; diff --git a/trunk/drivers/staging/imx-drm/Kconfig b/trunk/drivers/staging/imx-drm/Kconfig index ef699f753186..8c9e40390f42 100644 --- a/trunk/drivers/staging/imx-drm/Kconfig +++ b/trunk/drivers/staging/imx-drm/Kconfig @@ -1,7 +1,6 @@ config DRM_IMX tristate "DRM Support for Freescale i.MX" select DRM_KMS_HELPER - select VIDEOMODE_HELPERS select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) @@ -20,12 +19,10 @@ config DRM_IMX_FB_HELPER config DRM_IMX_PARALLEL_DISPLAY tristate "Support for parallel displays" depends on DRM_IMX - select VIDEOMODE_HELPERS config DRM_IMX_TVE tristate "Support for TV and VGA displays" depends on DRM_IMX - select REGMAP_MMIO help Choose this to enable the internal Television Encoder (TVe) found on i.MX53 processors. @@ -33,7 +30,6 @@ config DRM_IMX_TVE config DRM_IMX_IPUV3_CORE tristate "IPUv3 core support" depends on DRM_IMX - depends on RESET_CONTROLLER help Choose this if you have a i.MX5/6 system and want to use the IPU. This option only enables IPU base @@ -42,6 +38,5 @@ config DRM_IMX_IPUV3_CORE config DRM_IMX_IPUV3 tristate "DRM Support for i.MX IPUv3" depends on DRM_IMX - depends on DRM_IMX_IPUV3_CORE help Choose this if you have a i.MX5 or i.MX6 processor. diff --git a/trunk/drivers/staging/imx-drm/imx-tve.c b/trunk/drivers/staging/imx-drm/imx-tve.c index 03892de9bd7e..ac1634464407 100644 --- a/trunk/drivers/staging/imx-drm/imx-tve.c +++ b/trunk/drivers/staging/imx-drm/imx-tve.c @@ -670,9 +670,7 @@ static int imx_tve_probe(struct platform_device *pdev) tve->dac_reg = devm_regulator_get(&pdev->dev, "dac"); if (!IS_ERR(tve->dac_reg)) { regulator_set_voltage(tve->dac_reg, 2750000, 2750000); - ret = regulator_enable(tve->dac_reg); - if (ret) - return ret; + regulator_enable(tve->dac_reg); } tve->clk = devm_clk_get(&pdev->dev, "tve"); diff --git a/trunk/drivers/staging/media/solo6x10/Kconfig b/trunk/drivers/staging/media/solo6x10/Kconfig index df6569b997b8..ec32776ff547 100644 --- a/trunk/drivers/staging/media/solo6x10/Kconfig +++ b/trunk/drivers/staging/media/solo6x10/Kconfig @@ -1,7 +1,6 @@ config SOLO6X10 tristate "Softlogic 6x10 MPEG codec cards" depends on PCI && VIDEO_DEV && SND && I2C - depends on FONTS select VIDEOBUF2_DMA_SG select VIDEOBUF2_DMA_CONTIG select SND_PCM diff --git a/trunk/drivers/staging/nvec/nvec.c b/trunk/drivers/staging/nvec/nvec.c index 197c393c4ca7..a88959f9a07a 100644 --- a/trunk/drivers/staging/nvec/nvec.c +++ b/trunk/drivers/staging/nvec/nvec.c @@ -123,20 +123,6 @@ int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb, } EXPORT_SYMBOL_GPL(nvec_register_notifier); -/** - * nvec_unregister_notifier - Unregister a notifier with nvec - * @nvec: A &struct nvec_chip - * @nb: The notifier block to unregister - * - * Unregisters a notifier with @nvec. The notifier will be removed from the - * atomic notifier chain. - */ -int nvec_unregister_notifier(struct nvec_chip *nvec, struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&nvec->notifier_list, nb); -} -EXPORT_SYMBOL_GPL(nvec_unregister_notifier); - /** * nvec_status_notifier - The final notifier * @@ -199,7 +185,7 @@ static struct nvec_msg *nvec_msg_alloc(struct nvec_chip *nvec, * * Free the given message */ -void nvec_msg_free(struct nvec_chip *nvec, struct nvec_msg *msg) +inline void nvec_msg_free(struct nvec_chip *nvec, struct nvec_msg *msg) { if (msg != &nvec->tx_scratch) dev_vdbg(nvec->dev, "INFO: Free %ti\n", msg - nvec->msg_pool); @@ -814,6 +800,11 @@ static int tegra_nvec_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no mem resource?\n"); + return -ENODEV; + } + base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); @@ -824,7 +815,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) return -ENODEV; } - i2c_clk = devm_clk_get(&pdev->dev, "div-clk"); + i2c_clk = clk_get(&pdev->dev, "div-clk"); if (IS_ERR(i2c_clk)) { dev_err(nvec->dev, "failed to get controller clock\n"); return -ENODEV; @@ -911,11 +902,8 @@ static int tegra_nvec_remove(struct platform_device *pdev) nvec_toggle_global_events(nvec, false); mfd_remove_devices(nvec->dev); - nvec_unregister_notifier(nvec, &nvec->nvec_status_notifier); cancel_work_sync(&nvec->rx_work); cancel_work_sync(&nvec->tx_work); - /* FIXME: needs check wether nvec is responsible for power off */ - pm_power_off = NULL; return 0; } diff --git a/trunk/drivers/staging/nvec/nvec.h b/trunk/drivers/staging/nvec/nvec.h index 2b1316d87470..b7a14bc0ab91 100644 --- a/trunk/drivers/staging/nvec/nvec.h +++ b/trunk/drivers/staging/nvec/nvec.h @@ -197,8 +197,9 @@ extern int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb, unsigned int events); -extern int nvec_unregister_notifier(struct nvec_chip *dev, - struct notifier_block *nb); +extern int nvec_unregister_notifier(struct device *dev, + struct notifier_block *nb, + unsigned int events); extern void nvec_msg_free(struct nvec_chip *nvec, struct nvec_msg *msg); diff --git a/trunk/drivers/staging/nvec/nvec_kbd.c b/trunk/drivers/staging/nvec/nvec_kbd.c index a0ec52a4114f..7445ce6422bb 100644 --- a/trunk/drivers/staging/nvec/nvec_kbd.c +++ b/trunk/drivers/staging/nvec/nvec_kbd.c @@ -169,15 +169,8 @@ static int nvec_kbd_probe(struct platform_device *pdev) static int nvec_kbd_remove(struct platform_device *pdev) { - struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); - char disable_kbd[] = { NVEC_KBD, DISABLE_KBD }, - uncnfg_wake_key_reporting[] = { NVEC_KBD, CNFG_WAKE_KEY_REPORTING, - false }; - nvec_write_async(nvec, uncnfg_wake_key_reporting, 3); - nvec_write_async(nvec, disable_kbd, 2); - nvec_unregister_notifier(nvec, &keys_dev.notifier); - input_unregister_device(keys_dev.input); + input_free_device(keys_dev.input); return 0; } @@ -195,5 +188,4 @@ module_platform_driver(nvec_kbd_driver); MODULE_AUTHOR("Marc Dietrich "); MODULE_DESCRIPTION("NVEC keyboard driver"); -MODULE_ALIAS("platform:nvec-kbd"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/staging/nvec/nvec_power.c b/trunk/drivers/staging/nvec/nvec_power.c index aacfcd6954a3..296f7b9a8c8c 100644 --- a/trunk/drivers/staging/nvec/nvec_power.c +++ b/trunk/drivers/staging/nvec/nvec_power.c @@ -414,7 +414,6 @@ static int nvec_power_remove(struct platform_device *pdev) struct nvec_power *power = platform_get_drvdata(pdev); cancel_delayed_work_sync(&power->poller); - nvec_unregister_notifier(power->nvec, &power->notifier); switch (pdev->id) { case AC: power_supply_unregister(&nvec_psy); diff --git a/trunk/drivers/staging/nvec/nvec_ps2.c b/trunk/drivers/staging/nvec/nvec_ps2.c index 06dbb02085a9..aff6b9b9f9aa 100644 --- a/trunk/drivers/staging/nvec/nvec_ps2.c +++ b/trunk/drivers/staging/nvec/nvec_ps2.c @@ -106,7 +106,7 @@ static int nvec_mouse_probe(struct platform_device *pdev) struct serio *ser_dev; char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 }; - ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); + ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL); if (ser_dev == NULL) return -ENOMEM; @@ -133,11 +133,6 @@ static int nvec_mouse_probe(struct platform_device *pdev) static int nvec_mouse_remove(struct platform_device *pdev) { - struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); - - ps2_sendcommand(ps2_dev.ser_dev, DISABLE_MOUSE); - ps2_stopstreaming(ps2_dev.ser_dev); - nvec_unregister_notifier(nvec, &ps2_dev.notifier); serio_unregister_port(ps2_dev.ser_dev); return 0; @@ -184,5 +179,4 @@ module_platform_driver(nvec_mouse_driver); MODULE_DESCRIPTION("NVEC mouse driver"); MODULE_AUTHOR("Marc Dietrich "); -MODULE_ALIAS("platform:nvec-mouse"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/staging/sep/Kconfig b/trunk/drivers/staging/sep/Kconfig index aab945a316ea..185b676d858a 100644 --- a/trunk/drivers/staging/sep/Kconfig +++ b/trunk/drivers/staging/sep/Kconfig @@ -1,6 +1,6 @@ config DX_SEP tristate "Discretix SEP driver" - depends on PCI && CRYPTO + depends on PCI help Discretix SEP driver; used for the security processor subsystem on board the Intel Mobile Internet Device and adds SEP availability diff --git a/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 386362c9964f..fe667dde43ce 100644 --- a/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -1087,11 +1087,7 @@ static int synaptics_rmi4_resume(struct device *dev) unsigned char intr_status; struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); - retval = regulator_enable(rmi4_data->regulator); - if (retval) { - dev_err(dev, "Regulator enable failed (%d)\n", retval); - return retval; - } + regulator_enable(rmi4_data->regulator); enable_irq(rmi4_data->i2c_client->irq); rmi4_data->touch_stopped = false; diff --git a/trunk/drivers/staging/vt6656/hostap.c b/trunk/drivers/staging/vt6656/hostap.c index c699a3058b39..f4f1bf7a30fd 100644 --- a/trunk/drivers/staging/vt6656/hostap.c +++ b/trunk/drivers/staging/vt6656/hostap.c @@ -133,7 +133,7 @@ static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", pDevice->dev->name, pDevice->apdev->name); } - free_netdev(pDevice->apdev); + kfree(pDevice->apdev); pDevice->apdev = NULL; pDevice->bEnable8021x = false; pDevice->bEnableHostWEP = false; diff --git a/trunk/drivers/staging/vt6656/iwctl.c b/trunk/drivers/staging/vt6656/iwctl.c index d0cf7d8a20e5..c335808211ee 100644 --- a/trunk/drivers/staging/vt6656/iwctl.c +++ b/trunk/drivers/staging/vt6656/iwctl.c @@ -1345,12 +1345,9 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, return rc; } - spin_lock_irq(&pDevice->lock); - if (wrq->disabled) { pDevice->ePSMode = WMAC_POWER_CAM; PSvDisablePowerSaving(pDevice); - spin_unlock_irq(&pDevice->lock); return rc; } if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { @@ -1361,9 +1358,6 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info, pDevice->ePSMode = WMAC_POWER_FAST; PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } - - spin_unlock_irq(&pDevice->lock); - switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n"); diff --git a/trunk/drivers/staging/zcache/ramster/ramster-howto.txt b/trunk/drivers/staging/zcache/ramster/ramster-howto.txt deleted file mode 100644 index 7b1ee3bbfdd5..000000000000 --- a/trunk/drivers/staging/zcache/ramster/ramster-howto.txt +++ /dev/null @@ -1,366 +0,0 @@ - RAMSTER HOW-TO - -Author: Dan Magenheimer -Ramster maintainer: Konrad Wilk - -This is a HOWTO document for ramster which, as of this writing, is in -the kernel as a subdirectory of zcache in drivers/staging, called ramster. -(Zcache can be built with or without ramster functionality.) If enabled -and properly configured, ramster allows memory capacity load balancing -across multiple machines in a cluster. Further, the ramster code serves -as an example of asynchronous access for zcache (as well as cleancache and -frontswap) that may prove useful for future transcendent memory -implementations, such as KVM and NVRAM. While ramster works today on -any network connection that supports kernel sockets, its features may -become more interesting on future high-speed fabrics/interconnects. - -Ramster requires both kernel and userland support. The userland support, -called ramster-tools, is known to work with EL6-based distros, but is a -set of poorly-hacked slightly-modified cluster tools based on ocfs2, which -includes an init file, a config file, and a userland binary that interfaces -to the kernel. This state of userland support reflects the abysmal userland -skills of this suitably-embarrassed author; any help/patches to turn -ramster-tools into more distributable rpms/debs useful for a wider range -of distros would be appreciated. The source RPM that can be used as a -starting point is available at: - http://oss.oracle.com/projects/tmem/files/RAMster/ - -As a result of this author's ignorance, userland setup described in this -HOWTO assumes an EL6 distro and is described in EL6 syntax. Apologies -if this offends anyone! - -Kernel support has only been tested on x86_64. Systems with an active -ocfs2 filesystem should work, but since ramster leverages a lot of -code from ocfs2, there may be latent issues. A kernel configuration that -includes CONFIG_OCFS2_FS should build OK, and should certainly run OK -if no ocfs2 filesystem is mounted. - -This HOWTO demonstrates memory capacity load balancing for a two-node -cluster, where one node called the "local" node becomes overcommitted -and the other node called the "remote" node provides additional RAM -capacity for use by the local node. Ramster is capable of more complex -topologies; see the last section titled "ADVANCED RAMSTER TOPOLOGIES". - -If you find any terms in this HOWTO unfamiliar or don't understand the -motivation for ramster, the following LWN reading is recommended: --- Transcendent Memory in a Nutshell (lwn.net/Articles/454795) --- The future calculus of memory management (lwn.net/Articles/475681) -And since ramster is built on top of zcache, this article may be helpful: --- In-kernel memory compression (lwn.net/Articles/545244) - -Now that you've memorized the contents of those articles, let's get started! - -A. PRELIMINARY - -1) Install two x86_64 Linux systems that are known to work when - upgraded to a recent upstream Linux kernel version. - -On each system: - -2) Configure, build and install, then boot Linux, just to ensure it - can be done with an unmodified upstream kernel. Confirm you booted - the upstream kernel with "uname -a". - -3) If you plan to do any performance testing or unless you plan to - test only swapping, the "WasActive" patch is also highly recommended. - (Search lkml.org for WasActive, apply the patch, rebuild your kernel.) - For a demo or simple testing, the patch can be ignored. - -4) Install ramster-tools as root. An x86_64 rpm for EL6-based systems - can be found at: - http://oss.oracle.com/projects/tmem/files/RAMster/ - (Sorry but for now, non-EL6 users must recreate ramster-tools on - their own from source. See above.) - -5) Ensure that debugfs is mounted at each boot. Examples below assume it - is mounted at /sys/kernel/debug. - -B. BUILDING RAMSTER INTO THE KERNEL - -Do the following on each system: - -1) Using the kernel configuration mechanism of your choice, change - your config to include: - - CONFIG_CLEANCACHE=y - CONFIG_FRONTSWAP=y - CONFIG_STAGING=y - CONFIG_CONFIGFS_FS=y # NOTE: MUST BE y, not m - CONFIG_ZCACHE=y - CONFIG_RAMSTER=y - - For a linux-3.10 or later kernel, you should also set: - - CONFIG_ZCACHE_DEBUG=y - CONFIG_RAMSTER_DEBUG=y - - Before building the kernel please doublecheck your kernel config - file to ensure all of the settings are correct. - -2) Build this kernel and change your boot file (e.g. /etc/grub.conf) - so that the new kernel will boot. - -3) Add "zcache" and "ramster" as kernel boot parameters for the new kernel. - -4) Reboot each system approximately simultaneously. - -5) Check dmesg to ensure there are some messages from ramster, prefixed - by "ramster:" - - # dmesg | grep ramster - - You should also see a lot of files in: - - # ls /sys/kernel/debug/zcache - # ls /sys/kernel/debug/ramster - - These are mostly counters for various zcache and ramster activities. - You should also see files in: - - # ls /sys/kernel/mm/ramster - - These are sysfs files that control ramster as we shall see. - - Ramster now will act as a single-system zcache on each system - but doesn't yet know anything about the cluster so can't yet do - anything remotely. - -C. CONFIGURING THE RAMSTER CLUSTER - -This part can be error prone unless you are familiar with clustering -filesystems. We need to describe the cluster in a /etc/ramster.conf -file and the init scripts that parse it are extremely picky about -the syntax. - -1) Create a /etc/ramster.conf file and ensure it is identical on both - systems. This file mimics the ocfs2 format and there is a good amount - of documentation that can be searched for ocfs2.conf, but you can use: - - cluster: - name = ramster - node_count = 2 - node: - name = system1 - cluster = ramster - number = 0 - ip_address = my.ip.ad.r1 - ip_port = 7777 - node: - name = system2 - cluster = ramster - number = 1 - ip_address = my.ip.ad.r2 - ip_port = 7777 - - You must ensure that the "name" field in the file exactly matches - the output of "hostname" on each system; if "hostname" shows a - fully-qualified hostname, ensure the name is fully qualified in - /etc/ramster.conf. Obviously, substitute my.ip.ad.rx with proper - ip addresses. - -2) Enable the ramster service and configure it. If you used the - EL6 ramster-tools, this would be: - - # chkconfig --add ramster - # service ramster configure - - Set "load on boot" to "y", cluster to start is "ramster" (or whatever - name you chose in ramster.conf), heartbeat dead threshold as "500", - network idle timeout as "1000000". Leave the others as default. - -3) Reboot both systems. After reboot, try (assuming EL6 ramster-tools): - - # service ramster status - - You should see "Checking RAMSTER cluster "ramster": Online". If you do - not, something is wrong and ramster will not work. Note that you - should also see that the driver for "configfs" is loaded and mounted, - the driver for ocfs2_dlmfs is not loaded, and some numbers for network - parameters. You will also see "Checking RAMSTER heartbeat: Not active". - That's all OK. - -4) Now you need to start the cluster heartbeat; the cluster is not "up" - until all nodes detect a heartbeat. In a real cluster, heartbeat detection - is done via a cluster filesystem, but ramster doesn't require one. Some - hack-y kernel code in ramster can start the heartbeat for you though if - you tell it what nodes are "up". To enable the heartbeat, do: - - # echo 0 > /sys/kernel/mm/ramster/manual_node_up - # echo 1 > /sys/kernel/mm/ramster/manual_node_up - - This must be done on BOTH nodes and, to avoid timeouts, must be done - approximately concurrently on both nodes. On an EL6 system, it is - convenient to put these lines in /etc/rc.local. To confirm that the - cluster is now up, on both systems do: - - # dmesg | grep ramster - - You should see ramster "Accepted connection" messages in dmesg on both - nodes after this. Note that if you check userland status again with - - # service ramster status - - you will still see "Checking RAMSTER heartbeat: Not active". That's - still OK... the ramster kernel heartbeat hack doesn't communicate to - userland. - -5) You now must tell each node the node to which it should "remotify" pages. - On this two node cluster, we will assume the "local" node, node 0, has - memory overcommitted and will use ramster to utilize RAM capacity on - the "remote node", node 1. To configure this, on node 0, you do: - - # echo 1 > /sys/kernel/mm/ramster/remote_target_nodenum - - You should see "ramster: node 1 set as remotification target" in dmesg - on node 0. Again, on EL6, /etc/rc.local is a good place to put this - on node 0 so you don't forget to do it at each boot. - -6) One more step: By default, the ramster code does not "remotify" any - pages; this is primarily for testing purposes, but sometimes it is - useful. This may change in the future, but for now, on node 0, you do: - - # echo 1 > /sys/kernel/mm/ramster/pers_remotify_enable - # echo 1 > /sys/kernel/mm/ramster/eph_remotify_enable - - The first enables remotifying swap (persistent, aka frontswap) pages, - the second enables remotifying of page cache (ephemeral, cleancache) - pages. - - On EL6, these lines can also be put in /etc/rc.local (AFTER the - node_up lines), or at the beginning of a script that runs a workload. - -7) Note that most testing has been done with both/all machines booted - roughly simultaneously to avoid cluster timeouts. Ideally, you should - do this too unless you are trying to break ramster rather than just - use it. ;-) - -D. TESTING RAMSTER - -1) Note that ramster has no value unless pages get "remotified". For - swap/frontswap/persistent pages, this doesn't happen unless/until - the workload would cause swapping to occur, at which point pages - are put into frontswap/zcache, and the remotification thread starts - working. To get to the point where the system swaps, you either - need a workload for which the working set exceeds the RAM in the - system; or you need to somehow reduce the amount of RAM one of - the system sees. This latter is easy when testing in a VM, but - harder on physical systems. In some cases, "mem=xxxM" on the - kernel command line restricts memory, but for some values of xxx - the kernel may fail to boot. One may also try creating a fixed - RAMdisk, doing nothing with it, but ensuring that it eats up a fixed - amount of RAM. - -2) To see if ramster is working, on the "remote node", node 1, try: - - # grep . /sys/kernel/debug/ramster/foreign_* - # # note, that is space-dot-space between grep and the pathname - - to monitor the number (and max) ephemeral and persistent pages - that ramster has sent. If these stay at zero, ramster is not working - either because the workload on the local node (node 0) isn't creating - enough memory pressure or because "remotifying" isn't working. On the - local system, node 0, you can watch lots of useful information also. - Try: - - grep . /sys/kernel/debug/zcache/*pageframes* \ - /sys/kernel/debug/zcache/*zbytes* \ - /sys/kernel/debug/zcache/*zpages* \ - /sys/kernel/debug/ramster/*remote* - - Of particular note are the remote_*_pages_succ_get counters. These - show how many disk reads and/or disk writes have been avoided on the - overcommitted local system by storing pages remotely using ramster. - - At the risk of information overload, you can also grep: - - /sys/kernel/debug/cleancache/* and /sys/kernel/debug/frontswap/* - - These show, for example, how many disk reads and/or disk writes have - been avoided by using zcache to optimize RAM on the local system. - - -AUTOMATIC SWAP REPATRIATION - -You may notice that while the systems are idle, the foreign persistent -page count on the remote machine slowly decreases. This is because -ramster implements "frontswap selfshrinking": When possible, swap -pages that have been remotified are slowly repatriated to the local -machine. This is so that local RAM can be used when possible and -so that, in case of remote machine crash, the probability of loss -of data is reduced. - -REBOOTING / POWEROFF - -If a system is shut down while some of its swap pages still reside -on a remote system, the system may lock up during the shutdown -sequence. This will occur if the network is shut down before the -swap mechansim is shut down, which is the default ordering on many -distros. To avoid this annoying problem, simply shut off the swap -subsystem before starting the shutdown sequence, e.g.: - - # swapoff -a - # reboot - -Ideally, this swapoff-before-ifdown ordering should be enforced permanently -using shutdown scripts. - -KNOWN PROBLEMS - -1) You may periodically see messages such as: - - ramster_r2net, message length problem - - This is harmless but indicates that a node is sending messages - containing compressed pages that exceed the maximum for zcache - (PAGE_SIZE*15/16). The sender side needs to be fixed. - -2) If you see a "No longer connected to node..." message or a "No connection - established with node X after N seconds", it is possible you may - be in an unrecoverable state. If you are certain all of the - appropriate cluster configuration steps described above have been - performed, try rebooting the two servers concurrently to see if - the cluster starts. - - Note that "Connection to node... shutdown, state 7" is an intermediate - connection state. As long as you later see "Accepted connection", the - intermediate states are harmless. - -3) There are known issues in counting certain values. As a result - you may see periodic warnings from the kernel. Almost always you - will see "ramster: bad accounting for XXX". There are also "WARN_ONCE" - messages. If you see kernel warnings with a tombstone, please report - them. They are harmless but reflect bugs that need to be eventually fixed. - -ADVANCED RAMSTER TOPOLOGIES - -The kernel code for ramster can support up to eight nodes in a cluster, -but no testing has been done with more than three nodes. - -In the example described above, the "remote" node serves as a RAM -overflow for the "local" node. This can be made symmetric by appropriate -settings of the sysfs remote_target_nodenum file. For example, by setting: - - # echo 1 > /sys/kernel/mm/ramster/remote_target_nodenum - -on node 0, and - - # echo 0 > /sys/kernel/mm/ramster/remote_target_nodenum - -on node 1, each node can serve as a RAM overflow for the other. - -For more than two nodes, a "RAM server" can be configured. For a -three node system, set: - - # echo 0 > /sys/kernel/mm/ramster/remote_target_nodenum - -on node 1, and - - # echo 0 > /sys/kernel/mm/ramster/remote_target_nodenum - -on node 2. Then node 0 is a RAM server for node 1 and node 2. - -In this implementation of ramster, any remote node is potentially a single -point of failure (SPOF). Though the probability of failure is reduced -by automatic swap repatriation (see above), a proposed future enhancement -to ramster improves high-availability for the cluster by sending a copy -of each page of date to two other nodes. Patches welcome! diff --git a/trunk/drivers/staging/zcache/zcache-main.c b/trunk/drivers/staging/zcache/zcache-main.c index dcceed29d31a..522cb8e55142 100644 --- a/trunk/drivers/staging/zcache/zcache-main.c +++ b/trunk/drivers/staging/zcache/zcache-main.c @@ -1922,15 +1922,15 @@ static int zcache_init(void) #ifdef CONFIG_ZCACHE_MODULE #ifdef CONFIG_RAMSTER -module_param(ramster_enabled, bool, S_IRUGO); +module_param(ramster_enabled, int, S_IRUGO); module_param(disable_frontswap_selfshrink, int, S_IRUGO); #endif -module_param(disable_cleancache, bool, S_IRUGO); -module_param(disable_frontswap, bool, S_IRUGO); +module_param(disable_cleancache, int, S_IRUGO); +module_param(disable_frontswap, int, S_IRUGO); #ifdef FRONTSWAP_HAS_EXCLUSIVE_GETS module_param(frontswap_has_exclusive_gets, bool, S_IRUGO); #endif -module_param(disable_frontswap_ignore_nonactive, bool, S_IRUGO); +module_param(disable_frontswap_ignore_nonactive, int, S_IRUGO); module_param(zcache_comp_name, charp, S_IRUGO); module_init(zcache_init); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index 262ef1f23b38..ffbc6a94be52 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -1250,7 +1250,7 @@ static u32 iscsit_do_crypto_hash_sg( static void iscsit_do_crypto_hash_buf( struct hash_desc *hash, - const void *buf, + unsigned char *buf, u32 payload_length, u32 padding, u8 *pad_bytes, @@ -2524,8 +2524,9 @@ static int iscsit_send_conn_drop_async_message( if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); cmd->tx_size += ISCSI_CRC_LEN; pr_debug("Attaching CRC32C HeaderDigest to" @@ -2661,8 +2662,9 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)cmd->pdu, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); iov[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -2839,8 +2841,9 @@ iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn) if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, &cmd->pdu[0], - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)&cmd->pdu[0], ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); iov[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -2897,8 +2900,9 @@ static int iscsit_send_unsolicited_nopin( if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); tx_size += ISCSI_CRC_LEN; pr_debug("Attaching CRC32C HeaderDigest to" @@ -2945,8 +2949,9 @@ iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn) if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); iov[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -3035,8 +3040,9 @@ static int iscsit_send_r2t( if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -3250,8 +3256,9 @@ static int iscsit_send_response(struct iscsi_cmd *cmd, struct iscsi_conn *conn) if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)cmd->pdu, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); iov[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -3322,8 +3329,9 @@ iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn) if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -3496,8 +3504,9 @@ static int iscsit_send_text_rsp( if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); iov[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -3548,11 +3557,11 @@ static int iscsit_send_reject( struct iscsi_cmd *cmd, struct iscsi_conn *conn) { - struct iscsi_reject *hdr = (struct iscsi_reject *)&cmd->pdu[0]; + u32 iov_count = 0, tx_size = 0; + struct iscsi_reject *hdr; struct kvec *iov; - u32 iov_count = 0, tx_size; - iscsit_build_reject(cmd, conn, hdr); + iscsit_build_reject(cmd, conn, (struct iscsi_reject *)&cmd->pdu[0]); iov = &cmd->iov_misc[0]; iov[iov_count].iov_base = cmd->pdu; @@ -3565,8 +3574,9 @@ static int iscsit_send_reject( if (conn->conn_ops->HeaderDigest) { u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)hdr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)header_digest); iov[0].iov_len += ISCSI_CRC_LEN; tx_size += ISCSI_CRC_LEN; @@ -3575,8 +3585,9 @@ static int iscsit_send_reject( } if (conn->conn_ops->DataDigest) { - iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->buf_ptr, - ISCSI_HDR_LEN, 0, NULL, (u8 *)&cmd->data_crc); + iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, + (unsigned char *)cmd->buf_ptr, ISCSI_HDR_LEN, + 0, NULL, (u8 *)&cmd->data_crc); iov[iov_count].iov_base = &cmd->data_crc; iov[iov_count++].iov_len = ISCSI_CRC_LEN; diff --git a/trunk/drivers/target/iscsi/iscsi_target_erl1.c b/trunk/drivers/target/iscsi/iscsi_target_erl1.c index 40d9dbca987b..7816af6cdd12 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_erl1.c +++ b/trunk/drivers/target/iscsi/iscsi_target_erl1.c @@ -823,7 +823,7 @@ static int iscsit_attach_ooo_cmdsn( /* * CmdSN is greater than the tail of the list. */ - if (iscsi_sna_lt(ooo_tail->cmdsn, ooo_cmdsn->cmdsn)) + if (ooo_tail->cmdsn < ooo_cmdsn->cmdsn) list_add_tail(&ooo_cmdsn->ooo_list, &sess->sess_ooo_cmdsn_list); else { @@ -833,12 +833,11 @@ static int iscsit_attach_ooo_cmdsn( */ list_for_each_entry(ooo_tmp, &sess->sess_ooo_cmdsn_list, ooo_list) { - if (iscsi_sna_lt(ooo_tmp->cmdsn, ooo_cmdsn->cmdsn)) + if (ooo_tmp->cmdsn < ooo_cmdsn->cmdsn) continue; - /* Insert before this entry */ list_add(&ooo_cmdsn->ooo_list, - ooo_tmp->ooo_list.prev); + &ooo_tmp->ooo_list); break; } } diff --git a/trunk/drivers/target/iscsi/iscsi_target_parameters.c b/trunk/drivers/target/iscsi/iscsi_target_parameters.c index c2185fc31136..f690be9e5293 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_parameters.c +++ b/trunk/drivers/target/iscsi/iscsi_target_parameters.c @@ -436,7 +436,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) /* * Extra parameters for ISER from RFC-5046 */ - param = iscsi_set_default_param(pl, RDMAEXTENSIONS, INITIAL_RDMAEXTENSIONS, + param = iscsi_set_default_param(pl, RDMAEXTENTIONS, INITIAL_RDMAEXTENTIONS, PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_AND, USE_LEADING_ONLY); if (!param) @@ -529,7 +529,7 @@ int iscsi_set_keys_to_negotiate( SET_PSTATE_NEGOTIATE(param); } else if (!strcmp(param->name, OFMARKINT)) { SET_PSTATE_NEGOTIATE(param); - } else if (!strcmp(param->name, RDMAEXTENSIONS)) { + } else if (!strcmp(param->name, RDMAEXTENTIONS)) { if (iser == true) SET_PSTATE_NEGOTIATE(param); } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) { @@ -580,7 +580,7 @@ int iscsi_set_keys_irrelevant_for_discovery( param->state &= ~PSTATE_NEGOTIATE; else if (!strcmp(param->name, OFMARKINT)) param->state &= ~PSTATE_NEGOTIATE; - else if (!strcmp(param->name, RDMAEXTENSIONS)) + else if (!strcmp(param->name, RDMAEXTENTIONS)) param->state &= ~PSTATE_NEGOTIATE; else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) param->state &= ~PSTATE_NEGOTIATE; @@ -1977,7 +1977,7 @@ void iscsi_set_session_parameters( ops->SessionType = !strcmp(param->value, DISCOVERY); pr_debug("SessionType: %s\n", param->value); - } else if (!strcmp(param->name, RDMAEXTENSIONS)) { + } else if (!strcmp(param->name, RDMAEXTENTIONS)) { ops->RDMAExtensions = !strcmp(param->value, YES); pr_debug("RDMAExtensions: %s\n", param->value); diff --git a/trunk/drivers/target/iscsi/iscsi_target_parameters.h b/trunk/drivers/target/iscsi/iscsi_target_parameters.h index 915b06798505..f31b9c4b83f2 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_parameters.h +++ b/trunk/drivers/target/iscsi/iscsi_target_parameters.h @@ -91,7 +91,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *, /* * Parameter names of iSCSI Extentions for RDMA (iSER). See RFC-5046 */ -#define RDMAEXTENSIONS "RDMAExtensions" +#define RDMAEXTENTIONS "RDMAExtensions" #define INITIATORRECVDATASEGMENTLENGTH "InitiatorRecvDataSegmentLength" #define TARGETRECVDATASEGMENTLENGTH "TargetRecvDataSegmentLength" @@ -142,7 +142,7 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *, /* * Initial values for iSER parameters following RFC-5046 Section 6 */ -#define INITIAL_RDMAEXTENSIONS NO +#define INITIAL_RDMAEXTENTIONS NO #define INITIAL_INITIATORRECVDATASEGMENTLENGTH "262144" #define INITIAL_TARGETRECVDATASEGMENTLENGTH "8192" diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index 4a8bd36d3958..43b7ac6c5b1c 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -1584,13 +1584,6 @@ static struct target_core_configfs_attribute target_core_attr_dev_udev_path = { .store = target_core_store_dev_udev_path, }; -static ssize_t target_core_show_dev_enable(void *p, char *page) -{ - struct se_device *dev = p; - - return snprintf(page, PAGE_SIZE, "%d\n", !!(dev->dev_flags & DF_CONFIGURED)); -} - static ssize_t target_core_store_dev_enable( void *p, const char *page, @@ -1616,8 +1609,8 @@ static ssize_t target_core_store_dev_enable( static struct target_core_configfs_attribute target_core_attr_dev_enable = { .attr = { .ca_owner = THIS_MODULE, .ca_name = "enable", - .ca_mode = S_IRUGO | S_IWUSR }, - .show = target_core_show_dev_enable, + .ca_mode = S_IWUSR }, + .show = NULL, .store = target_core_store_dev_enable, }; diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 4630481b6043..2e4d655471bc 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -68,6 +68,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) struct se_dev_entry *deve = se_cmd->se_deve; deve->total_cmds++; + deve->total_bytes += se_cmd->data_length; if ((se_cmd->data_direction == DMA_TO_DEVICE) && (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)) { @@ -84,6 +85,8 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) else if (se_cmd->data_direction == DMA_FROM_DEVICE) deve->read_bytes += se_cmd->data_length; + deve->deve_cmds++; + se_lun = deve->se_lun; se_cmd->se_lun = deve->se_lun; se_cmd->pr_res_key = deve->pr_res_key; @@ -272,6 +275,17 @@ int core_free_device_list_for_node( return 0; } +void core_dec_lacl_count(struct se_node_acl *se_nacl, struct se_cmd *se_cmd) +{ + struct se_dev_entry *deve; + unsigned long flags; + + spin_lock_irqsave(&se_nacl->device_list_lock, flags); + deve = se_nacl->device_list[se_cmd->orig_fe_lun]; + deve->deve_cmds--; + spin_unlock_irqrestore(&se_nacl->device_list_lock, flags); +} + void core_update_device_list_access( u32 mapped_lun, u32 lun_access, diff --git a/trunk/drivers/target/target_core_file.c b/trunk/drivers/target/target_core_file.c index 1b1d544e927a..58ed683e04ae 100644 --- a/trunk/drivers/target/target_core_file.c +++ b/trunk/drivers/target/target_core_file.c @@ -153,6 +153,10 @@ static int fd_configure_device(struct se_device *dev) struct request_queue *q = bdev_get_queue(inode->i_bdev); unsigned long long dev_size; + dev->dev_attrib.hw_block_size = + bdev_logical_block_size(inode->i_bdev); + dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); + /* * Determine the number of bytes from i_size_read() minus * one (1) logical sector from underlying struct block_device @@ -199,6 +203,9 @@ static int fd_configure_device(struct se_device *dev) goto fail; } + dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; + dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; + /* * Limit UNMAP emulation to 8k Number of LBAs (NoLB) */ @@ -219,8 +226,6 @@ static int fd_configure_device(struct se_device *dev) fd_dev->fd_block_size = dev->dev_attrib.hw_block_size; - dev->dev_attrib.hw_block_size = FD_BLOCKSIZE; - dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS; dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH; if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) { diff --git a/trunk/drivers/target/target_core_iblock.c b/trunk/drivers/target/target_core_iblock.c index aa1620abec6d..07f5f94634bb 100644 --- a/trunk/drivers/target/target_core_iblock.c +++ b/trunk/drivers/target/target_core_iblock.c @@ -615,8 +615,6 @@ iblock_execute_rw(struct se_cmd *cmd) rw = WRITE_FUA; else if (!(q->flush_flags & REQ_FLUSH)) rw = WRITE_FUA; - else - rw = WRITE; } else { rw = WRITE; } diff --git a/trunk/drivers/target/target_core_internal.h b/trunk/drivers/target/target_core_internal.h index 18d49df4d0ac..853bab60e362 100644 --- a/trunk/drivers/target/target_core_internal.h +++ b/trunk/drivers/target/target_core_internal.h @@ -8,6 +8,7 @@ extern struct t10_alua_lu_gp *default_lu_gp; struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16); int core_free_device_list_for_node(struct se_node_acl *, struct se_portal_group *); +void core_dec_lacl_count(struct se_node_acl *, struct se_cmd *); void core_update_device_list_access(u32, u32, struct se_node_acl *); int core_enable_device_list_for_node(struct se_lun *, struct se_lun_acl *, u32, u32, struct se_node_acl *, struct se_portal_group *); diff --git a/trunk/drivers/target/target_core_rd.c b/trunk/drivers/target/target_core_rd.c index 0921a64b5550..e0b3c379aa14 100644 --- a/trunk/drivers/target/target_core_rd.c +++ b/trunk/drivers/target/target_core_rd.c @@ -291,11 +291,6 @@ rd_execute_rw(struct se_cmd *cmd) u32 src_len; u64 tmp; - if (dev->rd_flags & RDF_NULLIO) { - target_complete_cmd(cmd, SAM_STAT_GOOD); - return 0; - } - tmp = cmd->t_task_lba * se_dev->dev_attrib.block_size; rd_offset = do_div(tmp, PAGE_SIZE); rd_page = tmp; @@ -378,12 +373,11 @@ rd_execute_rw(struct se_cmd *cmd) } enum { - Opt_rd_pages, Opt_rd_nullio, Opt_err + Opt_rd_pages, Opt_err }; static match_table_t tokens = { {Opt_rd_pages, "rd_pages=%d"}, - {Opt_rd_nullio, "rd_nullio=%d"}, {Opt_err, NULL} }; @@ -414,14 +408,6 @@ static ssize_t rd_set_configfs_dev_params(struct se_device *dev, " Count: %u\n", rd_dev->rd_page_count); rd_dev->rd_flags |= RDF_HAS_PAGE_COUNT; break; - case Opt_rd_nullio: - match_int(args, &arg); - if (arg != 1) - break; - - pr_debug("RAMDISK: Setting NULLIO flag: %d\n", arg); - rd_dev->rd_flags |= RDF_NULLIO; - break; default: break; } @@ -438,9 +424,8 @@ static ssize_t rd_show_configfs_dev_params(struct se_device *dev, char *b) ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: rd_mcp\n", rd_dev->rd_dev_id); bl += sprintf(b + bl, " PAGES/PAGE_SIZE: %u*%lu" - " SG_table_count: %u nullio: %d\n", rd_dev->rd_page_count, - PAGE_SIZE, rd_dev->sg_table_count, - !!(rd_dev->rd_flags & RDF_NULLIO)); + " SG_table_count: %u\n", rd_dev->rd_page_count, + PAGE_SIZE, rd_dev->sg_table_count); return bl; } diff --git a/trunk/drivers/target/target_core_rd.h b/trunk/drivers/target/target_core_rd.h index 1789d1e14395..933b38b6e563 100644 --- a/trunk/drivers/target/target_core_rd.h +++ b/trunk/drivers/target/target_core_rd.h @@ -22,7 +22,6 @@ struct rd_dev_sg_table { } ____cacheline_aligned; #define RDF_HAS_PAGE_COUNT 0x01 -#define RDF_NULLIO 0x02 struct rd_dev { struct se_device dev; diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 4a793362309d..f8388b4024aa 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -2163,6 +2163,8 @@ void transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks) if (wait_for_tasks) transport_wait_for_tasks(cmd); + core_dec_lacl_count(cmd->se_sess->se_node_acl, cmd); + if (cmd->se_lun) transport_lun_remove_cmd(cmd); @@ -2211,19 +2213,21 @@ static void target_release_cmd_kref(struct kref *kref) { struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref); struct se_session *se_sess = se_cmd->se_sess; + unsigned long flags; + spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); if (list_empty(&se_cmd->se_cmd_list)) { - spin_unlock(&se_sess->sess_cmd_lock); + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); se_cmd->se_tfo->release_cmd(se_cmd); return; } if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) { - spin_unlock(&se_sess->sess_cmd_lock); + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); complete(&se_cmd->cmd_wait_comp); return; } list_del(&se_cmd->se_cmd_list); - spin_unlock(&se_sess->sess_cmd_lock); + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); se_cmd->se_tfo->release_cmd(se_cmd); } @@ -2234,8 +2238,7 @@ static void target_release_cmd_kref(struct kref *kref) */ int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd) { - return kref_put_spinlock_irqsave(&se_cmd->cmd_kref, target_release_cmd_kref, - &se_sess->sess_cmd_lock); + return kref_put(&se_cmd->cmd_kref, target_release_cmd_kref); } EXPORT_SYMBOL(target_put_sess_cmd); diff --git a/trunk/drivers/thermal/armada_thermal.c b/trunk/drivers/thermal/armada_thermal.c index 54ffd64ca3f7..5b4d75fd7b49 100644 --- a/trunk/drivers/thermal/armada_thermal.c +++ b/trunk/drivers/thermal/armada_thermal.c @@ -169,11 +169,21 @@ static int armada_thermal_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get platform resource\n"); + return -ENODEV; + } + priv->sensor = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->sensor)) return PTR_ERR(priv->sensor); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(&pdev->dev, "Failed to get platform resource\n"); + return -ENODEV; + } + priv->control = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->control)) return PTR_ERR(priv->control); diff --git a/trunk/drivers/thermal/dove_thermal.c b/trunk/drivers/thermal/dove_thermal.c index a088d1365ca5..4b15a5f270dc 100644 --- a/trunk/drivers/thermal/dove_thermal.c +++ b/trunk/drivers/thermal/dove_thermal.c @@ -149,6 +149,10 @@ static int dove_thermal_probe(struct platform_device *pdev) return PTR_ERR(priv->sensor); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(&pdev->dev, "Failed to get platform resource\n"); + return -ENODEV; + } priv->control = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->control)) return PTR_ERR(priv->control); diff --git a/trunk/drivers/thermal/exynos_thermal.c b/trunk/drivers/thermal/exynos_thermal.c index 788b1ddcac6c..d20ce9e61403 100644 --- a/trunk/drivers/thermal/exynos_thermal.c +++ b/trunk/drivers/thermal/exynos_thermal.c @@ -925,6 +925,11 @@ static int exynos_tmu_probe(struct platform_device *pdev) INIT_WORK(&data->irq_work, exynos_tmu_work); data->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!data->mem) { + dev_err(&pdev->dev, "Failed to get platform resource\n"); + return -ENOENT; + } + data->base = devm_ioremap_resource(&pdev->dev, data->mem); if (IS_ERR(data->base)) return PTR_ERR(data->base); diff --git a/trunk/drivers/tty/ehv_bytechan.c b/trunk/drivers/tty/ehv_bytechan.c index 9bffcec5ad82..6d0c27cd03da 100644 --- a/trunk/drivers/tty/ehv_bytechan.c +++ b/trunk/drivers/tty/ehv_bytechan.c @@ -859,7 +859,6 @@ static int __init ehv_bc_init(void) */ static void __exit ehv_bc_exit(void) { - platform_driver_unregister(&ehv_bc_tty_driver); tty_unregister_driver(ehv_bc_driver); put_tty_driver(ehv_bc_driver); kfree(bcs); diff --git a/trunk/drivers/tty/mxser.c b/trunk/drivers/tty/mxser.c index 4c4a23674569..71d6eb2c93b1 100644 --- a/trunk/drivers/tty/mxser.c +++ b/trunk/drivers/tty/mxser.c @@ -1618,12 +1618,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) if (ip->type == PORT_16550A) me->fifo[p] = 1; - if (ip->board->chip_flag == MOXA_MUST_MU860_HWID) { - opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); - opmode &= OP_MODE_MASK; - } else { - opmode = RS232_MODE; - } + opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); + opmode &= OP_MODE_MASK; me->iftype[p] = opmode; mutex_unlock(&port->mutex); } @@ -1680,9 +1676,6 @@ static int mxser_ioctl(struct tty_struct *tty, int shiftbit; unsigned char val, mask; - if (info->board->chip_flag != MOXA_MUST_MU860_HWID) - return -EFAULT; - p = tty->index % 4; if (cmd == MOXA_SET_OP_MODE) { if (get_user(opmode, (int __user *) argp)) diff --git a/trunk/drivers/tty/n_tty.c b/trunk/drivers/tty/n_tty.c index 6c7fe90ad72d..d655416087b7 100644 --- a/trunk/drivers/tty/n_tty.c +++ b/trunk/drivers/tty/n_tty.c @@ -1573,14 +1573,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) ldata->real_raw = 0; } n_tty_set_room(tty); - /* - * Fix tty hang when I_IXON(tty) is cleared, but the tty - * been stopped by STOP_CHAR(tty) before it. - */ - if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) { - start_tty(tty); - } - /* The termios change make the tty ready for I/O */ wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->read_wait); diff --git a/trunk/drivers/tty/rocket.c b/trunk/drivers/tty/rocket.c index 354564ea47c5..82d35c5a58fd 100644 --- a/trunk/drivers/tty/rocket.c +++ b/trunk/drivers/tty/rocket.c @@ -150,14 +150,12 @@ static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = { AIOP_INTR_BIT_3 }; -#ifdef CONFIG_PCI static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { UPCI_AIOP_INTR_BIT_0, UPCI_AIOP_INTR_BIT_1, UPCI_AIOP_INTR_BIT_2, UPCI_AIOP_INTR_BIT_3 }; -#endif static Byte_t RData[RDATASIZE] = { 0x00, 0x09, 0xf6, 0x82, @@ -229,6 +227,7 @@ static unsigned long nextLineNumber; static int __init init_ISA(int i); static void rp_wait_until_sent(struct tty_struct *tty, int timeout); static void rp_flush_buffer(struct tty_struct *tty); +static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model); static unsigned char GetLineNumber(int ctrl, int aiop, int ch); static unsigned char SetLineNumber(int ctrl, int aiop, int ch); static void rp_start(struct tty_struct *tty); @@ -242,6 +241,11 @@ static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); +static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, + ByteIO_t * AiopIOList, int AiopIOListSize, + WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, + int PeriodicOnly, int altChanRingIndicator, + int UPCIRingInd); static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum, Byte_t Frequency, int PeriodicOnly); @@ -1771,145 +1775,6 @@ static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = { }; MODULE_DEVICE_TABLE(pci, rocket_pci_ids); -/* Resets the speaker controller on RocketModem II and III devices */ -static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) -{ - ByteIO_t addr; - - /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ - if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { - addr = CtlP->AiopIO[0] + 0x4F; - sOutB(addr, 0); - } - - /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ - if ((model == MODEL_UPCI_RM3_8PORT) - || (model == MODEL_UPCI_RM3_4PORT)) { - addr = CtlP->AiopIO[0] + 0x88; - sOutB(addr, 0); - } -} - -/*************************************************************************** -Function: sPCIInitController -Purpose: Initialization of controller global registers and controller - structure. -Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, - IRQNum,Frequency,PeriodicOnly) - CONTROLLER_T *CtlP; Ptr to controller structure - int CtlNum; Controller number - ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. - This list must be in the order the AIOPs will be found on the - controller. Once an AIOP in the list is not found, it is - assumed that there are no more AIOPs on the controller. - int AiopIOListSize; Number of addresses in AiopIOList - int IRQNum; Interrupt Request number. Can be any of the following: - 0: Disable global interrupts - 3: IRQ 3 - 4: IRQ 4 - 5: IRQ 5 - 9: IRQ 9 - 10: IRQ 10 - 11: IRQ 11 - 12: IRQ 12 - 15: IRQ 15 - Byte_t Frequency: A flag identifying the frequency - of the periodic interrupt, can be any one of the following: - FREQ_DIS - periodic interrupt disabled - FREQ_137HZ - 137 Hertz - FREQ_69HZ - 69 Hertz - FREQ_34HZ - 34 Hertz - FREQ_17HZ - 17 Hertz - FREQ_9HZ - 9 Hertz - FREQ_4HZ - 4 Hertz - If IRQNum is set to 0 the Frequency parameter is - overidden, it is forced to a value of FREQ_DIS. - int PeriodicOnly: 1 if all interrupts except the periodic - interrupt are to be blocked. - 0 is both the periodic interrupt and - other channel interrupts are allowed. - If IRQNum is set to 0 the PeriodicOnly parameter is - overidden, it is forced to a value of 0. -Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller - initialization failed. - -Comments: - If periodic interrupts are to be disabled but AIOP interrupts - are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. - - If interrupts are to be completely disabled set IRQNum to 0. - - Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an - invalid combination. - - This function performs initialization of global interrupt modes, - but it does not actually enable global interrupts. To enable - and disable global interrupts use functions sEnGlobalInt() and - sDisGlobalInt(). Enabling of global interrupts is normally not - done until all other initializations are complete. - - Even if interrupts are globally enabled, they must also be - individually enabled for each channel that is to generate - interrupts. - -Warnings: No range checking on any of the parameters is done. - - No context switches are allowed while executing this function. - - After this function all AIOPs on the controller are disabled, - they can be enabled with sEnAiop(). -*/ -static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, - ByteIO_t * AiopIOList, int AiopIOListSize, - WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, - int PeriodicOnly, int altChanRingIndicator, - int UPCIRingInd) -{ - int i; - ByteIO_t io; - - CtlP->AltChanRingIndicator = altChanRingIndicator; - CtlP->UPCIRingInd = UPCIRingInd; - CtlP->CtlNum = CtlNum; - CtlP->CtlID = CTLID_0001; /* controller release 1 */ - CtlP->BusType = isPCI; /* controller release 1 */ - - if (ConfigIO) { - CtlP->isUPCI = 1; - CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; - CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; - CtlP->AiopIntrBits = upci_aiop_intr_bits; - } else { - CtlP->isUPCI = 0; - CtlP->PCIIO = - (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); - CtlP->AiopIntrBits = aiop_intr_bits; - } - - sPCIControllerEOI(CtlP); /* clear EOI if warm init */ - /* Init AIOPs */ - CtlP->NumAiop = 0; - for (i = 0; i < AiopIOListSize; i++) { - io = AiopIOList[i]; - CtlP->AiopIO[i] = (WordIO_t) io; - CtlP->AiopIntChanIO[i] = io + _INT_CHAN; - - CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ - if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ - break; /* done looking for AIOPs */ - - CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ - sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ - sOutB(io + _INDX_DATA, sClockPrescale); - CtlP->NumAiop++; /* bump count of AIOPs */ - } - - if (CtlP->NumAiop == 0) - return (-1); - else - return (CtlP->NumAiop); -} - /* * Called when a PCI card is found. Retrieves and stores model information, * init's aiopic and serial port hardware. @@ -2654,6 +2519,147 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, return (CtlP->NumAiop); } +#ifdef CONFIG_PCI +/*************************************************************************** +Function: sPCIInitController +Purpose: Initialization of controller global registers and controller + structure. +Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, + IRQNum,Frequency,PeriodicOnly) + CONTROLLER_T *CtlP; Ptr to controller structure + int CtlNum; Controller number + ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. + This list must be in the order the AIOPs will be found on the + controller. Once an AIOP in the list is not found, it is + assumed that there are no more AIOPs on the controller. + int AiopIOListSize; Number of addresses in AiopIOList + int IRQNum; Interrupt Request number. Can be any of the following: + 0: Disable global interrupts + 3: IRQ 3 + 4: IRQ 4 + 5: IRQ 5 + 9: IRQ 9 + 10: IRQ 10 + 11: IRQ 11 + 12: IRQ 12 + 15: IRQ 15 + Byte_t Frequency: A flag identifying the frequency + of the periodic interrupt, can be any one of the following: + FREQ_DIS - periodic interrupt disabled + FREQ_137HZ - 137 Hertz + FREQ_69HZ - 69 Hertz + FREQ_34HZ - 34 Hertz + FREQ_17HZ - 17 Hertz + FREQ_9HZ - 9 Hertz + FREQ_4HZ - 4 Hertz + If IRQNum is set to 0 the Frequency parameter is + overidden, it is forced to a value of FREQ_DIS. + int PeriodicOnly: 1 if all interrupts except the periodic + interrupt are to be blocked. + 0 is both the periodic interrupt and + other channel interrupts are allowed. + If IRQNum is set to 0 the PeriodicOnly parameter is + overidden, it is forced to a value of 0. +Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller + initialization failed. + +Comments: + If periodic interrupts are to be disabled but AIOP interrupts + are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. + + If interrupts are to be completely disabled set IRQNum to 0. + + Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an + invalid combination. + + This function performs initialization of global interrupt modes, + but it does not actually enable global interrupts. To enable + and disable global interrupts use functions sEnGlobalInt() and + sDisGlobalInt(). Enabling of global interrupts is normally not + done until all other initializations are complete. + + Even if interrupts are globally enabled, they must also be + individually enabled for each channel that is to generate + interrupts. + +Warnings: No range checking on any of the parameters is done. + + No context switches are allowed while executing this function. + + After this function all AIOPs on the controller are disabled, + they can be enabled with sEnAiop(). +*/ +static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, + ByteIO_t * AiopIOList, int AiopIOListSize, + WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, + int PeriodicOnly, int altChanRingIndicator, + int UPCIRingInd) +{ + int i; + ByteIO_t io; + + CtlP->AltChanRingIndicator = altChanRingIndicator; + CtlP->UPCIRingInd = UPCIRingInd; + CtlP->CtlNum = CtlNum; + CtlP->CtlID = CTLID_0001; /* controller release 1 */ + CtlP->BusType = isPCI; /* controller release 1 */ + + if (ConfigIO) { + CtlP->isUPCI = 1; + CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; + CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; + CtlP->AiopIntrBits = upci_aiop_intr_bits; + } else { + CtlP->isUPCI = 0; + CtlP->PCIIO = + (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); + CtlP->AiopIntrBits = aiop_intr_bits; + } + + sPCIControllerEOI(CtlP); /* clear EOI if warm init */ + /* Init AIOPs */ + CtlP->NumAiop = 0; + for (i = 0; i < AiopIOListSize; i++) { + io = AiopIOList[i]; + CtlP->AiopIO[i] = (WordIO_t) io; + CtlP->AiopIntChanIO[i] = io + _INT_CHAN; + + CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ + if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ + break; /* done looking for AIOPs */ + + CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ + sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ + sOutB(io + _INDX_DATA, sClockPrescale); + CtlP->NumAiop++; /* bump count of AIOPs */ + } + + if (CtlP->NumAiop == 0) + return (-1); + else + return (CtlP->NumAiop); +} + +/* Resets the speaker controller on RocketModem II and III devices */ +static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) +{ + ByteIO_t addr; + + /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ + if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { + addr = CtlP->AiopIO[0] + 0x4F; + sOutB(addr, 0); + } + + /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ + if ((model == MODEL_UPCI_RM3_8PORT) + || (model == MODEL_UPCI_RM3_4PORT)) { + addr = CtlP->AiopIO[0] + 0x88; + sOutB(addr, 0); + } +} +#endif + /*************************************************************************** Function: sReadAiopID Purpose: Read the AIOP idenfication number directly from an AIOP. diff --git a/trunk/drivers/tty/serial/8250/8250_dw.c b/trunk/drivers/tty/serial/8250/8250_dw.c index d07b6af3a937..beaa283f5cc6 100644 --- a/trunk/drivers/tty/serial/8250/8250_dw.c +++ b/trunk/drivers/tty/serial/8250/8250_dw.c @@ -338,8 +338,7 @@ static int dw8250_runtime_suspend(struct device *dev) { struct dw8250_data *data = dev_get_drvdata(dev); - if (!IS_ERR(data->clk)) - clk_disable_unprepare(data->clk); + clk_disable_unprepare(data->clk); return 0; } @@ -348,8 +347,7 @@ static int dw8250_runtime_resume(struct device *dev) { struct dw8250_data *data = dev_get_drvdata(dev); - if (!IS_ERR(data->clk)) - clk_prepare_enable(data->clk); + clk_prepare_enable(data->clk); return 0; } @@ -369,7 +367,6 @@ MODULE_DEVICE_TABLE(of, dw8250_of_match); static const struct acpi_device_id dw8250_acpi_match[] = { { "INT33C4", 0 }, { "INT33C5", 0 }, - { "80860F0A", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index e2774f9ecd59..8ab70a620919 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -332,7 +332,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * dmaengine_slave_config(chan, &rx_conf); uap->dmarx.chan = chan; - if (plat && plat->dma_rx_poll_enable) { + if (plat->dma_rx_poll_enable) { /* Set poll rate if specified. */ if (plat->dma_rx_poll_rate) { uap->dmarx.auto_poll_rate = false; diff --git a/trunk/drivers/tty/serial/mcf.c b/trunk/drivers/tty/serial/mcf.c index 65be0c00c4bf..e956377a38fe 100644 --- a/trunk/drivers/tty/serial/mcf.c +++ b/trunk/drivers/tty/serial/mcf.c @@ -707,10 +707,8 @@ static int __init mcf_init(void) if (rc) return rc; rc = platform_driver_register(&mcf_platform_driver); - if (rc) { - uart_unregister_driver(&mcf_driver); + if (rc) return rc; - } return 0; } diff --git a/trunk/drivers/tty/serial/mpc52xx_uart.c b/trunk/drivers/tty/serial/mpc52xx_uart.c index f51b280f3bf2..018bad922554 100644 --- a/trunk/drivers/tty/serial/mpc52xx_uart.c +++ b/trunk/drivers/tty/serial/mpc52xx_uart.c @@ -1497,23 +1497,18 @@ mpc52xx_uart_init(void) if (psc_ops && psc_ops->fifoc_init) { ret = psc_ops->fifoc_init(); if (ret) - goto err_init; + return ret; } ret = platform_driver_register(&mpc52xx_uart_of_driver); if (ret) { printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", __FILE__, ret); - goto err_reg; + uart_unregister_driver(&mpc52xx_uart_driver); + return ret; } return 0; -err_reg: - if (psc_ops && psc_ops->fifoc_uninit) - psc_ops->fifoc_uninit(); -err_init: - uart_unregister_driver(&mpc52xx_uart_driver); - return ret; } static void __exit diff --git a/trunk/drivers/tty/serial/nwpserial.c b/trunk/drivers/tty/serial/nwpserial.c index 549c70a2a63e..77287c54f331 100644 --- a/trunk/drivers/tty/serial/nwpserial.c +++ b/trunk/drivers/tty/serial/nwpserial.c @@ -199,7 +199,7 @@ static void nwpserial_shutdown(struct uart_port *port) dcr_write(up->dcr_host, UART_IER, up->ier); /* free irq */ - free_irq(up->port.irq, up); + free_irq(up->port.irq, port); } static int nwpserial_verify_port(struct uart_port *port, diff --git a/trunk/drivers/tty/serial/samsung.c b/trunk/drivers/tty/serial/samsung.c index 89429410a245..074b9194144f 100644 --- a/trunk/drivers/tty/serial/samsung.c +++ b/trunk/drivers/tty/serial/samsung.c @@ -1803,7 +1803,6 @@ static int __init s3c24xx_serial_modinit(void) static void __exit s3c24xx_serial_modexit(void) { - platform_driver_unregister(&samsung_serial_driver); uart_unregister_driver(&s3c24xx_uart_drv); } diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/tty/vt/vt.c index 740202d8a5c4..fbd447b390f7 100644 --- a/trunk/drivers/tty/vt/vt.c +++ b/trunk/drivers/tty/vt/vt.c @@ -779,6 +779,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ con_set_default_unimap(vc); vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); if (!vc->vc_screenbuf) { + tty_port_destroy(&vc->port); kfree(vc); vc_cons[currcons].d = NULL; return -ENOMEM; @@ -985,25 +986,26 @@ static int vt_resize(struct tty_struct *tty, struct winsize *ws) return ret; } -struct vc_data *vc_deallocate(unsigned int currcons) +void vc_deallocate(unsigned int currcons) { - struct vc_data *vc = NULL; - WARN_CONSOLE_UNLOCKED(); if (vc_cons_allocated(currcons)) { - struct vt_notifier_param param; + struct vc_data *vc = vc_cons[currcons].d; + struct vt_notifier_param param = { .vc = vc }; - param.vc = vc = vc_cons[currcons].d; atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); vcs_remove_sysfs(currcons); vc->vc_sw->con_deinit(vc); put_pid(vc->vt_pid); module_put(vc->vc_sw->owner); kfree(vc->vc_screenbuf); + if (currcons >= MIN_NR_CONSOLES) { + tty_port_destroy(&vc->port); + kfree(vc); + } vc_cons[currcons].d = NULL; } - return vc; } /* diff --git a/trunk/drivers/tty/vt/vt_ioctl.c b/trunk/drivers/tty/vt/vt_ioctl.c index fc2c06c66e89..98ff1735eafc 100644 --- a/trunk/drivers/tty/vt/vt_ioctl.c +++ b/trunk/drivers/tty/vt/vt_ioctl.c @@ -283,51 +283,6 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_ return 0; } -/* deallocate a single console, if possible (leave 0) */ -static int vt_disallocate(unsigned int vc_num) -{ - struct vc_data *vc = NULL; - int ret = 0; - - if (!vc_num) - return 0; - - console_lock(); - if (VT_BUSY(vc_num)) - ret = -EBUSY; - else - vc = vc_deallocate(vc_num); - console_unlock(); - - if (vc && vc_num >= MIN_NR_CONSOLES) { - tty_port_destroy(&vc->port); - kfree(vc); - } - - return ret; -} - -/* deallocate all unused consoles, but leave 0 */ -static void vt_disallocate_all(void) -{ - struct vc_data *vc[MAX_NR_CONSOLES]; - int i; - - console_lock(); - for (i = 1; i < MAX_NR_CONSOLES; i++) - if (!VT_BUSY(i)) - vc[i] = vc_deallocate(i); - else - vc[i] = NULL; - console_unlock(); - - for (i = 1; i < MAX_NR_CONSOLES; i++) { - if (vc[i] && i >= MIN_NR_CONSOLES) { - tty_port_destroy(&vc[i]->port); - kfree(vc[i]); - } - } -} /* @@ -814,10 +769,24 @@ int vt_ioctl(struct tty_struct *tty, ret = -ENXIO; break; } - if (arg == 0) - vt_disallocate_all(); - else - ret = vt_disallocate(--arg); + if (arg == 0) { + /* deallocate all unused consoles, but leave 0 */ + console_lock(); + for (i=1; iphy; - if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + if (!pdev->dev.dma_mask) { + pdev->dev.dma_mask = devm_kzalloc(&pdev->dev, + sizeof(*pdev->dev.dma_mask), GFP_KERNEL); + if (!pdev->dev.dma_mask) { + ret = -ENOMEM; + dev_err(&pdev->dev, "Failed to alloc dma_mask!\n"); + goto err; + } + *pdev->dev.dma_mask = DMA_BIT_MASK(32); + dma_set_coherent_mask(&pdev->dev, *pdev->dev.dma_mask); + } if (usbmisc_ops && usbmisc_ops->init) { ret = usbmisc_ops->init(&pdev->dev); diff --git a/trunk/drivers/usb/chipidea/core.c b/trunk/drivers/usb/chipidea/core.c index 49b098bedf9b..450107e5f657 100644 --- a/trunk/drivers/usb/chipidea/core.c +++ b/trunk/drivers/usb/chipidea/core.c @@ -370,6 +370,11 @@ static int ci_hdrc_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing resource\n"); + return -ENODEV; + } + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/trunk/drivers/usb/core/Kconfig b/trunk/drivers/usb/core/Kconfig index db535b0aa172..8772b3659296 100644 --- a/trunk/drivers/usb/core/Kconfig +++ b/trunk/drivers/usb/core/Kconfig @@ -51,7 +51,7 @@ config USB_DYNAMIC_MINORS config USB_OTG bool "OTG support" - depends on PM_RUNTIME + depends on USB_SUSPEND default n help The most notable feature of USB OTG is support for a diff --git a/trunk/drivers/usb/core/quirks.c b/trunk/drivers/usb/core/quirks.c index a63598895077..ab5638d9c707 100644 --- a/trunk/drivers/usb/core/quirks.c +++ b/trunk/drivers/usb/core/quirks.c @@ -88,9 +88,6 @@ static const struct usb_device_id usb_quirk_list[] = { /* Edirol SD-20 */ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Alcor Micro Corp. Hub */ - { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME }, - /* appletouch */ { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/trunk/drivers/usb/dwc3/Kconfig b/trunk/drivers/usb/dwc3/Kconfig index 757aa18027d0..ea5ee9c21c35 100644 --- a/trunk/drivers/usb/dwc3/Kconfig +++ b/trunk/drivers/usb/dwc3/Kconfig @@ -19,21 +19,21 @@ choice config USB_DWC3_HOST bool "Host only mode" - depends on USB=y || USB=USB_DWC3 + depends on USB help Select this when you want to use DWC3 in host mode only, thereby the gadget feature will be regressed. config USB_DWC3_GADGET bool "Gadget only mode" - depends on USB_GADGET=y || USB_GADGET=USB_DWC3 + depends on USB_GADGET help Select this when you want to use DWC3 in gadget mode only, thereby the host feature will be regressed. config USB_DWC3_DUAL_ROLE bool "Dual Role mode" - depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3)) + depends on (USB && USB_GADGET) help This is the default mode of working of DWC3 controller where both host and gadget features are enabled. diff --git a/trunk/drivers/usb/dwc3/dwc3-exynos.c b/trunk/drivers/usb/dwc3/dwc3-exynos.c index 929e7dd6e58b..a8afe6e26621 100644 --- a/trunk/drivers/usb/dwc3/dwc3-exynos.c +++ b/trunk/drivers/usb/dwc3/dwc3-exynos.c @@ -95,6 +95,8 @@ static int dwc3_exynos_remove_child(struct device *dev, void *unused) return 0; } +static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32); + static int dwc3_exynos_probe(struct platform_device *pdev) { struct dwc3_exynos *exynos; @@ -116,9 +118,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) * Once we move to full device tree support this will vanish off. */ if (!dev->dma_mask) - dev->dma_mask = &dev->coherent_dma_mask; - if (!dev->coherent_dma_mask) - dev->coherent_dma_mask = DMA_BIT_MASK(32); + dev->dma_mask = &dwc3_exynos_dma_mask; platform_set_drvdata(pdev, exynos); diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index f41aa0d0c414..83300d94a893 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -146,6 +146,7 @@ config USB_LPC32XX depends on ARCH_LPC32XX depends on USB_PHY select USB_ISP1301 + select USB_OTG_UTILS help This option selects the USB device controller in the LPC32xx SoC. diff --git a/trunk/drivers/usb/gadget/atmel_usba_udc.c b/trunk/drivers/usb/gadget/atmel_usba_udc.c index 5a5128a226f7..f2a970f75bfa 100644 --- a/trunk/drivers/usb/gadget/atmel_usba_udc.c +++ b/trunk/drivers/usb/gadget/atmel_usba_udc.c @@ -1992,6 +1992,8 @@ static int __init usba_udc_probe(struct platform_device *pdev) err_get_hclk: clk_put(pclk); + platform_set_drvdata(pdev, NULL); + return ret; } diff --git a/trunk/drivers/usb/gadget/bcm63xx_udc.c b/trunk/drivers/usb/gadget/bcm63xx_udc.c index fd24cb4540a4..6e6518264c42 100644 --- a/trunk/drivers/usb/gadget/bcm63xx_udc.c +++ b/trunk/drivers/usb/gadget/bcm63xx_udc.c @@ -2334,11 +2334,21 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "error finding USBD resource\n"); + return -ENXIO; + } + udc->usbd_regs = devm_ioremap_resource(dev, res); if (IS_ERR(udc->usbd_regs)) return PTR_ERR(udc->usbd_regs); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "error finding IUDMA resource\n"); + return -ENXIO; + } + udc->iudma_regs = devm_ioremap_resource(dev, res); if (IS_ERR(udc->iudma_regs)) return PTR_ERR(udc->iudma_regs); @@ -2410,6 +2420,7 @@ static int bcm63xx_udc_remove(struct platform_device *pdev) usb_del_gadget_udc(&udc->gadget); BUG_ON(udc->driver); + platform_set_drvdata(pdev, NULL); bcm63xx_uninit_udc_hw(udc); return 0; diff --git a/trunk/drivers/usb/gadget/configfs.c b/trunk/drivers/usb/gadget/configfs.c index 80e7f75a56c7..3d5cfc9c2c78 100644 --- a/trunk/drivers/usb/gadget/configfs.c +++ b/trunk/drivers/usb/gadget/configfs.c @@ -821,10 +821,8 @@ static int configfs_composite_bind(struct usb_gadget *gadget, gi->gstrings[i] = NULL; s = usb_gstrings_attach(&gi->cdev, gi->gstrings, USB_GADGET_FIRST_AVAIL_IDX); - if (IS_ERR(s)) { - ret = PTR_ERR(s); + if (IS_ERR(s)) goto err_comp_cleanup; - } gi->cdev.desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id; gi->cdev.desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id; @@ -849,10 +847,8 @@ static int configfs_composite_bind(struct usb_gadget *gadget, } cfg->gstrings[i] = NULL; s = usb_gstrings_attach(&gi->cdev, cfg->gstrings, 1); - if (IS_ERR(s)) { - ret = PTR_ERR(s); + if (IS_ERR(s)) goto err_comp_cleanup; - } c->iConfiguration = s[0].id; } diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index c588e8e486e5..a792e322f4f1 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -1001,6 +1001,7 @@ static int dummy_udc_remove(struct platform_device *pdev) struct dummy *dum = platform_get_drvdata(pdev); usb_del_gadget_udc(&dum->gadget); + platform_set_drvdata(pdev, NULL); device_remove_file(&dum->gadget.dev, &dev_attr_function); return 0; } @@ -2660,10 +2661,8 @@ static int __init init(void) } for (i = 0; i < mod_data.num; i++) { dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL); - if (!dum[i]) { - retval = -ENOMEM; + if (!dum[i]) goto err_add_pdata; - } retval = platform_device_add_data(the_hcd_pdev[i], &dum[i], sizeof(void *)); if (retval) diff --git a/trunk/drivers/usb/gadget/f_ecm.c b/trunk/drivers/usb/gadget/f_ecm.c index abf8a31ae146..d893d6929079 100644 --- a/trunk/drivers/usb/gadget/f_ecm.c +++ b/trunk/drivers/usb/gadget/f_ecm.c @@ -816,7 +816,6 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f) * @c: the configuration to support the network link * @ethaddr: a buffer in which the ethernet address of the host side * side of the link was recorded - * @dev: eth_dev structure * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. diff --git a/trunk/drivers/usb/gadget/f_subset.c b/trunk/drivers/usb/gadget/f_subset.c index 7be04b342494..185d6f5e4e4d 100644 --- a/trunk/drivers/usb/gadget/f_subset.c +++ b/trunk/drivers/usb/gadget/f_subset.c @@ -373,7 +373,6 @@ geth_unbind(struct usb_configuration *c, struct usb_function *f) * @c: the configuration to support the network link * @ethaddr: a buffer in which the ethernet address of the host side * side of the link was recorded - * @dev: eth_dev structure * Context: single threaded during gadget setup * * Returns zero on success, else negative errno. diff --git a/trunk/drivers/usb/gadget/f_uac2.c b/trunk/drivers/usb/gadget/f_uac2.c index 03c1fb686644..c7468b6c07b0 100644 --- a/trunk/drivers/usb/gadget/f_uac2.c +++ b/trunk/drivers/usb/gadget/f_uac2.c @@ -456,6 +456,8 @@ static int snd_uac2_remove(struct platform_device *pdev) { struct snd_card *card = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); + if (card) return snd_card_free(card); diff --git a/trunk/drivers/usb/gadget/fusb300_udc.c b/trunk/drivers/usb/gadget/fusb300_udc.c index b8632d40f8bf..cec8871b77f9 100644 --- a/trunk/drivers/usb/gadget/fusb300_udc.c +++ b/trunk/drivers/usb/gadget/fusb300_udc.c @@ -1461,10 +1461,8 @@ static int __init fusb300_probe(struct platform_device *pdev) fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, GFP_KERNEL); - if (fusb300->ep0_req == NULL) { - ret = -ENOMEM; + if (fusb300->ep0_req == NULL) goto clean_up3; - } init_controller(fusb300); ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget); diff --git a/trunk/drivers/usb/gadget/imx_udc.c b/trunk/drivers/usb/gadget/imx_udc.c index 9b2d24e4c95f..b5cebd6b0d7a 100644 --- a/trunk/drivers/usb/gadget/imx_udc.c +++ b/trunk/drivers/usb/gadget/imx_udc.c @@ -1511,6 +1511,8 @@ static int __exit imx_udc_remove(struct platform_device *pdev) if (pdata->exit) pdata->exit(&pdev->dev); + platform_set_drvdata(pdev, NULL); + return 0; } diff --git a/trunk/drivers/usb/gadget/m66592-udc.c b/trunk/drivers/usb/gadget/m66592-udc.c index 51cfe72da5bb..866ef0999247 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.c +++ b/trunk/drivers/usb/gadget/m66592-udc.c @@ -1660,10 +1660,8 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->epaddr2ep[0] = &m66592->ep[0]; m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); - if (m66592->ep0_req == NULL) { - ret = -ENOMEM; + if (m66592->ep0_req == NULL) goto clean_up3; - } m66592->ep0_req->complete = nop_completion; init_controller(m66592); diff --git a/trunk/drivers/usb/gadget/pxa25x_udc.c b/trunk/drivers/usb/gadget/pxa25x_udc.c index 95c531d5aa4f..ef47495dec8f 100644 --- a/trunk/drivers/usb/gadget/pxa25x_udc.c +++ b/trunk/drivers/usb/gadget/pxa25x_udc.c @@ -2236,6 +2236,7 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) dev->transceiver = NULL; } + platform_set_drvdata(pdev, NULL); the_controller = NULL; return 0; } diff --git a/trunk/drivers/usb/gadget/r8a66597-udc.c b/trunk/drivers/usb/gadget/r8a66597-udc.c index 7ff7d9cf2061..0b742d171843 100644 --- a/trunk/drivers/usb/gadget/r8a66597-udc.c +++ b/trunk/drivers/usb/gadget/r8a66597-udc.c @@ -1977,10 +1977,8 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep, GFP_KERNEL); - if (r8a66597->ep0_req == NULL) { - ret = -ENOMEM; + if (r8a66597->ep0_req == NULL) goto clean_up3; - } r8a66597->ep0_req->complete = nop_completion; ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget); diff --git a/trunk/drivers/usb/gadget/s3c-hsotg.c b/trunk/drivers/usb/gadget/s3c-hsotg.c index af22f24046b2..a3cdc32115d5 100644 --- a/trunk/drivers/usb/gadget/s3c-hsotg.c +++ b/trunk/drivers/usb/gadget/s3c-hsotg.c @@ -437,7 +437,7 @@ static void s3c_hsotg_unmap_dma(struct s3c_hsotg *hsotg, if (hs_req->req.length == 0) return; - usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in); + usb_gadget_unmap_request(&hsotg->gadget, hs_req, hs_ep->dir_in); } /** diff --git a/trunk/drivers/usb/gadget/s3c2410_udc.c b/trunk/drivers/usb/gadget/s3c2410_udc.c index 09c4f70c93c4..d0e75e1b3ccb 100644 --- a/trunk/drivers/usb/gadget/s3c2410_udc.c +++ b/trunk/drivers/usb/gadget/s3c2410_udc.c @@ -1851,7 +1851,6 @@ static int s3c2410_udc_probe(struct platform_device *pdev) irq = gpio_to_irq(udc_info->vbus_pin); if (irq < 0) { dev_err(dev, "no irq for gpio vbus pin\n"); - retval = irq; goto err_gpio_claim; } @@ -1949,6 +1948,8 @@ static int s3c2410_udc_remove(struct platform_device *pdev) iounmap(base_addr); release_mem_region(rsrc_start, rsrc_len); + platform_set_drvdata(pdev, NULL); + if (!IS_ERR(udc_clock) && udc_clock != NULL) { clk_disable(udc_clock); clk_put(udc_clock); diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index 0deb9d6cde26..2cd6262e8b71 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -284,16 +284,12 @@ static int __init zero_bind(struct usb_composite_dev *cdev) ss_opts->bulk_buflen = gzero_options.bulk_buflen; func_ss = usb_get_function(func_inst_ss); - if (IS_ERR(func_ss)) { - status = PTR_ERR(func_ss); + if (IS_ERR(func_ss)) goto err_put_func_inst_ss; - } func_inst_lb = usb_get_function_instance("Loopback"); - if (IS_ERR(func_inst_lb)) { - status = PTR_ERR(func_inst_lb); + if (IS_ERR(func_inst_lb)) goto err_put_func_ss; - } lb_opts = container_of(func_inst_lb, struct f_lb_opts, func_inst); lb_opts->bulk_buflen = gzero_options.bulk_buflen; diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 344d5e2f87d7..de94f2699063 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -507,7 +507,7 @@ endif # USB_OHCI_HCD config USB_UHCI_HCD tristate "UHCI HCD (most Intel and VIA) support" - depends on PCI || USB_UHCI_SUPPORT_NON_PCI_HC + depends on PCI || SPARC_LEON || ARCH_VT8500 ---help--- The Universal Host Controller Interface is a standard by Intel for accessing the USB hardware in the PC (which is also called the USB @@ -524,19 +524,26 @@ config USB_UHCI_HCD config USB_UHCI_SUPPORT_NON_PCI_HC bool - default y if (SPARC_LEON || USB_UHCI_PLATFORM) + depends on USB_UHCI_HCD + default y if (SPARC_LEON || ARCH_VT8500) config USB_UHCI_PLATFORM - bool + bool "Generic UHCI Platform Driver support" + depends on USB_UHCI_SUPPORT_NON_PCI_HC default y if ARCH_VT8500 + ---help--- + Enable support for generic UHCI platform devices that require no + additional configuration. config USB_UHCI_BIG_ENDIAN_MMIO bool - default y if SPARC_LEON + depends on USB_UHCI_SUPPORT_NON_PCI_HC && SPARC_LEON + default y config USB_UHCI_BIG_ENDIAN_DESC bool - default y if SPARC_LEON + depends on USB_UHCI_SUPPORT_NON_PCI_HC && SPARC_LEON + default y config USB_FHCI_HCD tristate "Freescale QE USB Host Controller support" diff --git a/trunk/drivers/usb/host/ehci-atmel.c b/trunk/drivers/usb/host/ehci-atmel.c index 02f4611faa62..66420097c242 100644 --- a/trunk/drivers/usb/host/ehci-atmel.c +++ b/trunk/drivers/usb/host/ehci-atmel.c @@ -63,6 +63,8 @@ static void atmel_stop_ehci(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ +static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32); + static int ehci_atmel_drv_probe(struct platform_device *pdev) { struct usb_hcd *hcd; @@ -91,9 +93,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &at91_ehci_dma_mask; hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 246e124e6ac5..312fc10da3c7 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -1286,6 +1286,23 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_sead3_driver #endif +#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \ + !IS_ENABLED(CONFIG_USB_CHIPIDEA_HOST) && \ + !IS_ENABLED(CONFIG_USB_EHCI_MXC) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_ORION) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_SPEAR) && \ + !IS_ENABLED(CONFIG_USB_EHCI_S5P) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_AT91) && \ + !IS_ENABLED(CONFIG_USB_EHCI_MSM) && \ + !defined(PLATFORM_DRIVER) && \ + !defined(PS3_SYSTEM_BUS_DRIVER) && \ + !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) +#error "missing bus glue for ehci-hcd" +#endif + static int __init ehci_hcd_init(void) { int retval = 0; diff --git a/trunk/drivers/usb/host/ehci-omap.c b/trunk/drivers/usb/host/ehci-omap.c index 16d7150e8557..3d1491b5f360 100644 --- a/trunk/drivers/usb/host/ehci-omap.c +++ b/trunk/drivers/usb/host/ehci-omap.c @@ -90,6 +90,8 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initdata = { .extra_priv_size = sizeof(struct omap_hcd), }; +static u64 omap_ehci_dma_mask = DMA_BIT_MASK(32); + /** * ehci_hcd_omap_probe - initialize TI-based HCDs * @@ -144,10 +146,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) * Since shared usb code relies on it, set it here for now. * Once we have dma capability bindings this can go away. */ - if (!dev->dma_mask) - dev->dma_mask = &dev->coherent_dma_mask; - if (!dev->coherent_dma_mask) - dev->coherent_dma_mask = DMA_BIT_MASK(32); + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &omap_ehci_dma_mask; hcd = usb_create_hcd(&ehci_omap_hc_driver, dev, dev_name(dev)); diff --git a/trunk/drivers/usb/host/ehci-orion.c b/trunk/drivers/usb/host/ehci-orion.c index efbc588b48c5..54c579485150 100644 --- a/trunk/drivers/usb/host/ehci-orion.c +++ b/trunk/drivers/usb/host/ehci-orion.c @@ -137,6 +137,8 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd, } } +static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32); + static int ehci_orion_drv_probe(struct platform_device *pdev) { struct orion_ehci_data *pd = pdev->dev.platform_data; @@ -181,9 +183,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) * now. Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &ehci_orion_dma_mask; if (!request_mem_region(res->start, resource_size(res), ehci_orion_hc_driver.description)) { diff --git a/trunk/drivers/usb/host/ehci-s5p.c b/trunk/drivers/usb/host/ehci-s5p.c index 379037f51a2f..635775278c7f 100644 --- a/trunk/drivers/usb/host/ehci-s5p.c +++ b/trunk/drivers/usb/host/ehci-s5p.c @@ -71,6 +71,8 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev) dev_err(dev, "can't request ehci vbus gpio %d", gpio); } +static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32); + static int s5p_ehci_probe(struct platform_device *pdev) { struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; @@ -88,7 +90,7 @@ static int s5p_ehci_probe(struct platform_device *pdev) * Once we move to full device tree support this will vanish off. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + pdev->dev.dma_mask = &ehci_s5p_dma_mask; if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); @@ -105,7 +107,6 @@ static int s5p_ehci_probe(struct platform_device *pdev) if (IS_ERR(phy)) { /* Fallback to pdata */ if (!pdata) { - usb_put_hcd(hcd); dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); return -EPROBE_DEFER; } else { diff --git a/trunk/drivers/usb/host/ehci-spear.c b/trunk/drivers/usb/host/ehci-spear.c index bd3e5cbc6240..61ecfb3d52f5 100644 --- a/trunk/drivers/usb/host/ehci-spear.c +++ b/trunk/drivers/usb/host/ehci-spear.c @@ -58,6 +58,8 @@ static int ehci_spear_drv_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend, ehci_spear_drv_resume); +static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32); + static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) { struct usb_hcd *hcd ; @@ -82,9 +84,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &spear_ehci_dma_mask; usbh_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(usbh_clk)) { diff --git a/trunk/drivers/usb/host/ehci-tegra.c b/trunk/drivers/usb/host/ehci-tegra.c index 59d111bf44a9..e3eddc31ac83 100644 --- a/trunk/drivers/usb/host/ehci-tegra.c +++ b/trunk/drivers/usb/host/ehci-tegra.c @@ -637,6 +637,8 @@ static void tegra_ehci_set_phcd(struct usb_phy *x, bool enable) writel(val, base + TEGRA_USB_PORTSC1); } +static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); + static int tegra_ehci_probe(struct platform_device *pdev) { struct resource *res; @@ -659,9 +661,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &tegra_ehci_dma_mask; setup_vbus_gpio(pdev, pdata); diff --git a/trunk/drivers/usb/host/isp1760-hcd.c b/trunk/drivers/usb/host/isp1760-hcd.c index 2facee53eab1..125e261f5bfc 100644 --- a/trunk/drivers/usb/host/isp1760-hcd.c +++ b/trunk/drivers/usb/host/isp1760-hcd.c @@ -1739,7 +1739,7 @@ static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf) int retval = 1; unsigned long flags; - /* if !PM_RUNTIME, root hub timers won't get shut down ... */ + /* if !USB_SUSPEND, root hub timers won't get shut down ... */ if (!HC_IS_RUNNING(hcd->state)) return 0; diff --git a/trunk/drivers/usb/host/isp1760-if.c b/trunk/drivers/usb/host/isp1760-if.c index a13709ee4e5d..bbb791bd7617 100644 --- a/trunk/drivers/usb/host/isp1760-if.c +++ b/trunk/drivers/usb/host/isp1760-if.c @@ -373,10 +373,8 @@ static int isp1760_plat_probe(struct platform_device *pdev) irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { pr_warning("isp1760: IRQ resource not available\n"); - ret = -ENODEV; - goto cleanup; + return -ENODEV; } - irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; if (priv) { diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 2ee1496dbc1d..a0cb44f0e724 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -504,6 +504,8 @@ static const struct of_device_id at91_ohci_dt_ids[] = { MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids); +static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32); + static int ohci_at91_of_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -520,9 +522,7 @@ static int ohci_at91_of_init(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &at91_ohci_dma_mask; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) diff --git a/trunk/drivers/usb/host/ohci-exynos.c b/trunk/drivers/usb/host/ohci-exynos.c index b0b542c14e31..07592c00af26 100644 --- a/trunk/drivers/usb/host/ohci-exynos.c +++ b/trunk/drivers/usb/host/ohci-exynos.c @@ -98,6 +98,8 @@ static const struct hc_driver exynos_ohci_hc_driver = { .start_port_reset = ohci_start_port_reset, }; +static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32); + static int exynos_ohci_probe(struct platform_device *pdev) { struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; @@ -115,7 +117,7 @@ static int exynos_ohci_probe(struct platform_device *pdev) * Once we move to full device tree support this will vanish off. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + pdev->dev.dma_mask = &ohci_exynos_dma_mask; if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index fc627fd54116..9e6de9586ae4 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -233,14 +233,14 @@ static int ohci_urb_enqueue ( urb->start_frame = frame; } } else if (ed->type == PIPE_ISOCHRONOUS) { - u16 next = ohci_frame_no(ohci) + 1; + u16 next = ohci_frame_no(ohci) + 2; u16 frame = ed->last_iso + ed->interval; /* Behind the scheduling threshold? */ if (unlikely(tick_before(frame, next))) { /* USB_ISO_ASAP: Round up to the first available slot */ - if (urb->transfer_flags & URB_ISO_ASAP) { + if (urb->transfer_flags & URB_ISO_ASAP) frame += (next - frame + ed->interval - 1) & -ed->interval; @@ -248,25 +248,21 @@ static int ohci_urb_enqueue ( * Not ASAP: Use the next slot in the stream. If * the entire URB falls before the threshold, fail. */ - } else { - if (tick_before(frame + ed->interval * + else if (tick_before(frame + ed->interval * (urb->number_of_packets - 1), next)) { - retval = -EXDEV; - usb_hcd_unlink_urb_from_ep(hcd, urb); - goto fail; - } - - /* - * Some OHCI hardware doesn't handle late TDs - * correctly. After retiring them it proceeds - * to the next ED instead of the next TD. - * Therefore we have to omit the late TDs - * entirely. - */ - urb_priv->td_cnt = DIV_ROUND_UP( - (u16) (next - frame), - ed->interval); + retval = -EXDEV; + usb_hcd_unlink_urb_from_ep(hcd, urb); + goto fail; } + + /* + * Some OHCI hardware doesn't handle late TDs + * correctly. After retiring them it proceeds to + * the next ED instead of the next TD. Therefore + * we have to omit the late TDs entirely. + */ + urb_priv->td_cnt = DIV_ROUND_UP(next - frame, + ed->interval); } urb->start_frame = frame; } diff --git a/trunk/drivers/usb/host/ohci-nxp.c b/trunk/drivers/usb/host/ohci-nxp.c index 5d7eb72c5064..f4988fbe78e7 100644 --- a/trunk/drivers/usb/host/ohci-nxp.c +++ b/trunk/drivers/usb/host/ohci-nxp.c @@ -223,7 +223,8 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) isp1301_i2c_client = isp1301_get_client(isp1301_node); if (!isp1301_i2c_client) { - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto out; } pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); @@ -233,7 +234,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) if (usb_disabled()) { dev_err(&pdev->dev, "USB is disabled\n"); ret = -ENODEV; - goto fail_disable; + goto out; } /* Enable AHB slave USB clock, needed for further USB clock control */ @@ -244,19 +245,19 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) if (IS_ERR(usb_pll_clk)) { dev_err(&pdev->dev, "failed to acquire USB PLL\n"); ret = PTR_ERR(usb_pll_clk); - goto fail_pll; + goto out1; } ret = clk_enable(usb_pll_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB PLL\n"); - goto fail_pllen; + goto out2; } ret = clk_set_rate(usb_pll_clk, 48000); if (ret < 0) { dev_err(&pdev->dev, "failed to set USB clock rate\n"); - goto fail_rate; + goto out3; } /* Enable USB device clock */ @@ -264,13 +265,13 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) if (IS_ERR(usb_dev_clk)) { dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); ret = PTR_ERR(usb_dev_clk); - goto fail_dev; + goto out4; } ret = clk_enable(usb_dev_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); - goto fail_deven; + goto out5; } /* Enable USB otg clocks */ @@ -278,7 +279,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) if (IS_ERR(usb_otg_clk)) { dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); ret = PTR_ERR(usb_otg_clk); - goto fail_otg; + goto out6; } __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); @@ -286,7 +287,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) ret = clk_enable(usb_otg_clk); if (ret < 0) { dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); - goto fail_otgen; + goto out7; } isp1301_configure(); @@ -295,14 +296,20 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) if (!hcd) { dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); ret = -ENOMEM; - goto fail_hcd; + goto out8; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get MEM resource\n"); + ret = -ENOMEM; + goto out8; + } + hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); - goto fail_resource; + goto out8; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); @@ -310,7 +317,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = -ENXIO; - goto fail_resource; + goto out8; } nxp_start_hc(); @@ -324,24 +331,23 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev) return ret; nxp_stop_hc(); -fail_resource: +out8: usb_put_hcd(hcd); -fail_hcd: +out7: clk_disable(usb_otg_clk); -fail_otgen: +out6: clk_put(usb_otg_clk); -fail_otg: +out5: clk_disable(usb_dev_clk); -fail_deven: +out4: clk_put(usb_dev_clk); -fail_dev: -fail_rate: +out3: clk_disable(usb_pll_clk); -fail_pllen: +out2: clk_put(usb_pll_clk); -fail_pll: -fail_disable: +out1: isp1301_i2c_client = NULL; +out: return ret; } diff --git a/trunk/drivers/usb/host/ohci-omap3.c b/trunk/drivers/usb/host/ohci-omap3.c index 8663851c8d8e..ddfc31427bc0 100644 --- a/trunk/drivers/usb/host/ohci-omap3.c +++ b/trunk/drivers/usb/host/ohci-omap3.c @@ -114,6 +114,8 @@ static const struct hc_driver ohci_omap3_hc_driver = { /*-------------------------------------------------------------------------*/ +static u64 omap_ohci_dma_mask = DMA_BIT_MASK(32); + /* * configure so an HC device and id are always provided * always called with process context; sleeping is OK @@ -166,10 +168,8 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev) * Since shared usb code relies on it, set it here for now. * Once we have dma capability bindings this can go away. */ - if (!dev->dma_mask) - dev->dma_mask = &dev->coherent_dma_mask; - if (!dev->coherent_dma_mask) - dev->coherent_dma_mask = DMA_BIT_MASK(32); + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &omap_ohci_dma_mask; hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev, dev_name(dev)); diff --git a/trunk/drivers/usb/host/ohci-pxa27x.c b/trunk/drivers/usb/host/ohci-pxa27x.c index 279b2ef17411..efe71f3ca477 100644 --- a/trunk/drivers/usb/host/ohci-pxa27x.c +++ b/trunk/drivers/usb/host/ohci-pxa27x.c @@ -282,6 +282,8 @@ static const struct of_device_id pxa_ohci_dt_ids[] = { MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids); +static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32); + static int ohci_pxa_of_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -296,9 +298,7 @@ static int ohci_pxa_of_init(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &pxa_ohci_dma_mask; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) diff --git a/trunk/drivers/usb/host/ohci-spear.c b/trunk/drivers/usb/host/ohci-spear.c index 3e19e0170d11..9020bf0e2eca 100644 --- a/trunk/drivers/usb/host/ohci-spear.c +++ b/trunk/drivers/usb/host/ohci-spear.c @@ -91,6 +91,8 @@ static const struct hc_driver ohci_spear_hc_driver = { .start_port_reset = ohci_start_port_reset, }; +static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32); + static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) { const struct hc_driver *driver = &ohci_spear_hc_driver; @@ -112,9 +114,7 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &spear_ohci_dma_mask; usbh_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(usbh_clk)) { diff --git a/trunk/drivers/usb/host/oxu210hp-hcd.c b/trunk/drivers/usb/host/oxu210hp-hcd.c index 0f401dbfaf07..4f0f0339532f 100644 --- a/trunk/drivers/usb/host/oxu210hp-hcd.c +++ b/trunk/drivers/usb/host/oxu210hp-hcd.c @@ -3084,7 +3084,7 @@ static int oxu_hub_status_data(struct usb_hcd *hcd, char *buf) int ports, i, retval = 1; unsigned long flags; - /* if !PM_RUNTIME, root hub timers won't get shut down ... */ + /* if !USB_SUSPEND, root hub timers won't get shut down ... */ if (!HC_IS_RUNNING(hcd->state)) return 0; diff --git a/trunk/drivers/usb/host/sl811-hcd.c b/trunk/drivers/usb/host/sl811-hcd.c index b2ec7fe758dd..ad4483efb6d6 100644 --- a/trunk/drivers/usb/host/sl811-hcd.c +++ b/trunk/drivers/usb/host/sl811-hcd.c @@ -22,7 +22,7 @@ * and usb-storage. * * TODO: - * - usb suspend/resume triggered by sl811 (with PM_RUNTIME) + * - usb suspend/resume triggered by sl811 (with USB_SUSPEND) * - various issues noted in the code * - performance work; use both register banks; ... * - use urb->iso_frame_desc[] with ISO transfers diff --git a/trunk/drivers/usb/host/uhci-hub.c b/trunk/drivers/usb/host/uhci-hub.c index 9189bc984c98..f87bee6d2789 100644 --- a/trunk/drivers/usb/host/uhci-hub.c +++ b/trunk/drivers/usb/host/uhci-hub.c @@ -225,8 +225,7 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) /* auto-stop if nothing connected for 1 second */ if (any_ports_active(uhci)) uhci->rh_state = UHCI_RH_RUNNING; - else if (time_after_eq(jiffies, uhci->auto_stop_time) && - !uhci->wait_for_hp) + else if (time_after_eq(jiffies, uhci->auto_stop_time)) suspend_rh(uhci, UHCI_RH_AUTO_STOPPED); break; diff --git a/trunk/drivers/usb/host/uhci-platform.c b/trunk/drivers/usb/host/uhci-platform.c index f1db61ada6a8..8c4dace4b14a 100644 --- a/trunk/drivers/usb/host/uhci-platform.c +++ b/trunk/drivers/usb/host/uhci-platform.c @@ -60,6 +60,8 @@ static const struct hc_driver uhci_platform_hc_driver = { .hub_control = uhci_hub_control, }; +static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32); + static int uhci_hcd_platform_probe(struct platform_device *pdev) { struct usb_hcd *hcd; @@ -76,9 +78,7 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev) * Once we have dma capability bindings this can go away. */ if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - if (!pdev->dev.coherent_dma_mask) - pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &platform_uhci_dma_mask; hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev, pdev->name); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 041c6ddb695c..f0976d8190bc 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -1287,7 +1287,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, return -EINVAL; /* Can't change the period */ } else { - next = uhci->frame_number + 1; + next = uhci->frame_number + 2; /* Find the next unused frame */ if (list_empty(&qh->queue)) { diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 2cfc465925bd..965b539bc474 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -1423,17 +1423,15 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ep_ctx->ep_info2 |= cpu_to_le32(xhci_get_endpoint_type(udev, ep)); /* Set the max packet size and max burst */ - max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); - max_burst = 0; switch (udev->speed) { case USB_SPEED_SUPER: + max_packet = usb_endpoint_maxp(&ep->desc); + ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); /* dig out max burst from ep companion desc */ - max_burst = ep->ss_ep_comp.bMaxBurst; + max_packet = ep->ss_ep_comp.bMaxBurst; + ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet)); break; case USB_SPEED_HIGH: - /* Some devices get this wrong */ - if (usb_endpoint_xfer_bulk(&ep->desc)) - max_packet = 512; /* bits 11:12 specify the number of additional transaction * opportunities per microframe (USB 2.0, section 9.6.6) */ @@ -1441,16 +1439,17 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, usb_endpoint_xfer_int(&ep->desc)) { max_burst = (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; + ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_burst)); } - break; + /* Fall through */ case USB_SPEED_FULL: case USB_SPEED_LOW: + max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); + ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); break; default: BUG(); } - ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | - MAX_BURST(max_burst)); max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); diff --git a/trunk/drivers/usb/musb/musb_dsps.c b/trunk/drivers/usb/musb/musb_dsps.c index e1b661d04021..3a18e44e9391 100644 --- a/trunk/drivers/usb/musb/musb_dsps.c +++ b/trunk/drivers/usb/musb/musb_dsps.c @@ -560,7 +560,6 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) if (!config) { dev_err(&pdev->dev, "failed to allocate musb hdrc config\n"); - ret = -ENOMEM; goto err2; } diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index 628b93fe5ccc..3551f1a30c65 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -549,8 +549,7 @@ static int omap2430_probe(struct platform_device *pdev) glue->control_otghs = omap_get_control_dev(); if (IS_ERR(glue->control_otghs)) { dev_vdbg(&pdev->dev, "Failed to get control device\n"); - ret = PTR_ERR(glue->control_otghs); - goto err2; + return -ENODEV; } } else { glue->control_otghs = ERR_PTR(-ENODEV); diff --git a/trunk/drivers/usb/phy/Kconfig b/trunk/drivers/usb/phy/Kconfig index 7ef3eb8617a6..371d0e74e909 100644 --- a/trunk/drivers/usb/phy/Kconfig +++ b/trunk/drivers/usb/phy/Kconfig @@ -25,7 +25,7 @@ config AB8500_USB config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_FSL_USB2 && PM_RUNTIME + depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_SUSPEND select USB_OTG help Enable this to support Freescale USB OTG transceiver. @@ -139,6 +139,7 @@ config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" depends on USB || USB_GADGET depends on I2C + select USB_OTG_UTILS help Say Y here to add support for the NXP ISP1301 USB transceiver driver. This chip is typically used as USB transceiver for USB host, gadget @@ -161,7 +162,7 @@ config USB_MSM_OTG config USB_MV_OTG tristate "Marvell USB OTG support" - depends on USB_EHCI_MV && USB_MV_UDC && PM_RUNTIME + depends on USB_EHCI_MV && USB_MV_UDC && USB_SUSPEND select USB_OTG help Say Y here if you want to build Marvell USB OTG transciever diff --git a/trunk/drivers/usb/phy/phy-ab8500-usb.c b/trunk/drivers/usb/phy/phy-ab8500-usb.c index e5eb1b5a04eb..4acef26a2ef5 100644 --- a/trunk/drivers/usb/phy/phy-ab8500-usb.c +++ b/trunk/drivers/usb/phy/phy-ab8500-usb.c @@ -892,6 +892,8 @@ static int ab8500_usb_remove(struct platform_device *pdev) else if (ab->mode == USB_PERIPHERAL) ab8500_usb_peri_phy_dis(ab); + platform_set_drvdata(pdev, NULL); + return 0; } diff --git a/trunk/drivers/usb/phy/phy-fsl-usb.c b/trunk/drivers/usb/phy/phy-fsl-usb.c index e771bafb9f1d..97b9308507c3 100644 --- a/trunk/drivers/usb/phy/phy-fsl-usb.c +++ b/trunk/drivers/usb/phy/phy-fsl-usb.c @@ -799,7 +799,6 @@ static int fsl_otg_conf(struct platform_device *pdev) /* initialize the otg structure */ fsl_otg_tc->phy.label = DRIVER_DESC; - fsl_otg_tc->phy.dev = &pdev->dev; fsl_otg_tc->phy.set_power = fsl_otg_set_power; fsl_otg_tc->phy.otg->phy = &fsl_otg_tc->phy; diff --git a/trunk/drivers/usb/phy/phy-gpio-vbus-usb.c b/trunk/drivers/usb/phy/phy-gpio-vbus-usb.c index 8443335c2ea0..4c76074e518d 100644 --- a/trunk/drivers/usb/phy/phy-gpio-vbus-usb.c +++ b/trunk/drivers/usb/phy/phy-gpio-vbus-usb.c @@ -266,7 +266,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpio_vbus); gpio_vbus->dev = &pdev->dev; gpio_vbus->phy.label = "gpio-vbus"; - gpio_vbus->phy.dev = gpio_vbus->dev; gpio_vbus->phy.set_power = gpio_vbus_set_power; gpio_vbus->phy.set_suspend = gpio_vbus_set_suspend; gpio_vbus->phy.state = OTG_STATE_UNDEFINED; @@ -344,6 +343,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) gpio_free(pdata->gpio_pullup); gpio_free(pdata->gpio_vbus); err_gpio: + platform_set_drvdata(pdev, NULL); kfree(gpio_vbus->phy.otg); kfree(gpio_vbus); return err; @@ -365,6 +365,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) if (gpio_is_valid(pdata->gpio_pullup)) gpio_free(pdata->gpio_pullup); gpio_free(gpio); + platform_set_drvdata(pdev, NULL); kfree(gpio_vbus->phy.otg); kfree(gpio_vbus); diff --git a/trunk/drivers/usb/phy/phy-isp1301.c b/trunk/drivers/usb/phy/phy-isp1301.c index 8a55b37d1a02..225ae6c97eeb 100644 --- a/trunk/drivers/usb/phy/phy-isp1301.c +++ b/trunk/drivers/usb/phy/phy-isp1301.c @@ -102,7 +102,6 @@ static int isp1301_probe(struct i2c_client *client, mutex_init(&isp->mutex); phy = &isp->phy; - phy->dev = &client->dev; phy->label = DRV_NAME; phy->init = isp1301_phy_init; phy->set_vbus = isp1301_phy_set_vbus; diff --git a/trunk/drivers/usb/phy/phy-mv-u3d-usb.c b/trunk/drivers/usb/phy/phy-mv-u3d-usb.c index 1568ea63e338..f7838a43347c 100644 --- a/trunk/drivers/usb/phy/phy-mv-u3d-usb.c +++ b/trunk/drivers/usb/phy/phy-mv-u3d-usb.c @@ -278,6 +278,11 @@ static int mv_u3d_phy_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing mem resource\n"); + return -ENODEV; + } + phy_base = devm_ioremap_resource(dev, res); if (IS_ERR(phy_base)) return PTR_ERR(phy_base); diff --git a/trunk/drivers/usb/phy/phy-mv-usb.c b/trunk/drivers/usb/phy/phy-mv-usb.c index 4a6b03c73876..c987bbe27851 100644 --- a/trunk/drivers/usb/phy/phy-mv-usb.c +++ b/trunk/drivers/usb/phy/phy-mv-usb.c @@ -667,6 +667,7 @@ int mv_otg_remove(struct platform_device *pdev) mv_otg_disable(mvotg); usb_remove_phy(&mvotg->phy); + platform_set_drvdata(pdev, NULL); return 0; } @@ -849,6 +850,8 @@ static int mv_otg_probe(struct platform_device *pdev) flush_workqueue(mvotg->qwork); destroy_workqueue(mvotg->qwork); + platform_set_drvdata(pdev, NULL); + return retval; } diff --git a/trunk/drivers/usb/phy/phy-mxs-usb.c b/trunk/drivers/usb/phy/phy-mxs-usb.c index bd601c537c8d..9d4381e64d51 100644 --- a/trunk/drivers/usb/phy/phy-mxs-usb.c +++ b/trunk/drivers/usb/phy/phy-mxs-usb.c @@ -130,6 +130,11 @@ static int mxs_phy_probe(struct platform_device *pdev) int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "can't get device resources\n"); + return -ENOENT; + } + base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); @@ -155,7 +160,6 @@ static int mxs_phy_probe(struct platform_device *pdev) mxs_phy->phy.set_suspend = mxs_phy_suspend; mxs_phy->phy.notify_connect = mxs_phy_on_connect; mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; - mxs_phy->phy.type = USB_PHY_TYPE_USB2; ATOMIC_INIT_NOTIFIER_HEAD(&mxs_phy->phy.notifier); @@ -176,6 +180,8 @@ static int mxs_phy_remove(struct platform_device *pdev) usb_remove_phy(&mxs_phy->phy); + platform_set_drvdata(pdev, NULL); + return 0; } diff --git a/trunk/drivers/usb/phy/phy-nop.c b/trunk/drivers/usb/phy/phy-nop.c index 638cc5dade35..2b10cc969bbb 100644 --- a/trunk/drivers/usb/phy/phy-nop.c +++ b/trunk/drivers/usb/phy/phy-nop.c @@ -254,6 +254,8 @@ static int nop_usb_xceiv_remove(struct platform_device *pdev) usb_remove_phy(&nop->phy); + platform_set_drvdata(pdev, NULL); + return 0; } diff --git a/trunk/drivers/usb/phy/phy-samsung-usb2.c b/trunk/drivers/usb/phy/phy-samsung-usb2.c index 9d5e273abcc7..45ffe036dacc 100644 --- a/trunk/drivers/usb/phy/phy-samsung-usb2.c +++ b/trunk/drivers/usb/phy/phy-samsung-usb2.c @@ -363,6 +363,11 @@ static int samsung_usb2phy_probe(struct platform_device *pdev) int ret; phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!phy_mem) { + dev_err(dev, "%s: missing mem resource\n", __func__); + return -ENODEV; + } + phy_base = devm_ioremap_resource(dev, phy_mem); if (IS_ERR(phy_base)) return PTR_ERR(phy_base); diff --git a/trunk/drivers/usb/phy/phy-samsung-usb3.c b/trunk/drivers/usb/phy/phy-samsung-usb3.c index 5a9efcbcb532..133f3d0c554f 100644 --- a/trunk/drivers/usb/phy/phy-samsung-usb3.c +++ b/trunk/drivers/usb/phy/phy-samsung-usb3.c @@ -239,6 +239,11 @@ static int samsung_usb3phy_probe(struct platform_device *pdev) int ret; phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!phy_mem) { + dev_err(dev, "%s: missing mem resource\n", __func__); + return -ENODEV; + } + phy_base = devm_ioremap_resource(dev, phy_mem); if (IS_ERR(phy_base)) return PTR_ERR(phy_base); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 7260ec660347..242b5776648a 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -189,8 +189,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) }, { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, - { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) }, - { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, @@ -926,8 +924,8 @@ static int ftdi_tiocmset(struct tty_struct *tty, static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void ftdi_break_ctl(struct tty_struct *tty, int break_state); -static bool ftdi_tx_empty(struct usb_serial_port *port); -static int ftdi_get_modem_status(struct usb_serial_port *port, +static int ftdi_chars_in_buffer(struct tty_struct *tty); +static int ftdi_get_modem_status(struct tty_struct *tty, unsigned char status[2]); static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); @@ -963,7 +961,7 @@ static struct usb_serial_driver ftdi_sio_device = { .ioctl = ftdi_ioctl, .set_termios = ftdi_set_termios, .break_ctl = ftdi_break_ctl, - .tx_empty = ftdi_tx_empty, + .chars_in_buffer = ftdi_chars_in_buffer, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -2058,18 +2056,27 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) } -static bool ftdi_tx_empty(struct usb_serial_port *port) +static int ftdi_chars_in_buffer(struct tty_struct *tty) { + struct usb_serial_port *port = tty->driver_data; + int chars; unsigned char buf[2]; int ret; - ret = ftdi_get_modem_status(port, buf); + chars = usb_serial_generic_chars_in_buffer(tty); + if (chars) + goto out; + + /* Check if hardware buffer is empty. */ + ret = ftdi_get_modem_status(tty, buf); if (ret == 2) { if (!(buf[1] & FTDI_RS_TEMT)) - return false; + chars = 1; } +out: + dev_dbg(&port->dev, "%s - %d\n", __func__, chars); - return true; + return chars; } /* old_termios contains the original termios settings and tty->termios contains @@ -2261,9 +2268,10 @@ static void ftdi_set_termios(struct tty_struct *tty, * Returns the number of status bytes retrieved (device dependant), or * negative error code. */ -static int ftdi_get_modem_status(struct usb_serial_port *port, +static int ftdi_get_modem_status(struct tty_struct *tty, unsigned char status[2]) { + struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); unsigned char *buf; int len; @@ -2328,7 +2336,7 @@ static int ftdi_tiocmget(struct tty_struct *tty) unsigned char buf[2]; int ret; - ret = ftdi_get_modem_status(port, buf); + ret = ftdi_get_modem_status(tty, buf); if (ret < 0) return ret; diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index 6dd79253205d..98528270c43c 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -772,8 +772,6 @@ */ #define NEWPORT_VID 0x104D #define NEWPORT_AGILIS_PID 0x3000 -#define NEWPORT_CONEX_CC_PID 0x3002 -#define NEWPORT_CONEX_AGP_PID 0x3006 /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index ba45170c78e5..297665fdd16d 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -253,37 +253,6 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) } EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer); -void usb_serial_generic_wait_until_sent(struct tty_struct *tty, long timeout) -{ - struct usb_serial_port *port = tty->driver_data; - unsigned int bps; - unsigned long period; - unsigned long expire; - - bps = tty_get_baud_rate(tty); - if (!bps) - bps = 9600; /* B0 */ - /* - * Use a poll-period of roughly the time it takes to send one - * character or at least one jiffy. - */ - period = max_t(unsigned long, (10 * HZ / bps), 1); - period = min_t(unsigned long, period, timeout); - - dev_dbg(&port->dev, "%s - timeout = %u ms, period = %u ms\n", - __func__, jiffies_to_msecs(timeout), - jiffies_to_msecs(period)); - expire = jiffies + timeout; - while (!port->serial->type->tx_empty(port)) { - schedule_timeout_interruptible(period); - if (signal_pending(current)) - break; - if (time_after(jiffies, expire)) - break; - } -} -EXPORT_SYMBOL_GPL(usb_serial_generic_wait_until_sent); - static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, int index, gfp_t mem_flags) { diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 1be6ba7bee27..158bf4bc29cc 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -2019,6 +2019,8 @@ static int edge_chars_in_buffer(struct tty_struct *tty) struct edgeport_port *edge_port = usb_get_serial_port_data(port); int chars = 0; unsigned long flags; + int ret; + if (edge_port == NULL) return 0; @@ -2026,22 +2028,16 @@ static int edge_chars_in_buffer(struct tty_struct *tty) chars = kfifo_len(&edge_port->write_fifo); spin_unlock_irqrestore(&edge_port->ep_lock, flags); + if (!chars) { + ret = tx_active(edge_port); + if (ret > 0) + chars = ret; + } + dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); return chars; } -static bool edge_tx_empty(struct usb_serial_port *port) -{ - struct edgeport_port *edge_port = usb_get_serial_port_data(port); - int ret; - - ret = tx_active(edge_port); - if (ret > 0) - return false; - - return true; -} - static void edge_throttle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; @@ -2561,7 +2557,6 @@ static struct usb_serial_driver edgeport_1port_device = { .write = edge_write, .write_room = edge_write_room, .chars_in_buffer = edge_chars_in_buffer, - .tx_empty = edge_tx_empty, .break_ctl = edge_break, .read_int_callback = edge_interrupt_callback, .read_bulk_callback = edge_bulk_in_callback, @@ -2594,7 +2589,6 @@ static struct usb_serial_driver edgeport_2port_device = { .write = edge_write, .write_room = edge_write_room, .chars_in_buffer = edge_chars_in_buffer, - .tx_empty = edge_tx_empty, .break_ctl = edge_break, .read_int_callback = edge_interrupt_callback, .read_bulk_callback = edge_bulk_in_callback, diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 93d02bc4eb52..734372846abb 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -196,7 +196,6 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ #define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ -#define DELL_PRODUCT_5804_MINICARD_ATT 0x819b /* Novatel E371 */ #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da @@ -342,8 +341,8 @@ static void option_instat_callback(struct urb *urb); #define CINTERION_PRODUCT_EU3_E 0x0051 #define CINTERION_PRODUCT_EU3_P 0x0052 #define CINTERION_PRODUCT_PH8 0x0053 -#define CINTERION_PRODUCT_AHXX 0x0055 -#define CINTERION_PRODUCT_PLXX 0x0060 +#define CINTERION_PRODUCT_AH6 0x0055 +#define CINTERION_PRODUCT_PLS8 0x0060 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -772,7 +771,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5804_MINICARD_ATT, 0xff, 0xff, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -968,8 +966,6 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */ - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), @@ -1268,9 +1264,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), - .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index c92c5ed4e580..cac47aef2918 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -101,7 +101,6 @@ static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *data, int count); static int ti_write_room(struct tty_struct *tty); static int ti_chars_in_buffer(struct tty_struct *tty); -static bool ti_tx_empty(struct usb_serial_port *port); static void ti_throttle(struct tty_struct *tty); static void ti_unthrottle(struct tty_struct *tty); static int ti_ioctl(struct tty_struct *tty, @@ -223,7 +222,6 @@ static struct usb_serial_driver ti_1port_device = { .write = ti_write, .write_room = ti_write_room, .chars_in_buffer = ti_chars_in_buffer, - .tx_empty = ti_tx_empty, .throttle = ti_throttle, .unthrottle = ti_unthrottle, .ioctl = ti_ioctl, @@ -255,7 +253,6 @@ static struct usb_serial_driver ti_2port_device = { .write = ti_write, .write_room = ti_write_room, .chars_in_buffer = ti_chars_in_buffer, - .tx_empty = ti_tx_empty, .throttle = ti_throttle, .unthrottle = ti_unthrottle, .ioctl = ti_ioctl, @@ -687,6 +684,8 @@ static int ti_chars_in_buffer(struct tty_struct *tty) struct ti_port *tport = usb_get_serial_port_data(port); int chars = 0; unsigned long flags; + int ret; + u8 lsr; if (tport == NULL) return 0; @@ -695,22 +694,16 @@ static int ti_chars_in_buffer(struct tty_struct *tty) chars = kfifo_len(&tport->write_fifo); spin_unlock_irqrestore(&tport->tp_lock, flags); + if (!chars) { + ret = ti_get_lsr(tport, &lsr); + if (!ret && !(lsr & TI_LSR_TX_EMPTY)) + chars = 1; + } + dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); return chars; } -static bool ti_tx_empty(struct usb_serial_port *port) -{ - struct ti_port *tport = usb_get_serial_port_data(port); - int ret; - u8 lsr; - - ret = ti_get_lsr(tport, &lsr); - if (!ret && !(lsr & TI_LSR_TX_EMPTY)) - return false; - - return true; -} static void ti_throttle(struct tty_struct *tty) { diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 4753c005cfb6..cf75beb1251b 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -359,29 +359,20 @@ static int serial_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; + int count = 0; dev_dbg(tty->dev, "%s\n", __func__); - if (serial->disconnected) - return 0; - - return serial->type->chars_in_buffer(tty); -} - -static void serial_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct usb_serial_port *port = tty->driver_data; - struct usb_serial *serial = port->serial; - - dev_dbg(tty->dev, "%s\n", __func__); - - if (!port->serial->type->wait_until_sent) - return; - mutex_lock(&serial->disc_mutex); - if (!serial->disconnected) - port->serial->type->wait_until_sent(tty, timeout); + /* if the device was unplugged then any remaining characters + fell out of the connector ;) */ + if (serial->disconnected) + count = 0; + else + count = serial->type->chars_in_buffer(tty); mutex_unlock(&serial->disc_mutex); + + return count; } static void serial_throttle(struct tty_struct *tty) @@ -1200,7 +1191,6 @@ static const struct tty_operations serial_ops = { .unthrottle = serial_unthrottle, .break_ctl = serial_break, .chars_in_buffer = serial_chars_in_buffer, - .wait_until_sent = serial_wait_until_sent, .tiocmget = serial_tiocmget, .tiocmset = serial_tiocmset, .get_icount = serial_get_icount, @@ -1326,8 +1316,6 @@ static void usb_serial_operations_init(struct usb_serial_driver *device) set_to_generic_if_null(device, close); set_to_generic_if_null(device, write_room); set_to_generic_if_null(device, chars_in_buffer); - if (device->tx_empty) - set_to_generic_if_null(device, wait_until_sent); set_to_generic_if_null(device, read_bulk_callback); set_to_generic_if_null(device, write_bulk_callback); set_to_generic_if_null(device, process_read_urb); diff --git a/trunk/drivers/usb/storage/realtek_cr.c b/trunk/drivers/usb/storage/realtek_cr.c index 281be56d5648..8623577bbbe7 100644 --- a/trunk/drivers/usb/storage/realtek_cr.c +++ b/trunk/drivers/usb/storage/realtek_cr.c @@ -105,9 +105,8 @@ struct rts51x_chip { int status_len; u32 flag; - struct us_data *us; - #ifdef CONFIG_REALTEK_AUTOPM + struct us_data *us; struct timer_list rts51x_suspend_timer; unsigned long timer_expires; int pwr_state; @@ -989,7 +988,6 @@ static int init_realtek_cr(struct us_data *us) us->extra = chip; us->extra_destructor = realtek_cr_destructor; us->max_lun = chip->max_lun = rts51x_get_max_lun(us); - chip->us = us; usb_stor_dbg(us, "chip->max_lun = %d\n", chip->max_lun); @@ -1012,8 +1010,10 @@ static int init_realtek_cr(struct us_data *us) SET_AUTO_DELINK(chip); } #ifdef CONFIG_REALTEK_AUTOPM - if (ss_en) + if (ss_en) { + chip->us = us; realtek_cr_autosuspend_setup(us); + } #endif usb_stor_dbg(us, "chip->flag = 0x%x\n", chip->flag); diff --git a/trunk/drivers/video/console/Makefile b/trunk/drivers/video/console/Makefile index 48da25c96cd3..a862e9173ebe 100644 --- a/trunk/drivers/video/console/Makefile +++ b/trunk/drivers/video/console/Makefile @@ -18,8 +18,6 @@ font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o font-objs += $(font-objs-y) -obj-$(CONFIG_FONTS) += font.o - # Each configuration option enables a list of files. obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o diff --git a/trunk/drivers/video/omap2/dss/hdmi.c b/trunk/drivers/video/omap2/dss/hdmi.c index a109934c0478..17f4d55c621c 100644 --- a/trunk/drivers/video/omap2/dss/hdmi.c +++ b/trunk/drivers/video/omap2/dss/hdmi.c @@ -1065,6 +1065,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) mutex_init(&hdmi.ip_data.lock); res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); + if (!res) { + DSSERR("can't get IORESOURCE_MEM HDMI\n"); + return -EINVAL; + } /* Base address taken from platform */ hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res); diff --git a/trunk/drivers/video/omap2/vrfb.c b/trunk/drivers/video/omap2/vrfb.c index f346b02eee1d..5261229c79af 100644 --- a/trunk/drivers/video/omap2/vrfb.c +++ b/trunk/drivers/video/omap2/vrfb.c @@ -353,6 +353,11 @@ static int __init vrfb_probe(struct platform_device *pdev) /* first resource is the register res, the rest are vrfb contexts */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "can't get vrfb base address\n"); + return -EINVAL; + } + vrfb_base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(vrfb_base)) return PTR_ERR(vrfb_base); diff --git a/trunk/drivers/w1/masters/omap_hdq.c b/trunk/drivers/w1/masters/omap_hdq.c index 6e94d8dd3d00..db2390aed387 100644 --- a/trunk/drivers/w1/masters/omap_hdq.c +++ b/trunk/drivers/w1/masters/omap_hdq.c @@ -555,6 +555,11 @@ static int omap_hdq_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hdq_data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_dbg(&pdev->dev, "unable to get resource\n"); + return -ENXIO; + } + hdq_data->hdq_base = devm_ioremap_resource(dev, res); if (IS_ERR(hdq_data->hdq_base)) return PTR_ERR(hdq_data->hdq_base); diff --git a/trunk/drivers/watchdog/ath79_wdt.c b/trunk/drivers/watchdog/ath79_wdt.c index 37cb09b27b63..d184c48a0482 100644 --- a/trunk/drivers/watchdog/ath79_wdt.c +++ b/trunk/drivers/watchdog/ath79_wdt.c @@ -248,6 +248,11 @@ static int ath79_wdt_probe(struct platform_device *pdev) return -EBUSY; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no memory resource found\n"); + return -EINVAL; + } + wdt_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(wdt_base)) return PTR_ERR(wdt_base); diff --git a/trunk/drivers/watchdog/davinci_wdt.c b/trunk/drivers/watchdog/davinci_wdt.c index bead7740c86a..100d4fbfde2a 100644 --- a/trunk/drivers/watchdog/davinci_wdt.c +++ b/trunk/drivers/watchdog/davinci_wdt.c @@ -217,6 +217,11 @@ static int davinci_wdt_probe(struct platform_device *pdev) dev_info(dev, "heartbeat %d sec\n", heartbeat); wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (wdt_mem == NULL) { + dev_err(dev, "failed to get memory region resource\n"); + return -ENOENT; + } + wdt_base = devm_ioremap_resource(dev, wdt_mem); if (IS_ERR(wdt_base)) return PTR_ERR(wdt_base); diff --git a/trunk/drivers/watchdog/imx2_wdt.c b/trunk/drivers/watchdog/imx2_wdt.c index 62946c2cb4f8..ff908823688c 100644 --- a/trunk/drivers/watchdog/imx2_wdt.c +++ b/trunk/drivers/watchdog/imx2_wdt.c @@ -257,6 +257,11 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "can't get device resources\n"); + return -ENODEV; + } + imx2_wdt.base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(imx2_wdt.base)) return PTR_ERR(imx2_wdt.base); diff --git a/trunk/drivers/xen/Kconfig b/trunk/drivers/xen/Kconfig index 9e02d60a364b..f03bf501527f 100644 --- a/trunk/drivers/xen/Kconfig +++ b/trunk/drivers/xen/Kconfig @@ -19,10 +19,11 @@ config XEN_SELFBALLOONING by the current usage of anonymous memory ("committed AS") and controlled by various sysfs-settable parameters. Configuring FRONTSWAP is highly recommended; if it is not configured, self- - ballooning is disabled by default. If FRONTSWAP is configured, + ballooning is disabled by default but can be enabled with the + 'selfballooning' kernel boot parameter. If FRONTSWAP is configured, frontswap-selfshrinking is enabled by default but can be disabled - with the 'tmem.selfshrink=0' kernel boot parameter; and self-ballooning - is enabled by default but can be disabled with the 'tmem.selfballooning=0' + with the 'noselfshrink' kernel boot parameter; and self-ballooning + is enabled by default but can be disabled with the 'noselfballooning' kernel boot parameter. Note that systems without a sufficiently large swap device should not enable self-ballooning. diff --git a/trunk/drivers/xen/balloon.c b/trunk/drivers/xen/balloon.c index 930fb6817901..a56776dbe095 100644 --- a/trunk/drivers/xen/balloon.c +++ b/trunk/drivers/xen/balloon.c @@ -407,8 +407,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) nr_pages = ARRAY_SIZE(frame_list); for (i = 0; i < nr_pages; i++) { - page = alloc_page(gfp); - if (page == NULL) { + if ((page = alloc_page(gfp)) == NULL) { nr_pages = i; state = BP_EAGAIN; break; diff --git a/trunk/drivers/xen/privcmd.c b/trunk/drivers/xen/privcmd.c index 2cfc24d76fc5..ca2b00e9d558 100644 --- a/trunk/drivers/xen/privcmd.c +++ b/trunk/drivers/xen/privcmd.c @@ -504,7 +504,7 @@ static void privcmd_close(struct vm_area_struct *vma) struct page **pages = vma->vm_private_data; int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages) + if (!xen_feature(XENFEAT_auto_translated_physmap || !numpgs || !pages)) return; xen_unmap_domain_mfn_range(vma, numpgs, pages); diff --git a/trunk/drivers/xen/tmem.c b/trunk/drivers/xen/tmem.c index 18e8bd8fa947..e3600be4e7fa 100644 --- a/trunk/drivers/xen/tmem.c +++ b/trunk/drivers/xen/tmem.c @@ -11,7 +11,11 @@ #include #include #include + +/* temporary ifdef until include/linux/frontswap.h is upstream */ +#ifdef CONFIG_FRONTSWAP #include +#endif #include #include @@ -20,34 +24,6 @@ #include #include -#ifndef CONFIG_XEN_TMEM_MODULE -bool __read_mostly tmem_enabled = false; - -static int __init enable_tmem(char *s) -{ - tmem_enabled = true; - return 1; -} -__setup("tmem", enable_tmem); -#endif - -#ifdef CONFIG_CLEANCACHE -static bool cleancache __read_mostly = true; -module_param(cleancache, bool, S_IRUGO); -static bool selfballooning __read_mostly = true; -module_param(selfballooning, bool, S_IRUGO); -#endif /* CONFIG_CLEANCACHE */ - -#ifdef CONFIG_FRONTSWAP -static bool frontswap __read_mostly = true; -module_param(frontswap, bool, S_IRUGO); -#endif /* CONFIG_FRONTSWAP */ - -#ifdef CONFIG_XEN_SELFBALLOONING -static bool selfshrinking __read_mostly = true; -module_param(selfshrinking, bool, S_IRUGO); -#endif /* CONFIG_XEN_SELFBALLOONING */ - #define TMEM_CONTROL 0 #define TMEM_NEW_POOL 1 #define TMEM_DESTROY_POOL 2 @@ -153,6 +129,16 @@ static int xen_tmem_flush_object(u32 pool_id, struct tmem_oid oid) return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0); } +#ifndef CONFIG_XEN_TMEM_MODULE +bool __read_mostly tmem_enabled = false; + +static int __init enable_tmem(char *s) +{ + tmem_enabled = true; + return 1; +} +__setup("tmem", enable_tmem); +#endif #ifdef CONFIG_CLEANCACHE static int xen_tmem_destroy_pool(u32 pool_id) @@ -244,6 +230,20 @@ static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize) return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize); } +static bool disable_cleancache __read_mostly; +static bool disable_selfballooning __read_mostly; +#ifdef CONFIG_XEN_TMEM_MODULE +module_param(disable_cleancache, bool, S_IRUGO); +module_param(disable_selfballooning, bool, S_IRUGO); +#else +static int __init no_cleancache(char *s) +{ + disable_cleancache = true; + return 1; +} +__setup("nocleancache", no_cleancache); +#endif + static struct cleancache_ops tmem_cleancache_ops = { .put_page = tmem_cleancache_put_page, .get_page = tmem_cleancache_get_page, @@ -361,6 +361,20 @@ static void tmem_frontswap_init(unsigned ignored) xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE); } +static bool disable_frontswap __read_mostly; +static bool disable_frontswap_selfshrinking __read_mostly; +#ifdef CONFIG_XEN_TMEM_MODULE +module_param(disable_frontswap, bool, S_IRUGO); +module_param(disable_frontswap_selfshrinking, bool, S_IRUGO); +#else +static int __init no_frontswap(char *s) +{ + disable_frontswap = true; + return 1; +} +__setup("nofrontswap", no_frontswap); +#endif + static struct frontswap_ops tmem_frontswap_ops = { .store = tmem_frontswap_store, .load = tmem_frontswap_load, @@ -368,6 +382,8 @@ static struct frontswap_ops tmem_frontswap_ops = { .invalidate_area = tmem_frontswap_flush_area, .init = tmem_frontswap_init }; +#else /* CONFIG_FRONTSWAP */ +#define disable_frontswap_selfshrinking 1 #endif static int xen_tmem_init(void) @@ -375,7 +391,7 @@ static int xen_tmem_init(void) if (!xen_domain()) return 0; #ifdef CONFIG_FRONTSWAP - if (tmem_enabled && frontswap) { + if (tmem_enabled && !disable_frontswap) { char *s = ""; struct frontswap_ops *old_ops = frontswap_register_ops(&tmem_frontswap_ops); @@ -392,7 +408,7 @@ static int xen_tmem_init(void) #endif #ifdef CONFIG_CLEANCACHE BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); - if (tmem_enabled && cleancache) { + if (tmem_enabled && !disable_cleancache) { char *s = ""; struct cleancache_ops *old_ops = cleancache_register_ops(&tmem_cleancache_ops); @@ -403,15 +419,8 @@ static int xen_tmem_init(void) } #endif #ifdef CONFIG_XEN_SELFBALLOONING - /* - * There is no point of driving pages to the swap system if they - * aren't going anywhere in tmem universe. - */ - if (!frontswap) { - selfshrinking = false; - selfballooning = false; - } - xen_selfballoon_init(selfballooning, selfshrinking); + xen_selfballoon_init(!disable_selfballooning, + !disable_frontswap_selfshrinking); #endif return 0; } diff --git a/trunk/drivers/xen/xen-selfballoon.c b/trunk/drivers/xen/xen-selfballoon.c index f70984a892aa..f2ef569c7cc1 100644 --- a/trunk/drivers/xen/xen-selfballoon.c +++ b/trunk/drivers/xen/xen-selfballoon.c @@ -53,12 +53,15 @@ * System configuration note: Selfballooning should not be enabled on * systems without a sufficiently large swap device configured; for best * results, it is recommended that total swap be increased by the size - * of the guest memory. Note, that selfballooning should be disabled by default - * if frontswap is not configured. Similarly selfballooning should be enabled - * by default if frontswap is configured and can be disabled with the - * "tmem.selfballooning=0" kernel boot option. Finally, when frontswap is - * configured, frontswap-selfshrinking can be disabled with the - * "tmem.selfshrink=0" kernel boot option. + * of the guest memory. Also, while technically not required to be + * configured, it is highly recommended that frontswap also be configured + * and enabled when selfballooning is running. So, selfballooning + * is disabled by default if frontswap is not configured and can only + * be enabled with the "selfballooning" kernel boot option; similarly + * selfballooning is enabled by default if frontswap is configured and + * can be disabled with the "noselfballooning" kernel boot option. Finally, + * when frontswap is configured, frontswap-selfshrinking can be disabled + * with the "noselfshrink" kernel boot option. * * Selfballooning is disallowed in domain0 and force-disabled. * @@ -117,6 +120,9 @@ static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); /* Enable/disable with sysfs. */ static bool frontswap_selfshrinking __read_mostly; +/* Enable/disable with kernel boot option. */ +static bool use_frontswap_selfshrink = true; + /* * The default values for the following parameters were deemed reasonable * by experimentation, may be workload-dependent, and can all be @@ -170,6 +176,35 @@ static void frontswap_selfshrink(void) frontswap_shrink(tgt_frontswap_pages); } +static int __init xen_nofrontswap_selfshrink_setup(char *s) +{ + use_frontswap_selfshrink = false; + return 1; +} + +__setup("noselfshrink", xen_nofrontswap_selfshrink_setup); + +/* Disable with kernel boot option. */ +static bool use_selfballooning = true; + +static int __init xen_noselfballooning_setup(char *s) +{ + use_selfballooning = false; + return 1; +} + +__setup("noselfballooning", xen_noselfballooning_setup); +#else /* !CONFIG_FRONTSWAP */ +/* Enable with kernel boot option. */ +static bool use_selfballooning; + +static int __init xen_selfballooning_setup(char *s) +{ + use_selfballooning = true; + return 1; +} + +__setup("selfballooning", xen_selfballooning_setup); #endif /* CONFIG_FRONTSWAP */ #define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) diff --git a/trunk/drivers/xen/xenbus/xenbus_dev_backend.c b/trunk/drivers/xen/xenbus/xenbus_dev_backend.c index a6f42fc01407..d73000800762 100644 --- a/trunk/drivers/xen/xenbus/xenbus_dev_backend.c +++ b/trunk/drivers/xen/xenbus/xenbus_dev_backend.c @@ -70,21 +70,22 @@ static long xenbus_alloc(domid_t domid) return err; } -static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, - unsigned long data) +static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned long data) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; switch (cmd) { - case IOCTL_XENBUS_BACKEND_EVTCHN: - if (xen_store_evtchn > 0) - return xen_store_evtchn; - return -ENODEV; - case IOCTL_XENBUS_BACKEND_SETUP: - return xenbus_alloc(data); - default: - return -ENOTTY; + case IOCTL_XENBUS_BACKEND_EVTCHN: + if (xen_store_evtchn > 0) + return xen_store_evtchn; + return -ENODEV; + + case IOCTL_XENBUS_BACKEND_SETUP: + return xenbus_alloc(data); + + default: + return -ENOTTY; } } diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index 290e347b6db3..b4fb41558111 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -918,8 +918,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, ref->parent, bsz, 0); if (!eb || !extent_buffer_uptodate(eb)) { free_extent_buffer(eb); - ret = -EIO; - goto out; + return -EIO; } ret = find_extent_in_eb(eb, bytenr, *extent_item_pos, &eie); diff --git a/trunk/fs/btrfs/check-integrity.c b/trunk/fs/btrfs/check-integrity.c index 1431a6965017..18af6f48781a 100644 --- a/trunk/fs/btrfs/check-integrity.c +++ b/trunk/fs/btrfs/check-integrity.c @@ -1700,7 +1700,7 @@ static int btrfsic_read_block(struct btrfsic_state *state, unsigned int j; DECLARE_COMPLETION_ONSTACK(complete); - bio = btrfs_io_bio_alloc(GFP_NOFS, num_pages - i); + bio = bio_alloc(GFP_NOFS, num_pages - i); if (!bio) { printk(KERN_INFO "btrfsic: bio_alloc() for %u pages failed!\n", diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index 02fae7f7e42c..de6de8e60b46 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -951,12 +951,10 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, BUG_ON(ret); /* -ENOMEM */ } if (new_flags != 0) { - int level = btrfs_header_level(buf); - ret = btrfs_set_disk_extent_flags(trans, root, buf->start, buf->len, - new_flags, level, 0); + new_flags, 0); if (ret) return ret; } diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index d6dd49b51ba8..63c328a9ce95 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -88,12 +88,12 @@ struct btrfs_ordered_sum; /* holds checksums of all the data extents */ #define BTRFS_CSUM_TREE_OBJECTID 7ULL -/* holds quota configuration and tracking */ -#define BTRFS_QUOTA_TREE_OBJECTID 8ULL - /* for storing balance parameters in the root tree */ #define BTRFS_BALANCE_OBJECTID -4ULL +/* holds quota configuration and tracking */ +#define BTRFS_QUOTA_TREE_OBJECTID 8ULL + /* orhpan objectid for tracking unlinked/truncated files */ #define BTRFS_ORPHAN_OBJECTID -5ULL @@ -3075,7 +3075,7 @@ int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 flags, - int level, int is_data); + int is_data); int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, diff --git a/trunk/fs/btrfs/delayed-ref.h b/trunk/fs/btrfs/delayed-ref.h index 70b962cc177d..f75fcaf79aeb 100644 --- a/trunk/fs/btrfs/delayed-ref.h +++ b/trunk/fs/btrfs/delayed-ref.h @@ -60,7 +60,6 @@ struct btrfs_delayed_ref_node { struct btrfs_delayed_extent_op { struct btrfs_disk_key key; u64 flags_to_set; - int level; unsigned int update_key:1; unsigned int update_flags:1; unsigned int is_data:1; diff --git a/trunk/fs/btrfs/dev-replace.c b/trunk/fs/btrfs/dev-replace.c index 65241f32d3f8..7ba7b3900cb8 100644 --- a/trunk/fs/btrfs/dev-replace.c +++ b/trunk/fs/btrfs/dev-replace.c @@ -313,11 +313,6 @@ int btrfs_dev_replace_start(struct btrfs_root *root, struct btrfs_device *tgt_device = NULL; struct btrfs_device *src_device = NULL; - if (btrfs_fs_incompat(fs_info, RAID56)) { - pr_warn("btrfs: dev_replace cannot yet handle RAID5/RAID6\n"); - return -EINVAL; - } - switch (args->start.cont_reading_from_srcdev_mode) { case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_ALWAYS: case BTRFS_IOCTL_DEV_REPLACE_CONT_READING_FROM_SRCDEV_MODE_AVOID: diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index e7b3cb5286a5..4e9ebe1f1827 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -152,7 +152,7 @@ static struct btrfs_lockdep_keyset { { .id = BTRFS_DEV_TREE_OBJECTID, .name_stem = "dev" }, { .id = BTRFS_FS_TREE_OBJECTID, .name_stem = "fs" }, { .id = BTRFS_CSUM_TREE_OBJECTID, .name_stem = "csum" }, - { .id = BTRFS_QUOTA_TREE_OBJECTID, .name_stem = "quota" }, + { .id = BTRFS_ORPHAN_OBJECTID, .name_stem = "orphan" }, { .id = BTRFS_TREE_LOG_OBJECTID, .name_stem = "log" }, { .id = BTRFS_TREE_RELOC_OBJECTID, .name_stem = "treloc" }, { .id = BTRFS_DATA_RELOC_TREE_OBJECTID, .name_stem = "dreloc" }, @@ -1513,6 +1513,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, } root->commit_root = btrfs_root_node(root); + BUG_ON(!root->node); /* -ENOMEM */ out: if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { root->ref_cows = 1; @@ -1987,33 +1988,30 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) { free_extent_buffer(info->tree_root->node); free_extent_buffer(info->tree_root->commit_root); - info->tree_root->node = NULL; - info->tree_root->commit_root = NULL; - - if (info->dev_root) { - free_extent_buffer(info->dev_root->node); - free_extent_buffer(info->dev_root->commit_root); - info->dev_root->node = NULL; - info->dev_root->commit_root = NULL; - } - if (info->extent_root) { - free_extent_buffer(info->extent_root->node); - free_extent_buffer(info->extent_root->commit_root); - info->extent_root->node = NULL; - info->extent_root->commit_root = NULL; - } - if (info->csum_root) { - free_extent_buffer(info->csum_root->node); - free_extent_buffer(info->csum_root->commit_root); - info->csum_root->node = NULL; - info->csum_root->commit_root = NULL; - } + free_extent_buffer(info->dev_root->node); + free_extent_buffer(info->dev_root->commit_root); + free_extent_buffer(info->extent_root->node); + free_extent_buffer(info->extent_root->commit_root); + free_extent_buffer(info->csum_root->node); + free_extent_buffer(info->csum_root->commit_root); if (info->quota_root) { free_extent_buffer(info->quota_root->node); free_extent_buffer(info->quota_root->commit_root); + } + + info->tree_root->node = NULL; + info->tree_root->commit_root = NULL; + info->dev_root->node = NULL; + info->dev_root->commit_root = NULL; + info->extent_root->node = NULL; + info->extent_root->commit_root = NULL; + info->csum_root->node = NULL; + info->csum_root->commit_root = NULL; + if (info->quota_root) { info->quota_root->node = NULL; info->quota_root->commit_root = NULL; } + if (chunk_root) { free_extent_buffer(info->chunk_root->node); free_extent_buffer(info->chunk_root->commit_root); @@ -3130,7 +3128,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait) * caller */ device->flush_bio = NULL; - bio = btrfs_io_bio_alloc(GFP_NOFS, 0); + bio = bio_alloc(GFP_NOFS, 0); if (!bio) return -ENOMEM; @@ -3661,11 +3659,8 @@ static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t, ordered_operations); list_del_init(&btrfs_inode->ordered_operations); - spin_unlock(&root->fs_info->ordered_extent_lock); btrfs_invalidate_inodes(btrfs_inode->root); - - spin_lock(&root->fs_info->ordered_extent_lock); } spin_unlock(&root->fs_info->ordered_extent_lock); @@ -3787,11 +3782,8 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) list_del_init(&btrfs_inode->delalloc_inodes); clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, &btrfs_inode->runtime_flags); - spin_unlock(&root->fs_info->delalloc_lock); btrfs_invalidate_inodes(btrfs_inode->root); - - spin_lock(&root->fs_info->delalloc_lock); } spin_unlock(&root->fs_info->delalloc_lock); @@ -3816,7 +3808,7 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root, while (start <= end) { eb = btrfs_find_tree_block(root, start, root->leafsize); - start += root->leafsize; + start += eb->len; if (!eb) continue; wait_on_extent_buffer_writeback(eb); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index df472ab1b5ac..2305b5c5cf00 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -2070,7 +2070,8 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, u32 item_size; int ret; int err = 0; - int metadata = !extent_op->is_data; + int metadata = (node->type == BTRFS_TREE_BLOCK_REF_KEY || + node->type == BTRFS_SHARED_BLOCK_REF_KEY); if (trans->aborted) return 0; @@ -2085,8 +2086,11 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, key.objectid = node->bytenr; if (metadata) { + struct btrfs_delayed_tree_ref *tree_ref; + + tree_ref = btrfs_delayed_node_to_tree_ref(node); key.type = BTRFS_METADATA_ITEM_KEY; - key.offset = extent_op->level; + key.offset = tree_ref->level; } else { key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = node->num_bytes; @@ -2715,7 +2719,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 flags, - int level, int is_data) + int is_data) { struct btrfs_delayed_extent_op *extent_op; int ret; @@ -2728,7 +2732,6 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, extent_op->update_flags = 1; extent_op->update_key = 0; extent_op->is_data = is_data ? 1 : 0; - extent_op->level = level; ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr, num_bytes, extent_op); @@ -3106,11 +3109,6 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, WARN_ON(ret); if (i_size_read(inode) > 0) { - ret = btrfs_check_trunc_cache_free_space(root, - &root->fs_info->global_block_rsv); - if (ret) - goto out_put; - ret = btrfs_truncate_free_space_cache(root, trans, path, inode); if (ret) @@ -4564,8 +4562,6 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info) fs_info->csum_root->block_rsv = &fs_info->global_block_rsv; fs_info->dev_root->block_rsv = &fs_info->global_block_rsv; fs_info->tree_root->block_rsv = &fs_info->global_block_rsv; - if (fs_info->quota_root) - fs_info->quota_root->block_rsv = &fs_info->global_block_rsv; fs_info->chunk_root->block_rsv = &fs_info->chunk_block_rsv; update_global_block_rsv(fs_info); @@ -6655,51 +6651,51 @@ use_block_rsv(struct btrfs_trans_handle *trans, struct btrfs_block_rsv *block_rsv; struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv; int ret; - bool global_updated = false; block_rsv = get_block_rsv(trans, root); - if (unlikely(block_rsv->size == 0)) - goto try_reserve; -again: - ret = block_rsv_use_bytes(block_rsv, blocksize); - if (!ret) + if (block_rsv->size == 0) { + ret = reserve_metadata_bytes(root, block_rsv, blocksize, + BTRFS_RESERVE_NO_FLUSH); + /* + * If we couldn't reserve metadata bytes try and use some from + * the global reserve. + */ + if (ret && block_rsv != global_rsv) { + ret = block_rsv_use_bytes(global_rsv, blocksize); + if (!ret) + return global_rsv; + return ERR_PTR(ret); + } else if (ret) { + return ERR_PTR(ret); + } return block_rsv; - - if (block_rsv->failfast) - return ERR_PTR(ret); - - if (block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL && !global_updated) { - global_updated = true; - update_global_block_rsv(root->fs_info); - goto again; } - if (btrfs_test_opt(root, ENOSPC_DEBUG)) { - static DEFINE_RATELIMIT_STATE(_rs, - DEFAULT_RATELIMIT_INTERVAL * 10, - /*DEFAULT_RATELIMIT_BURST*/ 1); - if (__ratelimit(&_rs)) - WARN(1, KERN_DEBUG - "btrfs: block rsv returned %d\n", ret); - } -try_reserve: - ret = reserve_metadata_bytes(root, block_rsv, blocksize, - BTRFS_RESERVE_NO_FLUSH); + ret = block_rsv_use_bytes(block_rsv, blocksize); if (!ret) return block_rsv; - /* - * If we couldn't reserve metadata bytes try and use some from - * the global reserve if its space type is the same as the global - * reservation. - */ - if (block_rsv->type != BTRFS_BLOCK_RSV_GLOBAL && - block_rsv->space_info == global_rsv->space_info) { - ret = block_rsv_use_bytes(global_rsv, blocksize); - if (!ret) - return global_rsv; + if (ret && !block_rsv->failfast) { + if (btrfs_test_opt(root, ENOSPC_DEBUG)) { + static DEFINE_RATELIMIT_STATE(_rs, + DEFAULT_RATELIMIT_INTERVAL * 10, + /*DEFAULT_RATELIMIT_BURST*/ 1); + if (__ratelimit(&_rs)) + WARN(1, KERN_DEBUG + "btrfs: block rsv returned %d\n", ret); + } + ret = reserve_metadata_bytes(root, block_rsv, blocksize, + BTRFS_RESERVE_NO_FLUSH); + if (!ret) { + return block_rsv; + } else if (ret && block_rsv != global_rsv) { + ret = block_rsv_use_bytes(global_rsv, blocksize); + if (!ret) + return global_rsv; + } } - return ERR_PTR(ret); + + return ERR_PTR(-ENOSPC); } static void unuse_block_rsv(struct btrfs_fs_info *fs_info, @@ -6767,7 +6763,6 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, extent_op->update_key = 1; extent_op->update_flags = 1; extent_op->is_data = 0; - extent_op->level = level; ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, ins.objectid, @@ -6939,8 +6934,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); BUG_ON(ret); /* -ENOMEM */ ret = btrfs_set_disk_extent_flags(trans, root, eb->start, - eb->len, flag, - btrfs_header_level(eb), 0); + eb->len, flag, 0); BUG_ON(ret); /* -ENOMEM */ wc->flags[level] |= flag; } diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index e7e7afb4a872..32d67a822e93 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -23,7 +23,6 @@ static struct kmem_cache *extent_state_cache; static struct kmem_cache *extent_buffer_cache; -static struct bio_set *btrfs_bioset; #ifdef CONFIG_BTRFS_DEBUG static LIST_HEAD(buffers); @@ -126,20 +125,10 @@ int __init extent_io_init(void) SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL); if (!extent_buffer_cache) goto free_state_cache; - - btrfs_bioset = bioset_create(BIO_POOL_SIZE, - offsetof(struct btrfs_io_bio, bio)); - if (!btrfs_bioset) - goto free_buffer_cache; return 0; -free_buffer_cache: - kmem_cache_destroy(extent_buffer_cache); - extent_buffer_cache = NULL; - free_state_cache: kmem_cache_destroy(extent_state_cache); - extent_state_cache = NULL; return -ENOMEM; } @@ -156,8 +145,6 @@ void extent_io_exit(void) kmem_cache_destroy(extent_state_cache); if (extent_buffer_cache) kmem_cache_destroy(extent_buffer_cache); - if (btrfs_bioset) - bioset_free(btrfs_bioset); } void extent_io_tree_init(struct extent_io_tree *tree, @@ -1960,6 +1947,28 @@ static void check_page_uptodate(struct extent_io_tree *tree, struct page *page) SetPageUptodate(page); } +/* + * helper function to unlock a page if all the extents in the tree + * for that page are unlocked + */ +static void check_page_locked(struct extent_io_tree *tree, struct page *page) +{ + u64 start = page_offset(page); + u64 end = start + PAGE_CACHE_SIZE - 1; + if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL)) + unlock_page(page); +} + +/* + * helper function to end page writeback if all the extents + * in the tree for that page are done with writeback + */ +static void check_page_writeback(struct extent_io_tree *tree, + struct page *page) +{ + end_page_writeback(page); +} + /* * When IO fails, either with EIO or csum verification fails, we * try other mirrors that might have a good copy of the data. This @@ -2037,7 +2046,7 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, if (btrfs_is_parity_mirror(map_tree, logical, length, mirror_num)) return 0; - bio = btrfs_io_bio_alloc(GFP_NOFS, 1); + bio = bio_alloc(GFP_NOFS, 1); if (!bio) return -EIO; bio->bi_private = &compl; @@ -2327,7 +2336,7 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page, return -EIO; } - bio = btrfs_io_bio_alloc(GFP_NOFS, 1); + bio = bio_alloc(GFP_NOFS, 1); if (!bio) { free_io_failure(inode, failrec, 0); return -EIO; @@ -2389,24 +2398,19 @@ static void end_bio_extent_writepage(struct bio *bio, int err) struct extent_io_tree *tree; u64 start; u64 end; + int whole_page; do { struct page *page = bvec->bv_page; tree = &BTRFS_I(page->mapping->host)->io_tree; - /* We always issue full-page reads, but if some block - * in a page fails to read, blk_update_request() will - * advance bv_offset and adjust bv_len to compensate. - * Print a warning for nonzero offsets, and an error - * if they don't add up to a full page. */ - if (bvec->bv_offset || bvec->bv_len != PAGE_CACHE_SIZE) - printk("%s page write in btrfs with offset %u and length %u\n", - bvec->bv_offset + bvec->bv_len != PAGE_CACHE_SIZE - ? KERN_ERR "partial" : KERN_INFO "incomplete", - bvec->bv_offset, bvec->bv_len); + start = page_offset(page) + bvec->bv_offset; + end = start + bvec->bv_len - 1; - start = page_offset(page); - end = start + bvec->bv_offset + bvec->bv_len - 1; + if (bvec->bv_offset == 0 && bvec->bv_len == PAGE_CACHE_SIZE) + whole_page = 1; + else + whole_page = 0; if (--bvec >= bio->bi_io_vec) prefetchw(&bvec->bv_page->flags); @@ -2414,7 +2418,10 @@ static void end_bio_extent_writepage(struct bio *bio, int err) if (end_extent_writepage(page, err, start, end)) continue; - end_page_writeback(page); + if (whole_page) + end_page_writeback(page); + else + check_page_writeback(tree, page); } while (bvec >= bio->bi_io_vec); bio_put(bio); @@ -2439,6 +2446,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err) struct extent_io_tree *tree; u64 start; u64 end; + int whole_page; int mirror; int ret; @@ -2449,26 +2457,19 @@ static void end_bio_extent_readpage(struct bio *bio, int err) struct page *page = bvec->bv_page; struct extent_state *cached = NULL; struct extent_state *state; - struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, " - "mirror=%lu\n", (u64)bio->bi_sector, err, - io_bio->mirror_num); + "mirror=%ld\n", (u64)bio->bi_sector, err, + (long int)bio->bi_bdev); tree = &BTRFS_I(page->mapping->host)->io_tree; - /* We always issue full-page reads, but if some block - * in a page fails to read, blk_update_request() will - * advance bv_offset and adjust bv_len to compensate. - * Print a warning for nonzero offsets, and an error - * if they don't add up to a full page. */ - if (bvec->bv_offset || bvec->bv_len != PAGE_CACHE_SIZE) - printk("%s page read in btrfs with offset %u and length %u\n", - bvec->bv_offset + bvec->bv_len != PAGE_CACHE_SIZE - ? KERN_ERR "partial" : KERN_INFO "incomplete", - bvec->bv_offset, bvec->bv_len); + start = page_offset(page) + bvec->bv_offset; + end = start + bvec->bv_len - 1; - start = page_offset(page); - end = start + bvec->bv_offset + bvec->bv_len - 1; + if (bvec->bv_offset == 0 && bvec->bv_len == PAGE_CACHE_SIZE) + whole_page = 1; + else + whole_page = 0; if (++bvec <= bvec_end) prefetchw(&bvec->bv_page->flags); @@ -2484,7 +2485,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err) } spin_unlock(&tree->lock); - mirror = io_bio->mirror_num; + mirror = (int)(unsigned long)bio->bi_bdev; if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { ret = tree->ops->readpage_end_io_hook(page, start, end, state, mirror); @@ -2527,35 +2528,39 @@ static void end_bio_extent_readpage(struct bio *bio, int err) } unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC); - if (uptodate) { - SetPageUptodate(page); + if (whole_page) { + if (uptodate) { + SetPageUptodate(page); + } else { + ClearPageUptodate(page); + SetPageError(page); + } + unlock_page(page); } else { - ClearPageUptodate(page); - SetPageError(page); + if (uptodate) { + check_page_uptodate(tree, page); + } else { + ClearPageUptodate(page); + SetPageError(page); + } + check_page_locked(tree, page); } - unlock_page(page); } while (bvec <= bvec_end); bio_put(bio); } -/* - * this allocates from the btrfs_bioset. We're returning a bio right now - * but you can call btrfs_io_bio for the appropriate container_of magic - */ struct bio * btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, gfp_t gfp_flags) { struct bio *bio; - bio = bio_alloc_bioset(gfp_flags, nr_vecs, btrfs_bioset); + bio = bio_alloc(gfp_flags, nr_vecs); if (bio == NULL && (current->flags & PF_MEMALLOC)) { - while (!bio && (nr_vecs /= 2)) { - bio = bio_alloc_bioset(gfp_flags, - nr_vecs, btrfs_bioset); - } + while (!bio && (nr_vecs /= 2)) + bio = bio_alloc(gfp_flags, nr_vecs); } if (bio) { @@ -2566,19 +2571,6 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, return bio; } -struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask) -{ - return bio_clone_bioset(bio, gfp_mask, btrfs_bioset); -} - - -/* this also allocates from the btrfs_bioset */ -struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs) -{ - return bio_alloc_bioset(gfp_mask, nr_iovecs, btrfs_bioset); -} - - static int __must_check submit_one_bio(int rw, struct bio *bio, int mirror_num, unsigned long bio_flags) { @@ -3996,7 +3988,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, last_for_get_extent = isize; } - lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len - 1, 0, + lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, &cached_state); em = get_extent_skip_holes(inode, start, last_for_get_extent, @@ -4083,7 +4075,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, out_free: free_extent_map(em); out: - unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len - 1, + unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len, &cached_state, GFP_NOFS); return ret; } diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index 41fb81e7ec53..a2c03a175009 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -336,8 +336,6 @@ int extent_clear_unlock_delalloc(struct inode *inode, struct bio * btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, gfp_t gfp_flags); -struct bio *btrfs_io_bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs); -struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask); struct btrfs_fs_info; diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index e53009657f0e..ecca6c7375a6 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -197,33 +197,31 @@ int create_free_space_inode(struct btrfs_root *root, block_group->key.objectid); } -int btrfs_check_trunc_cache_free_space(struct btrfs_root *root, - struct btrfs_block_rsv *rsv) -{ - u64 needed_bytes; - int ret; - - /* 1 for slack space, 1 for updating the inode */ - needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) + - btrfs_calc_trans_metadata_size(root, 1); - - spin_lock(&rsv->lock); - if (rsv->reserved < needed_bytes) - ret = -ENOSPC; - else - ret = 0; - spin_unlock(&rsv->lock); - return 0; -} - int btrfs_truncate_free_space_cache(struct btrfs_root *root, struct btrfs_trans_handle *trans, struct btrfs_path *path, struct inode *inode) { + struct btrfs_block_rsv *rsv; + u64 needed_bytes; loff_t oldsize; int ret = 0; + rsv = trans->block_rsv; + trans->block_rsv = &root->fs_info->global_block_rsv; + + /* 1 for slack space, 1 for updating the inode */ + needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) + + btrfs_calc_trans_metadata_size(root, 1); + + spin_lock(&trans->block_rsv->lock); + if (trans->block_rsv->reserved < needed_bytes) { + spin_unlock(&trans->block_rsv->lock); + trans->block_rsv = rsv; + return -ENOSPC; + } + spin_unlock(&trans->block_rsv->lock); + oldsize = i_size_read(inode); btrfs_i_size_write(inode, 0); truncate_pagecache(inode, oldsize, 0); @@ -234,7 +232,9 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, */ ret = btrfs_truncate_inode_items(trans, root, inode, 0, BTRFS_EXTENT_DATA_KEY); + if (ret) { + trans->block_rsv = rsv; btrfs_abort_transaction(trans, root, ret); return ret; } @@ -242,6 +242,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, ret = btrfs_update_inode(trans, root, inode); if (ret) btrfs_abort_transaction(trans, root, ret); + trans->block_rsv = rsv; return ret; } @@ -919,8 +920,10 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, /* Make sure we can fit our crcs into the first page */ if (io_ctl.check_crcs && - (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) + (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) { + WARN_ON(1); goto out_nospc; + } io_ctl_set_generation(&io_ctl, trans->transid); diff --git a/trunk/fs/btrfs/free-space-cache.h b/trunk/fs/btrfs/free-space-cache.h index 8b7f19f44961..4dc17d8809c7 100644 --- a/trunk/fs/btrfs/free-space-cache.h +++ b/trunk/fs/btrfs/free-space-cache.h @@ -54,8 +54,6 @@ int create_free_space_inode(struct btrfs_root *root, struct btrfs_block_group_cache *block_group, struct btrfs_path *path); -int btrfs_check_trunc_cache_free_space(struct btrfs_root *root, - struct btrfs_block_rsv *rsv); int btrfs_truncate_free_space_cache(struct btrfs_root *root, struct btrfs_trans_handle *trans, struct btrfs_path *path, diff --git a/trunk/fs/btrfs/inode-map.c b/trunk/fs/btrfs/inode-map.c index 2c66ddbbe670..d26f67a59e36 100644 --- a/trunk/fs/btrfs/inode-map.c +++ b/trunk/fs/btrfs/inode-map.c @@ -429,12 +429,11 @@ int btrfs_save_ino_cache(struct btrfs_root *root, num_bytes = trans->bytes_reserved; /* * 1 item for inode item insertion if need - * 4 items for inode item update (in the worst case) - * 1 items for slack space if we need do truncation + * 3 items for inode item update (in the worst case) * 1 item for free space object * 3 items for pre-allocation */ - trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 10); + trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8); ret = btrfs_block_rsv_add(root, trans->block_rsv, trans->bytes_reserved, BTRFS_RESERVE_NO_FLUSH); @@ -469,8 +468,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root, if (i_size_read(inode) > 0) { ret = btrfs_truncate_free_space_cache(root, trans, path, inode); if (ret) { - if (ret != -ENOSPC) - btrfs_abort_transaction(trans, root, ret); + btrfs_abort_transaction(trans, root, ret); goto out_put; } } diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index af978f7682b3..9b31b3b091fc 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -715,10 +715,8 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->ram_size - 1, 0); em = alloc_extent_map(); - if (!em) { - ret = -ENOMEM; + if (!em) goto out_free_reserve; - } em->start = async_extent->start; em->len = async_extent->ram_size; em->orig_start = em->start; @@ -925,10 +923,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans, } em = alloc_extent_map(); - if (!em) { - ret = -ENOMEM; + if (!em) goto out_reserve; - } em->start = start; em->orig_start = em->start; ram_size = ins.offset; @@ -4728,7 +4724,6 @@ void btrfs_evict_inode(struct inode *inode) btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root); no_delete: - btrfs_remove_delayed_node(inode); clear_inode(inode); return; } @@ -4844,13 +4839,14 @@ static void inode_tree_add(struct inode *inode) struct rb_node **p; struct rb_node *parent; u64 ino = btrfs_ino(inode); +again: + p = &root->inode_tree.rb_node; + parent = NULL; if (inode_unhashed(inode)) return; -again: - parent = NULL; + spin_lock(&root->inode_lock); - p = &root->inode_tree.rb_node; while (*p) { parent = *p; entry = rb_entry(parent, struct btrfs_inode, rb_node); @@ -6932,11 +6928,7 @@ struct btrfs_dio_private { /* IO errors */ int errors; - /* orig_bio is our btrfs_io_bio */ struct bio *orig_bio; - - /* dio_bio came from fs/direct-io.c */ - struct bio *dio_bio; }; static void btrfs_endio_direct_read(struct bio *bio, int err) @@ -6946,7 +6938,6 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) struct bio_vec *bvec = bio->bi_io_vec; struct inode *inode = dip->inode; struct btrfs_root *root = BTRFS_I(inode)->root; - struct bio *dio_bio; u64 start; start = dip->logical_offset; @@ -6986,15 +6977,14 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, dip->logical_offset + dip->bytes - 1); - dio_bio = dip->dio_bio; + bio->bi_private = dip->private; kfree(dip); /* If we had a csum failure make sure to clear the uptodate flag */ if (err) - clear_bit(BIO_UPTODATE, &dio_bio->bi_flags); - dio_end_io(dio_bio, err); - bio_put(bio); + clear_bit(BIO_UPTODATE, &bio->bi_flags); + dio_end_io(bio, err); } static void btrfs_endio_direct_write(struct bio *bio, int err) @@ -7005,7 +6995,6 @@ static void btrfs_endio_direct_write(struct bio *bio, int err) struct btrfs_ordered_extent *ordered = NULL; u64 ordered_offset = dip->logical_offset; u64 ordered_bytes = dip->bytes; - struct bio *dio_bio; int ret; if (err) @@ -7033,15 +7022,14 @@ static void btrfs_endio_direct_write(struct bio *bio, int err) goto again; } out_done: - dio_bio = dip->dio_bio; + bio->bi_private = dip->private; kfree(dip); /* If we had an error make sure to clear the uptodate flag */ if (err) - clear_bit(BIO_UPTODATE, &dio_bio->bi_flags); - dio_end_io(dio_bio, err); - bio_put(bio); + clear_bit(BIO_UPTODATE, &bio->bi_flags); + dio_end_io(bio, err); } static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, @@ -7077,10 +7065,10 @@ static void btrfs_end_dio_bio(struct bio *bio, int err) if (!atomic_dec_and_test(&dip->pending_bios)) goto out; - if (dip->errors) { + if (dip->errors) bio_io_error(dip->orig_bio); - } else { - set_bit(BIO_UPTODATE, &dip->dio_bio->bi_flags); + else { + set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); bio_endio(dip->orig_bio, 0); } out: @@ -7255,34 +7243,25 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, return 0; } -static void btrfs_submit_direct(int rw, struct bio *dio_bio, - struct inode *inode, loff_t file_offset) +static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, + loff_t file_offset) { struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_dio_private *dip; - struct bio_vec *bvec = dio_bio->bi_io_vec; - struct bio *io_bio; + struct bio_vec *bvec = bio->bi_io_vec; int skip_sum; int write = rw & REQ_WRITE; int ret = 0; skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; - io_bio = btrfs_bio_clone(dio_bio, GFP_NOFS); - - if (!io_bio) { - ret = -ENOMEM; - goto free_ordered; - } - dip = kmalloc(sizeof(*dip), GFP_NOFS); if (!dip) { ret = -ENOMEM; - goto free_io_bio; + goto free_ordered; } - dip->private = dio_bio->bi_private; - io_bio->bi_private = dio_bio->bi_private; + dip->private = bio->bi_private; dip->inode = inode; dip->logical_offset = file_offset; @@ -7290,27 +7269,22 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio, do { dip->bytes += bvec->bv_len; bvec++; - } while (bvec <= (dio_bio->bi_io_vec + dio_bio->bi_vcnt - 1)); + } while (bvec <= (bio->bi_io_vec + bio->bi_vcnt - 1)); - dip->disk_bytenr = (u64)dio_bio->bi_sector << 9; - io_bio->bi_private = dip; + dip->disk_bytenr = (u64)bio->bi_sector << 9; + bio->bi_private = dip; dip->errors = 0; - dip->orig_bio = io_bio; - dip->dio_bio = dio_bio; + dip->orig_bio = bio; atomic_set(&dip->pending_bios, 0); if (write) - io_bio->bi_end_io = btrfs_endio_direct_write; + bio->bi_end_io = btrfs_endio_direct_write; else - io_bio->bi_end_io = btrfs_endio_direct_read; + bio->bi_end_io = btrfs_endio_direct_read; ret = btrfs_submit_direct_hook(rw, dip, skip_sum); if (!ret) return; - -free_io_bio: - bio_put(io_bio); - free_ordered: /* * If this is a write, we need to clean up the reserved space and kill @@ -7326,7 +7300,7 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio, btrfs_put_ordered_extent(ordered); btrfs_put_ordered_extent(ordered); } - bio_endio(dio_bio, ret); + bio_endio(bio, ret); } static ssize_t check_direct_IO(struct btrfs_root *root, int rw, struct kiocb *iocb, @@ -8005,6 +7979,7 @@ void btrfs_destroy_inode(struct inode *inode) inode_tree_del(inode); btrfs_drop_extent_cache(inode, 0, (u64)-1, 0); free: + btrfs_remove_delayed_node(inode); call_rcu(&inode->i_rcu, btrfs_i_callback); } diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 0f81d67cdc8d..0de4a2fcfb24 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -1801,11 +1801,7 @@ static noinline int copy_to_sk(struct btrfs_root *root, item_off = btrfs_item_ptr_offset(leaf, i); item_len = btrfs_item_size_nr(leaf, i); - btrfs_item_key_to_cpu(leaf, key, i); - if (!key_in_sk(key, sk)) - continue; - - if (sizeof(sh) + item_len > BTRFS_SEARCH_ARGS_BUFSIZE) + if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE) item_len = 0; if (sizeof(sh) + item_len + *sk_offset > @@ -1814,6 +1810,10 @@ static noinline int copy_to_sk(struct btrfs_root *root, goto overflow; } + btrfs_item_key_to_cpu(leaf, key, i); + if (!key_in_sk(key, sk)) + continue; + sh.objectid = key->objectid; sh.offset = key->offset; sh.type = key->type; diff --git a/trunk/fs/btrfs/raid56.c b/trunk/fs/btrfs/raid56.c index 0525e1389f5b..0740621daf6c 100644 --- a/trunk/fs/btrfs/raid56.c +++ b/trunk/fs/btrfs/raid56.c @@ -1050,7 +1050,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio, } /* put a new bio on the list */ - bio = btrfs_io_bio_alloc(GFP_NOFS, bio_max_len >> PAGE_SHIFT?:1); + bio = bio_alloc(GFP_NOFS, bio_max_len >> PAGE_SHIFT?:1); if (!bio) return -ENOMEM; diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index 395b82031a42..704a1b8d2a2b 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -1773,7 +1773,7 @@ int replace_path(struct btrfs_trans_handle *trans, if (!eb || !extent_buffer_uptodate(eb)) { ret = (!eb) ? -ENOMEM : -EIO; free_extent_buffer(eb); - break; + return ret; } btrfs_tree_lock(eb); if (cow) { @@ -3350,11 +3350,6 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info, } truncate: - ret = btrfs_check_trunc_cache_free_space(root, - &fs_info->global_block_rsv); - if (ret) - goto out; - path = btrfs_alloc_path(); if (!path) { ret = -ENOMEM; diff --git a/trunk/fs/btrfs/scrub.c b/trunk/fs/btrfs/scrub.c index 79bd479317cb..f489e24659a4 100644 --- a/trunk/fs/btrfs/scrub.c +++ b/trunk/fs/btrfs/scrub.c @@ -1296,7 +1296,7 @@ static void scrub_recheck_block(struct btrfs_fs_info *fs_info, } WARN_ON(!page->page); - bio = btrfs_io_bio_alloc(GFP_NOFS, 1); + bio = bio_alloc(GFP_NOFS, 1); if (!bio) { page->io_error = 1; sblock->no_io_error_seen = 0; @@ -1431,7 +1431,7 @@ static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, return -EIO; } - bio = btrfs_io_bio_alloc(GFP_NOFS, 1); + bio = bio_alloc(GFP_NOFS, 1); if (!bio) return -EIO; bio->bi_bdev = page_bad->dev->bdev; @@ -1522,7 +1522,7 @@ static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx, sbio->dev = wr_ctx->tgtdev; bio = sbio->bio; if (!bio) { - bio = btrfs_io_bio_alloc(GFP_NOFS, wr_ctx->pages_per_wr_bio); + bio = bio_alloc(GFP_NOFS, wr_ctx->pages_per_wr_bio); if (!bio) { mutex_unlock(&wr_ctx->wr_lock); return -ENOMEM; @@ -1930,7 +1930,7 @@ static int scrub_add_page_to_rd_bio(struct scrub_ctx *sctx, sbio->dev = spage->dev; bio = sbio->bio; if (!bio) { - bio = btrfs_io_bio_alloc(GFP_NOFS, sctx->pages_per_rd_bio); + bio = bio_alloc(GFP_NOFS, sctx->pages_per_rd_bio); if (!bio) return -ENOMEM; sbio->bio = bio; @@ -3307,7 +3307,7 @@ static int write_page_nocow(struct scrub_ctx *sctx, "btrfs: scrub write_page_nocow(bdev == NULL) is unexpected!\n"); return -EIO; } - bio = btrfs_io_bio_alloc(GFP_NOFS, 1); + bio = bio_alloc(GFP_NOFS, 1); if (!bio) { spin_lock(&sctx->stat_lock); sctx->stat.malloc_errors++; diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index f0857e092a3c..a4807ced23cc 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -1263,7 +1263,6 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) btrfs_dev_replace_suspend_for_unmount(fs_info); btrfs_scrub_cancel(fs_info); - btrfs_pause_balance(fs_info); ret = btrfs_commit_super(root); if (ret) diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 8bffb9174afb..0e925ced971b 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -3120,13 +3120,14 @@ int btrfs_balance(struct btrfs_balance_control *bctl, allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE; if (num_devices == 1) allowed |= BTRFS_BLOCK_GROUP_DUP; - else if (num_devices > 1) + else if (num_devices < 4) allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1); - if (num_devices > 2) - allowed |= BTRFS_BLOCK_GROUP_RAID5; - if (num_devices > 3) - allowed |= (BTRFS_BLOCK_GROUP_RAID10 | - BTRFS_BLOCK_GROUP_RAID6); + else + allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | + BTRFS_BLOCK_GROUP_RAID10 | + BTRFS_BLOCK_GROUP_RAID5 | + BTRFS_BLOCK_GROUP_RAID6); + if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && (!alloc_profile_is_valid(bctl->data.target, 1) || (bctl->data.target & ~allowed))) { @@ -5018,16 +5019,42 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, return 0; } +static void *merge_stripe_index_into_bio_private(void *bi_private, + unsigned int stripe_index) +{ + /* + * with single, dup, RAID0, RAID1 and RAID10, stripe_index is + * at most 1. + * The alternative solution (instead of stealing bits from the + * pointer) would be to allocate an intermediate structure + * that contains the old private pointer plus the stripe_index. + */ + BUG_ON((((uintptr_t)bi_private) & 3) != 0); + BUG_ON(stripe_index > 3); + return (void *)(((uintptr_t)bi_private) | stripe_index); +} + +static struct btrfs_bio *extract_bbio_from_bio_private(void *bi_private) +{ + return (struct btrfs_bio *)(((uintptr_t)bi_private) & ~((uintptr_t)3)); +} + +static unsigned int extract_stripe_index_from_bio_private(void *bi_private) +{ + return (unsigned int)((uintptr_t)bi_private) & 3; +} + static void btrfs_end_bio(struct bio *bio, int err) { - struct btrfs_bio *bbio = bio->bi_private; + struct btrfs_bio *bbio = extract_bbio_from_bio_private(bio->bi_private); int is_orig_bio = 0; if (err) { atomic_inc(&bbio->error); if (err == -EIO || err == -EREMOTEIO) { unsigned int stripe_index = - btrfs_io_bio(bio)->stripe_index; + extract_stripe_index_from_bio_private( + bio->bi_private); struct btrfs_device *dev; BUG_ON(stripe_index >= bbio->num_stripes); @@ -5057,7 +5084,8 @@ static void btrfs_end_bio(struct bio *bio, int err) } bio->bi_private = bbio->private; bio->bi_end_io = bbio->end_io; - btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; + bio->bi_bdev = (struct block_device *) + (unsigned long)bbio->mirror_num; /* only send an error to the higher layers if it is * beyond the tolerance of the btrfs bio */ @@ -5183,7 +5211,8 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio, struct btrfs_device *dev = bbio->stripes[dev_nr].dev; bio->bi_private = bbio; - btrfs_io_bio(bio)->stripe_index = dev_nr; + bio->bi_private = merge_stripe_index_into_bio_private( + bio->bi_private, (unsigned int)dev_nr); bio->bi_end_io = btrfs_end_bio; bio->bi_sector = physical >> 9; #ifdef DEBUG @@ -5244,7 +5273,8 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical) if (atomic_dec_and_test(&bbio->stripes_pending)) { bio->bi_private = bbio->private; bio->bi_end_io = bbio->end_io; - btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; + bio->bi_bdev = (struct block_device *) + (unsigned long)bbio->mirror_num; bio->bi_sector = logical >> 9; kfree(bbio); bio_endio(bio, -EIO); @@ -5322,7 +5352,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, } if (dev_nr < total_devs - 1) { - bio = btrfs_bio_clone(first_bio, GFP_NOFS); + bio = bio_clone(first_bio, GFP_NOFS); BUG_ON(!bio); /* -ENOMEM */ } else { bio = first_bio; diff --git a/trunk/fs/btrfs/volumes.h b/trunk/fs/btrfs/volumes.h index f6247e2a47f7..845ccbb0d2e3 100644 --- a/trunk/fs/btrfs/volumes.h +++ b/trunk/fs/btrfs/volumes.h @@ -152,26 +152,6 @@ struct btrfs_fs_devices { int rotating; }; -/* - * we need the mirror number and stripe index to be passed around - * the call chain while we are processing end_io (especially errors). - * Really, what we need is a btrfs_bio structure that has this info - * and is properly sized with its stripe array, but we're not there - * quite yet. We have our own btrfs bioset, and all of the bios - * we allocate are actually btrfs_io_bios. We'll cram as much of - * struct btrfs_bio as we can into this over time. - */ -struct btrfs_io_bio { - unsigned long mirror_num; - unsigned long stripe_index; - struct bio bio; -}; - -static inline struct btrfs_io_bio *btrfs_io_bio(struct bio *bio) -{ - return container_of(bio, struct btrfs_io_bio, bio); -} - struct btrfs_bio_stripe { struct btrfs_device *dev; u64 physical; diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 5aae3d12d400..0aabb344b02e 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -209,6 +209,7 @@ typedef struct ext4_io_end { ssize_t size; /* size of the extent */ struct kiocb *iocb; /* iocb struct for AIO */ int result; /* error value for AIO */ + atomic_t count; /* reference counter */ } ext4_io_end_t; struct ext4_io_submit { @@ -2650,11 +2651,14 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, /* page-io.c */ extern int __init ext4_init_pageio(void); -extern void ext4_add_complete_io(ext4_io_end_t *io_end); extern void ext4_exit_pageio(void); extern void ext4_ioend_shutdown(struct inode *); -extern void ext4_free_io_end(ext4_io_end_t *io); extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); +extern ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end); +extern int ext4_put_io_end(ext4_io_end_t *io_end); +extern void ext4_put_io_end_defer(ext4_io_end_t *io_end); +extern void ext4_io_submit_init(struct ext4_io_submit *io, + struct writeback_control *wbc); extern void ext4_end_io_work(struct work_struct *work); extern void ext4_io_submit(struct ext4_io_submit *io); extern int ext4_bio_write_page(struct ext4_io_submit *io, diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index bc0f1910b9cf..107936db244e 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -3642,7 +3642,7 @@ int ext4_find_delalloc_range(struct inode *inode, { struct extent_status es; - ext4_es_find_delayed_extent_range(inode, lblk_start, lblk_end, &es); + ext4_es_find_delayed_extent(inode, lblk_start, &es); if (es.es_len == 0) return 0; /* there is no delay extent in this tree */ else if (es.es_lblk <= lblk_start && @@ -4608,10 +4608,9 @@ static int ext4_find_delayed_extent(struct inode *inode, struct extent_status es; ext4_lblk_t block, next_del; - if (newes->es_pblk == 0) { - ext4_es_find_delayed_extent_range(inode, newes->es_lblk, - newes->es_lblk + newes->es_len - 1, &es); + ext4_es_find_delayed_extent(inode, newes->es_lblk, &es); + if (newes->es_pblk == 0) { /* * No extent in extent-tree contains block @newes->es_pblk, * then the block may stay in 1)a hole or 2)delayed-extent. @@ -4631,7 +4630,7 @@ static int ext4_find_delayed_extent(struct inode *inode, } block = newes->es_lblk + newes->es_len; - ext4_es_find_delayed_extent_range(inode, block, EXT_MAX_BLOCKS, &es); + ext4_es_find_delayed_extent(inode, block, &es); if (es.es_len == 0) next_del = EXT_MAX_BLOCKS; else diff --git a/trunk/fs/ext4/extents_status.c b/trunk/fs/ext4/extents_status.c index e6941e622d31..fe3337a85ede 100644 --- a/trunk/fs/ext4/extents_status.c +++ b/trunk/fs/ext4/extents_status.c @@ -232,16 +232,14 @@ static struct extent_status *__es_tree_search(struct rb_root *root, } /* - * ext4_es_find_delayed_extent_range: find the 1st delayed extent covering - * @es->lblk if it exists, otherwise, the next extent after @es->lblk. + * ext4_es_find_delayed_extent: find the 1st delayed extent covering @es->lblk + * if it exists, otherwise, the next extent after @es->lblk. * * @inode: the inode which owns delayed extents * @lblk: the offset where we start to search - * @end: the offset where we stop to search * @es: delayed extent that we found */ -void ext4_es_find_delayed_extent_range(struct inode *inode, - ext4_lblk_t lblk, ext4_lblk_t end, +void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk, struct extent_status *es) { struct ext4_es_tree *tree = NULL; @@ -249,8 +247,7 @@ void ext4_es_find_delayed_extent_range(struct inode *inode, struct rb_node *node; BUG_ON(es == NULL); - BUG_ON(end < lblk); - trace_ext4_es_find_delayed_extent_range_enter(inode, lblk); + trace_ext4_es_find_delayed_extent_enter(inode, lblk); read_lock(&EXT4_I(inode)->i_es_lock); tree = &EXT4_I(inode)->i_es_tree; @@ -273,10 +270,6 @@ void ext4_es_find_delayed_extent_range(struct inode *inode, if (es1 && !ext4_es_is_delayed(es1)) { while ((node = rb_next(&es1->rb_node)) != NULL) { es1 = rb_entry(node, struct extent_status, rb_node); - if (es1->es_lblk > end) { - es1 = NULL; - break; - } if (ext4_es_is_delayed(es1)) break; } @@ -292,7 +285,7 @@ void ext4_es_find_delayed_extent_range(struct inode *inode, read_unlock(&EXT4_I(inode)->i_es_lock); ext4_es_lru_add(inode); - trace_ext4_es_find_delayed_extent_range_exit(inode, es); + trace_ext4_es_find_delayed_extent_exit(inode, es); } static struct extent_status * diff --git a/trunk/fs/ext4/extents_status.h b/trunk/fs/ext4/extents_status.h index f740eb03b707..d8e2d4dc311e 100644 --- a/trunk/fs/ext4/extents_status.h +++ b/trunk/fs/ext4/extents_status.h @@ -62,8 +62,7 @@ extern int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, unsigned long long status); extern int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len); -extern void ext4_es_find_delayed_extent_range(struct inode *inode, - ext4_lblk_t lblk, ext4_lblk_t end, +extern void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk, struct extent_status *es); extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, struct extent_status *es); diff --git a/trunk/fs/ext4/file.c b/trunk/fs/ext4/file.c index b1b4d51b5d86..4959e29573b6 100644 --- a/trunk/fs/ext4/file.c +++ b/trunk/fs/ext4/file.c @@ -465,7 +465,7 @@ static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) * If there is a delay extent at this offset, * it will be as a data. */ - ext4_es_find_delayed_extent_range(inode, last, last, &es); + ext4_es_find_delayed_extent(inode, last, &es); if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { if (last != start) dataoff = last << blkbits; @@ -548,7 +548,7 @@ static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) * If there is a delay extent at this offset, * we will skip this extent. */ - ext4_es_find_delayed_extent_range(inode, last, last, &es); + ext4_es_find_delayed_extent(inode, last, &es); if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { last = es.es_lblk + es.es_len; holeoff = last << blkbits; diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index d6382b89ecbd..0723774bdfb5 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -1488,7 +1488,10 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, struct ext4_io_submit io_submit; BUG_ON(mpd->next_page <= mpd->first_page); - memset(&io_submit, 0, sizeof(io_submit)); + ext4_io_submit_init(&io_submit, mpd->wbc); + io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS); + if (!io_submit.io_end) + return -ENOMEM; /* * We need to start from the first_page to the next_page - 1 * to make sure we also write the mapped dirty buffer_heads. @@ -1576,6 +1579,8 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, pagevec_release(&pvec); } ext4_io_submit(&io_submit); + /* Drop io_end reference we got from init */ + ext4_put_io_end_defer(io_submit.io_end); return ret; } @@ -2234,9 +2239,16 @@ static int ext4_writepage(struct page *page, */ return __ext4_journalled_writepage(page, len); - memset(&io_submit, 0, sizeof(io_submit)); + ext4_io_submit_init(&io_submit, wbc); + io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS); + if (!io_submit.io_end) { + redirty_page_for_writepage(wbc, page); + return -ENOMEM; + } ret = ext4_bio_write_page(&io_submit, page, len, wbc); ext4_io_submit(&io_submit); + /* Drop io_end reference we got from init */ + ext4_put_io_end_defer(io_submit.io_end); return ret; } @@ -3067,9 +3079,13 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, struct inode *inode = file_inode(iocb->ki_filp); ext4_io_end_t *io_end = iocb->private; - /* if not async direct IO or dio with 0 bytes write, just return */ - if (!io_end || !size) - goto out; + /* if not async direct IO just return */ + if (!io_end) { + inode_dio_done(inode); + if (is_async) + aio_complete(iocb, ret, 0); + return; + } ext_debug("ext4_end_io_dio(): io_end 0x%p " "for inode %lu, iocb 0x%p, offset %llu, size %zd\n", @@ -3077,25 +3093,13 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, size); iocb->private = NULL; - - /* if not aio dio with unwritten extents, just free io and return */ - if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { - ext4_free_io_end(io_end); -out: - inode_dio_done(inode); - if (is_async) - aio_complete(iocb, ret, 0); - return; - } - io_end->offset = offset; io_end->size = size; if (is_async) { io_end->iocb = iocb; io_end->result = ret; } - - ext4_add_complete_io(io_end); + ext4_put_io_end_defer(io_end); } /* @@ -3129,6 +3133,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, get_block_t *get_block_func = NULL; int dio_flags = 0; loff_t final_size = offset + count; + ext4_io_end_t *io_end = NULL; /* Use the old path for reads and writes beyond i_size. */ if (rw != WRITE || final_size > inode->i_size) @@ -3167,13 +3172,16 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, iocb->private = NULL; ext4_inode_aio_set(inode, NULL); if (!is_sync_kiocb(iocb)) { - ext4_io_end_t *io_end = ext4_init_io_end(inode, GFP_NOFS); + io_end = ext4_init_io_end(inode, GFP_NOFS); if (!io_end) { ret = -ENOMEM; goto retake_lock; } io_end->flag |= EXT4_IO_END_DIRECT; - iocb->private = io_end; + /* + * Grab reference for DIO. Will be dropped in ext4_end_io_dio() + */ + iocb->private = ext4_get_io_end(io_end); /* * we save the io structure for current async direct * IO, so that later ext4_map_blocks() could flag the @@ -3197,26 +3205,27 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, NULL, dio_flags); - if (iocb->private) - ext4_inode_aio_set(inode, NULL); /* - * The io_end structure takes a reference to the inode, that - * structure needs to be destroyed and the reference to the - * inode need to be dropped, when IO is complete, even with 0 - * byte write, or failed. - * - * In the successful AIO DIO case, the io_end structure will - * be destroyed and the reference to the inode will be dropped - * after the end_io call back function is called. - * - * In the case there is 0 byte write, or error case, since VFS - * direct IO won't invoke the end_io call back function, we - * need to free the end_io structure here. + * Put our reference to io_end. This can free the io_end structure e.g. + * in sync IO case or in case of error. It can even perform extent + * conversion if all bios we submitted finished before we got here. + * Note that in that case iocb->private can be already set to NULL + * here. */ - if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) { - ext4_free_io_end(iocb->private); - iocb->private = NULL; - } else if (ret > 0 && !overwrite && ext4_test_inode_state(inode, + if (io_end) { + ext4_inode_aio_set(inode, NULL); + ext4_put_io_end(io_end); + /* + * In case of error or no write ext4_end_io_dio() was not + * called so we have to put iocb's reference. + */ + if (ret <= 0 && ret != -EIOCBQUEUED) { + WARN_ON(iocb->private != io_end); + ext4_put_io_end(io_end); + iocb->private = NULL; + } + } + if (ret > 0 && !overwrite && ext4_test_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN)) { int err; /* diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index def84082a9a9..b1ed9e07434b 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -2105,11 +2105,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) group = ac->ac_g_ex.fe_group; for (i = 0; i < ngroups; group++, i++) { - /* - * Artificially restricted ngroups for non-extent - * files makes group > ngroups possible on first loop. - */ - if (group >= ngroups) + if (group == ngroups) group = 0; /* This now checks without needing the buddy page */ diff --git a/trunk/fs/ext4/page-io.c b/trunk/fs/ext4/page-io.c index 4acf1f78881b..19599bded62a 100644 --- a/trunk/fs/ext4/page-io.c +++ b/trunk/fs/ext4/page-io.c @@ -62,15 +62,28 @@ void ext4_ioend_shutdown(struct inode *inode) cancel_work_sync(&EXT4_I(inode)->i_unwritten_work); } -void ext4_free_io_end(ext4_io_end_t *io) +static void ext4_release_io_end(ext4_io_end_t *io_end) { - BUG_ON(!io); - BUG_ON(!list_empty(&io->list)); - BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN); + BUG_ON(!list_empty(&io_end->list)); + BUG_ON(io_end->flag & EXT4_IO_END_UNWRITTEN); + + if (atomic_dec_and_test(&EXT4_I(io_end->inode)->i_ioend_count)) + wake_up_all(ext4_ioend_wq(io_end->inode)); + if (io_end->flag & EXT4_IO_END_DIRECT) + inode_dio_done(io_end->inode); + if (io_end->iocb) + aio_complete(io_end->iocb, io_end->result, 0); + kmem_cache_free(io_end_cachep, io_end); +} + +static void ext4_clear_io_unwritten_flag(ext4_io_end_t *io_end) +{ + struct inode *inode = io_end->inode; - if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count)) - wake_up_all(ext4_ioend_wq(io->inode)); - kmem_cache_free(io_end_cachep, io); + io_end->flag &= ~EXT4_IO_END_UNWRITTEN; + /* Wake up anyone waiting on unwritten extent conversion */ + if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten)) + wake_up_all(ext4_ioend_wq(inode)); } /* check a range of space and convert unwritten extents to written. */ @@ -93,13 +106,8 @@ static int ext4_end_io(ext4_io_end_t *io) "(inode %lu, offset %llu, size %zd, error %d)", inode->i_ino, offset, size, ret); } - /* Wake up anyone waiting on unwritten extent conversion */ - if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten)) - wake_up_all(ext4_ioend_wq(inode)); - if (io->flag & EXT4_IO_END_DIRECT) - inode_dio_done(inode); - if (io->iocb) - aio_complete(io->iocb, io->result, 0); + ext4_clear_io_unwritten_flag(io); + ext4_release_io_end(io); return ret; } @@ -130,7 +138,7 @@ static void dump_completed_IO(struct inode *inode) } /* Add the io_end to per-inode completed end_io list. */ -void ext4_add_complete_io(ext4_io_end_t *io_end) +static void ext4_add_complete_io(ext4_io_end_t *io_end) { struct ext4_inode_info *ei = EXT4_I(io_end->inode); struct workqueue_struct *wq; @@ -167,8 +175,6 @@ static int ext4_do_flush_completed_IO(struct inode *inode) err = ext4_end_io(io); if (unlikely(!ret && err)) ret = err; - io->flag &= ~EXT4_IO_END_UNWRITTEN; - ext4_free_io_end(io); } return ret; } @@ -200,10 +206,43 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) atomic_inc(&EXT4_I(inode)->i_ioend_count); io->inode = inode; INIT_LIST_HEAD(&io->list); + atomic_set(&io->count, 1); } return io; } +void ext4_put_io_end_defer(ext4_io_end_t *io_end) +{ + if (atomic_dec_and_test(&io_end->count)) { + if (!(io_end->flag & EXT4_IO_END_UNWRITTEN) || !io_end->size) { + ext4_release_io_end(io_end); + return; + } + ext4_add_complete_io(io_end); + } +} + +int ext4_put_io_end(ext4_io_end_t *io_end) +{ + int err = 0; + + if (atomic_dec_and_test(&io_end->count)) { + if (io_end->flag & EXT4_IO_END_UNWRITTEN) { + err = ext4_convert_unwritten_extents(io_end->inode, + io_end->offset, io_end->size); + ext4_clear_io_unwritten_flag(io_end); + } + ext4_release_io_end(io_end); + } + return err; +} + +ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end) +{ + atomic_inc(&io_end->count); + return io_end; +} + /* * Print an buffer I/O error compatible with the fs/buffer.c. This * provides compatibility with dmesg scrapers that look for a specific @@ -286,12 +325,7 @@ static void ext4_end_bio(struct bio *bio, int error) bi_sector >> (inode->i_blkbits - 9)); } - if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { - ext4_free_io_end(io_end); - return; - } - - ext4_add_complete_io(io_end); + ext4_put_io_end_defer(io_end); } void ext4_io_submit(struct ext4_io_submit *io) @@ -305,40 +339,37 @@ void ext4_io_submit(struct ext4_io_submit *io) bio_put(io->io_bio); } io->io_bio = NULL; - io->io_op = 0; +} + +void ext4_io_submit_init(struct ext4_io_submit *io, + struct writeback_control *wbc) +{ + io->io_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE); + io->io_bio = NULL; io->io_end = NULL; } -static int io_submit_init(struct ext4_io_submit *io, - struct inode *inode, - struct writeback_control *wbc, - struct buffer_head *bh) +static int io_submit_init_bio(struct ext4_io_submit *io, + struct buffer_head *bh) { - ext4_io_end_t *io_end; - struct page *page = bh->b_page; int nvecs = bio_get_nr_vecs(bh->b_bdev); struct bio *bio; - io_end = ext4_init_io_end(inode, GFP_NOFS); - if (!io_end) - return -ENOMEM; bio = bio_alloc(GFP_NOIO, min(nvecs, BIO_MAX_PAGES)); bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9); bio->bi_bdev = bh->b_bdev; - bio->bi_private = io->io_end = io_end; bio->bi_end_io = ext4_end_bio; - - io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); - + bio->bi_private = ext4_get_io_end(io->io_end); + if (!io->io_end->size) + io->io_end->offset = (bh->b_page->index << PAGE_CACHE_SHIFT) + + bh_offset(bh); io->io_bio = bio; - io->io_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE); io->io_next_block = bh->b_blocknr; return 0; } static int io_submit_add_bh(struct ext4_io_submit *io, struct inode *inode, - struct writeback_control *wbc, struct buffer_head *bh) { ext4_io_end_t *io_end; @@ -349,18 +380,18 @@ static int io_submit_add_bh(struct ext4_io_submit *io, ext4_io_submit(io); } if (io->io_bio == NULL) { - ret = io_submit_init(io, inode, wbc, bh); + ret = io_submit_init_bio(io, bh); if (ret) return ret; } + ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh)); + if (ret != bh->b_size) + goto submit_and_retry; io_end = io->io_end; if (test_clear_buffer_uninit(bh)) ext4_set_io_unwritten_flag(inode, io_end); - io->io_end->size += bh->b_size; + io_end->size += bh->b_size; io->io_next_block++; - ret = bio_add_page(io->io_bio, bh->b_page, bh->b_size, bh_offset(bh)); - if (ret != bh->b_size) - goto submit_and_retry; return 0; } @@ -432,7 +463,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, do { if (!buffer_async_write(bh)) continue; - ret = io_submit_add_bh(io, inode, wbc, bh); + ret = io_submit_add_bh(io, inode, bh); if (ret) { /* * We only get here on ENOMEM. Not much else diff --git a/trunk/fs/gfs2/Kconfig b/trunk/fs/gfs2/Kconfig index 5a376ab81feb..eb08c9e43c2a 100644 --- a/trunk/fs/gfs2/Kconfig +++ b/trunk/fs/gfs2/Kconfig @@ -26,7 +26,7 @@ config GFS2_FS config GFS2_FS_LOCKING_DLM bool "GFS2 DLM locking" depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \ - HOTPLUG && CONFIGFS_FS && SYSFS && (DLM=y || DLM=GFS2_FS) + HOTPLUG && DLM && CONFIGFS_FS && SYSFS help Multiple node locking module for GFS2 diff --git a/trunk/fs/gfs2/lops.c b/trunk/fs/gfs2/lops.c index 68b4c8f1fce8..c5fa758fd844 100644 --- a/trunk/fs/gfs2/lops.c +++ b/trunk/fs/gfs2/lops.c @@ -212,7 +212,7 @@ static void gfs2_end_log_write(struct bio *bio, int error) fs_err(sdp, "Error %d writing to log\n", error); } - bio_for_each_segment_all(bvec, bio, i) { + bio_for_each_segment(bvec, bio, i) { page = bvec->bv_page; if (page_has_buffers(page)) gfs2_end_log_write_bh(sdp, bvec, error); diff --git a/trunk/fs/gfs2/quota.c b/trunk/fs/gfs2/quota.c index c253b13722e8..c7c840e916f8 100644 --- a/trunk/fs/gfs2/quota.c +++ b/trunk/fs/gfs2/quota.c @@ -121,7 +121,7 @@ static u64 qd2index(struct gfs2_quota_data *qd) { struct kqid qid = qd->qd_id; return (2 * (u64)from_kqid(&init_user_ns, qid)) + - ((qid.type == USRQUOTA) ? 0 : 1); + (qid.type == USRQUOTA) ? 0 : 1; } static u64 qd2offset(struct gfs2_quota_data *qd) @@ -721,7 +721,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, goto unlock_out; } - gfs2_trans_add_data(ip->i_gl, bh); + gfs2_trans_add_meta(ip->i_gl, bh); kaddr = kmap_atomic(page); if (offset + sizeof(struct gfs2_quota) > PAGE_CACHE_SIZE) diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 5232525934ae..0c5a575b513e 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -1401,14 +1401,9 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, u32 extlen; u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved; int ret; - struct inode *inode = &ip->i_inode; - if (S_ISDIR(inode->i_mode)) - extlen = 1; - else { - extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); - extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); - } + extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); + extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen)) return; diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 64b8c7639520..5b3d2bd4813a 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -77,7 +77,7 @@ struct acpi_signal_fatal_info { /* * OSL Initialization and shutdown primitives */ -acpi_status __init acpi_os_initialize(void); +acpi_status __initdata acpi_os_initialize(void); acpi_status acpi_os_terminate(void); diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index ea69367fdd3b..b327b5a9296d 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -329,16 +329,10 @@ int acpi_processor_power_init(struct acpi_processor *pr); int acpi_processor_power_exit(struct acpi_processor *pr); int acpi_processor_cst_has_changed(struct acpi_processor *pr); int acpi_processor_hotplug(struct acpi_processor *pr); +int acpi_processor_suspend(struct device *dev); +int acpi_processor_resume(struct device *dev); extern struct cpuidle_driver acpi_idle_driver; -#ifdef CONFIG_PM_SLEEP -void acpi_processor_syscore_init(void); -void acpi_processor_syscore_exit(void); -#else -static inline void acpi_processor_syscore_init(void) {} -static inline void acpi_processor_syscore_exit(void) {} -#endif - /* in processor_thermal.c */ int acpi_processor_get_limit_info(struct acpi_processor *pr); extern const struct thermal_cooling_device_ops processor_cooling_ops; diff --git a/trunk/include/drm/drm_os_linux.h b/trunk/include/drm/drm_os_linux.h index 675ddf4b441f..393369147a2d 100644 --- a/trunk/include/drm/drm_os_linux.h +++ b/trunk/include/drm/drm_os_linux.h @@ -87,6 +87,15 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size) /** Other copying of data from kernel space */ #define DRM_COPY_TO_USER(arg1, arg2, arg3) \ copy_to_user(arg1, arg2, arg3) +/* Macros for copyfrom user, but checking readability only once */ +#define DRM_VERIFYAREA_READ( uaddr, size ) \ + (access_ok( VERIFY_READ, uaddr, size ) ? 0 : -EFAULT) +#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \ + __copy_from_user(arg1, arg2, arg3) +#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \ + __copy_to_user(arg1, arg2, arg3) +#define DRM_GET_USER_UNCHECKED(val, uaddr) \ + __get_user(val, uaddr) #define DRM_HZ HZ diff --git a/trunk/include/drm/drm_pciids.h b/trunk/include/drm/drm_pciids.h index bb1bc485390b..c2af598f701d 100644 --- a/trunk/include/drm/drm_pciids.h +++ b/trunk/include/drm/drm_pciids.h @@ -152,12 +152,6 @@ {0x1002, 0x6621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6623, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6631, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_OLAND|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6665, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x6667, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x666F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAYMAN|RADEON_NEW_MEMMAP}, \ diff --git a/trunk/include/linux/journal-head.h b/trunk/include/linux/journal-head.h index 98cd41bb39c8..13a3da25ff07 100644 --- a/trunk/include/linux/journal-head.h +++ b/trunk/include/linux/journal-head.h @@ -30,19 +30,15 @@ struct journal_head { /* * Journalling list for this buffer [jbd_lock_bh_state()] - * NOTE: We *cannot* combine this with b_modified into a bitfield - * as gcc would then (which the C standard allows but which is - * very unuseful) make 64-bit accesses to the bitfield and clobber - * b_jcount if its update races with bitfield modification. */ - unsigned b_jlist; + unsigned b_jlist:4; /* * This flag signals the buffer has been modified by * the currently running transaction * [jbd_lock_bh_state()] */ - unsigned b_modified; + unsigned b_modified:1; /* * Copy of the buffer data frozen for writing to the log. diff --git a/trunk/include/linux/kref.h b/trunk/include/linux/kref.h index 484604d184be..e15828fd71f1 100644 --- a/trunk/include/linux/kref.h +++ b/trunk/include/linux/kref.h @@ -19,7 +19,6 @@ #include #include #include -#include struct kref { atomic_t refcount; @@ -99,38 +98,6 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) return kref_sub(kref, 1, release); } -/** - * kref_put_spinlock_irqsave - decrement refcount for object. - * @kref: object. - * @release: pointer to the function that will clean up the object when the - * last reference to the object is released. - * This pointer is required, and it is not acceptable to pass kfree - * in as this function. - * @lock: lock to take in release case - * - * Behaves identical to kref_put with one exception. If the reference count - * drops to zero, the lock will be taken atomically wrt dropping the reference - * count. The release function has to call spin_unlock() without _irqrestore. - */ -static inline int kref_put_spinlock_irqsave(struct kref *kref, - void (*release)(struct kref *kref), - spinlock_t *lock) -{ - unsigned long flags; - - WARN_ON(release == NULL); - if (atomic_add_unless(&kref->refcount, -1, 1)) - return 0; - spin_lock_irqsave(lock, flags); - if (atomic_dec_and_test(&kref->refcount)) { - release(kref); - local_irq_restore(flags); - return 1; - } - spin_unlock_irqrestore(lock, flags); - return 0; -} - static inline int kref_put_mutex(struct kref *kref, void (*release)(struct kref *kref), struct mutex *lock) diff --git a/trunk/include/linux/mfd/abx500/ab8500.h b/trunk/include/linux/mfd/abx500/ab8500.h index 0390d5943ed6..fb1bf7d6a410 100644 --- a/trunk/include/linux/mfd/abx500/ab8500.h +++ b/trunk/include/linux/mfd/abx500/ab8500.h @@ -373,11 +373,13 @@ struct ab8500_sysctrl_platform_data; /** * struct ab8500_platform_data - AB8500 platform data * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used + * @pm_power_off: Should machine pm power off hook be registered or not * @init: board-specific initialization after detection of ab8500 * @regulator: machine-specific constraints for regulators */ struct ab8500_platform_data { int irq_base; + bool pm_power_off; void (*init) (struct ab8500 *); struct ab8500_regulator_platform_data *regulator; struct abx500_gpio_platform_data *gpio; diff --git a/trunk/include/linux/netfilter_ipv6.h b/trunk/include/linux/netfilter_ipv6.h index 98ffb54988b6..2d4df6ce043e 100644 --- a/trunk/include/linux/netfilter_ipv6.h +++ b/trunk/include/linux/netfilter_ipv6.h @@ -17,6 +17,22 @@ extern __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, extern int ipv6_netfilter_init(void); extern void ipv6_netfilter_fini(void); + +/* + * Hook functions for ipv6 to allow xt_* modules to be built-in even + * if IPv6 is a module. + */ +struct nf_ipv6_ops { + int (*chk_addr)(struct net *net, const struct in6_addr *addr, + const struct net_device *dev, int strict); +}; + +extern const struct nf_ipv6_ops __rcu *nf_ipv6_ops; +static inline const struct nf_ipv6_ops *nf_get_ipv6_ops(void) +{ + return rcu_dereference(nf_ipv6_ops); +} + #else /* CONFIG_NETFILTER */ static inline int ipv6_netfilter_init(void) { return 0; } static inline void ipv6_netfilter_fini(void) { return; } diff --git a/trunk/include/linux/of_platform.h b/trunk/include/linux/of_platform.h index 2a93b64a3869..3863a4dbdf18 100644 --- a/trunk/include/linux/of_platform.h +++ b/trunk/include/linux/of_platform.h @@ -11,10 +11,9 @@ * */ +#ifdef CONFIG_OF_DEVICE #include #include - -#ifdef CONFIG_OF_DEVICE #include #include #include @@ -101,7 +100,7 @@ extern int of_platform_populate(struct device_node *root, #if !defined(CONFIG_OF_ADDRESS) struct of_dev_auxdata; -struct device_node; +struct device; static inline int of_platform_populate(struct device_node *root, const struct of_device_id *matches, const struct of_dev_auxdata *lookup, diff --git a/trunk/include/linux/pci-acpi.h b/trunk/include/linux/pci-acpi.h index 170447977278..81b31613eb25 100644 --- a/trunk/include/linux/pci-acpi.h +++ b/trunk/include/linux/pci-acpi.h @@ -60,13 +60,11 @@ static inline void acpi_pci_slot_remove(struct pci_bus *bus) { } void acpiphp_init(void); void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle); void acpiphp_remove_slots(struct pci_bus *bus); -void acpiphp_check_host_bridge(acpi_handle handle); #else static inline void acpiphp_init(void) { } static inline void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) { } static inline void acpiphp_remove_slots(struct pci_bus *bus) { } -static inline void acpiphp_check_host_bridge(acpi_handle handle) { } #endif #else /* CONFIG_ACPI */ diff --git a/trunk/include/linux/pinctrl/pinconf-generic.h b/trunk/include/linux/pinctrl/pinconf-generic.h index 6aa238096622..72474e18f1e0 100644 --- a/trunk/include/linux/pinctrl/pinconf-generic.h +++ b/trunk/include/linux/pinctrl/pinconf-generic.h @@ -37,17 +37,17 @@ * if it is 0, pull-down is disabled. * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and * low, this is the most typical case and is typically achieved with two - * active transistors on the output. Setting this config will enable + * active transistors on the output. Sending this config will enabale * push-pull mode, the argument is ignored. * @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open * collector) which means it is usually wired with other output ports - * which are then pulled up with an external resistor. Setting this - * config will enable open drain mode, the argument is ignored. + * which are then pulled up with an external resistor. Sending this + * config will enabale open drain mode, the argument is ignored. * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source - * (open emitter). Setting this config will enable open drain mode, the + * (open emitter). Sending this config will enabale open drain mode, the * argument is ignored. - * @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current - * passed as argument. The argument is in mA. + * @PIN_CONFIG_DRIVE_STRENGTH: the pin will output the current passed as + * argument. The argument is in mA. * @PIN_CONFIG_INPUT_SCHMITT_ENABLE: control schmitt-trigger mode on the pin. * If the argument != 0, schmitt-trigger mode is enabled. If it's 0, * schmitt-trigger mode is disabled. diff --git a/trunk/include/linux/printk.h b/trunk/include/linux/printk.h index 22c7052e9372..6af944ab38f0 100644 --- a/trunk/include/linux/printk.h +++ b/trunk/include/linux/printk.h @@ -4,7 +4,6 @@ #include #include #include -#include extern const char linux_banner[]; extern const char linux_proc_banner[]; diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index 33bf2dfab19d..428c37a1f95c 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -305,6 +305,7 @@ struct ucred { extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred); +extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, int offset, int len); extern int csum_partial_copy_fromiovecend(unsigned char *kdata, @@ -313,6 +314,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata, unsigned int len, __wsum *csump); extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *address, int mode); +extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, int offset, int len); extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr); diff --git a/trunk/include/linux/time.h b/trunk/include/linux/time.h index d5d229b2e5af..22d81b3c955b 100644 --- a/trunk/include/linux/time.h +++ b/trunk/include/linux/time.h @@ -117,10 +117,14 @@ static inline bool timespec_valid_strict(const struct timespec *ts) extern bool persistent_clock_exist; +#ifdef ALWAYS_USE_PERSISTENT_CLOCK +#define has_persistent_clock() true +#else static inline bool has_persistent_clock(void) { return persistent_clock_exist; } +#endif extern void read_persistent_clock(struct timespec *ts); extern void read_boot_clock(struct timespec *ts); diff --git a/trunk/include/linux/uio.h b/trunk/include/linux/uio.h index c55ce243cc09..629aaf51f30b 100644 --- a/trunk/include/linux/uio.h +++ b/trunk/include/linux/uio.h @@ -35,7 +35,4 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs) } unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); - -int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); -int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); #endif diff --git a/trunk/include/linux/usb/gadget.h b/trunk/include/linux/usb/gadget.h index f1b0dca60f12..c454a88abf2e 100644 --- a/trunk/include/linux/usb/gadget.h +++ b/trunk/include/linux/usb/gadget.h @@ -563,8 +563,9 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g) } /** - * gadget_is_superspeed() - return true if the hardware handles superspeed - * @g: controller that might support superspeed + * gadget_is_superspeed() - return true if the hardware handles + * supperspeed + * @g: controller that might support supper speed */ static inline int gadget_is_superspeed(struct usb_gadget *g) { diff --git a/trunk/include/linux/usb/serial.h b/trunk/include/linux/usb/serial.h index 302ddf55d2da..b9b0f7b4e43b 100644 --- a/trunk/include/linux/usb/serial.h +++ b/trunk/include/linux/usb/serial.h @@ -268,8 +268,6 @@ struct usb_serial_driver { struct usb_serial_port *port, struct ktermios *old); void (*break_ctl)(struct tty_struct *tty, int break_state); int (*chars_in_buffer)(struct tty_struct *tty); - void (*wait_until_sent)(struct tty_struct *tty, long timeout); - bool (*tx_empty)(struct usb_serial_port *port); void (*throttle)(struct tty_struct *tty); void (*unthrottle)(struct tty_struct *tty); int (*tiocmget)(struct tty_struct *tty); @@ -329,8 +327,6 @@ extern void usb_serial_generic_close(struct usb_serial_port *port); extern int usb_serial_generic_resume(struct usb_serial *serial); extern int usb_serial_generic_write_room(struct tty_struct *tty); extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty); -extern void usb_serial_generic_wait_until_sent(struct tty_struct *tty, - long timeout); extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); diff --git a/trunk/include/linux/vt_kern.h b/trunk/include/linux/vt_kern.h index 0d33fca48774..e8d65718560b 100644 --- a/trunk/include/linux/vt_kern.h +++ b/trunk/include/linux/vt_kern.h @@ -36,7 +36,7 @@ extern int fg_console, last_console, want_console; int vc_allocate(unsigned int console); int vc_cons_allocated(unsigned int console); int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); -struct vc_data *vc_deallocate(unsigned int console); +void vc_deallocate(unsigned int console); void reset_palette(struct vc_data *vc); void do_blank_screen(int entering_gfx); void do_unblank_screen(int leaving_gfx); diff --git a/trunk/include/net/addrconf.h b/trunk/include/net/addrconf.h index 84a6440f1f19..21f702704f24 100644 --- a/trunk/include/net/addrconf.h +++ b/trunk/include/net/addrconf.h @@ -65,7 +65,7 @@ extern int addrconf_set_dstaddr(struct net *net, extern int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, - struct net_device *dev, + const struct net_device *dev, int strict); #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) diff --git a/trunk/include/target/target_core_base.h b/trunk/include/target/target_core_base.h index e773dfa5f98f..c4af592f7057 100644 --- a/trunk/include/target/target_core_base.h +++ b/trunk/include/target/target_core_base.h @@ -463,6 +463,7 @@ struct se_cmd { #define CMD_T_ABORTED (1 << 0) #define CMD_T_ACTIVE (1 << 1) #define CMD_T_COMPLETE (1 << 2) +#define CMD_T_QUEUED (1 << 3) #define CMD_T_SENT (1 << 4) #define CMD_T_STOP (1 << 5) #define CMD_T_FAILED (1 << 6) @@ -571,8 +572,12 @@ struct se_dev_entry { bool def_pr_registered; /* See transport_lunflags_table */ u32 lun_flags; + u32 deve_cmds; u32 mapped_lun; + u32 average_bytes; + u32 last_byte_count; u32 total_cmds; + u32 total_bytes; u64 pr_res_key; u64 creation_time; u32 attach_count; diff --git a/trunk/include/trace/events/ext4.h b/trunk/include/trace/events/ext4.h index 8ee15b97cd38..d0e686402df8 100644 --- a/trunk/include/trace/events/ext4.h +++ b/trunk/include/trace/events/ext4.h @@ -2139,7 +2139,7 @@ TRACE_EVENT(ext4_es_remove_extent, __entry->lblk, __entry->len) ); -TRACE_EVENT(ext4_es_find_delayed_extent_range_enter, +TRACE_EVENT(ext4_es_find_delayed_extent_enter, TP_PROTO(struct inode *inode, ext4_lblk_t lblk), TP_ARGS(inode, lblk), @@ -2161,7 +2161,7 @@ TRACE_EVENT(ext4_es_find_delayed_extent_range_enter, (unsigned long) __entry->ino, __entry->lblk) ); -TRACE_EVENT(ext4_es_find_delayed_extent_range_exit, +TRACE_EVENT(ext4_es_find_delayed_extent_exit, TP_PROTO(struct inode *inode, struct extent_status *es), TP_ARGS(inode, es), diff --git a/trunk/include/uapi/linux/virtio_console.h b/trunk/include/uapi/linux/virtio_console.h index c312f16bc4e7..ee13ab6c3614 100644 --- a/trunk/include/uapi/linux/virtio_console.h +++ b/trunk/include/uapi/linux/virtio_console.h @@ -39,7 +39,7 @@ #define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */ #define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */ -#define VIRTIO_CONSOLE_BAD_ID (~(__u32)0) +#define VIRTIO_CONSOLE_BAD_ID (~(u32)0) struct virtio_console_config { /* colums of the screens */ diff --git a/trunk/kernel/cpu/idle.c b/trunk/kernel/cpu/idle.c index d5585f5e038e..8b86c0c68edf 100644 --- a/trunk/kernel/cpu/idle.c +++ b/trunk/kernel/cpu/idle.c @@ -40,13 +40,11 @@ __setup("hlt", cpu_idle_nopoll_setup); static inline int cpu_idle_poll(void) { - rcu_idle_enter(); trace_cpu_idle_rcuidle(0, smp_processor_id()); local_irq_enable(); while (!need_resched()) cpu_relax(); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); - rcu_idle_exit(); return 1; } diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index 9dc297faf7c0..6b41c1899a8b 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -4394,64 +4394,6 @@ perf_event_read_event(struct perf_event *event, perf_output_end(&handle); } -typedef int (perf_event_aux_match_cb)(struct perf_event *event, void *data); -typedef void (perf_event_aux_output_cb)(struct perf_event *event, void *data); - -static void -perf_event_aux_ctx(struct perf_event_context *ctx, - perf_event_aux_match_cb match, - perf_event_aux_output_cb output, - void *data) -{ - struct perf_event *event; - - list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { - if (event->state < PERF_EVENT_STATE_INACTIVE) - continue; - if (!event_filter_match(event)) - continue; - if (match(event, data)) - output(event, data); - } -} - -static void -perf_event_aux(perf_event_aux_match_cb match, - perf_event_aux_output_cb output, - void *data, - struct perf_event_context *task_ctx) -{ - struct perf_cpu_context *cpuctx; - struct perf_event_context *ctx; - struct pmu *pmu; - int ctxn; - - rcu_read_lock(); - list_for_each_entry_rcu(pmu, &pmus, entry) { - cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); - if (cpuctx->unique_pmu != pmu) - goto next; - perf_event_aux_ctx(&cpuctx->ctx, match, output, data); - if (task_ctx) - goto next; - ctxn = pmu->task_ctx_nr; - if (ctxn < 0) - goto next; - ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); - if (ctx) - perf_event_aux_ctx(ctx, match, output, data); -next: - put_cpu_ptr(pmu->pmu_cpu_context); - } - - if (task_ctx) { - preempt_disable(); - perf_event_aux_ctx(task_ctx, match, output, data); - preempt_enable(); - } - rcu_read_unlock(); -} - /* * task tracking -- fork/exit * @@ -4474,9 +4416,8 @@ struct perf_task_event { }; static void perf_event_task_output(struct perf_event *event, - void *data) + struct perf_task_event *task_event) { - struct perf_task_event *task_event = data; struct perf_output_handle handle; struct perf_sample_data sample; struct task_struct *task = task_event->task; @@ -4504,11 +4445,62 @@ static void perf_event_task_output(struct perf_event *event, task_event->event_id.header.size = size; } -static int perf_event_task_match(struct perf_event *event, - void *data __maybe_unused) +static int perf_event_task_match(struct perf_event *event) +{ + if (event->state < PERF_EVENT_STATE_INACTIVE) + return 0; + + if (!event_filter_match(event)) + return 0; + + if (event->attr.comm || event->attr.mmap || + event->attr.mmap_data || event->attr.task) + return 1; + + return 0; +} + +static void perf_event_task_ctx(struct perf_event_context *ctx, + struct perf_task_event *task_event) { - return event->attr.comm || event->attr.mmap || - event->attr.mmap_data || event->attr.task; + struct perf_event *event; + + list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { + if (perf_event_task_match(event)) + perf_event_task_output(event, task_event); + } +} + +static void perf_event_task_event(struct perf_task_event *task_event) +{ + struct perf_cpu_context *cpuctx; + struct perf_event_context *ctx; + struct pmu *pmu; + int ctxn; + + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); + if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_task_ctx(&cpuctx->ctx, task_event); + + ctx = task_event->task_ctx; + if (!ctx) { + ctxn = pmu->task_ctx_nr; + if (ctxn < 0) + goto next; + ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); + if (ctx) + perf_event_task_ctx(ctx, task_event); + } +next: + put_cpu_ptr(pmu->pmu_cpu_context); + } + if (task_event->task_ctx) + perf_event_task_ctx(task_event->task_ctx, task_event); + + rcu_read_unlock(); } static void perf_event_task(struct task_struct *task, @@ -4539,10 +4531,7 @@ static void perf_event_task(struct task_struct *task, }, }; - perf_event_aux(perf_event_task_match, - perf_event_task_output, - &task_event, - task_ctx); + perf_event_task_event(&task_event); } void perf_event_fork(struct task_struct *task) @@ -4568,9 +4557,8 @@ struct perf_comm_event { }; static void perf_event_comm_output(struct perf_event *event, - void *data) + struct perf_comm_event *comm_event) { - struct perf_comm_event *comm_event = data; struct perf_output_handle handle; struct perf_sample_data sample; int size = comm_event->event_id.header.size; @@ -4597,16 +4585,39 @@ static void perf_event_comm_output(struct perf_event *event, comm_event->event_id.header.size = size; } -static int perf_event_comm_match(struct perf_event *event, - void *data __maybe_unused) +static int perf_event_comm_match(struct perf_event *event) +{ + if (event->state < PERF_EVENT_STATE_INACTIVE) + return 0; + + if (!event_filter_match(event)) + return 0; + + if (event->attr.comm) + return 1; + + return 0; +} + +static void perf_event_comm_ctx(struct perf_event_context *ctx, + struct perf_comm_event *comm_event) { - return event->attr.comm; + struct perf_event *event; + + list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { + if (perf_event_comm_match(event)) + perf_event_comm_output(event, comm_event); + } } static void perf_event_comm_event(struct perf_comm_event *comm_event) { + struct perf_cpu_context *cpuctx; + struct perf_event_context *ctx; char comm[TASK_COMM_LEN]; unsigned int size; + struct pmu *pmu; + int ctxn; memset(comm, 0, sizeof(comm)); strlcpy(comm, comm_event->task->comm, sizeof(comm)); @@ -4616,11 +4627,24 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) comm_event->comm_size = size; comm_event->event_id.header.size = sizeof(comm_event->event_id) + size; + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); + if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_comm_ctx(&cpuctx->ctx, comm_event); - perf_event_aux(perf_event_comm_match, - perf_event_comm_output, - comm_event, - NULL); + ctxn = pmu->task_ctx_nr; + if (ctxn < 0) + goto next; + + ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); + if (ctx) + perf_event_comm_ctx(ctx, comm_event); +next: + put_cpu_ptr(pmu->pmu_cpu_context); + } + rcu_read_unlock(); } void perf_event_comm(struct task_struct *task) @@ -4682,9 +4706,8 @@ struct perf_mmap_event { }; static void perf_event_mmap_output(struct perf_event *event, - void *data) + struct perf_mmap_event *mmap_event) { - struct perf_mmap_event *mmap_event = data; struct perf_output_handle handle; struct perf_sample_data sample; int size = mmap_event->event_id.header.size; @@ -4711,24 +4734,46 @@ static void perf_event_mmap_output(struct perf_event *event, } static int perf_event_mmap_match(struct perf_event *event, - void *data) + struct perf_mmap_event *mmap_event, + int executable) { - struct perf_mmap_event *mmap_event = data; - struct vm_area_struct *vma = mmap_event->vma; - int executable = vma->vm_flags & VM_EXEC; + if (event->state < PERF_EVENT_STATE_INACTIVE) + return 0; + + if (!event_filter_match(event)) + return 0; + + if ((!executable && event->attr.mmap_data) || + (executable && event->attr.mmap)) + return 1; + + return 0; +} - return (!executable && event->attr.mmap_data) || - (executable && event->attr.mmap); +static void perf_event_mmap_ctx(struct perf_event_context *ctx, + struct perf_mmap_event *mmap_event, + int executable) +{ + struct perf_event *event; + + list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { + if (perf_event_mmap_match(event, mmap_event, executable)) + perf_event_mmap_output(event, mmap_event); + } } static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) { + struct perf_cpu_context *cpuctx; + struct perf_event_context *ctx; struct vm_area_struct *vma = mmap_event->vma; struct file *file = vma->vm_file; unsigned int size; char tmp[16]; char *buf = NULL; const char *name; + struct pmu *pmu; + int ctxn; memset(tmp, 0, sizeof(tmp)); @@ -4784,10 +4829,27 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size; - perf_event_aux(perf_event_mmap_match, - perf_event_mmap_output, - mmap_event, - NULL); + rcu_read_lock(); + list_for_each_entry_rcu(pmu, &pmus, entry) { + cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); + if (cpuctx->unique_pmu != pmu) + goto next; + perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, + vma->vm_flags & VM_EXEC); + + ctxn = pmu->task_ctx_nr; + if (ctxn < 0) + goto next; + + ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); + if (ctx) { + perf_event_mmap_ctx(ctx, mmap_event, + vma->vm_flags & VM_EXEC); + } +next: + put_cpu_ptr(pmu->pmu_cpu_context); + } + rcu_read_unlock(); kfree(buf); } diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 8241906c4b61..1296e72e4161 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -569,11 +569,6 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait) int retval = 0; helper_lock(); - if (!sub_info->path) { - retval = -EINVAL; - goto out; - } - if (sub_info->path[0] == '\0') goto out; diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index cab4bce49c23..b049939177f6 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -2431,10 +2431,10 @@ static void kmemleak_load_module(const struct module *mod, kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); for (i = 1; i < info->hdr->e_shnum; i++) { - /* Scan all writable sections that's not executable */ - if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) || - !(info->sechdrs[i].sh_flags & SHF_WRITE) || - (info->sechdrs[i].sh_flags & SHF_EXECINSTR)) + const char *name = info->secstrings + info->sechdrs[i].sh_name; + if (!(info->sechdrs[i].sh_flags & SHF_ALLOC)) + continue; + if (!strstarts(name, ".data") && !strstarts(name, ".bss")) continue; kmemleak_scan_area((void *)info->sechdrs[i].sh_addr, @@ -2769,11 +2769,24 @@ static void find_module_sections(struct module *mod, struct load_info *info) mod->trace_events = section_objs(info, "_ftrace_events", sizeof(*mod->trace_events), &mod->num_trace_events); + /* + * This section contains pointers to allocated objects in the trace + * code and not scanning it leads to false positives. + */ + kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * + mod->num_trace_events, GFP_KERNEL); #endif #ifdef CONFIG_TRACING mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt", sizeof(*mod->trace_bprintk_fmt_start), &mod->num_trace_bprintk_fmt); + /* + * This section contains pointers to allocated objects in the trace + * code and not scanning it leads to false positives. + */ + kmemleak_scan_area(mod->trace_bprintk_fmt_start, + sizeof(*mod->trace_bprintk_fmt_start) * + mod->num_trace_bprintk_fmt, GFP_KERNEL); #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD /* sechdrs[0].sh_size is always zero */ diff --git a/trunk/kernel/rcutree_plugin.h b/trunk/kernel/rcutree_plugin.h index 3db5a375d8dd..170814dc418f 100644 --- a/trunk/kernel/rcutree_plugin.h +++ b/trunk/kernel/rcutree_plugin.h @@ -88,7 +88,7 @@ static void __init rcu_bootup_announce_oddness(void) #ifdef CONFIG_RCU_NOCB_CPU #ifndef CONFIG_RCU_NOCB_CPU_NONE if (!have_rcu_nocb_mask) { - zalloc_cpumask_var(&rcu_nocb_mask, GFP_KERNEL); + alloc_bootmem_cpumask_var(&rcu_nocb_mask); have_rcu_nocb_mask = true; } #ifdef CONFIG_RCU_NOCB_CPU_ZERO @@ -1667,7 +1667,7 @@ int rcu_needs_cpu(int cpu, unsigned long *dj) rdtp->last_accelerate = jiffies; /* Request timer delay depending on laziness, and round. */ - if (!rdtp->all_lazy) { + if (rdtp->all_lazy) { *dj = round_up(rcu_idle_gp_delay + jiffies, rcu_idle_gp_delay) - jiffies; } else { diff --git a/trunk/kernel/time/Kconfig b/trunk/kernel/time/Kconfig index 70f27e89012b..e4c07b0692bb 100644 --- a/trunk/kernel/time/Kconfig +++ b/trunk/kernel/time/Kconfig @@ -12,6 +12,11 @@ config CLOCKSOURCE_WATCHDOG config ARCH_CLOCKSOURCE_DATA bool +# Platforms has a persistent clock +config ALWAYS_USE_PERSISTENT_CLOCK + bool + default n + # Timekeeping vsyscall support config GENERIC_TIME_VSYSCALL bool diff --git a/trunk/kernel/time/tick-broadcast.c b/trunk/kernel/time/tick-broadcast.c index 24938d577669..206bbfb34e09 100644 --- a/trunk/kernel/time/tick-broadcast.c +++ b/trunk/kernel/time/tick-broadcast.c @@ -786,11 +786,11 @@ bool tick_broadcast_oneshot_available(void) void __init tick_broadcast_init(void) { - zalloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT); - zalloc_cpumask_var(&tmpmask, GFP_NOWAIT); + alloc_cpumask_var(&tick_broadcast_mask, GFP_NOWAIT); + alloc_cpumask_var(&tmpmask, GFP_NOWAIT); #ifdef CONFIG_TICK_ONESHOT - zalloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT); - zalloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT); - zalloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT); + alloc_cpumask_var(&tick_broadcast_oneshot_mask, GFP_NOWAIT); + alloc_cpumask_var(&tick_broadcast_pending_mask, GFP_NOWAIT); + alloc_cpumask_var(&tick_broadcast_force_mask, GFP_NOWAIT); #endif } diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index f4208138fbf4..bc67d4245e1d 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -717,7 +717,6 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) if (unlikely(!cpu_online(cpu))) { if (cpu == tick_do_timer_cpu) tick_do_timer_cpu = TICK_DO_TIMER_NONE; - return false; } if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) @@ -1169,7 +1168,7 @@ void tick_cancel_sched_timer(int cpu) hrtimer_cancel(&ts->sched_timer); # endif - memset(ts, 0, sizeof(*ts)); + ts->nohz_mode = NOHZ_MODE_INACTIVE; } #endif diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index 15ffdb3f1948..a860bba34412 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -1539,12 +1539,12 @@ static int __cpuinit init_timers_cpu(int cpu) boot_done = 1; base = &boot_tvec_bases; } - spin_lock_init(&base->lock); tvec_base_done[cpu] = 1; } else { base = per_cpu(tvec_bases, cpu); } + spin_lock_init(&base->lock); for (j = 0; j < TVN_SIZE; j++) { INIT_LIST_HEAD(base->tv5.vec + j); diff --git a/trunk/kernel/trace/trace_events_filter.c b/trunk/kernel/trace/trace_events_filter.c index e1b653f7e1ca..a6361178de5a 100644 --- a/trunk/kernel/trace/trace_events_filter.c +++ b/trunk/kernel/trace/trace_events_filter.c @@ -750,11 +750,7 @@ static int filter_set_pred(struct event_filter *filter, static void __free_preds(struct event_filter *filter) { - int i; - if (filter->preds) { - for (i = 0; i < filter->n_preds; i++) - kfree(filter->preds[i].ops); kfree(filter->preds); filter->preds = NULL; } diff --git a/trunk/kernel/trace/trace_kprobe.c b/trunk/kernel/trace/trace_kprobe.c index 9f46e98ba8f2..636d45fe69b3 100644 --- a/trunk/kernel/trace/trace_kprobe.c +++ b/trunk/kernel/trace/trace_kprobe.c @@ -35,7 +35,7 @@ struct trace_probe { const char *symbol; /* symbol name */ struct ftrace_event_class class; struct ftrace_event_call call; - struct ftrace_event_file * __rcu *files; + struct ftrace_event_file **files; ssize_t size; /* trace entry size */ unsigned int nr_args; struct probe_arg args[]; @@ -185,14 +185,9 @@ static struct trace_probe *find_trace_probe(const char *event, static int trace_probe_nr_files(struct trace_probe *tp) { - struct ftrace_event_file **file; + struct ftrace_event_file **file = tp->files; int ret = 0; - /* - * Since all tp->files updater is protected by probe_enable_lock, - * we don't need to lock an rcu_read_lock. - */ - file = rcu_dereference_raw(tp->files); if (file) while (*(file++)) ret++; @@ -214,10 +209,9 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) mutex_lock(&probe_enable_lock); if (file) { - struct ftrace_event_file **new, **old; + struct ftrace_event_file **new, **old = tp->files; int n = trace_probe_nr_files(tp); - old = rcu_dereference_raw(tp->files); /* 1 is for new one and 1 is for stopper */ new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *), GFP_KERNEL); @@ -257,17 +251,11 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) static int trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file) { - struct ftrace_event_file **files; int i; - /* - * Since all tp->files updater is protected by probe_enable_lock, - * we don't need to lock an rcu_read_lock. - */ - files = rcu_dereference_raw(tp->files); - if (files) { - for (i = 0; files[i]; i++) - if (files[i] == file) + if (tp->files) { + for (i = 0; tp->files[i]; i++) + if (tp->files[i] == file) return i; } @@ -286,11 +274,10 @@ disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) mutex_lock(&probe_enable_lock); if (file) { - struct ftrace_event_file **new, **old; + struct ftrace_event_file **new, **old = tp->files; int n = trace_probe_nr_files(tp); int i, j; - old = rcu_dereference_raw(tp->files); if (n == 0 || trace_probe_file_index(tp, file) < 0) { ret = -EINVAL; goto out_unlock; @@ -885,16 +872,9 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, static __kprobes void kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs) { - /* - * Note: preempt is already disabled around the kprobe handler. - * However, we still need an smp_read_barrier_depends() corresponding - * to smp_wmb() in rcu_assign_pointer() to access the pointer. - */ - struct ftrace_event_file **file = rcu_dereference_raw(tp->files); - - if (unlikely(!file)) - return; + struct ftrace_event_file **file = tp->files; + /* Note: preempt is already disabled around the kprobe handler */ while (*file) { __kprobe_trace_func(tp, regs, *file); file++; @@ -945,16 +925,9 @@ static __kprobes void kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, struct pt_regs *regs) { - /* - * Note: preempt is already disabled around the kprobe handler. - * However, we still need an smp_read_barrier_depends() corresponding - * to smp_wmb() in rcu_assign_pointer() to access the pointer. - */ - struct ftrace_event_file **file = rcu_dereference_raw(tp->files); - - if (unlikely(!file)) - return; + struct ftrace_event_file **file = tp->files; + /* Note: preempt is already disabled around the kprobe handler */ while (*file) { __kretprobe_trace_func(tp, ri, regs, *file); file++; @@ -962,7 +935,7 @@ kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, } /* Event entry printers */ -static enum print_line_t +enum print_line_t print_kprobe_event(struct trace_iterator *iter, int flags, struct trace_event *event) { @@ -998,7 +971,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags, return TRACE_TYPE_PARTIAL_LINE; } -static enum print_line_t +enum print_line_t print_kretprobe_event(struct trace_iterator *iter, int flags, struct trace_event *event) { diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index ee8e29a2320c..4aa9f5bc6b2d 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -296,7 +296,7 @@ static DEFINE_HASHTABLE(unbound_pool_hash, UNBOUND_POOL_HASH_ORDER); static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS]; struct workqueue_struct *system_wq __read_mostly; -EXPORT_SYMBOL(system_wq); +EXPORT_SYMBOL_GPL(system_wq); struct workqueue_struct *system_highpri_wq __read_mostly; EXPORT_SYMBOL_GPL(system_highpri_wq); struct workqueue_struct *system_long_wq __read_mostly; @@ -1411,7 +1411,7 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq, local_irq_restore(flags); return ret; } -EXPORT_SYMBOL(queue_work_on); +EXPORT_SYMBOL_GPL(queue_work_on); void delayed_work_timer_fn(unsigned long __data) { @@ -1485,7 +1485,7 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, local_irq_restore(flags); return ret; } -EXPORT_SYMBOL(queue_delayed_work_on); +EXPORT_SYMBOL_GPL(queue_delayed_work_on); /** * mod_delayed_work_on - modify delay of or queue a delayed work on specific CPU @@ -2059,7 +2059,6 @@ static bool manage_workers(struct worker *worker) if (unlikely(!mutex_trylock(&pool->manager_mutex))) { spin_unlock_irq(&pool->lock); mutex_lock(&pool->manager_mutex); - spin_lock_irq(&pool->lock); ret = true; } @@ -4312,12 +4311,6 @@ bool current_is_workqueue_rescuer(void) * no synchronization around this function and the test result is * unreliable and only useful as advisory hints or for debugging. * - * If @cpu is WORK_CPU_UNBOUND, the test is performed on the local CPU. - * Note that both per-cpu and unbound workqueues may be associated with - * multiple pool_workqueues which have separate congested states. A - * workqueue being congested on one CPU doesn't mean the workqueue is also - * contested on other CPUs / NUMA nodes. - * * RETURNS: * %true if congested, %false otherwise. */ @@ -4328,9 +4321,6 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) rcu_read_lock_sched(); - if (cpu == WORK_CPU_UNBOUND) - cpu = smp_processor_id(); - if (!(wq->flags & WQ_UNBOUND)) pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); else @@ -4905,8 +4895,7 @@ static void __init wq_numa_init(void) BUG_ON(!tbl); for_each_node(node) - BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL, - node_online(node) ? node : NUMA_NO_NODE)); + BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL, node)); for_each_possible_cpu(cpu) { node = cpu_to_node(cpu); diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index c55a037a354e..e9c52e1b853a 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -23,7 +23,7 @@ lib-y += kobject.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ - gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o \ + gcd.o lcm.o list_sort.o uuid.o flex_array.o \ bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o obj-y += string_helpers.o obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o diff --git a/trunk/lib/iovec.c b/trunk/lib/iovec.c deleted file mode 100644 index 454baa88bf27..000000000000 --- a/trunk/lib/iovec.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include - -/* - * Copy iovec to kernel. Returns -EFAULT on error. - * - * Note: this modifies the original iovec. - */ - -int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) -{ - while (len > 0) { - if (iov->iov_len) { - int copy = min_t(unsigned int, len, iov->iov_len); - if (copy_from_user(kdata, iov->iov_base, copy)) - return -EFAULT; - len -= copy; - kdata += copy; - iov->iov_base += copy; - iov->iov_len -= copy; - } - iov++; - } - - return 0; -} -EXPORT_SYMBOL(memcpy_fromiovec); - -/* - * Copy kernel to iovec. Returns -EFAULT on error. - * - * Note: this modifies the original iovec. - */ - -int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) -{ - while (len > 0) { - if (iov->iov_len) { - int copy = min_t(unsigned int, iov->iov_len, len); - if (copy_to_user(iov->iov_base, kdata, copy)) - return -EFAULT; - kdata += copy; - len -= copy; - iov->iov_len -= copy; - iov->iov_base += copy; - } - iov++; - } - - return 0; -} -EXPORT_SYMBOL(memcpy_toiovec); diff --git a/trunk/lib/klist.c b/trunk/lib/klist.c index 358a368a2947..0874e41609a6 100644 --- a/trunk/lib/klist.c +++ b/trunk/lib/klist.c @@ -193,10 +193,10 @@ static void klist_release(struct kref *kref) if (waiter->node != n) continue; - list_del(&waiter->list); waiter->woken = 1; mb(); wake_up_process(waiter->process); + list_del(&waiter->list); } spin_unlock(&klist_remove_lock); knode_set_klist(n, NULL); diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 378a15bcd649..98cbdf6e5532 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -5158,7 +5158,7 @@ unsigned long free_reserved_area(unsigned long start, unsigned long end, for (pages = 0; pos < end; pos += PAGE_SIZE, pages++) { if (poison) memset((void *)pos, poison, PAGE_SIZE); - free_reserved_page(virt_to_page((void *)pos)); + free_reserved_page(virt_to_page(pos)); } if (pages && s) diff --git a/trunk/net/ceph/osd_client.c b/trunk/net/ceph/osd_client.c index d5953b87918c..a3395fdfbd4f 100644 --- a/trunk/net/ceph/osd_client.c +++ b/trunk/net/ceph/osd_client.c @@ -1204,7 +1204,6 @@ void ceph_osdc_unregister_linger_request(struct ceph_osd_client *osdc, mutex_lock(&osdc->request_mutex); if (req->r_linger) { __unregister_linger_request(osdc, req); - req->r_linger = 0; ceph_osdc_put_request(req); } mutex_unlock(&osdc->request_mutex); @@ -2121,9 +2120,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, down_read(&osdc->map_sem); mutex_lock(&osdc->request_mutex); __register_request(osdc, req); - req->r_sent = 0; - req->r_got_reply = 0; - req->r_completed = 0; + WARN_ON(req->r_sent); rc = __map_request(osdc, req, 0); if (rc < 0) { if (nofail) { diff --git a/trunk/net/core/iovec.c b/trunk/net/core/iovec.c index de178e462682..7e7aeb01de45 100644 --- a/trunk/net/core/iovec.c +++ b/trunk/net/core/iovec.c @@ -73,6 +73,31 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a return err; } +/* + * Copy kernel to iovec. Returns -EFAULT on error. + * + * Note: this modifies the original iovec. + */ + +int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) +{ + while (len > 0) { + if (iov->iov_len) { + int copy = min_t(unsigned int, iov->iov_len, len); + if (copy_to_user(iov->iov_base, kdata, copy)) + return -EFAULT; + kdata += copy; + len -= copy; + iov->iov_len -= copy; + iov->iov_base += copy; + } + iov++; + } + + return 0; +} +EXPORT_SYMBOL(memcpy_toiovec); + /* * Copy kernel to iovec. Returns -EFAULT on error. */ @@ -99,6 +124,31 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, } EXPORT_SYMBOL(memcpy_toiovecend); +/* + * Copy iovec to kernel. Returns -EFAULT on error. + * + * Note: this modifies the original iovec. + */ + +int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) +{ + while (len > 0) { + if (iov->iov_len) { + int copy = min_t(unsigned int, len, iov->iov_len); + if (copy_from_user(kdata, iov->iov_base, copy)) + return -EFAULT; + len -= copy; + kdata += copy; + iov->iov_base += copy; + iov->iov_len -= copy; + } + iov++; + } + + return 0; +} +EXPORT_SYMBOL(memcpy_fromiovec); + /* * Copy iovec from kernel. Returns -EFAULT on error. */ diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 88868a9d21da..6ba327da79e1 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -210,7 +210,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , - "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX" + "sk_lock-AF_NFC" , "sk_lock-AF_MAX" }; static const char *const af_family_slock_key_strings[AF_MAX+1] = { "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , @@ -226,7 +226,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , - "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX" + "slock-AF_NFC" , "slock-AF_MAX" }; static const char *const af_family_clock_key_strings[AF_MAX+1] = { "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , @@ -242,7 +242,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , - "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX" + "clock-AF_NFC" , "clock-AF_MAX" }; /* diff --git a/trunk/net/ipv4/ip_tunnel.c b/trunk/net/ipv4/ip_tunnel.c index be2f8da0ae8e..e4147ec1665a 100644 --- a/trunk/net/ipv4/ip_tunnel.c +++ b/trunk/net/ipv4/ip_tunnel.c @@ -503,7 +503,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, inner_iph = (const struct iphdr *)skb_inner_network_header(skb); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); dst = tnl_params->daddr; if (dst == 0) { /* NBMA tunnel */ @@ -659,6 +658,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, skb_dst_drop(skb); skb_dst_set(skb, &rt->dst); + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); /* Push down and install the IP header. */ skb_push(skb, sizeof(struct iphdr)); diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index d35bbf0cf404..550781a17b34 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -737,15 +737,10 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf { struct rtable *rt; struct flowi4 fl4; - const struct iphdr *iph = (const struct iphdr *) skb->data; - int oif = skb->dev->ifindex; - u8 tos = RT_TOS(iph->tos); - u8 prot = iph->protocol; - u32 mark = skb->mark; rt = (struct rtable *) dst; - __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0); + ip_rt_build_flow_key(&fl4, sk, skb); __ip_do_redirect(rt, skb, &fl4, true); } diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index ec335fabd5cc..536d40929ba6 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -874,13 +874,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, &md5); tcp_header_size = tcp_options_size + sizeof(struct tcphdr); - if (tcp_packets_in_flight(tp) == 0) + if (tcp_packets_in_flight(tp) == 0) { tcp_ca_event(sk, CA_EVENT_TX_START); - - /* if no packet is in qdisc/device queue, then allow XPS to select - * another queue. - */ - skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; + skb->ooo_okay = 1; + } else + skb->ooo_okay = 0; skb_push(skb, tcp_header_size); skb_reset_transport_header(skb); diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index d1ab6ab29a55..d1b2d8034b54 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -1487,7 +1487,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev) } int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, - struct net_device *dev, int strict) + const struct net_device *dev, int strict) { struct inet6_ifaddr *ifp; unsigned int hash = inet6_addr_hash(addr); diff --git a/trunk/net/ipv6/netfilter.c b/trunk/net/ipv6/netfilter.c index 72836f40b730..95f3f1da0d7f 100644 --- a/trunk/net/ipv6/netfilter.c +++ b/trunk/net/ipv6/netfilter.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -186,6 +187,10 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook, return csum; }; +static const struct nf_ipv6_ops ipv6ops = { + .chk_addr = ipv6_chk_addr, +}; + static const struct nf_afinfo nf_ip6_afinfo = { .family = AF_INET6, .checksum = nf_ip6_checksum, @@ -198,6 +203,7 @@ static const struct nf_afinfo nf_ip6_afinfo = { int __init ipv6_netfilter_init(void) { + RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops); return nf_register_afinfo(&nf_ip6_afinfo); } @@ -206,5 +212,6 @@ int __init ipv6_netfilter_init(void) */ void ipv6_netfilter_fini(void) { + RCU_INIT_POINTER(nf_ipv6_ops, NULL); nf_unregister_afinfo(&nf_ip6_afinfo); } diff --git a/trunk/net/netfilter/core.c b/trunk/net/netfilter/core.c index 07c865a31a3d..857ca9f35177 100644 --- a/trunk/net/netfilter/core.c +++ b/trunk/net/netfilter/core.c @@ -30,6 +30,8 @@ static DEFINE_MUTEX(afinfo_mutex); const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; EXPORT_SYMBOL(nf_afinfo); +const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly; +EXPORT_SYMBOL_GPL(nf_ipv6_ops); int nf_register_afinfo(const struct nf_afinfo *afinfo) { diff --git a/trunk/net/netfilter/xt_addrtype.c b/trunk/net/netfilter/xt_addrtype.c index 49c5ff7f6dd6..68ff29f60867 100644 --- a/trunk/net/netfilter/xt_addrtype.c +++ b/trunk/net/netfilter/xt_addrtype.c @@ -22,6 +22,7 @@ #include #endif +#include #include #include @@ -33,12 +34,12 @@ MODULE_ALIAS("ip6t_addrtype"); #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, - const struct in6_addr *addr) + const struct in6_addr *addr, u16 mask) { const struct nf_afinfo *afinfo; struct flowi6 flow; struct rt6_info *rt; - u32 ret; + u32 ret = 0; int route_err; memset(&flow, 0, sizeof(flow)); @@ -49,12 +50,19 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, rcu_read_lock(); afinfo = nf_get_afinfo(NFPROTO_IPV6); - if (afinfo != NULL) + if (afinfo != NULL) { + const struct nf_ipv6_ops *v6ops; + + if (dev && (mask & XT_ADDRTYPE_LOCAL)) { + v6ops = nf_get_ipv6_ops(); + if (v6ops && v6ops->chk_addr(net, addr, dev, true)) + ret = XT_ADDRTYPE_LOCAL; + } route_err = afinfo->route(net, (struct dst_entry **)&rt, - flowi6_to_flowi(&flow), !!dev); - else + flowi6_to_flowi(&flow), false); + } else { route_err = 1; - + } rcu_read_unlock(); if (route_err) @@ -62,15 +70,12 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, if (rt->rt6i_flags & RTF_REJECT) ret = XT_ADDRTYPE_UNREACHABLE; - else - ret = 0; - if (rt->rt6i_flags & RTF_LOCAL) + if (dev == NULL && rt->rt6i_flags & RTF_LOCAL) ret |= XT_ADDRTYPE_LOCAL; if (rt->rt6i_flags & RTF_ANYCAST) ret |= XT_ADDRTYPE_ANYCAST; - dst_release(&rt->dst); return ret; } @@ -90,7 +95,7 @@ static bool match_type6(struct net *net, const struct net_device *dev, if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | XT_ADDRTYPE_UNREACHABLE) & mask) - return !!(mask & match_lookup_rt6(net, dev, addr)); + return !!(mask & match_lookup_rt6(net, dev, addr, mask)); return true; } diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 9ff6366fee13..6b94633ca61d 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -2075,12 +2075,8 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, fla { int fput_needed, err; struct msghdr msg_sys; - struct socket *sock; - - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; + struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); - sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -2153,8 +2149,6 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags) { - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; return __sys_sendmmsg(fd, mmsg, vlen, flags); } @@ -2255,12 +2249,8 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, { int fput_needed, err; struct msghdr msg_sys; - struct socket *sock; - - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; + struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); - sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -2385,9 +2375,6 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, int datagrams; struct timespec timeout_sys; - if (flags & MSG_CMSG_COMPAT) - return -EINVAL; - if (!timeout) return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); @@ -2505,31 +2492,15 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) (int __user *)a[4]); break; case SYS_SENDMSG: - if (a[2] & MSG_CMSG_COMPAT) { - err = -EINVAL; - break; - } err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]); break; case SYS_SENDMMSG: - if (a[3] & MSG_CMSG_COMPAT) { - err = -EINVAL; - break; - } err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); break; case SYS_RECVMSG: - if (a[2] & MSG_CMSG_COMPAT) { - err = -EINVAL; - break; - } err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); break; case SYS_RECVMMSG: - if (a[3] & MSG_CMSG_COMPAT) { - err = -EINVAL; - break; - } err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], (struct timespec __user *)a[4]); break; diff --git a/trunk/scripts/package/Makefile b/trunk/scripts/package/Makefile index a4f31c900fa6..84a406070f6f 100644 --- a/trunk/scripts/package/Makefile +++ b/trunk/scripts/package/Makefile @@ -63,7 +63,7 @@ binrpm-pkg: FORCE mv -f $(objtree)/.tmp_version $(objtree)/.version $(RPM) $(RPMOPTS) --define "_builddir $(objtree)" --target \ - $(UTS_MACHINE) -bb $(objtree)/binkernel.spec + $(UTS_MACHINE) -bb $< rm binkernel.spec # Deb target diff --git a/trunk/sound/aoa/fabrics/layout.c b/trunk/sound/aoa/fabrics/layout.c index 61ab640e195f..552b97afbca5 100644 --- a/trunk/sound/aoa/fabrics/layout.c +++ b/trunk/sound/aoa/fabrics/layout.c @@ -113,7 +113,6 @@ MODULE_ALIAS("sound-layout-100"); MODULE_ALIAS("aoa-device-id-14"); MODULE_ALIAS("aoa-device-id-22"); MODULE_ALIAS("aoa-device-id-35"); -MODULE_ALIAS("aoa-device-id-44"); /* onyx with all but microphone connected */ static struct codec_connection onyx_connections_nomic[] = { @@ -362,13 +361,6 @@ static struct layout layouts[] = { .connections = tas_connections_nolineout, }, }, - /* PowerBook6,5 */ - { .device_id = 44, - .codecs[0] = { - .name = "tas", - .connections = tas_connections_all, - }, - }, /* PowerBook6,7 */ { .layout_id = 80, .codecs[0] = { diff --git a/trunk/sound/aoa/soundbus/i2sbus/core.c b/trunk/sound/aoa/soundbus/i2sbus/core.c index 15e76131b501..010658335881 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/core.c @@ -200,8 +200,7 @@ static int i2sbus_add_dev(struct macio_dev *macio, * We probably cannot handle all device-id machines, * so restrict to those we do handle for now. */ - if (id && (*id == 22 || *id == 14 || *id == 35 || - *id == 44)) { + if (id && (*id == 22 || *id == 14 || *id == 35)) { snprintf(dev->sound.modalias, 32, "aoa-device-id-%d", *id); ok = 1; diff --git a/trunk/sound/oss/Kconfig b/trunk/sound/oss/Kconfig index 1a9640254433..51c4ba95a32d 100644 --- a/trunk/sound/oss/Kconfig +++ b/trunk/sound/oss/Kconfig @@ -250,7 +250,7 @@ config MSND_FIFOSIZE menuconfig SOUND_OSS tristate "OSS sound modules" depends on ISA_DMA_API && VIRT_TO_BUS - depends on !GENERIC_ISA_DMA_SUPPORT_BROKEN + depends on !ISA_DMA_SUPPORT_BROKEN help OSS is the Open Sound System suite of sound card drivers. They make sound programming easier since they provide a common API. Say Y or diff --git a/trunk/sound/pci/hda/hda_generic.c b/trunk/sound/pci/hda/hda_generic.c index ae85bbd2e6f8..ac079f93c535 100644 --- a/trunk/sound/pci/hda/hda_generic.c +++ b/trunk/sound/pci/hda/hda_generic.c @@ -606,10 +606,6 @@ static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid, return false; } -/* check whether the NID is referred by any active paths */ -#define is_active_nid_for_any(codec, nid) \ - is_active_nid(codec, nid, HDA_OUTPUT, 0) - /* get the default amp value for the target state */ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int caps, bool enable) @@ -763,8 +759,7 @@ static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path) for (i = 0; i < path->depth; i++) { hda_nid_t nid = path->path[i]; - if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3) && - !is_active_nid_for_any(codec, nid)) { + if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3)) { snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); @@ -4162,7 +4157,7 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, return power_state; if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER) return power_state; - if (is_active_nid_for_any(codec, nid)) + if (is_active_nid(codec, nid, HDA_OUTPUT, 0)) return power_state; return AC_PWRST_D3; } diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 59d2e91a9ab6..6bf47f7326ad 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -3482,7 +3482,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), diff --git a/trunk/sound/soc/codecs/ab8500-codec.h b/trunk/sound/soc/codecs/ab8500-codec.h index 306d0bc8455f..114f69a0c629 100644 --- a/trunk/sound/soc/codecs/ab8500-codec.h +++ b/trunk/sound/soc/codecs/ab8500-codec.h @@ -348,25 +348,25 @@ /* AB8500_ADSLOTSELX */ #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00 -#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x10 -#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x20 -#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x30 -#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x40 -#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x50 -#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x60 -#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x70 -#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x80 -#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0 +#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x01 +#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x02 +#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x03 +#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x04 +#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x05 +#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x06 +#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x07 +#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x08 +#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00 -#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01 -#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02 -#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03 -#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04 -#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05 -#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06 -#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07 -#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x08 -#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0x0F +#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10 +#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20 +#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30 +#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40 +#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50 +#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60 +#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70 +#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x80 +#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0xF0 #define AB8500_ADSLOTSELX_EVEN_SHIFT 0 #define AB8500_ADSLOTSELX_ODD_SHIFT 4 diff --git a/trunk/sound/soc/codecs/da7213.c b/trunk/sound/soc/codecs/da7213.c index 4a6f1daf911f..41230ad1c3e0 100644 --- a/trunk/sound/soc/codecs/da7213.c +++ b/trunk/sound/soc/codecs/da7213.c @@ -1488,17 +1488,17 @@ static int da7213_probe(struct snd_soc_codec *codec) DA7213_DMIC_DATA_SEL_SHIFT); break; } - switch (pdata->dmic_samplephase) { + switch (pdata->dmic_data_sel) { case DA7213_DMIC_SAMPLE_ON_CLKEDGE: case DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE: - dmic_cfg |= (pdata->dmic_samplephase << + dmic_cfg |= (pdata->dmic_data_sel << DA7213_DMIC_SAMPLEPHASE_SHIFT); break; } - switch (pdata->dmic_clk_rate) { + switch (pdata->dmic_data_sel) { case DA7213_DMIC_CLK_3_0MHZ: case DA7213_DMIC_CLK_1_5MHZ: - dmic_cfg |= (pdata->dmic_clk_rate << + dmic_cfg |= (pdata->dmic_data_sel << DA7213_DMIC_CLK_RATE_SHIFT); break; } diff --git a/trunk/sound/soc/codecs/wm0010.c b/trunk/sound/soc/codecs/wm0010.c index 370af0cbcc9a..8df2b6e1a1a6 100644 --- a/trunk/sound/soc/codecs/wm0010.c +++ b/trunk/sound/soc/codecs/wm0010.c @@ -667,7 +667,6 @@ static int wm0010_boot(struct snd_soc_codec *codec) /* On wm0010 only the CLKCTRL1 value is used */ pll_rec.clkctrl1 = wm0010->pll_clkctrl1; - ret = -ENOMEM; len = pll_rec.length + 8; out = kzalloc(len, GFP_KERNEL); if (!out) { diff --git a/trunk/sound/soc/fsl/imx-ssi.c b/trunk/sound/soc/fsl/imx-ssi.c index c6fa03e2114a..902fab02b851 100644 --- a/trunk/sound/soc/fsl/imx-ssi.c +++ b/trunk/sound/soc/fsl/imx-ssi.c @@ -540,6 +540,11 @@ static int imx_ssi_probe(struct platform_device *pdev) clk_prepare_enable(ssi->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + goto failed_get_resource; + } + ssi->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ssi->base)) { ret = PTR_ERR(ssi->base); @@ -628,6 +633,7 @@ static int imx_ssi_probe(struct platform_device *pdev) snd_soc_unregister_component(&pdev->dev); failed_register: release_mem_region(res->start, resource_size(res)); +failed_get_resource: clk_disable_unprepare(ssi->clk); failed_clk: diff --git a/trunk/sound/soc/kirkwood/kirkwood-i2s.c b/trunk/sound/soc/kirkwood/kirkwood-i2s.c index 4c9dad3263c5..befe68f59285 100644 --- a/trunk/sound/soc/kirkwood/kirkwood-i2s.c +++ b/trunk/sound/soc/kirkwood/kirkwood-i2s.c @@ -471,6 +471,11 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, priv); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "platform_get_resource failed\n"); + return -ENXIO; + } + priv->io = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(priv->io)) return PTR_ERR(priv->io); diff --git a/trunk/sound/usb/proc.c b/trunk/sound/usb/proc.c index 5f761ab34c01..135c76871063 100644 --- a/trunk/sound/usb/proc.c +++ b/trunk/sound/usb/proc.c @@ -116,22 +116,21 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s } static void proc_dump_ep_status(struct snd_usb_substream *subs, - struct snd_usb_endpoint *data_ep, - struct snd_usb_endpoint *sync_ep, + struct snd_usb_endpoint *ep, struct snd_info_buffer *buffer) { - if (!data_ep) + if (!ep) return; - snd_iprintf(buffer, " Packet Size = %d\n", data_ep->curpacksize); + snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize); snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", subs->speed == USB_SPEED_FULL - ? get_full_speed_hz(data_ep->freqm) - : get_high_speed_hz(data_ep->freqm), - data_ep->freqm >> 16, data_ep->freqm & 0xffff); - if (sync_ep && data_ep->freqshift != INT_MIN) { - int res = 16 - data_ep->freqshift; + ? get_full_speed_hz(ep->freqm) + : get_high_speed_hz(ep->freqm), + ep->freqm >> 16, ep->freqm & 0xffff); + if (ep->freqshift != INT_MIN) { + int res = 16 - ep->freqshift; snd_iprintf(buffer, " Feedback Format = %d.%d\n", - (sync_ep->syncmaxsize > 3 ? 32 : 24) - res, res); + (ep->syncmaxsize > 3 ? 32 : 24) - res, res); } } @@ -141,7 +140,8 @@ static void proc_dump_substream_status(struct snd_usb_substream *subs, struct sn snd_iprintf(buffer, " Status: Running\n"); snd_iprintf(buffer, " Interface = %d\n", subs->interface); snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx); - proc_dump_ep_status(subs, subs->data_endpoint, subs->sync_endpoint, buffer); + proc_dump_ep_status(subs, subs->data_endpoint, buffer); + proc_dump_ep_status(subs, subs->sync_endpoint, buffer); } else { snd_iprintf(buffer, " Status: Stop\n"); }