]> Git Repo - linux.git/commitdiff
Merge tag 'pm+acpi-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
authorLinus Torvalds <[email protected]>
Wed, 3 Jul 2013 21:35:40 +0000 (14:35 -0700)
committerLinus Torvalds <[email protected]>
Wed, 3 Jul 2013 21:35:40 +0000 (14:35 -0700)
Pull power management and ACPI updates from Rafael Wysocki:
 "This time the total number of ACPI commits is slightly greater than
  the number of cpufreq commits, but Viresh Kumar (who works on cpufreq)
  remains the most active patch submitter.

  To me, the most significant change is the addition of offline/online
  device operations to the driver core (with the Greg's blessing) and
  the related modifications of the ACPI core hotplug code.  Next are the
  freezer updates from Colin Cross that should make the freezing of
  tasks a bit less heavy weight.

  We also have a couple of regression fixes, a number of fixes for
  issues that have not been identified as regressions, two new drivers
  and a bunch of cleanups all over.

  Highlights:

   - Hotplug changes to support graceful hot-removal failures.

     It sometimes is necessary to fail device hot-removal operations
     gracefully if they cannot be carried out completely.  For example,
     if memory from a memory module being hot-removed has been allocated
     for the kernel's own use and cannot be moved elsewhere, it's
     desirable to fail the hot-removal operation in a graceful way
     rather than to crash the kernel, but currenty a success or a kernel
     crash are the only possible outcomes of an attempted memory
     hot-removal.  Needless to say, that is not a very attractive
     alternative and it had to be addressed.

     However, in order to make it work for memory, I first had to make
     it work for CPUs and for this purpose I needed to modify the ACPI
     processor driver.  It's been split into two parts, a resident one
     handling the low-level initialization/cleanup and a modular one
     playing the actual driver's role (but it binds to the CPU system
     device objects rather than to the ACPI device objects representing
     processors).  That's been sort of like a live brain surgery on a
     patient who's riding a bike.

     So this is a little scary, but since we found and fixed a couple of
     regressions it caused to happen during the early linux-next testing
     (a month ago), nobody has complained.

     As a bonus we remove some duplicated ACPI hotplug code, because the
     ACPI-based CPU hotplug is now going to use the common ACPI hotplug
     code.

   - Lighter weight freezing of tasks.

     These changes from Colin Cross and Mandeep Singh Baines are
     targeted at making the freezing of tasks a bit less heavy weight
     operation.  They reduce the number of tasks woken up every time
     during the freezing, by using the observation that the freezer
     simply doesn't need to wake up some of them and wait for them all
     to call refrigerator().  The time needed for the freezer to decide
     to report a failure is reduced too.

     Also reintroduced is the check causing a lockdep warining to
     trigger when try_to_freeze() is called with locks held (which is
     generally unsafe and shouldn't happen).

   - cpufreq updates

     First off, a commit from Srivatsa S Bhat fixes a resume regression
     introduced during the 3.10 cycle causing some cpufreq sysfs
     attributes to return wrong values to user space after resume.  The
     fix is kind of fresh, but also it's pretty obvious once Srivatsa
     has identified the root cause.

     Second, we have a new freqdomain_cpus sysfs attribute for the
     acpi-cpufreq driver to provide information previously available via
     related_cpus.  From Lan Tianyu.

     Finally, we fix a number of issues, mostly related to the
     CPUFREQ_POSTCHANGE notifier and cpufreq Kconfig options and clean
     up some code.  The majority of changes from Viresh Kumar with bits
     from Jacob Shin, Heiko Stübner, Xiaoguang Chen, Ezequiel Garcia,
     Arnd Bergmann, and Tang Yuantian.

   - ACPICA update

     A usual bunch of updates from the ACPICA upstream.

     During the 3.4 cycle we introduced support for ACPI 5 extended
     sleep registers, but they are only supposed to be used if the
     HW-reduced mode bit is set in the FADT flags and the code attempted
     to use them without checking that bit.  That caused suspend/resume
     regressions to happen on some systems.  Fix from Lv Zheng causes
     those registers to be used only if the HW-reduced mode bit is set.

     Apart from this some other ACPICA bugs are fixed and code cleanups
     are made by Bob Moore, Tomasz Nowicki, Lv Zheng, Chao Guan, and
     Zhang Rui.

   - cpuidle updates

     New driver for Xilinx Zynq processors is added by Michal Simek.

     Multidriver support simplification, addition of some missing
     kerneldoc comments and Kconfig-related fixes come from Daniel
     Lezcano.

   - ACPI power management updates

     Changes to make suspend/resume work correctly in Xen guests from
     Konrad Rzeszutek Wilk, sparse warning fix from Fengguang Wu and
     cleanups and fixes of the ACPI device power state selection
     routine.

   - ACPI documentation updates

     Some previously missing pieces of ACPI documentation are added by
     Lv Zheng and Aaron Lu (hopefully, that will help people to
     uderstand how the ACPI subsystem works) and one outdated doc is
     updated by Hanjun Guo.

   - Assorted ACPI updates

     We finally nailed down the IA-64 issue that was the reason for
     reverting commit 9f29ab11ddbf ("ACPI / scan: do not match drivers
     against objects having scan handlers"), so we can fix it and move
     the ACPI scan handler check added to the ACPI video driver back to
     the core.

     A mechanism for adding CMOS RTC address space handlers is
     introduced by Lan Tianyu to allow some EC-related breakage to be
     fixed on some systems.

     A spec-compliant implementation of acpi_os_get_timer() is added by
     Mika Westerberg.

     The evaluation of _STA is added to do_acpi_find_child() to avoid
     situations in which a pointer to a disabled device object is
     returned instead of an enabled one with the same _ADR value.  From
     Jeff Wu.

     Intel BayTrail PCH (Platform Controller Hub) support is added to
     the ACPI driver for Intel Low-Power Subsystems (LPSS) and that
     driver is modified to work around a couple of known BIOS issues.
     Changes from Mika Westerberg and Heikki Krogerus.

     The EC driver is fixed by Vasiliy Kulikov to use get_user() and
     put_user() instead of dereferencing user space pointers blindly.

     Code cleanups are made by Bjorn Helgaas, Nicholas Mazzuca and Toshi
     Kani.

   - Assorted power management updates

     The "runtime idle" helper routine is changed to take the return
     values of the callbacks executed by it into account and to call
     rpm_suspend() if they return 0, which allows us to reduce the
     overall code bloat a bit (by dropping some code that's not
     necessary any more after that modification).

     The runtime PM documentation is updated by Alan Stern (to reflect
     the "runtime idle" behavior change).

     New trace points for PM QoS are added by Sahara
     (<[email protected]>).

     PM QoS documentation is updated by Lan Tianyu.

     Code cleanups are made and minor issues are addressed by Bernie
     Thompson, Bjorn Helgaas, Julius Werner, and Shuah Khan.

   - devfreq updates

     New driver for the Exynos5-bus device from Abhilash Kesavan.

     Minor cleanups, fixes and MAINTAINERS update from MyungJoo Ham,
     Abhilash Kesavan, Paul Bolle, Rajagopal Venkat, and Wei Yongjun.

   - OMAP power management updates

     Adaptive Voltage Scaling (AVS) SmartReflex voltage control driver
     updates from Andrii Tseglytskyi and Nishanth Menon."

* tag 'pm+acpi-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (162 commits)
  cpufreq: Fix cpufreq regression after suspend/resume
  ACPI / PM: Fix possible NULL pointer deref in acpi_pm_device_sleep_state()
  PM / Sleep: Warn about system time after resume with pm_trace
  cpufreq: don't leave stale policy pointer in cdbs->cur_policy
  acpi-cpufreq: Add new sysfs attribute freqdomain_cpus
  cpufreq: make sure frequency transitions are serialized
  ACPI: implement acpi_os_get_timer() according the spec
  ACPI / EC: Add HP Folio 13 to ec_dmi_table in order to skip DSDT scan
  ACPI: Add CMOS RTC Operation Region handler support
  ACPI / processor: Drop unused variable from processor_perflib.c
  cpufreq: tegra: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: s3c64xx: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: omap: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: imx6q: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: exynos: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: dbx500: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: davinci: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: arm-big-little: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: powernow-k8: call CPUFREQ_POSTCHANGE notfier in error cases
  cpufreq: pcc: call CPUFREQ_POSTCHANGE notfier in error cases
  ...

22 files changed:
1  2 
Documentation/cpu-hotplug.txt
Documentation/kernel-parameters.txt
MAINTAINERS
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-tegra/Kconfig
arch/arm/plat-samsung/include/plat/cpu-freq-core.h
arch/cris/Kconfig
drivers/base/core.c
drivers/base/cpu.c
drivers/base/memory.c
drivers/base/platform.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpuidle/Kconfig
drivers/gpio/gpio-langwell.c
drivers/mfd/db8500-prcmu.c
drivers/staging/android/binder.c
drivers/tty/serial/mfd.c
drivers/usb/core/port.c
fs/cifs/transport.c
include/linux/device.h

index 0efd1b905b9dd8f909e9e7bd184af4e66cd1e0f5,67f733d6f848d897fad19698fd2017675164d650..edd4b4df393202ac99b27269966b0ab15c44fff0
@@@ -128,7 -128,7 +128,7 @@@ A: When doing make defconfig, Enable CP
  
     "Processor type and Features" -> Support for Hotpluggable CPUs
  
 -Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well.
 +Make sure that you have CONFIG_SMP turned on as well.
  
  You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support
  as well.
@@@ -370,8 -370,10 +370,10 @@@ A: There is no clear spec defined way f
     CPUs in MADT as hotpluggable CPUS.  In the case there are no disabled CPUS
     we assume 1/2 the number of CPUs currently present can be hotplugged.
  
-    Caveat: Today's ACPI MADT can only provide 256 entries since the apicid field
-    in MADT is only 8 bits.
+    Caveat: ACPI MADT can only provide 256 entries in systems with only ACPI 2.0c
+    or earlier ACPI version supported, because the apicid field in MADT is only
+    8 bits. From ACPI 3.0, this limitation was removed since the apicid field
+    was extended to 32 bits with x2APIC introduced.
  
  User Space Notification
  
index 3c80382a84dd3d5aefda493c20489e30fbf64ada,7f64e0f0258ae013bccc5766128420d7efaf12a4..ef8bd35814cfadf8026d0c84502f539c01fffd96
@@@ -1129,6 -1129,11 +1129,6 @@@ bytes respectively. Such letter suffixe
                        The builtin appraise policy appraises all files
                        owned by uid=0.
  
 -      ima_audit=      [IMA]
 -                      Format: { "0" | "1" }
 -                      0 -- integrity auditing messages. (Default)
 -                      1 -- enable informational integrity auditing messages.
 -
        ima_hash=       [IMA]
                        Format: { "sha1" | "md5" }
                        default: "sha1"
        inport.irq=     [HW] Inport (ATI XL and Microsoft) busmouse driver
                        Format: <irq>
  
 +      int_pln_enable  [x86] Enable power limit notification interrupt
 +
 +      integrity_audit=[IMA]
 +                      Format: { "0" | "1" }
 +                      0 -- basic integrity auditing messages. (Default)
 +                      1 -- additional integrity auditing messages.
 +
        intel_iommu=    [DMAR] Intel IOMMU driver (DMAR) option
                on
                        Enable intel iommu driver.
        video=          [FB] Frame buffer configuration
                        See Documentation/fb/modedb.txt.
  
+       video.brightness_switch_enabled= [0,1]
+                       If set to 1, on receiving an ACPI notify event
+                       generated by hotkey, video driver will adjust brightness
+                       level and then send out the event to user space through
+                       the allocated input device; If set to 0, video driver
+                       will only send out the event without touching backlight
+                       brightness level.
+                       default: 1
        virtio_mmio.device=
                        [VMMIO] Memory mapped virtio (platform) device.
  
                        that this also can be controlled per-workqueue for
                        workqueues visible under /sys/bus/workqueue/.
  
 +      workqueue.power_efficient
 +                      Per-cpu workqueues are generally preferred because
 +                      they show better performance thanks to cache
 +                      locality; unfortunately, per-cpu workqueues tend to
 +                      be more power hungry than unbound workqueues.
 +
 +                      Enabling this makes the per-cpu workqueues which
 +                      were observed to contribute significantly to power
 +                      consumption unbound, leading to measurably lower
 +                      power usage at the cost of small performance
 +                      overhead.
 +
 +                      The default value of this parameter is determined by
 +                      the config option CONFIG_WQ_POWER_EFFICIENT_DEFAULT.
 +
        x2apic_phys     [X86-64,APIC] Use x2apic physical mode instead of
                        default x2apic cluster mode on platforms
                        supporting x2apic.
diff --combined MAINTAINERS
index 85c1402e8a124242a02c66a4f70410b9dbb6af70,04a5fef844159f762193a72d9cd72fa40cf48df1..6d9578131c311a66367505038c43b40527e13590
@@@ -242,6 -242,8 +242,8 @@@ F: drivers/acpi
  F:    drivers/pnp/pnpacpi/
  F:    include/linux/acpi.h
  F:    include/acpi/
+ F:    Documentation/acpi
+ F:    Documentation/ABI/testing/sysfs-bus-acpi
  
  ACPI FAN DRIVER
  M:    Zhang Rui <[email protected]>
@@@ -797,7 -799,6 +799,7 @@@ F: arch/arm/mach-gemini
  ARM/CSR SIRFPRIMA2 MACHINE SUPPORT
  M:    Barry Song <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git
  S:    Maintained
  F:    arch/arm/mach-prima2/
  F:    drivers/dma/sirf-dma.c
@@@ -1136,7 -1137,6 +1138,7 @@@ L:      [email protected] (m
  S:    Maintained
  F:    arch/arm/mach-s5p*/
  F:    arch/arm/mach-exynos*/
 +N:    exynos
  
  ARM/SAMSUNG MOBILE MACHINE SUPPORT
  M:    Kyungmin Park <[email protected]>
@@@ -1203,15 -1203,6 +1205,15 @@@ M:    Dinh Nguyen <[email protected]
  S:    Maintained
  F:    drivers/clk/socfpga/
  
 +ARM/STI ARCHITECTURE
 +M:    Srinivas Kandagatla <[email protected]>
 +M:    Stuart Menefy <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +L:    [email protected]
 +W:    http://www.stlinux.com
 +S:    Maintained
 +F:    arch/arm/mach-sti/
 +
  ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
  M:    Lennert Buytenhek <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -1320,6 -1311,7 +1322,7 @@@ W:      http://wiki.xilinx.co
  T:    git git://git.xilinx.com/linux-xlnx.git
  S:    Supported
  F:    arch/arm/mach-zynq/
+ F:    drivers/cpuidle/cpuidle-zynq.c
  
  ARM64 PORT (AARCH64 ARCHITECTURE)
  M:    Catalin Marinas <[email protected]>
@@@ -2131,10 -2123,9 +2134,10 @@@ M:    Mike Turquette <[email protected]
  L:    [email protected] (same as CLK API & CLKDEV)
  T:    git git://git.linaro.org/people/mturquette/linux.git
  S:    Maintained
 -F:    drivers/clk/clk.c
 -F:    drivers/clk/clk-*
 +F:    drivers/clk/
 +X:    drivers/clk/clkdev.c
  F:    include/linux/clk-pr*
 +F:    include/linux/clk/
  
  COMMON INTERNET FILE SYSTEM (CIFS)
  M:    Steve French <[email protected]>
@@@ -2227,7 -2218,8 +2230,8 @@@ M:      Viresh Kumar <[email protected]
  L:    [email protected]
  L:    [email protected]
  S:    Maintained
- T:    git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
+ T:    git git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
  F:    drivers/cpufreq/
  F:    include/linux/cpufreq.h
  
@@@ -2528,7 -2520,7 +2532,7 @@@ F:      drivers/usb/dwc3
  DEVICE FREQUENCY (DEVFREQ)
  M:    MyungJoo Ham <[email protected]>
  M:    Kyungmin Park <[email protected]>
- L:    linux-kernel@vger.kernel.org
+ L:    linux-pm@vger.kernel.org
  S:    Maintained
  F:    drivers/devfreq/
  
@@@ -3232,7 -3224,7 +3236,7 @@@ F:      lib/fault-inject.
  
  FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
  M:    Robert Love <[email protected]>
 -L:    [email protected]
 +L:    fcoe-[email protected]
  W:    www.Open-FCoE.org
  S:    Supported
  F:    drivers/scsi/libfc/
@@@ -3321,15 -3313,6 +3325,15 @@@ T:    git git://git.kernel.org/pub/scm/lin
  S:    Odd fixes
  F:    drivers/block/floppy.c
  
 +FMC SUBSYSTEM
 +M:    Alessandro Rubini <[email protected]>
 +W:    http://www.ohwr.org/projects/fmc-bus
 +S:    Supported
 +F:    drivers/fmc/
 +F:    include/linux/fmc*.h
 +F:    include/linux/ipmi-fru.h
 +K:    fmc_d.*register
 +
  FPU EMULATOR
  M:    Bill Metzenthen <[email protected]>
  W:    http://floatingpoint.sourceforge.net/emulator/index.html
@@@ -3588,7 -3571,6 +3592,7 @@@ GPIO SUBSYSTE
  M:    Grant Likely <[email protected]>
  M:    Linus Walleij <[email protected]>
  S:    Maintained
 +L:    [email protected]
  T:    git git://git.secretlab.ca/git/linux-2.6.git
  F:    Documentation/gpio.txt
  F:    drivers/gpio/
@@@ -4001,8 -3983,7 +4005,8 @@@ S:      Maintaine
  F:    arch/ia64/
  
  IBM Power in-Nest Crypto Acceleration
 -M:    Kent Yoder <[email protected]>
 +M:    Marcelo Henrique Cerri <[email protected]>
 +M:    Fionnuala Gunter <[email protected]>
  L:    [email protected]
  S:    Supported
  F:    drivers/crypto/nx/
@@@ -4131,7 -4112,6 +4135,7 @@@ F:      drivers/ipack
  
  INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
  M:    Mimi Zohar <[email protected]>
 +M:    Dmitry Kasatkin <[email protected]>
  S:    Supported
  F:    security/integrity/ima/
  
@@@ -4601,7 -4581,7 +4605,7 @@@ F:      fs/jbd2
  F:    include/linux/jbd2.h
  
  JSM Neo PCI based serial card
 -M:    Lucas Tavares <lucaskt@linux.vnet.ibm.com>
 +M:    Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
  L:    [email protected]
  S:    Maintained
  F:    drivers/tty/serial/jsm/
@@@ -4735,23 -4715,14 +4739,23 @@@ F:   arch/s390/kvm
  F:    drivers/s390/kvm/
  
  KERNEL VIRTUAL MACHINE (KVM) FOR ARM
 -M:    Christoffer Dall <c[email protected]>
 +M:    Christoffer Dall <c[email protected]>
  L:    [email protected]
  W:    http://systems.cs.columbia.edu/projects/kvm-arm
 -S:    Maintained
 +S:    Supported
  F:    arch/arm/include/uapi/asm/kvm*
  F:    arch/arm/include/asm/kvm*
  F:    arch/arm/kvm/
  
 +KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
 +M:    Marc Zyngier <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +L:    [email protected]
 +S:    Maintained
 +F:    arch/arm64/include/uapi/asm/kvm*
 +F:    arch/arm64/include/asm/kvm*
 +F:    arch/arm64/kvm/
 +
  KEXEC
  M:    Eric Biederman <[email protected]>
  W:    http://kernel.org/pub/linux/utils/kernel/kexec/
  S:    Maintained
  F:    drivers/pinctrl/pinctrl-at91.c
  
 +PIN CONTROLLER - SAMSUNG
 +M:    Tomasz Figa <[email protected]>
 +M:    Thomas Abraham <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +L:    [email protected] (moderated for non-subscribers)
 +S:    Maintained
 +F:    drivers/pinctrl/pinctrl-exynos.*
 +F:    drivers/pinctrl/pinctrl-s3c*
 +F:    drivers/pinctrl/pinctrl-samsung.*
 +
  PIN CONTROLLER - ST SPEAR
  M:    Viresh Kumar <[email protected]>
  L:    [email protected]
@@@ -7710,7 -7671,6 +7714,7 @@@ STABLE BRANC
  M:    Greg Kroah-Hartman <[email protected]>
  L:    [email protected]
  S:    Supported
 +F:    Documentation/stable_kernel_rules.txt
  
  STAGING SUBSYSTEM
  M:    Greg Kroah-Hartman <[email protected]>
@@@ -7827,7 -7787,7 +7831,7 @@@ F:      drivers/staging/media/solo6x10
  STAGING - SPEAKUP CONSOLE SPEECH DRIVER
  M:    William Hubbs <[email protected]>
  M:    Chris Brannon <[email protected]>
 -M:    Kirk Reiser <kirk@braille.uwo.ca>
 +M:    Kirk Reiser <kirk@reisers.ca>
  M:    Samuel Thibault <[email protected]>
  L:    [email protected]
  W:    http://www.linux-speakup.org/
@@@ -8284,8 -8244,7 +8288,8 @@@ S:      Odd fixe
  F:    drivers/media/usb/tm6000/
  
  TPM DEVICE DRIVER
 -M:    Kent Yoder <[email protected]>
 +M:    Leonidas Da Silva Barbosa <[email protected]>
 +M:    Ashley Lai <[email protected]>
  M:    Rajiv Andrade <[email protected]>
  W:    http://tpmdd.sourceforge.net
  M:    Marcel Selhorst <[email protected]>
@@@ -9159,13 -9118,6 +9163,13 @@@ S:    Supporte
  F:    arch/arm/xen/
  F:    arch/arm/include/asm/xen/
  
 +XEN HYPERVISOR ARM64
 +M:    Stefano Stabellini <[email protected]>
 +L:    [email protected] (moderated for non-subscribers)
 +S:    Supported
 +F:    arch/arm64/xen/
 +F:    arch/arm64/include/asm/xen/
 +
  XEN NETWORK BACKEND DRIVER
  M:    Ian Campbell <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
index 68be532f8688c30e857cc4463c414ab4ffc18c9c,e37feb2f05a3355b4ebc52bad9246451ee859409..5cc92874be7e6f22d81767c0f75e141376ab83d6
@@@ -170,6 -170,9 +170,6 @@@ static int omap_device_build_from_dt(st
                        r->name = dev_name(&pdev->dev);
        }
  
 -      if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
 -              omap_device_disable_idle_on_suspend(pdev);
 -
        pdev->dev.pm_domain = &omap_device_pm_domain;
  
  odbfd_exit1:
@@@ -588,11 -591,6 +588,6 @@@ static int _od_runtime_suspend(struct d
        return ret;
  }
  
- static int _od_runtime_idle(struct device *dev)
- {
-       return pm_generic_runtime_idle(dev);
- }
  static int _od_runtime_resume(struct device *dev)
  {
        struct platform_device *pdev = to_platform_device(dev);
@@@ -618,7 -616,8 +613,7 @@@ static int _od_suspend_noirq(struct dev
  
        if (!ret && !pm_runtime_status_suspended(dev)) {
                if (pm_generic_runtime_suspend(dev) == 0) {
 -                      if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND))
 -                              omap_device_idle(pdev);
 +                      omap_device_idle(pdev);
                        od->flags |= OMAP_DEVICE_SUSPENDED;
                }
        }
@@@ -634,7 -633,8 +629,7 @@@ static int _od_resume_noirq(struct devi
        if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
            !pm_runtime_status_suspended(dev)) {
                od->flags &= ~OMAP_DEVICE_SUSPENDED;
 -              if (!(od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND))
 -                      omap_device_enable(pdev);
 +              omap_device_enable(pdev);
                pm_generic_runtime_resume(dev);
        }
  
  struct dev_pm_domain omap_device_pm_domain = {
        .ops = {
                SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
-                                  _od_runtime_idle)
+                                  NULL)
                USE_PLATFORM_PM_SLEEP_OPS
                .suspend_noirq = _od_suspend_noirq,
                .resume_noirq = _od_resume_noirq,
index 65c5ae6fa386ac34fa2ac3a5ab032e655ce1432f,5c0db065baa411f56722e17409968eb25b027aac..ef3a8da49b2d223616514c364e554f14add271d1
@@@ -28,7 -28,6 +28,6 @@@ config ARCH_TEGRA_2x_SO
        select ARM_ERRATA_754327 if SMP
        select ARM_ERRATA_764369 if SMP
        select ARM_GIC
-       select CPU_FREQ_TABLE if CPU_FREQ
        select CPU_V7
        select PINCTRL
        select PINCTRL_TEGRA20
@@@ -46,7 -45,6 +45,6 @@@ config ARCH_TEGRA_3x_SO
        select ARM_ERRATA_754322
        select ARM_ERRATA_764369 if SMP
        select ARM_GIC
-       select CPU_FREQ_TABLE if CPU_FREQ
        select CPU_V7
        select PINCTRL
        select PINCTRL_TEGRA30
  
  config ARCH_TEGRA_114_SOC
        bool "Enable support for Tegra114 family"
 -      select ARM_ARCH_TIMER
 +      select HAVE_ARM_ARCH_TIMER
        select ARM_GIC
        select ARM_L1_CACHE_SHIFT_6
-       select CPU_FREQ_TABLE if CPU_FREQ
        select CPU_V7
        select PINCTRL
        select PINCTRL_TEGRA114
index d7e17150028a678f1a9042a921a77f48b9d7681e,a8a760ddfae1c0216f8da907fcc255b420fce3dc..7231c8e4975e5ed2a15d9124531b1f8240fa91dd
@@@ -202,7 -202,7 +202,7 @@@ extern int s3c_plltab_register(struct c
  extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
  extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
  
 -#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
 +#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS
  #define s3c_cpufreq_debugfs_call(x) x
  #else
  #define s3c_cpufreq_debugfs_call(x) NULL
@@@ -259,17 -259,17 +259,17 @@@ extern void s3c2412_iotiming_set(struc
  #define s3c2412_iotiming_set NULL
  #endif /* CONFIG_S3C2412_IOTIMING */
  
 -#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
 +#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG
  #define s3c_freq_dbg(x...) printk(KERN_INFO x)
  #else
  #define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
 -#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
 +#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */
  
 -#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
 +#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG
  #define s3c_freq_iodbg(x...) printk(KERN_INFO x)
  #else
  #define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
 -#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
 +#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */
  
  static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
                                      int index, size_t table_size,
                s3c_freq_dbg("%s: { %d = %u kHz }\n",
                             __func__, index, freq);
  
-               table[index].index = index;
+               table[index].driver_data = index;
                table[index].frequency = freq;
        }
  
diff --combined arch/cris/Kconfig
index 9f3c54360e7852058378f6b9af4289a0d0562acc,5f7530cc9a279a133f1f17a278c5fb53fb39f43b..3201ddb8da6a039d3fd56b3fa13969648a004d08
@@@ -134,11 -134,13 +134,13 @@@ config SVINTO_SI
  
  config ETRAXFS
        bool "ETRAX-FS-V32"
+       select CPU_FREQ_TABLE if CPU_FREQ
        help
          Support CRIS V32.
  
  config CRIS_MACH_ARTPEC3
          bool "ARTPEC-3"
+       select CPU_FREQ_TABLE if CPU_FREQ
          help
            Support Axis ARTPEC-3.
  
@@@ -637,10 -639,40 +639,10 @@@ endchoic
  
  endmenu
  
 -source "drivers/base/Kconfig"
 -
 -# standard linux drivers
 -source "drivers/mtd/Kconfig"
 -
 -source "drivers/parport/Kconfig"
 -
 -source "drivers/pnp/Kconfig"
 -
 -source "drivers/block/Kconfig"
 -
 -source "drivers/ide/Kconfig"
 -
 -source "drivers/net/Kconfig"
 -
 -source "drivers/i2c/Kconfig"
 -
 -source "drivers/rtc/Kconfig"
 -
 -#
 -# input before char - char/joystick depends on it. As does USB.
 -#
 -source "drivers/input/Kconfig"
 -
 -source "drivers/char/Kconfig"
 +source "drivers/Kconfig"
  
  source "fs/Kconfig"
  
 -source "drivers/usb/Kconfig"
 -
 -source "drivers/uwb/Kconfig"
 -
 -source "drivers/staging/Kconfig"
 -
  source "arch/cris/Kconfig.debug"
  
  source "security/Kconfig"
diff --combined drivers/base/core.c
index 6fdc53d46fa05ee244d46cd0787c55292c247b07,2166f34b7d842ac7fa8d129858dac244e9e5394a..dc3ea237f086948ec5fe4a5ccd74bb47050fc336
@@@ -193,12 -193,12 +193,12 @@@ ssize_t device_show_bool(struct device 
  EXPORT_SYMBOL_GPL(device_show_bool);
  
  /**
 - *    device_release - free device structure.
 - *    @kobj:  device's kobject.
 + * device_release - free device structure.
 + * @kobj: device's kobject.
   *
 - *    This is called once the reference count for the object
 - *    reaches 0. We forward the call to the device's release
 - *    method, which should handle actually freeing the structure.
 + * This is called once the reference count for the object
 + * reaches 0. We forward the call to the device's release
 + * method, which should handle actually freeing the structure.
   */
  static void device_release(struct kobject *kobj)
  {
@@@ -403,6 -403,36 +403,36 @@@ static ssize_t store_uevent(struct devi
  static struct device_attribute uevent_attr =
        __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
  
+ static ssize_t show_online(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+ {
+       bool val;
+       lock_device_hotplug();
+       val = !dev->offline;
+       unlock_device_hotplug();
+       return sprintf(buf, "%u\n", val);
+ }
+ static ssize_t store_online(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+ {
+       bool val;
+       int ret;
+       ret = strtobool(buf, &val);
+       if (ret < 0)
+               return ret;
+       lock_device_hotplug();
+       ret = val ? device_online(dev) : device_offline(dev);
+       unlock_device_hotplug();
+       return ret < 0 ? ret : count;
+ }
+ static struct device_attribute online_attr =
+       __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
  static int device_add_attributes(struct device *dev,
                                 struct device_attribute *attrs)
  {
@@@ -516,6 -546,12 +546,12 @@@ static int device_add_attrs(struct devi
        if (error)
                goto err_remove_type_groups;
  
+       if (device_supports_offline(dev) && !dev->offline_disabled) {
+               error = device_create_file(dev, &online_attr);
+               if (error)
+                       goto err_remove_type_groups;
+       }
        return 0;
  
   err_remove_type_groups:
@@@ -536,6 -572,7 +572,7 @@@ static void device_remove_attrs(struct 
        struct class *class = dev->class;
        const struct device_type *type = dev->type;
  
+       device_remove_file(dev, &online_attr);
        device_remove_groups(dev, dev->groups);
  
        if (type)
@@@ -1334,8 -1371,8 +1371,8 @@@ const char *device_get_devnode(struct d
  /**
   * device_for_each_child - device child iterator.
   * @parent: parent struct device.
 - * @data: data for the callback.
   * @fn: function to be called for each device.
 + * @data: data for the callback.
   *
   * Iterate over @parent's child devices, and call @fn for each,
   * passing it @data.
@@@ -1363,8 -1400,8 +1400,8 @@@ int device_for_each_child(struct devic
  /**
   * device_find_child - device iterator for locating a particular device.
   * @parent: parent struct device
 - * @data: Data to pass to match function
   * @match: Callback function to check device
 + * @data: Data to pass to match function
   *
   * This is similar to the device_for_each_child() function above, but it
   * returns a reference to a device that is 'found' for later use, as
   * if it does.  If the callback returns non-zero and a reference to the
   * current device can be obtained, this function will return to the caller
   * and not iterate over any more devices.
 + *
 + * NOTE: you will need to drop the reference with put_device() after use.
   */
  struct device *device_find_child(struct device *parent, void *data,
                                 int (*match)(struct device *dev, void *data))
@@@ -1435,6 -1470,99 +1472,99 @@@ EXPORT_SYMBOL_GPL(put_device)
  EXPORT_SYMBOL_GPL(device_create_file);
  EXPORT_SYMBOL_GPL(device_remove_file);
  
+ static DEFINE_MUTEX(device_hotplug_lock);
+ void lock_device_hotplug(void)
+ {
+       mutex_lock(&device_hotplug_lock);
+ }
+ void unlock_device_hotplug(void)
+ {
+       mutex_unlock(&device_hotplug_lock);
+ }
+ static int device_check_offline(struct device *dev, void *not_used)
+ {
+       int ret;
+       ret = device_for_each_child(dev, NULL, device_check_offline);
+       if (ret)
+               return ret;
+       return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0;
+ }
+ /**
+  * device_offline - Prepare the device for hot-removal.
+  * @dev: Device to be put offline.
+  *
+  * Execute the device bus type's .offline() callback, if present, to prepare
+  * the device for a subsequent hot-removal.  If that succeeds, the device must
+  * not be used until either it is removed or its bus type's .online() callback
+  * is executed.
+  *
+  * Call under device_hotplug_lock.
+  */
+ int device_offline(struct device *dev)
+ {
+       int ret;
+       if (dev->offline_disabled)
+               return -EPERM;
+       ret = device_for_each_child(dev, NULL, device_check_offline);
+       if (ret)
+               return ret;
+       device_lock(dev);
+       if (device_supports_offline(dev)) {
+               if (dev->offline) {
+                       ret = 1;
+               } else {
+                       ret = dev->bus->offline(dev);
+                       if (!ret) {
+                               kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+                               dev->offline = true;
+                       }
+               }
+       }
+       device_unlock(dev);
+       return ret;
+ }
+ /**
+  * device_online - Put the device back online after successful device_offline().
+  * @dev: Device to be put back online.
+  *
+  * If device_offline() has been successfully executed for @dev, but the device
+  * has not been removed subsequently, execute its bus type's .online() callback
+  * to indicate that the device can be used again.
+  *
+  * Call under device_hotplug_lock.
+  */
+ int device_online(struct device *dev)
+ {
+       int ret = 0;
+       device_lock(dev);
+       if (device_supports_offline(dev)) {
+               if (dev->offline) {
+                       ret = dev->bus->online(dev);
+                       if (!ret) {
+                               kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+                               dev->offline = false;
+                       }
+               } else {
+                       ret = 1;
+               }
+       }
+       device_unlock(dev);
+       return ret;
+ }
  struct root_device {
        struct device dev;
        struct module *owner;
diff --combined drivers/base/cpu.c
index c377673320eda18e32c7eb25aa87e72e4deb12e6,1d110dc6f0c1f371ac262a9f6e352b5d626bf2fa..a16d20e389f0f2fead522d97edee5f3c66bc9112
  #include <linux/gfp.h>
  #include <linux/slab.h>
  #include <linux/percpu.h>
+ #include <linux/acpi.h>
  
  #include "base.h"
  
- struct bus_type cpu_subsys = {
-       .name = "cpu",
-       .dev_name = "cpu",
- };
- EXPORT_SYMBOL_GPL(cpu_subsys);
  static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
  
+ static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
+ {
+       /* ACPI style match is the only one that may succeed. */
+       if (acpi_driver_match_device(dev, drv))
+               return 1;
+       return 0;
+ }
  #ifdef CONFIG_HOTPLUG_CPU
  static void change_cpu_under_node(struct cpu *cpu,
                        unsigned int from_nid, unsigned int to_nid)
        cpu->node_id = to_nid;
  }
  
- static ssize_t show_online(struct device *dev,
-                          struct device_attribute *attr,
-                          char *buf)
+ static int __ref cpu_subsys_online(struct device *dev)
  {
        struct cpu *cpu = container_of(dev, struct cpu, dev);
+       int cpuid = dev->id;
+       int from_nid, to_nid;
+       int ret;
+       cpu_hotplug_driver_lock();
  
-       return sprintf(buf, "%u\n", !!cpu_online(cpu->dev.id));
+       from_nid = cpu_to_node(cpuid);
+       ret = cpu_up(cpuid);
+       /*
+        * When hot adding memory to memoryless node and enabling a cpu
+        * on the node, node number of the cpu may internally change.
+        */
+       to_nid = cpu_to_node(cpuid);
+       if (from_nid != to_nid)
+               change_cpu_under_node(cpu, from_nid, to_nid);
+       cpu_hotplug_driver_unlock();
+       return ret;
  }
  
- static ssize_t __ref store_online(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
+ static int cpu_subsys_offline(struct device *dev)
  {
-       struct cpu *cpu = container_of(dev, struct cpu, dev);
-       int cpuid = cpu->dev.id;
-       int from_nid, to_nid;
-       ssize_t ret;
+       int ret;
  
        cpu_hotplug_driver_lock();
-       switch (buf[0]) {
-       case '0':
-               ret = cpu_down(cpuid);
-               if (!ret)
-                       kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
-               break;
-       case '1':
-               from_nid = cpu_to_node(cpuid);
-               ret = cpu_up(cpuid);
-               /*
-                * When hot adding memory to memoryless node and enabling a cpu
-                * on the node, node number of the cpu may internally change.
-                */
-               to_nid = cpu_to_node(cpuid);
-               if (from_nid != to_nid)
-                       change_cpu_under_node(cpu, from_nid, to_nid);
-               if (!ret)
-                       kobject_uevent(&dev->kobj, KOBJ_ONLINE);
-               break;
-       default:
-               ret = -EINVAL;
-       }
+       ret = cpu_down(dev->id);
        cpu_hotplug_driver_unlock();
-       if (ret >= 0)
-               ret = count;
        return ret;
  }
- static DEVICE_ATTR(online, 0644, show_online, store_online);
- static struct attribute *hotplug_cpu_attrs[] = {
-       &dev_attr_online.attr,
-       NULL
- };
- static struct attribute_group hotplug_cpu_attr_group = {
-       .attrs = hotplug_cpu_attrs,
- };
  
  void unregister_cpu(struct cpu *cpu)
  {
@@@ -125,8 -102,20 +102,19 @@@ static ssize_t cpu_release_store(struc
  static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
  static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
  #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 -
  #endif /* CONFIG_HOTPLUG_CPU */
  
+ struct bus_type cpu_subsys = {
+       .name = "cpu",
+       .dev_name = "cpu",
+       .match = cpu_subsys_match,
+ #ifdef CONFIG_HOTPLUG_CPU
+       .online = cpu_subsys_online,
+       .offline = cpu_subsys_offline,
+ #endif
+ };
+ EXPORT_SYMBOL_GPL(cpu_subsys);
  #ifdef CONFIG_KEXEC
  #include <linux/kexec.h>
  
@@@ -162,35 -151,8 +150,32 @@@ static ssize_t show_crash_notes_size(st
        return rc;
  }
  static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);
 +
 +static struct attribute *crash_note_cpu_attrs[] = {
 +      &dev_attr_crash_notes.attr,
 +      &dev_attr_crash_notes_size.attr,
 +      NULL
 +};
 +
 +static struct attribute_group crash_note_cpu_attr_group = {
 +      .attrs = crash_note_cpu_attrs,
 +};
  #endif
  
- #endif
- #ifdef CONFIG_HOTPLUG_CPU
-       &hotplug_cpu_attr_group,
 +static const struct attribute_group *common_cpu_attr_groups[] = {
 +#ifdef CONFIG_KEXEC
 +      &crash_note_cpu_attr_group,
 +#endif
 +      NULL
 +};
 +
 +static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
 +#ifdef CONFIG_KEXEC
 +      &crash_note_cpu_attr_group,
 +#endif
 +      NULL
 +};
 +
  /*
   * Print cpu online, possible, present, and system maps
   */
@@@ -302,18 -264,24 +287,20 @@@ int __cpuinit register_cpu(struct cpu *
        cpu->dev.id = num;
        cpu->dev.bus = &cpu_subsys;
        cpu->dev.release = cpu_device_release;
+       cpu->dev.offline_disabled = !cpu->hotpluggable;
+       cpu->dev.offline = !cpu_online(num);
  #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
        cpu->dev.bus->uevent = arch_cpu_uevent;
  #endif
 +      cpu->dev.groups = common_cpu_attr_groups;
 +      if (cpu->hotpluggable)
 +              cpu->dev.groups = hotplugable_cpu_attr_groups;
        error = device_register(&cpu->dev);
        if (!error)
                per_cpu(cpu_sys_devices, num) = &cpu->dev;
        if (!error)
                register_cpu_under_node(num, cpu_to_node(num));
  
 -#ifdef CONFIG_KEXEC
 -      if (!error)
 -              error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
 -      if (!error)
 -              error = device_create_file(&cpu->dev,
 -                                         &dev_attr_crash_notes_size);
 -#endif
        return error;
  }
  
diff --combined drivers/base/memory.c
index e315051cfeebbdb25a4420b7d3eaeb7d4d57b74f,4ebf97f99fae0f84fb7d8f28bc9a9bd513f7b5aa..2b7813ec6d02f31e842d181b61b01fa6be6f4b9d
@@@ -37,9 -37,14 +37,14 @@@ static inline int base_memory_block_id(
        return section_nr / sections_per_block;
  }
  
+ static int memory_subsys_online(struct device *dev);
+ static int memory_subsys_offline(struct device *dev);
  static struct bus_type memory_subsys = {
        .name = MEMORY_CLASS_NAME,
        .dev_name = MEMORY_CLASS_NAME,
+       .online = memory_subsys_online,
+       .offline = memory_subsys_offline,
  };
  
  static BLOCKING_NOTIFIER_HEAD(memory_chain);
@@@ -77,6 -82,23 +82,6 @@@ static void memory_block_release(struc
        kfree(mem);
  }
  
 -/*
 - * register_memory - Setup a sysfs device for a memory block
 - */
 -static
 -int register_memory(struct memory_block *memory)
 -{
 -      int error;
 -
 -      memory->dev.bus = &memory_subsys;
 -      memory->dev.id = memory->start_section_nr / sections_per_block;
 -      memory->dev.release = memory_block_release;
 -      memory->dev.offline = memory->state == MEM_OFFLINE;
 -
 -      error = device_register(&memory->dev);
 -      return error;
 -}
 -
  unsigned long __weak memory_block_size_bytes(void)
  {
        return MIN_MEMORY_BLOCK_SIZE;
@@@ -262,33 -284,64 +267,64 @@@ static int __memory_block_change_state(
  {
        int ret = 0;
  
-       if (mem->state != from_state_req) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (mem->state != from_state_req)
+               return -EINVAL;
  
        if (to_state == MEM_OFFLINE)
                mem->state = MEM_GOING_OFFLINE;
  
        ret = memory_block_action(mem->start_section_nr, to_state, online_type);
+       mem->state = ret ? from_state_req : to_state;
+       return ret;
+ }
  
-       if (ret) {
-               mem->state = from_state_req;
-               goto out;
-       }
+ static int memory_subsys_online(struct device *dev)
+ {
+       struct memory_block *mem = container_of(dev, struct memory_block, dev);
+       int ret;
  
-       mem->state = to_state;
-       switch (mem->state) {
-       case MEM_OFFLINE:
-               kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
-               break;
-       case MEM_ONLINE:
-               kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
-               break;
-       default:
-               break;
+       mutex_lock(&mem->state_mutex);
+       ret = mem->state == MEM_ONLINE ? 0 :
+               __memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE,
+                                           ONLINE_KEEP);
+       mutex_unlock(&mem->state_mutex);
+       return ret;
+ }
+ static int memory_subsys_offline(struct device *dev)
+ {
+       struct memory_block *mem = container_of(dev, struct memory_block, dev);
+       int ret;
+       mutex_lock(&mem->state_mutex);
+       ret = mem->state == MEM_OFFLINE ? 0 :
+               __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
+       mutex_unlock(&mem->state_mutex);
+       return ret;
+ }
+ static int __memory_block_change_state_uevent(struct memory_block *mem,
+               unsigned long to_state, unsigned long from_state_req,
+               int online_type)
+ {
+       int ret = __memory_block_change_state(mem, to_state, from_state_req,
+                                             online_type);
+       if (!ret) {
+               switch (mem->state) {
+               case MEM_OFFLINE:
+                       kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
+                       break;
+               case MEM_ONLINE:
+                       kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
+                       break;
+               default:
+                       break;
+               }
        }
- out:
        return ret;
  }
  
@@@ -299,8 -352,8 +335,8 @@@ static int memory_block_change_state(st
        int ret;
  
        mutex_lock(&mem->state_mutex);
-       ret = __memory_block_change_state(mem, to_state, from_state_req,
-                                         online_type);
+       ret = __memory_block_change_state_uevent(mem, to_state, from_state_req,
+                                                online_type);
        mutex_unlock(&mem->state_mutex);
  
        return ret;
@@@ -310,22 -363,34 +346,34 @@@ store_mem_state(struct device *dev
                struct device_attribute *attr, const char *buf, size_t count)
  {
        struct memory_block *mem;
+       bool offline;
        int ret = -EINVAL;
  
        mem = container_of(dev, struct memory_block, dev);
  
-       if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
+       lock_device_hotplug();
+       if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
+               offline = false;
                ret = memory_block_change_state(mem, MEM_ONLINE,
                                                MEM_OFFLINE, ONLINE_KERNEL);
-       else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
+       } else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) {
+               offline = false;
                ret = memory_block_change_state(mem, MEM_ONLINE,
                                                MEM_OFFLINE, ONLINE_MOVABLE);
-       else if (!strncmp(buf, "online", min_t(int, count, 6)))
+       } else if (!strncmp(buf, "online", min_t(int, count, 6))) {
+               offline = false;
                ret = memory_block_change_state(mem, MEM_ONLINE,
                                                MEM_OFFLINE, ONLINE_KEEP);
-       else if(!strncmp(buf, "offline", min_t(int, count, 7)))
+       } else if(!strncmp(buf, "offline", min_t(int, count, 7))) {
+               offline = true;
                ret = memory_block_change_state(mem, MEM_OFFLINE,
                                                MEM_ONLINE, -1);
+       }
+       if (!ret)
+               dev->offline = offline;
+       unlock_device_hotplug();
  
        if (ret)
                return ret;
@@@ -355,6 -420,11 +403,6 @@@ static DEVICE_ATTR(state, 0644, show_me
  static DEVICE_ATTR(phys_device, 0444, show_phys_device, NULL);
  static DEVICE_ATTR(removable, 0444, show_mem_removable, NULL);
  
 -#define mem_create_simple_file(mem, attr_name)        \
 -      device_create_file(&mem->dev, &dev_attr_##attr_name)
 -#define mem_remove_simple_file(mem, attr_name)        \
 -      device_remove_file(&mem->dev, &dev_attr_##attr_name)
 -
  /*
   * Block size attribute stuff
   */
@@@ -367,6 -437,12 +415,6 @@@ print_block_size(struct device *dev, st
  
  static DEVICE_ATTR(block_size_bytes, 0444, print_block_size, NULL);
  
 -static int block_size_init(void)
 -{
 -      return device_create_file(memory_subsys.dev_root,
 -                                &dev_attr_block_size_bytes);
 -}
 -
  /*
   * Some architectures will have custom drivers to do this, and
   * will not need to do it from userspace.  The fake hot-add code
@@@ -402,8 -478,17 +450,8 @@@ memory_probe_store(struct device *dev, 
  out:
        return ret;
  }
 -static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
  
 -static int memory_probe_init(void)
 -{
 -      return device_create_file(memory_subsys.dev_root, &dev_attr_probe);
 -}
 -#else
 -static inline int memory_probe_init(void)
 -{
 -      return 0;
 -}
 +static DEVICE_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
  #endif
  
  #ifdef CONFIG_MEMORY_FAILURE
@@@ -449,6 -534,23 +497,6 @@@ store_hard_offline_page(struct device *
  
  static DEVICE_ATTR(soft_offline_page, S_IWUSR, NULL, store_soft_offline_page);
  static DEVICE_ATTR(hard_offline_page, S_IWUSR, NULL, store_hard_offline_page);
 -
 -static __init int memory_fail_init(void)
 -{
 -      int err;
 -
 -      err = device_create_file(memory_subsys.dev_root,
 -                              &dev_attr_soft_offline_page);
 -      if (!err)
 -              err = device_create_file(memory_subsys.dev_root,
 -                              &dev_attr_hard_offline_page);
 -      return err;
 -}
 -#else
 -static inline int memory_fail_init(void)
 -{
 -      return 0;
 -}
  #endif
  
  /*
@@@ -493,41 -595,6 +541,42 @@@ struct memory_block *find_memory_block(
        return find_memory_block_hinted(section, NULL);
  }
  
 +static struct attribute *memory_memblk_attrs[] = {
 +      &dev_attr_phys_index.attr,
 +      &dev_attr_end_phys_index.attr,
 +      &dev_attr_state.attr,
 +      &dev_attr_phys_device.attr,
 +      &dev_attr_removable.attr,
 +      NULL
 +};
 +
 +static struct attribute_group memory_memblk_attr_group = {
 +      .attrs = memory_memblk_attrs,
 +};
 +
 +static const struct attribute_group *memory_memblk_attr_groups[] = {
 +      &memory_memblk_attr_group,
 +      NULL,
 +};
 +
 +/*
 + * register_memory - Setup a sysfs device for a memory block
 + */
 +static
 +int register_memory(struct memory_block *memory)
 +{
 +      int error;
 +
 +      memory->dev.bus = &memory_subsys;
 +      memory->dev.id = memory->start_section_nr / sections_per_block;
 +      memory->dev.release = memory_block_release;
 +      memory->dev.groups = memory_memblk_attr_groups;
++      memory->dev.offline = memory->state == MEM_OFFLINE;
 +
 +      error = device_register(&memory->dev);
 +      return error;
 +}
 +
  static int init_memory_block(struct memory_block **memory,
                             struct mem_section *section, unsigned long state)
  {
        mem->phys_device = arch_get_memory_phys_device(start_pfn);
  
        ret = register_memory(mem);
 -      if (!ret)
 -              ret = mem_create_simple_file(mem, phys_index);
 -      if (!ret)
 -              ret = mem_create_simple_file(mem, end_phys_index);
 -      if (!ret)
 -              ret = mem_create_simple_file(mem, state);
 -      if (!ret)
 -              ret = mem_create_simple_file(mem, phys_device);
 -      if (!ret)
 -              ret = mem_create_simple_file(mem, removable);
  
        *memory = mem;
        return ret;
@@@ -628,9 -705,14 +677,9 @@@ static int remove_memory_block(unsigne
        unregister_mem_sect_under_nodes(mem, __section_nr(section));
  
        mem->section_count--;
 -      if (mem->section_count == 0) {
 -              mem_remove_simple_file(mem, phys_index);
 -              mem_remove_simple_file(mem, end_phys_index);
 -              mem_remove_simple_file(mem, state);
 -              mem_remove_simple_file(mem, phys_device);
 -              mem_remove_simple_file(mem, removable);
 +      if (mem->section_count == 0)
                unregister_memory(mem);
 -      else
 +      else
                kobject_put(&mem->dev.kobj);
  
        mutex_unlock(&mem_sysfs_mutex);
@@@ -646,50 -728,12 +695,35 @@@ int unregister_memory_section(struct me
  }
  #endif /* CONFIG_MEMORY_HOTREMOVE */
  
- /*
-  * offline one memory block. If the memory block has been offlined, do nothing.
-  */
- int offline_memory_block(struct memory_block *mem)
- {
-       int ret = 0;
-       mutex_lock(&mem->state_mutex);
-       if (mem->state != MEM_OFFLINE)
-               ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
-       mutex_unlock(&mem->state_mutex);
-       return ret;
- }
  /* return true if the memory block is offlined, otherwise, return false */
  bool is_memblock_offlined(struct memory_block *mem)
  {
        return mem->state == MEM_OFFLINE;
  }
  
 +static struct attribute *memory_root_attrs[] = {
 +#ifdef CONFIG_ARCH_MEMORY_PROBE
 +      &dev_attr_probe.attr,
 +#endif
 +
 +#ifdef CONFIG_MEMORY_FAILURE
 +      &dev_attr_soft_offline_page.attr,
 +      &dev_attr_hard_offline_page.attr,
 +#endif
 +
 +      &dev_attr_block_size_bytes.attr,
 +      NULL
 +};
 +
 +static struct attribute_group memory_root_attr_group = {
 +      .attrs = memory_root_attrs,
 +};
 +
 +static const struct attribute_group *memory_root_attr_groups[] = {
 +      &memory_root_attr_group,
 +      NULL,
 +};
 +
  /*
   * Initialize the sysfs support for memory devices...
   */
@@@ -701,7 -745,7 +735,7 @@@ int __init memory_dev_init(void
        unsigned long block_sz;
        struct memory_block *mem = NULL;
  
 -      ret = subsys_system_register(&memory_subsys, NULL);
 +      ret = subsys_system_register(&memory_subsys, memory_root_attr_groups);
        if (ret)
                goto out;
  
                        ret = err;
        }
  
 -      err = memory_probe_init();
 -      if (!ret)
 -              ret = err;
 -      err = memory_fail_init();
 -      if (!ret)
 -              ret = err;
 -      err = block_size_init();
 -      if (!ret)
 -              ret = err;
  out:
        if (ret)
                printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
diff --combined drivers/base/platform.c
index ed75cf6ef9c9f121c50cb96c3ec9ea6bf4174b48,96a930387ebc749977b3f4ec6007f1478ba95fe3..6eaa7ab9e4bc6199c4fe9ce49b30a85068c78fe7
@@@ -523,13 -523,11 +523,13 @@@ static void platform_drv_shutdown(struc
  }
  
  /**
 - * platform_driver_register - register a driver for platform-level devices
 + * __platform_driver_register - register a driver for platform-level devices
   * @drv: platform driver structure
   */
 -int platform_driver_register(struct platform_driver *drv)
 +int __platform_driver_register(struct platform_driver *drv,
 +                              struct module *owner)
  {
 +      drv->driver.owner = owner;
        drv->driver.bus = &platform_bus_type;
        if (drv->probe)
                drv->driver.probe = platform_drv_probe;
  
        return driver_register(&drv->driver);
  }
 -EXPORT_SYMBOL_GPL(platform_driver_register);
 +EXPORT_SYMBOL_GPL(__platform_driver_register);
  
  /**
   * platform_driver_unregister - unregister a driver for platform-level devices
@@@ -890,7 -888,6 +890,6 @@@ int platform_pm_restore(struct device *
  static const struct dev_pm_ops platform_dev_pm_ops = {
        .runtime_suspend = pm_generic_runtime_suspend,
        .runtime_resume = pm_generic_runtime_resume,
-       .runtime_idle = pm_generic_runtime_idle,
        USE_PLATFORM_PM_SLEEP_OPS
  };
  
index a924408968682961cac83f70f8fef85f8d8ee893,fee9f489269a2564aafeeee32ba3b0b2d22db983..de4d5d93c3fdc826ae013c6f7e0652b13e550f2d
@@@ -5,6 -5,7 +5,7 @@@
  config ARM_BIG_LITTLE_CPUFREQ
        tristate "Generic ARM big LITTLE CPUfreq driver"
        depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
+       select CPU_FREQ_TABLE
        help
          This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
  
@@@ -18,6 -19,7 +19,7 @@@ config ARM_DT_BL_CPUFRE
  config ARM_EXYNOS_CPUFREQ
        bool "SAMSUNG EXYNOS SoCs"
        depends on ARCH_EXYNOS
+       select CPU_FREQ_TABLE
        default y
        help
          This adds the CPUFreq driver common part for Samsung
@@@ -46,6 -48,7 +48,7 @@@ config ARM_EXYNOS5250_CPUFRE
  config ARM_EXYNOS5440_CPUFREQ
        def_bool SOC_EXYNOS5440
        depends on HAVE_CLK && PM_OPP && OF
+       select CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for Samsung EXYNOS5440
          SoC. The nature of exynos5440 clock controller is
@@@ -55,7 -58,6 +58,6 @@@
  config ARM_HIGHBANK_CPUFREQ
        tristate "Calxeda Highbank-based"
        depends on ARCH_HIGHBANK
-       select CPU_FREQ_TABLE
        select GENERIC_CPUFREQ_CPU0
        select PM_OPP
        select REGULATOR
@@@ -71,6 -73,7 +73,7 @@@ config ARM_IMX6Q_CPUFRE
        tristate "Freescale i.MX6Q cpufreq support"
        depends on SOC_IMX6Q
        depends on REGULATOR_ANATOP
+       select CPU_FREQ_TABLE
        help
          This adds cpufreq driver support for Freescale i.MX6Q SOC.
  
@@@ -86,6 -89,7 +89,7 @@@ config ARM_INTEGRATO
  
  config ARM_KIRKWOOD_CPUFREQ
        def_bool ARCH_KIRKWOOD && OF
+       select CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for Marvell Kirkwood
          SoCs.
@@@ -96,59 -100,10 +100,60 @@@ config ARM_OMAP2PLUS_CPUFRE
        default ARCH_OMAP2PLUS
        select CPU_FREQ_TABLE
  
 +config ARM_S3C_CPUFREQ
 +      bool
 +      help
 +        Internal configuration node for common cpufreq on Samsung SoC
 +
 +config ARM_S3C24XX_CPUFREQ
 +      bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
 +      depends on ARCH_S3C24XX
 +      select ARM_S3C_CPUFREQ
 +      help
 +        This enables the CPUfreq driver for the Samsung S3C24XX family
 +        of CPUs.
 +
 +        For details, take a look at <file:Documentation/cpu-freq>.
 +
 +        If in doubt, say N.
 +
 +config ARM_S3C24XX_CPUFREQ_DEBUG
 +      bool "Debug CPUfreq Samsung driver core"
 +      depends on ARM_S3C24XX_CPUFREQ
 +      help
 +        Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
 +
 +config ARM_S3C24XX_CPUFREQ_IODEBUG
 +      bool "Debug CPUfreq Samsung driver IO timing"
 +      depends on ARM_S3C24XX_CPUFREQ
 +      help
 +        Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
 +
 +config ARM_S3C24XX_CPUFREQ_DEBUGFS
 +      bool "Export debugfs for CPUFreq"
 +      depends on ARM_S3C24XX_CPUFREQ && DEBUG_FS
 +      help
 +        Export status information via debugfs.
 +
 +config ARM_S3C2410_CPUFREQ
 +      bool
 +      depends on ARM_S3C24XX_CPUFREQ && CPU_S3C2410
 +      select S3C2410_CPUFREQ_UTILS
 +      help
 +        CPU Frequency scaling support for S3C2410
 +
 +config ARM_S3C2412_CPUFREQ
 +      bool
 +      depends on ARM_S3C24XX_CPUFREQ && CPU_S3C2412
 +      default y
 +      select S3C2412_IOTIMING
 +      help
 +        CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
 +
  config ARM_S3C2416_CPUFREQ
        bool "S3C2416 CPU Frequency scaling support"
        depends on CPU_S3C2416
+       select CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for the Samsung S3C2416 and
          S3C2450 SoC. The S3C2416 supports changing the rate of the
@@@ -168,17 -123,10 +173,18 @@@ config ARM_S3C2416_CPUFREQ_VCORESCAL
  
          If in doubt, say N.
  
 +config ARM_S3C2440_CPUFREQ
 +      bool "S3C2440/S3C2442 CPU Frequency scaling support"
 +      depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2440 || CPU_S3C2442)
 +      select S3C2410_CPUFREQ_UTILS
 +      default y
 +      help
 +        CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
 +
  config ARM_S3C64XX_CPUFREQ
        bool "Samsung S3C64XX"
        depends on CPU_S3C6410
+       select CPU_FREQ_TABLE
        default y
        help
          This adds the CPUFreq driver for Samsung S3C6410 SoC.
@@@ -205,6 -153,15 +211,15 @@@ config ARM_SA1110_CPUFRE
  config ARM_SPEAR_CPUFREQ
        bool "SPEAr CPUFreq support"
        depends on PLAT_SPEAR
+       select CPU_FREQ_TABLE
        default y
        help
          This adds the CPUFreq driver support for SPEAr SOCs.
+ config ARM_TEGRA_CPUFREQ
+       bool "TEGRA CPUFreq support"
+       depends on ARCH_TEGRA
+       select CPU_FREQ_TABLE
+       default y
+       help
+         This adds the CPUFreq driver support for TEGRA SOCs.
diff --combined drivers/cpufreq/Makefile
index 6ad0b913ca176c54bb2ef2669d16de355d560541,0c8d0c69306d68c29913caaafe70f4816c5310e3..d345b5a7aa719e52fd660013afdf96b4d3da6335
@@@ -65,18 -65,13 +65,18 @@@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)        += 
  obj-$(CONFIG_PXA25x)                  += pxa2xx-cpufreq.o
  obj-$(CONFIG_PXA27x)                  += pxa2xx-cpufreq.o
  obj-$(CONFIG_PXA3xx)                  += pxa3xx-cpufreq.o
 +obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)     += s3c24xx-cpufreq.o
 +obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o
 +obj-$(CONFIG_ARM_S3C2410_CPUFREQ)     += s3c2410-cpufreq.o
 +obj-$(CONFIG_ARM_S3C2412_CPUFREQ)     += s3c2412-cpufreq.o
  obj-$(CONFIG_ARM_S3C2416_CPUFREQ)     += s3c2416-cpufreq.o
 +obj-$(CONFIG_ARM_S3C2440_CPUFREQ)     += s3c2440-cpufreq.o
  obj-$(CONFIG_ARM_S3C64XX_CPUFREQ)     += s3c64xx-cpufreq.o
  obj-$(CONFIG_ARM_S5PV210_CPUFREQ)     += s5pv210-cpufreq.o
  obj-$(CONFIG_ARM_SA1100_CPUFREQ)      += sa1100-cpufreq.o
  obj-$(CONFIG_ARM_SA1110_CPUFREQ)      += sa1110-cpufreq.o
  obj-$(CONFIG_ARM_SPEAR_CPUFREQ)               += spear-cpufreq.o
- obj-$(CONFIG_ARCH_TEGRA)              += tegra-cpufreq.o
+ obj-$(CONFIG_ARM_TEGRA_CPUFREQ)               += tegra-cpufreq.o
  
  ##################################################################################
  # PowerPC platform drivers
@@@ -84,11 -79,15 +84,15 @@@ obj-$(CONFIG_CPU_FREQ_CBE)         += ppc-cbe-
  ppc-cbe-cpufreq-y                     += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
  obj-$(CONFIG_CPU_FREQ_CBE_PMI)                += ppc_cbe_cpufreq_pmi.o
  obj-$(CONFIG_CPU_FREQ_MAPLE)          += maple-cpufreq.o
+ obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
+ obj-$(CONFIG_CPU_FREQ_PMAC)           += pmac32-cpufreq.o
+ obj-$(CONFIG_CPU_FREQ_PMAC64)         += pmac64-cpufreq.o
+ obj-$(CONFIG_PPC_PASEMI_CPUFREQ)      += pasemi-cpufreq.o
  
  ##################################################################################
  # Other platform drivers
  obj-$(CONFIG_AVR32_AT32AP_CPUFREQ)    += at32ap-cpufreq.o
- obj-$(CONFIG_BLACKFIN)                        += blackfin-cpufreq.o
+ obj-$(CONFIG_BFIN_CPU_FREQ)           += blackfin-cpufreq.o
  obj-$(CONFIG_CRIS_MACH_ARTPEC3)               += cris-artpec3-cpufreq.o
  obj-$(CONFIG_ETRAXFS)                 += cris-etraxfs-cpufreq.o
  obj-$(CONFIG_IA64_ACPI_CPUFREQ)               += ia64-acpi-cpufreq.o
index 3c0e78ede0da0fcaa82512c6f9f91f3af2260f7b,0000000000000000000000000000000000000000..3513e747716007f0700dc58df1e8c96bffdc2151
mode 100644,000000..100644
--- /dev/null
@@@ -1,711 -1,0 +1,711 @@@
-       cfg->pll.index = __raw_readl(S3C2410_MPLLCON);
 +/*
 + * Copyright (c) 2006-2008 Simtec Electronics
 + *    http://armlinux.simtec.co.uk/
 + *    Ben Dooks <[email protected]>
 + *
 + * S3C24XX CPU Frequency scaling
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 +*/
 +
 +#include <linux/init.h>
 +#include <linux/module.h>
 +#include <linux/interrupt.h>
 +#include <linux/ioport.h>
 +#include <linux/cpufreq.h>
 +#include <linux/cpu.h>
 +#include <linux/clk.h>
 +#include <linux/err.h>
 +#include <linux/io.h>
 +#include <linux/device.h>
 +#include <linux/sysfs.h>
 +#include <linux/slab.h>
 +
 +#include <asm/mach/arch.h>
 +#include <asm/mach/map.h>
 +
 +#include <plat/cpu.h>
 +#include <plat/clock.h>
 +#include <plat/cpu-freq-core.h>
 +
 +#include <mach/regs-clock.h>
 +
 +/* note, cpufreq support deals in kHz, no Hz */
 +
 +static struct cpufreq_driver s3c24xx_driver;
 +static struct s3c_cpufreq_config cpu_cur;
 +static struct s3c_iotimings s3c24xx_iotiming;
 +static struct cpufreq_frequency_table *pll_reg;
 +static unsigned int last_target = ~0;
 +static unsigned int ftab_size;
 +static struct cpufreq_frequency_table *ftab;
 +
 +static struct clk *_clk_mpll;
 +static struct clk *_clk_xtal;
 +static struct clk *clk_fclk;
 +static struct clk *clk_hclk;
 +static struct clk *clk_pclk;
 +static struct clk *clk_arm;
 +
 +#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
 +struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
 +{
 +      return &cpu_cur;
 +}
 +
 +struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
 +{
 +      return &s3c24xx_iotiming;
 +}
 +#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */
 +
 +static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
 +{
 +      unsigned long fclk, pclk, hclk, armclk;
 +
 +      cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
 +      cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
 +      cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
 +      cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
 +
-       suspend_pll.index = __raw_readl(S3C2410_MPLLCON);
++      cfg->pll.driver_data = __raw_readl(S3C2410_MPLLCON);
 +      cfg->pll.frequency = fclk;
 +
 +      cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
 +
 +      cfg->divs.h_divisor = fclk / hclk;
 +      cfg->divs.p_divisor = fclk / pclk;
 +}
 +
 +static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
 +{
 +      unsigned long pll = cfg->pll.frequency;
 +
 +      cfg->freq.fclk = pll;
 +      cfg->freq.hclk = pll / cfg->divs.h_divisor;
 +      cfg->freq.pclk = pll / cfg->divs.p_divisor;
 +
 +      /* convert hclk into 10ths of nanoseconds for io calcs */
 +      cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
 +}
 +
 +static inline int closer(unsigned int target, unsigned int n, unsigned int c)
 +{
 +      int diff_cur = abs(target - c);
 +      int diff_new = abs(target - n);
 +
 +      return (diff_new < diff_cur);
 +}
 +
 +static void s3c_cpufreq_show(const char *pfx,
 +                               struct s3c_cpufreq_config *cfg)
 +{
 +      s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
 +                   pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
 +                   cfg->freq.hclk, cfg->divs.h_divisor,
 +                   cfg->freq.pclk, cfg->divs.p_divisor);
 +}
 +
 +/* functions to wrapper the driver info calls to do the cpu specific work */
 +
 +static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
 +{
 +      if (cfg->info->set_iotiming)
 +              (cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
 +}
 +
 +static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
 +{
 +      if (cfg->info->calc_iotiming)
 +              return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
 +
 +      return 0;
 +}
 +
 +static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
 +{
 +      (cfg->info->set_refresh)(cfg);
 +}
 +
 +static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
 +{
 +      (cfg->info->set_divs)(cfg);
 +}
 +
 +static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
 +{
 +      return (cfg->info->calc_divs)(cfg);
 +}
 +
 +static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
 +{
 +      (cfg->info->set_fvco)(cfg);
 +}
 +
 +static inline void s3c_cpufreq_resume_clocks(void)
 +{
 +      cpu_cur.info->resume_clocks();
 +}
 +
 +static inline void s3c_cpufreq_updateclk(struct clk *clk,
 +                                       unsigned int freq)
 +{
 +      clk_set_rate(clk, freq);
 +}
 +
 +static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
 +                               unsigned int target_freq,
 +                               struct cpufreq_frequency_table *pll)
 +{
 +      struct s3c_cpufreq_freqs freqs;
 +      struct s3c_cpufreq_config cpu_new;
 +      unsigned long flags;
 +
 +      cpu_new = cpu_cur;  /* copy new from current */
 +
 +      s3c_cpufreq_show("cur", &cpu_cur);
 +
 +      /* TODO - check for DMA currently outstanding */
 +
 +      cpu_new.pll = pll ? *pll : cpu_cur.pll;
 +
 +      if (pll)
 +              freqs.pll_changing = 1;
 +
 +      /* update our frequencies */
 +
 +      cpu_new.freq.armclk = target_freq;
 +      cpu_new.freq.fclk = cpu_new.pll.frequency;
 +
 +      if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
 +              printk(KERN_ERR "no divisors for %d\n", target_freq);
 +              goto err_notpossible;
 +      }
 +
 +      s3c_freq_dbg("%s: got divs\n", __func__);
 +
 +      s3c_cpufreq_calc(&cpu_new);
 +
 +      s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
 +
 +      if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
 +              if (s3c_cpufreq_calcio(&cpu_new) < 0) {
 +                      printk(KERN_ERR "%s: no IO timings\n", __func__);
 +                      goto err_notpossible;
 +              }
 +      }
 +
 +      s3c_cpufreq_show("new", &cpu_new);
 +
 +      /* setup our cpufreq parameters */
 +
 +      freqs.old = cpu_cur.freq;
 +      freqs.new = cpu_new.freq;
 +
 +      freqs.freqs.old = cpu_cur.freq.armclk / 1000;
 +      freqs.freqs.new = cpu_new.freq.armclk / 1000;
 +
 +      /* update f/h/p clock settings before we issue the change
 +       * notification, so that drivers do not need to do anything
 +       * special if they want to recalculate on CPUFREQ_PRECHANGE. */
 +
 +      s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
 +      s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
 +      s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
 +      s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
 +
 +      /* start the frequency change */
 +      cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);
 +
 +      /* If hclk is staying the same, then we do not need to
 +       * re-write the IO or the refresh timings whilst we are changing
 +       * speed. */
 +
 +      local_irq_save(flags);
 +
 +      /* is our memory clock slowing down? */
 +      if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
 +              s3c_cpufreq_setrefresh(&cpu_new);
 +              s3c_cpufreq_setio(&cpu_new);
 +      }
 +
 +      if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
 +              /* not changing PLL, just set the divisors */
 +
 +              s3c_cpufreq_setdivs(&cpu_new);
 +      } else {
 +              if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
 +                      /* slow the cpu down, then set divisors */
 +
 +                      s3c_cpufreq_setfvco(&cpu_new);
 +                      s3c_cpufreq_setdivs(&cpu_new);
 +              } else {
 +                      /* set the divisors, then speed up */
 +
 +                      s3c_cpufreq_setdivs(&cpu_new);
 +                      s3c_cpufreq_setfvco(&cpu_new);
 +              }
 +      }
 +
 +      /* did our memory clock speed up */
 +      if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
 +              s3c_cpufreq_setrefresh(&cpu_new);
 +              s3c_cpufreq_setio(&cpu_new);
 +      }
 +
 +      /* update our current settings */
 +      cpu_cur = cpu_new;
 +
 +      local_irq_restore(flags);
 +
 +      /* notify everyone we've done this */
 +      cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);
 +
 +      s3c_freq_dbg("%s: finished\n", __func__);
 +      return 0;
 +
 + err_notpossible:
 +      printk(KERN_ERR "no compatible settings for %d\n", target_freq);
 +      return -EINVAL;
 +}
 +
 +/* s3c_cpufreq_target
 + *
 + * called by the cpufreq core to adjust the frequency that the CPU
 + * is currently running at.
 + */
 +
 +static int s3c_cpufreq_target(struct cpufreq_policy *policy,
 +                            unsigned int target_freq,
 +                            unsigned int relation)
 +{
 +      struct cpufreq_frequency_table *pll;
 +      unsigned int index;
 +
 +      /* avoid repeated calls which cause a needless amout of duplicated
 +       * logging output (and CPU time as the calculation process is
 +       * done) */
 +      if (target_freq == last_target)
 +              return 0;
 +
 +      last_target = target_freq;
 +
 +      s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
 +                   __func__, policy, target_freq, relation);
 +
 +      if (ftab) {
 +              if (cpufreq_frequency_table_target(policy, ftab,
 +                                                 target_freq, relation,
 +                                                 &index)) {
 +                      s3c_freq_dbg("%s: table failed\n", __func__);
 +                      return -EINVAL;
 +              }
 +
 +              s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
 +                           target_freq, index, ftab[index].frequency);
 +              target_freq = ftab[index].frequency;
 +      }
 +
 +      target_freq *= 1000;  /* convert target to Hz */
 +
 +      /* find the settings for our new frequency */
 +
 +      if (!pll_reg || cpu_cur.lock_pll) {
 +              /* either we've not got any PLL values, or we've locked
 +               * to the current one. */
 +              pll = NULL;
 +      } else {
 +              struct cpufreq_policy tmp_policy;
 +              int ret;
 +
 +              /* we keep the cpu pll table in Hz, to ensure we get an
 +               * accurate value for the PLL output. */
 +
 +              tmp_policy.min = policy->min * 1000;
 +              tmp_policy.max = policy->max * 1000;
 +              tmp_policy.cpu = policy->cpu;
 +
 +              /* cpufreq_frequency_table_target uses a pointer to 'index'
 +               * which is the number of the table entry, not the value of
 +               * the table entry's index field. */
 +
 +              ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
 +                                                   target_freq, relation,
 +                                                   &index);
 +
 +              if (ret < 0) {
 +                      printk(KERN_ERR "%s: no PLL available\n", __func__);
 +                      goto err_notpossible;
 +              }
 +
 +              pll = pll_reg + index;
 +
 +              s3c_freq_dbg("%s: target %u => %u\n",
 +                           __func__, target_freq, pll->frequency);
 +
 +              target_freq = pll->frequency;
 +      }
 +
 +      return s3c_cpufreq_settarget(policy, target_freq, pll);
 +
 + err_notpossible:
 +      printk(KERN_ERR "no compatible settings for %d\n", target_freq);
 +      return -EINVAL;
 +}
 +
 +static unsigned int s3c_cpufreq_get(unsigned int cpu)
 +{
 +      return clk_get_rate(clk_arm) / 1000;
 +}
 +
 +struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
 +{
 +      struct clk *clk;
 +
 +      clk = clk_get(dev, name);
 +      if (IS_ERR(clk))
 +              printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
 +
 +      return clk;
 +}
 +
 +static int s3c_cpufreq_init(struct cpufreq_policy *policy)
 +{
 +      printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
 +
 +      if (policy->cpu != 0)
 +              return -EINVAL;
 +
 +      policy->cur = s3c_cpufreq_get(0);
 +      policy->min = policy->cpuinfo.min_freq = 0;
 +      policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
 +      policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 +
 +      /* feed the latency information from the cpu driver */
 +      policy->cpuinfo.transition_latency = cpu_cur.info->latency;
 +
 +      if (ftab)
 +              cpufreq_frequency_table_cpuinfo(policy, ftab);
 +
 +      return 0;
 +}
 +
 +static __init int s3c_cpufreq_initclks(void)
 +{
 +      _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
 +      _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
 +      clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
 +      clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
 +      clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
 +      clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
 +
 +      if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
 +          IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
 +              printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
 +              return -ENOENT;
 +      }
 +
 +      printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
 +             clk_get_rate(clk_fclk) / 1000,
 +             clk_get_rate(clk_hclk) / 1000,
 +             clk_get_rate(clk_pclk) / 1000,
 +             clk_get_rate(clk_arm) / 1000);
 +
 +      return 0;
 +}
 +
 +static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
 +{
 +      if (policy->cpu != 0)
 +              return -EINVAL;
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_PM
 +static struct cpufreq_frequency_table suspend_pll;
 +static unsigned int suspend_freq;
 +
 +static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
 +{
 +      suspend_pll.frequency = clk_get_rate(_clk_mpll);
++      suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON);
 +      suspend_freq = s3c_cpufreq_get(0) * 1000;
 +
 +      return 0;
 +}
 +
 +static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
 +{
 +      int ret;
 +
 +      s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
 +
 +      last_target = ~0;       /* invalidate last_target setting */
 +
 +      /* first, find out what speed we resumed at. */
 +      s3c_cpufreq_resume_clocks();
 +
 +      /* whilst we will be called later on, we try and re-set the
 +       * cpu frequencies as soon as possible so that we do not end
 +       * up resuming devices and then immediately having to re-set
 +       * a number of settings once these devices have restarted.
 +       *
 +       * as a note, it is expected devices are not used until they
 +       * have been un-suspended and at that time they should have
 +       * used the updated clock settings.
 +       */
 +
 +      ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
 +      if (ret) {
 +              printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
 +              return ret;
 +      }
 +
 +      return 0;
 +}
 +#else
 +#define s3c_cpufreq_resume NULL
 +#define s3c_cpufreq_suspend NULL
 +#endif
 +
 +static struct cpufreq_driver s3c24xx_driver = {
 +      .flags          = CPUFREQ_STICKY,
 +      .verify         = s3c_cpufreq_verify,
 +      .target         = s3c_cpufreq_target,
 +      .get            = s3c_cpufreq_get,
 +      .init           = s3c_cpufreq_init,
 +      .suspend        = s3c_cpufreq_suspend,
 +      .resume         = s3c_cpufreq_resume,
 +      .name           = "s3c24xx",
 +};
 +
 +
 +int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
 +{
 +      if (!info || !info->name) {
 +              printk(KERN_ERR "%s: failed to pass valid information\n",
 +                     __func__);
 +              return -EINVAL;
 +      }
 +
 +      printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
 +             info->name);
 +
 +      /* check our driver info has valid data */
 +
 +      BUG_ON(info->set_refresh == NULL);
 +      BUG_ON(info->set_divs == NULL);
 +      BUG_ON(info->calc_divs == NULL);
 +
 +      /* info->set_fvco is optional, depending on whether there
 +       * is a need to set the clock code. */
 +
 +      cpu_cur.info = info;
 +
 +      /* Note, driver registering should probably update locktime */
 +
 +      return 0;
 +}
 +
 +int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
 +{
 +      struct s3c_cpufreq_board *ours;
 +
 +      if (!board) {
 +              printk(KERN_INFO "%s: no board data\n", __func__);
 +              return -EINVAL;
 +      }
 +
 +      /* Copy the board information so that each board can make this
 +       * initdata. */
 +
 +      ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
 +      if (ours == NULL) {
 +              printk(KERN_ERR "%s: no memory\n", __func__);
 +              return -ENOMEM;
 +      }
 +
 +      *ours = *board;
 +      cpu_cur.board = ours;
 +
 +      return 0;
 +}
 +
 +int __init s3c_cpufreq_auto_io(void)
 +{
 +      int ret;
 +
 +      if (!cpu_cur.info->get_iotiming) {
 +              printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
 +              return -ENOENT;
 +      }
 +
 +      printk(KERN_INFO "%s: working out IO settings\n", __func__);
 +
 +      ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
 +      if (ret)
 +              printk(KERN_ERR "%s: failed to get timings\n", __func__);
 +
 +      return ret;
 +}
 +
 +/* if one or is zero, then return the other, otherwise return the min */
 +#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
 +
 +/**
 + * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
 + * @dst: The destination structure
 + * @a: One argument.
 + * @b: The other argument.
 + *
 + * Create a minimum of each frequency entry in the 'struct s3c_freq',
 + * unless the entry is zero when it is ignored and the non-zero argument
 + * used.
 + */
 +static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
 +                               struct s3c_freq *a, struct s3c_freq *b)
 +{
 +      dst->fclk = do_min(a->fclk, b->fclk);
 +      dst->hclk = do_min(a->hclk, b->hclk);
 +      dst->pclk = do_min(a->pclk, b->pclk);
 +      dst->armclk = do_min(a->armclk, b->armclk);
 +}
 +
 +static inline u32 calc_locktime(u32 freq, u32 time_us)
 +{
 +      u32 result;
 +
 +      result = freq * time_us;
 +      result = DIV_ROUND_UP(result, 1000 * 1000);
 +
 +      return result;
 +}
 +
 +static void s3c_cpufreq_update_loctkime(void)
 +{
 +      unsigned int bits = cpu_cur.info->locktime_bits;
 +      u32 rate = (u32)clk_get_rate(_clk_xtal);
 +      u32 val;
 +
 +      if (bits == 0) {
 +              WARN_ON(1);
 +              return;
 +      }
 +
 +      val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
 +      val |= calc_locktime(rate, cpu_cur.info->locktime_m);
 +
 +      printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
 +      __raw_writel(val, S3C2410_LOCKTIME);
 +}
 +
 +static int s3c_cpufreq_build_freq(void)
 +{
 +      int size, ret;
 +
 +      if (!cpu_cur.info->calc_freqtable)
 +              return -EINVAL;
 +
 +      kfree(ftab);
 +      ftab = NULL;
 +
 +      size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
 +      size++;
 +
 +      ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
 +      if (!ftab) {
 +              printk(KERN_ERR "%s: no memory for tables\n", __func__);
 +              return -ENOMEM;
 +      }
 +
 +      ftab_size = size;
 +
 +      ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
 +      s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
 +
 +      return 0;
 +}
 +
 +static int __init s3c_cpufreq_initcall(void)
 +{
 +      int ret = 0;
 +
 +      if (cpu_cur.info && cpu_cur.board) {
 +              ret = s3c_cpufreq_initclks();
 +              if (ret)
 +                      goto out;
 +
 +              /* get current settings */
 +              s3c_cpufreq_getcur(&cpu_cur);
 +              s3c_cpufreq_show("cur", &cpu_cur);
 +
 +              if (cpu_cur.board->auto_io) {
 +                      ret = s3c_cpufreq_auto_io();
 +                      if (ret) {
 +                              printk(KERN_ERR "%s: failed to get io timing\n",
 +                                     __func__);
 +                              goto out;
 +                      }
 +              }
 +
 +              if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
 +                      printk(KERN_ERR "%s: no IO support registered\n",
 +                             __func__);
 +                      ret = -EINVAL;
 +                      goto out;
 +              }
 +
 +              if (!cpu_cur.info->need_pll)
 +                      cpu_cur.lock_pll = 1;
 +
 +              s3c_cpufreq_update_loctkime();
 +
 +              s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
 +                                   &cpu_cur.info->max);
 +
 +              if (cpu_cur.info->calc_freqtable)
 +                      s3c_cpufreq_build_freq();
 +
 +              ret = cpufreq_register_driver(&s3c24xx_driver);
 +      }
 +
 + out:
 +      return ret;
 +}
 +
 +late_initcall(s3c_cpufreq_initcall);
 +
 +/**
 + * s3c_plltab_register - register CPU PLL table.
 + * @plls: The list of PLL entries.
 + * @plls_no: The size of the PLL entries @plls.
 + *
 + * Register the given set of PLLs with the system.
 + */
 +int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
 +                             unsigned int plls_no)
 +{
 +      struct cpufreq_frequency_table *vals;
 +      unsigned int size;
 +
 +      size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
 +
 +      vals = kmalloc(size, GFP_KERNEL);
 +      if (vals) {
 +              memcpy(vals, plls, size);
 +              pll_reg = vals;
 +
 +              /* write a terminating entry, we don't store it in the
 +               * table that is stored in the kernel */
 +              vals += plls_no;
 +              vals->frequency = CPUFREQ_TABLE_END;
 +
 +              printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
 +      } else
 +              printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
 +
 +      return vals ? 0 : -ENOMEM;
 +}
diff --combined drivers/cpuidle/Kconfig
index e21cdfa4002a17bc28f1285dfe3433bb1ba195b5,81de5d96749bcdc0f4c9a7f6722671eb30a6cd03..0e2cd5cab4d0924392d8c4d0a99ffb9a75d4485e
@@@ -1,7 -1,9 +1,9 @@@
  
- config CPU_IDLE
menuconfig CPU_IDLE
        bool "CPU idle PM support"
        default y if ACPI || PPC_PSERIES
+       select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
+       select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
        help
          CPU idle is a generic framework for supporting software-controlled
          idle processor power management.  It includes modular cross-platform
  
          If you're using an ACPI-enabled platform, you should say Y here.
  
+ if CPU_IDLE
  config CPU_IDLE_MULTIPLE_DRIVERS
          bool "Support multiple cpuidle drivers"
-         depends on CPU_IDLE
          default n
          help
           Allows the cpuidle framework to use different drivers for each CPU.
           states. If unsure say N.
  
  config CPU_IDLE_GOV_LADDER
-       bool
-       depends on CPU_IDLE
+       bool "Ladder governor (for periodic timer tick)"
        default y
  
  config CPU_IDLE_GOV_MENU
-       bool
-       depends on CPU_IDLE && NO_HZ
+       bool "Menu governor (for tickless system)"
        default y
  
- config ARCH_NEEDS_CPU_IDLE_COUPLED
-       def_bool n
- if CPU_IDLE
  config CPU_IDLE_CALXEDA
        bool "CPU Idle Driver for Calxeda processors"
        depends on ARCH_HIGHBANK
 +      select ARM_CPU_SUSPEND
        help
          Select this to enable cpuidle on Calxeda processors.
  
+ config CPU_IDLE_ZYNQ
+       bool "CPU Idle Driver for Xilinx Zynq processors"
+       depends on ARCH_ZYNQ
+       help
+         Select this to enable cpuidle on Xilinx Zynq processors.
  endif
+ config ARCH_NEEDS_CPU_IDLE_COUPLED
+       def_bool n
index f4b72456faaf0e3060ae060a7384ddd0d09170ea,89d0d2a3b1bb62289a6c9a862abc19f98ad30097..bfa1af1b519fdf74f30080b5e7701ac641bc999e
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * Moorestown platform Langwell chip GPIO driver
   *
 - * Copyright (c) 2008 - 2009,  Intel Corporation.
 + * Copyright (c) 2008, 2009, 2013, Intel Corporation.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -20,6 -20,7 +20,6 @@@
  /* Supports:
   * Moorestown platform Langwell chip.
   * Medfield platform Penwell chip.
 - * Whitney point.
   */
  
  #include <linux/module.h>
@@@ -64,7 -65,7 +64,7 @@@ enum GPIO_REG 
  
  struct lnw_gpio {
        struct gpio_chip                chip;
 -      void                            *reg_base;
 +      void __iomem                    *reg_base;
        spinlock_t                      lock;
        struct pci_dev                  *pdev;
        struct irq_domain               *domain;
  #define to_lnw_priv(chip)     container_of(chip, struct lnw_gpio, chip)
  
  static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
 -                      enum GPIO_REG reg_type)
 +                            enum GPIO_REG reg_type)
  {
        struct lnw_gpio *lnw = to_lnw_priv(chip);
        unsigned nreg = chip->ngpio / 32;
        u8 reg = offset / 32;
 -      void __iomem *ptr;
  
 -      ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4);
 -      return ptr;
 +      return lnw->reg_base + reg_type * nreg * 4 + reg * 4;
  }
  
  static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset,
        struct lnw_gpio *lnw = to_lnw_priv(chip);
        unsigned nreg = chip->ngpio / 32;
        u8 reg = offset / 16;
 -      void __iomem *ptr;
  
 -      ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4);
 -      return ptr;
 +      return lnw->reg_base + reg_type * nreg * 4 + reg * 4;
  }
  
  static int lnw_gpio_request(struct gpio_chip *chip, unsigned offset)
@@@ -300,11 -305,7 +300,7 @@@ static const struct irq_domain_ops lnw_
  
  static int lnw_gpio_runtime_idle(struct device *dev)
  {
-       int err = pm_schedule_suspend(dev, 500);
-       if (!err)
-               return 0;
+       pm_schedule_suspend(dev, 500);
        return -EBUSY;
  }
  
@@@ -313,40 -314,56 +309,40 @@@ static const struct dev_pm_ops lnw_gpio
  };
  
  static int lnw_gpio_probe(struct pci_dev *pdev,
 -                      const struct pci_device_id *id)
 +                        const struct pci_device_id *id)
  {
 -      void *base;
 -      resource_size_t start, len;
 +      void __iomem *base;
        struct lnw_gpio *lnw;
        u32 gpio_base;
        u32 irq_base;
        int retval;
        int ngpio = id->driver_data;
  
 -      retval = pci_enable_device(pdev);
 +      retval = pcim_enable_device(pdev);
        if (retval)
                return retval;
  
 -      retval = pci_request_regions(pdev, "langwell_gpio");
 +      retval = pcim_iomap_regions(pdev, 1 << 0 | 1 << 1, pci_name(pdev));
        if (retval) {
 -              dev_err(&pdev->dev, "error requesting resources\n");
 -              goto err_pci_req_region;
 -      }
 -      /* get the gpio_base from bar1 */
 -      start = pci_resource_start(pdev, 1);
 -      len = pci_resource_len(pdev, 1);
 -      base = ioremap_nocache(start, len);
 -      if (!base) {
 -              dev_err(&pdev->dev, "error mapping bar1\n");
 -              retval = -EFAULT;
 -              goto err_ioremap;
 +              dev_err(&pdev->dev, "I/O memory mapping error\n");
 +              return retval;
        }
 -      irq_base = *(u32 *)base;
 -      gpio_base = *((u32 *)base + 1);
 +
 +      base = pcim_iomap_table(pdev)[1];
 +
 +      irq_base = readl(base);
 +      gpio_base = readl(sizeof(u32) + base);
 +
        /* release the IO mapping, since we already get the info from bar1 */
 -      iounmap(base);
 -      /* get the register base from bar0 */
 -      start = pci_resource_start(pdev, 0);
 -      len = pci_resource_len(pdev, 0);
 -      base = devm_ioremap_nocache(&pdev->dev, start, len);
 -      if (!base) {
 -              dev_err(&pdev->dev, "error mapping bar0\n");
 -              retval = -EFAULT;
 -              goto err_ioremap;
 -      }
 +      pcim_iounmap_regions(pdev, 1 << 1);
  
        lnw = devm_kzalloc(&pdev->dev, sizeof(*lnw), GFP_KERNEL);
        if (!lnw) {
 -              dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n");
 -              retval = -ENOMEM;
 -              goto err_ioremap;
 +              dev_err(&pdev->dev, "can't allocate chip data\n");
 +              return -ENOMEM;
        }
  
 -      lnw->reg_base = base;
 +      lnw->reg_base = pcim_iomap_table(pdev)[0];
        lnw->chip.label = dev_name(&pdev->dev);
        lnw->chip.request = lnw_gpio_request;
        lnw->chip.direction_input = lnw_gpio_direction_input;
        lnw->chip.can_sleep = 0;
        lnw->pdev = pdev;
  
 +      spin_lock_init(&lnw->lock);
 +
        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;
 -      }
 +      if (!lnw->domain)
 +              return -ENOMEM;
  
        pci_set_drvdata(pdev, lnw);
        retval = gpiochip_add(&lnw->chip);
        if (retval) {
 -              dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
 -              goto err_ioremap;
 +              dev_err(&pdev->dev, "gpiochip_add error %d\n", retval);
 +              return retval;
        }
  
        lnw_irq_init_hw(lnw);
        irq_set_handler_data(pdev->irq, lnw);
        irq_set_chained_handler(pdev->irq, lnw_irq_handler);
  
 -      spin_lock_init(&lnw->lock);
 -
        pm_runtime_put_noidle(&pdev->dev);
        pm_runtime_allow(&pdev->dev);
  
        return 0;
 -
 -err_ioremap:
 -      pci_release_regions(pdev);
 -err_pci_req_region:
 -      pci_disable_device(pdev);
 -      return retval;
  }
  
  static struct pci_driver lnw_gpio_driver = {
        },
  };
  
 -
 -static int wp_gpio_probe(struct platform_device *pdev)
 -{
 -      struct lnw_gpio *lnw;
 -      struct gpio_chip *gc;
 -      struct resource *rc;
 -      int retval = 0;
 -
 -      rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      if (!rc)
 -              return -EINVAL;
 -
 -      lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
 -      if (!lnw) {
 -              dev_err(&pdev->dev,
 -                      "can't allocate whitneypoint_gpio chip data\n");
 -              return -ENOMEM;
 -      }
 -      lnw->reg_base = ioremap_nocache(rc->start, resource_size(rc));
 -      if (lnw->reg_base == NULL) {
 -              retval = -EINVAL;
 -              goto err_kmalloc;
 -      }
 -      spin_lock_init(&lnw->lock);
 -      gc = &lnw->chip;
 -      gc->label = dev_name(&pdev->dev);
 -      gc->owner = THIS_MODULE;
 -      gc->direction_input = lnw_gpio_direction_input;
 -      gc->direction_output = lnw_gpio_direction_output;
 -      gc->get = lnw_gpio_get;
 -      gc->set = lnw_gpio_set;
 -      gc->to_irq = NULL;
 -      gc->base = 0;
 -      gc->ngpio = 64;
 -      gc->can_sleep = 0;
 -      retval = gpiochip_add(gc);
 -      if (retval) {
 -              dev_err(&pdev->dev, "whitneypoint gpiochip_add error %d\n",
 -                                                              retval);
 -              goto err_ioremap;
 -      }
 -      platform_set_drvdata(pdev, lnw);
 -      return 0;
 -err_ioremap:
 -      iounmap(lnw->reg_base);
 -err_kmalloc:
 -      kfree(lnw);
 -      return retval;
 -}
 -
 -static int wp_gpio_remove(struct platform_device *pdev)
 -{
 -      struct lnw_gpio *lnw = platform_get_drvdata(pdev);
 -      int err;
 -      err = gpiochip_remove(&lnw->chip);
 -      if (err)
 -              dev_err(&pdev->dev, "failed to remove gpio_chip.\n");
 -      iounmap(lnw->reg_base);
 -      kfree(lnw);
 -      platform_set_drvdata(pdev, NULL);
 -      return 0;
 -}
 -
 -static struct platform_driver wp_gpio_driver = {
 -      .probe          = wp_gpio_probe,
 -      .remove         = wp_gpio_remove,
 -      .driver         = {
 -              .name   = "wp_gpio",
 -              .owner  = THIS_MODULE,
 -      },
 -};
 -
  static int __init lnw_gpio_init(void)
  {
 -      int ret;
 -      ret =  pci_register_driver(&lnw_gpio_driver);
 -      if (ret < 0)
 -              return ret;
 -      ret = platform_driver_register(&wp_gpio_driver);
 -      if (ret < 0)
 -              pci_unregister_driver(&lnw_gpio_driver);
 -      return ret;
 +      return pci_register_driver(&lnw_gpio_driver);
  }
  
  device_initcall(lnw_gpio_init);
index a292a1deff9aa4d03d401e0925901f892748429d,ed79d7b78e7d85692fc56e175fb49befda4d14cd..3c157faee645805f398cc2047d5f7b035555aacc
@@@ -480,7 -480,6 +480,7 @@@ struct clk_mgt clk_mgt[PRCMU_NUM_REG_CL
        CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true),
        CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true),
        CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true),
 +      CLK_MGT_ENTRY(BML8580CLK, PLL_DIV, true),
        CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true),
        CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true),
        CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true),
@@@ -1725,9 -1724,9 +1725,9 @@@ static long round_clock_rate(u8 clock, 
  
  /* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
  static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
-       { .frequency = 200000, .index = ARM_EXTCLK,},
-       { .frequency = 400000, .index = ARM_50_OPP,},
-       { .frequency = 800000, .index = ARM_100_OPP,},
+       { .frequency = 200000, .driver_data = ARM_EXTCLK,},
+       { .frequency = 400000, .driver_data = ARM_50_OPP,},
+       { .frequency = 800000, .driver_data = ARM_100_OPP,},
        { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
        { .frequency = CPUFREQ_TABLE_END,},
  };
@@@ -1902,7 -1901,7 +1902,7 @@@ static int set_armss_rate(unsigned lon
                return -EINVAL;
  
        /* Set the new arm opp. */
-       return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index);
+       return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].driver_data);
  }
  
  static int set_plldsi_rate(unsigned long rate)
@@@ -3106,7 -3105,7 +3106,7 @@@ static void db8500_prcmu_update_cpufreq
  {
        if (prcmu_has_arm_maxopp()) {
                db8500_cpufreq_table[3].frequency = 1000000;
-               db8500_cpufreq_table[3].index = ARM_MAX_OPP;
+               db8500_cpufreq_table[3].driver_data = ARM_MAX_OPP;
        }
  }
  
index c6dc1846943fbe06d21974a2c6adb453d6d6f388,1ffc2ebdf612df7afbf90371e7ba4a4b226131b3..119d486a5cf7fa76dad2fa49593b03e5f169b29a
@@@ -20,6 -20,7 +20,7 @@@
  #include <asm/cacheflush.h>
  #include <linux/fdtable.h>
  #include <linux/file.h>
+ #include <linux/freezer.h>
  #include <linux/fs.h>
  #include <linux/list.h>
  #include <linux/miscdevice.h>
@@@ -790,7 -791,7 +791,7 @@@ static void binder_delete_free_buffer(s
        list_del(&buffer->entry);
        if (free_page_start || free_page_end) {
                binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
 -                           "%d: merge free, buffer %p do not share page%s%s with with %p or %p\n",
 +                           "%d: merge free, buffer %p do not share page%s%s with %p or %p\n",
                             proc->pid, buffer, free_page_start ? "" : " end",
                             free_page_end ? "" : " start", prev, next);
                binder_update_page_range(proc, 0, free_page_start ?
@@@ -2140,13 -2141,13 +2141,13 @@@ retry
                        if (!binder_has_proc_work(proc, thread))
                                ret = -EAGAIN;
                } else
-                       ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
+                       ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
        } else {
                if (non_block) {
                        if (!binder_has_thread_work(thread))
                                ret = -EAGAIN;
                } else
-                       ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
+                       ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
        }
  
        binder_lock(__func__);
diff --combined drivers/tty/serial/mfd.c
index e266eca0ec7642d26dfeae72d70d0170b7308fc0,5dfcf3bae23aa62ddb3d90dc8b72f06eac81e99c..4a82267af83fcc95786a79df2b260b84a5dea931
   *    be triggered
   */
  
 +#if defined(CONFIG_SERIAL_MFD_HSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 +#define SUPPORT_SYSRQ
 +#endif
 +
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/console.h>
@@@ -1252,13 -1248,8 +1252,8 @@@ static int serial_hsu_resume(struct pci
  #ifdef CONFIG_PM_RUNTIME
  static int serial_hsu_runtime_idle(struct device *dev)
  {
-       int err;
-       err = pm_schedule_suspend(dev, 500);
-       if (err)
-               return -EBUSY;
-       return 0;
+       pm_schedule_suspend(dev, 500);
+       return -EBUSY;
  }
  
  static int serial_hsu_runtime_suspend(struct device *dev)
diff --combined drivers/usb/core/port.c
index 5fd3fee58f8b9ebc746e2e9372da5be94ee478b8,8c1b2c509467bf1dae5ef83a8a4dd9064ab93a4d..d6b0fadf53e9de9d3c8b074c50be95b301e176e4
@@@ -86,7 -86,7 +86,7 @@@ static int usb_port_runtime_resume(stru
        usb_autopm_get_interface(intf);
        set_bit(port1, hub->busy_bits);
  
 -      retval = usb_hub_set_port_power(hdev, port1, true);
 +      retval = usb_hub_set_port_power(hdev, hub, port1, true);
        if (port_dev->child && !retval) {
                /*
                 * Wait for usb hub port to be reconnected in order to make
@@@ -128,7 -128,7 +128,7 @@@ static int usb_port_runtime_suspend(str
  
        usb_autopm_get_interface(intf);
        set_bit(port1, hub->busy_bits);
 -      retval = usb_hub_set_port_power(hdev, port1, false);
 +      retval = usb_hub_set_port_power(hdev, hub, port1, false);
        usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
        usb_clear_port_feature(hdev, port1,     USB_PORT_FEAT_C_ENABLE);
        clear_bit(port1, hub->busy_bits);
@@@ -141,7 -141,6 +141,6 @@@ static const struct dev_pm_ops usb_port
  #ifdef CONFIG_PM_RUNTIME
        .runtime_suspend =      usb_port_runtime_suspend,
        .runtime_resume =       usb_port_runtime_resume,
-       .runtime_idle =         pm_generic_runtime_idle,
  #endif
  };
  
diff --combined fs/cifs/transport.c
index 1996d6ceb8338651dd1fce8df90af787ae2ad680,b70aa7c913940c3766263b67e564a053883f9f32..6fdcb1b4a106747779ae77ed365116256e79edec
@@@ -447,7 -447,7 +447,7 @@@ wait_for_response(struct TCP_Server_Inf
  {
        int error;
  
-       error = wait_event_freezekillable(server->response_q,
+       error = wait_event_freezekillable_unsafe(server->response_q,
                                    midQ->mid_state != MID_REQUEST_SUBMITTED);
        if (error < 0)
                return -ERESTARTSYS;
@@@ -463,7 -463,7 +463,7 @@@ cifs_setup_async_request(struct TCP_Ser
        struct mid_q_entry *mid;
  
        /* enable signing if server requires it */
 -      if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
 +      if (server->sign)
                hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
  
        mid = AllocMidQEntry(hdr, server);
@@@ -612,7 -612,7 +612,7 @@@ cifs_check_receive(struct mid_q_entry *
        dump_smb(mid->resp_buf, min_t(u32, 92, len));
  
        /* convert the length into a more usable form */
 -      if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
 +      if (server->sign) {
                struct kvec iov;
                int rc = 0;
                struct smb_rqst rqst = { .rq_iov = &iov,
diff --combined include/linux/device.h
index 9d4835a8f8b8df4f3d277b7244c2f1b7abeebe5c,eeb33315514c332ddf83b9fcf4183a580555bab6..bcf8c0d4cd981b49ff9b545d8942d9810fd1f169
@@@ -71,6 -71,10 +71,10 @@@ extern void bus_remove_file(struct bus_
   *            the specific driver's probe to initial the matched device.
   * @remove:   Called when a device removed from this bus.
   * @shutdown: Called at shut-down time to quiesce the device.
+  *
+  * @online:   Called to put the device back online (after offlining it).
+  * @offline:  Called to put the device offline for hot-removal. May fail.
+  *
   * @suspend:  Called when a device on this bus wants to go to sleep mode.
   * @resume:   Called to bring a device on this bus out of sleep mode.
   * @pm:               Power management operations of this bus, callback the specific
@@@ -80,7 -84,6 +84,7 @@@
   *              bus-specific setup
   * @p:                The private data of the driver core, only the driver core can
   *            touch this.
 + * @lock_key: Lock class key for use by the lock validator
   *
   * A bus is a channel between the processor and one or more devices. For the
   * purposes of the device model, all devices are connected via a bus, even if
@@@ -105,6 -108,9 +109,9 @@@ struct bus_type 
        int (*remove)(struct device *dev);
        void (*shutdown)(struct device *dev);
  
+       int (*online)(struct device *dev);
+       int (*offline)(struct device *dev);
        int (*suspend)(struct device *dev, pm_message_t state);
        int (*resume)(struct device *dev);
  
@@@ -636,7 -642,6 +643,7 @@@ struct acpi_dev_node 
   *            segment limitations.
   * @dma_pools:        Dma pools (if dma'ble device).
   * @dma_mem:  Internal for coherent mem override.
 + * @cma_area: Contiguous memory area for dma allocations
   * @archdata: For arch-specific additions.
   * @of_node:  Associated device tree node.
   * @acpi_node:        Associated ACPI device node.
   * @release:  Callback to free the device after all references have
   *            gone away. This should be set by the allocator of the
   *            device (i.e. the bus driver that discovered the device).
 + * @iommu_group: IOMMU group the device belongs to.
 + *
+  * @offline_disabled: If set, the device is permanently online.
+  * @offline:  Set after successful invocation of bus type's .offline().
+  *
   * At the lowest level, every device in a Linux system is represented by an
   * instance of struct device. The device structure contains the information
   * that the device model core needs to model the system. Most subsystems,
@@@ -723,6 -729,9 +733,9 @@@ struct device 
  
        void    (*release)(struct device *dev);
        struct iommu_group      *iommu_group;
+       bool                    offline_disabled:1;
+       bool                    offline:1;
  };
  
  static inline struct device *kobj_to_dev(struct kobject *kobj)
@@@ -859,6 -868,15 +872,15 @@@ extern const char *device_get_devnode(s
  extern void *dev_get_drvdata(const struct device *dev);
  extern int dev_set_drvdata(struct device *dev, void *data);
  
+ static inline bool device_supports_offline(struct device *dev)
+ {
+       return dev->bus && dev->bus->offline && dev->bus->online;
+ }
+ extern void lock_device_hotplug(void);
+ extern void unlock_device_hotplug(void);
+ extern int device_offline(struct device *dev);
+ extern int device_online(struct device *dev);
  /*
   * Root device objects for grouping under /sys/devices
   */
This page took 0.300712 seconds and 4 git commands to generate.