Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 May 2011 23:46:07 +0000 (16:46 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 May 2011 23:46:07 +0000 (16:46 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6: (34 commits)
  PM: Introduce generic prepare and complete callbacks for subsystems
  PM: Allow drivers to allocate memory from .prepare() callbacks safely
  PM: Remove CONFIG_PM_VERBOSE
  Revert "PM / Hibernate: Reduce autotuned default image size"
  PM / Hibernate: Add sysfs knob to control size of memory for drivers
  PM / Wakeup: Remove useless synchronize_rcu() call
  kmod: always provide usermodehelper_disable()
  PM / ACPI: Remove acpi_sleep=s4_nonvs
  PM / Wakeup: Fix build warning related to the "wakeup" sysfs file
  PM: Print a warning if firmware is requested when tasks are frozen
  PM / Runtime: Rework runtime PM handling during driver removal
  Freezer: Use SMP barriers
  PM / Suspend: Do not ignore error codes returned by suspend_enter()
  PM: Fix build issue in clock_ops.c for CONFIG_PM_RUNTIME unset
  PM: Revert "driver core: platform_bus: allow runtime override of dev_pm_ops"
  OMAP1 / PM: Use generic clock manipulation routines for runtime PM
  PM: Remove sysdev suspend, resume and shutdown operations
  PM / PowerPC: Use struct syscore_ops instead of sysdevs for PM
  PM / UNICORE32: Use struct syscore_ops instead of sysdevs for PM
  PM / AVR32: Use struct syscore_ops instead of sysdevs for PM
  ...

118 files changed:
Documentation/ABI/testing/sysfs-power
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
Documentation/power/devices.txt
Documentation/power/notifiers.txt
arch/arm/common/vic.c
arch/arm/include/asm/mach/time.h
arch/arm/kernel/leds.c
arch/arm/kernel/time.c
arch/arm/mach-exynos4/pm.c
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-omap1/pm_bus.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/pm_bus.c [deleted file]
arch/arm/mach-pxa/balloon3.c
arch/arm/mach-pxa/clock-pxa2xx.c
arch/arm/mach-pxa/clock-pxa3xx.c
arch/arm/mach-pxa/clock.h
arch/arm/mach-pxa/cm-x270.c
arch/arm/mach-pxa/cm-x2xx.c
arch/arm/mach-pxa/colibri-evalboard.c
arch/arm/mach-pxa/colibri-pxa270-income.c
arch/arm/mach-pxa/colibri-pxa270.c
arch/arm/mach-pxa/generic.h
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/mfp-pxa3xx.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmtreo.c
arch/arm/mach-pxa/palmz72.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa95x.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/smemc.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/vpac270.c
arch/arm/mach-s3c2410/irq.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/pm.c
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2412/irq.c
arch/arm/mach-s3c2412/mach-jive.c
arch/arm/mach-s3c2412/pm.c
arch/arm/mach-s3c2412/s3c2412.c
arch/arm/mach-s3c2416/irq.c
arch/arm/mach-s3c2416/pm.c
arch/arm/mach-s3c2416/s3c2416.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/arm/mach-s3c2440/s3c2440.c
arch/arm/mach-s3c2440/s3c2442.c
arch/arm/mach-s3c2440/s3c244x-irq.c
arch/arm/mach-s3c2440/s3c244x.c
arch/arm/mach-s3c64xx/irq-pm.c
arch/arm/mach-s5pv210/pm.c
arch/arm/mach-sa1100/irq.c
arch/arm/mach-shmobile/pm_runtime.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/omap_device.c
arch/arm/plat-pxa/gpio.c
arch/arm/plat-pxa/mfp.c
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-s3c24xx/irq-pm.c
arch/arm/plat-s5p/irq-pm.c
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/pm.h
arch/arm/vfp/vfpmodule.c
arch/avr32/mach-at32ap/intc.c
arch/blackfin/kernel/nmi.c
arch/powerpc/include/asm/mpic.h
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/sysdev/ipic.c
arch/powerpc/sysdev/mpic.c
arch/sh/Kconfig
arch/sh/configs/apsh4ad0a_defconfig
arch/sh/configs/sdk7786_defconfig
arch/sh/kernel/cpu/shmobile/pm_runtime.c
arch/unicore32/kernel/irq.c
arch/x86/Kconfig
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/apm_32.c
drivers/base/Kconfig
drivers/base/base.h
drivers/base/dd.c
drivers/base/firmware_class.c
drivers/base/platform.c
drivers/base/power/Makefile
drivers/base/power/clock_ops.c [new file with mode: 0644]
drivers/base/power/generic_ops.c
drivers/base/power/main.c
drivers/base/power/runtime.c
drivers/base/power/sysfs.c
drivers/base/power/wakeup.c
drivers/base/sys.c
drivers/xen/manage.c
include/linux/device.h
include/linux/kmod.h
include/linux/platform_device.h
include/linux/pm.h
include/linux/pm_runtime.h
include/linux/sysdev.h
kernel/freezer.c
kernel/kexec.c
kernel/kmod.c
kernel/power/Kconfig
kernel/power/hibernate.c
kernel/power/main.c
kernel/power/power.h
kernel/power/snapshot.c
kernel/power/suspend.c
kernel/sys.c

index 194ca44..b464d12 100644 (file)
@@ -158,3 +158,17 @@ Description:
                successful, will make the kernel abort a subsequent transition
                to a sleep state if any wakeup events are reported after the
                write has returned.
+
+What:          /sys/power/reserved_size
+Date:          May 2011
+Contact:       Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+               The /sys/power/reserved_size file allows user space to control
+               the amount of memory reserved for allocations made by device
+               drivers during the "device freeze" stage of hibernation.  It can
+               be written a string representing a non-negative integer that
+               will be used as the amount of memory to reserve for allocations
+               made by device drivers' "freeze" callbacks, in bytes.
+
+               Reading from this file will display the current value, which is
+               set to 1 MB by default.
index 492e81d..f6a24e8 100644 (file)
@@ -460,14 +460,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ----------------------------
 
-What:  The acpi_sleep=s4_nonvs command line option
-When:  2.6.37
-Files: arch/x86/kernel/acpi/sleep.c
-Why:   superseded by acpi_sleep=nonvs
-Who:   Rafael J. Wysocki <rjw@sisk.pl>
-
-----------------------------
-
 What:  PCI DMA unmap state API
 When:  August 2012
 Why:   PCI DMA unmap state API (include/linux/pci-dma.h) was replaced
index cc85a92..259037b 100644 (file)
@@ -245,7 +245,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
        acpi_sleep=     [HW,ACPI] Sleep options
                        Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
-                                 old_ordering, s4_nonvs, sci_force_enable }
+                                 old_ordering, nonvs, sci_force_enable }
                        See Documentation/power/video.txt for information on
                        s3_bios and s3_mode.
                        s3_beep is for debugging; it makes the PC's speaker beep
index 1971bcf..8888083 100644 (file)
@@ -279,11 +279,15 @@ When the system goes into the standby or memory sleep state, the phases are:
        time.)  Unlike the other suspend-related phases, during the prepare
        phase the device tree is traversed top-down.
 
-       The prepare phase uses only a bus callback.  After the callback method
-       returns, no new children may be registered below the device.  The method
-       may also prepare the device or driver in some way for the upcoming
-       system power transition, but it should not put the device into a
-       low-power state.
+       In addition to that, if device drivers need to allocate additional
+       memory to be able to hadle device suspend correctly, that should be
+       done in the prepare phase.
+
+       After the prepare callback method returns, no new children may be
+       registered below the device.  The method may also prepare the device or
+       driver in some way for the upcoming system power transition (for
+       example, by allocating additional memory required for this purpose), but
+       it should not put the device into a low-power state.
 
     2. The suspend methods should quiesce the device to stop it from performing
        I/O.  They also may save the device registers and put it into the
index cf98070..c2a4a34 100644 (file)
@@ -1,46 +1,41 @@
 Suspend notifiers
-       (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
-
-There are some operations that device drivers may want to carry out in their
-.suspend() routines, but shouldn't, because they can cause the hibernation or
-suspend to fail. For example, a driver may want to allocate a substantial amount
-of memory (like 50 MB) in .suspend(), but that shouldn't be done after the
-swsusp's memory shrinker has run.
-
-Also, there may be some operations, that subsystems want to carry out before a
-hibernation/suspend or after a restore/resume, requiring the system to be fully
-functional, so the drivers' .suspend() and .resume() routines are not suitable
-for this purpose.  For example, device drivers may want to upload firmware to
-their devices after a restore from a hibernation image, but they cannot do it by
-calling request_firmware() from their .resume() routines (user land processes
-are frozen at this point).  The solution may be to load the firmware into
-memory before processes are frozen and upload it from there in the .resume()
-routine.  Of course, a hibernation notifier may be used for this purpose.
-
-The subsystems that have such needs can register suspend notifiers that will be
-called upon the following events by the suspend core:
+       (C) 2007-2011 Rafael J. Wysocki <rjw@sisk.pl>, GPL
+
+There are some operations that subsystems or drivers may want to carry out
+before hibernation/suspend or after restore/resume, but they require the system
+to be fully functional, so the drivers' and subsystems' .suspend() and .resume()
+or even .prepare() and .complete() callbacks are not suitable for this purpose.
+For example, device drivers may want to upload firmware to their devices after
+resume/restore, but they cannot do it by calling request_firmware() from their
+.resume() or .complete() routines (user land processes are frozen at these
+points).  The solution may be to load the firmware into memory before processes
+are frozen and upload it from there in the .resume() routine.
+A suspend/hibernation notifier may be used for this purpose.
+
+The subsystems or drivers having such needs can register suspend notifiers that
+will be called upon the following events by the PM core:
 
 PM_HIBERNATION_PREPARE The system is going to hibernate or suspend, tasks will
                        be frozen immediately.
 
 PM_POST_HIBERNATION    The system memory state has been restored from a
-                       hibernation image or an error occurred during the
-                       hibernation.  Device drivers' .resume() callbacks have
+                       hibernation image or an error occurred during
+                       hibernation.  Device drivers' restore callbacks have
                        been executed and tasks have been thawed.
 
 PM_RESTORE_PREPARE     The system is going to restore a hibernation image.
-                       If all goes well the restored kernel will issue a
+                       If all goes well, the restored kernel will issue a
                        PM_POST_HIBERNATION notification.
 
-PM_POST_RESTORE                An error occurred during the hibernation restore.
-                       Device drivers' .resume() callbacks have been executed
+PM_POST_RESTORE                An error occurred during restore from hibernation.
+                       Device drivers' restore callbacks have been executed
                        and tasks have been thawed.
 
-PM_SUSPEND_PREPARE     The system is preparing for suspend.
+PM_SUSPEND_PREPARE     The system is preparing for suspend.
 
 PM_POST_SUSPEND                The system has just resumed or an error occurred during
-                       the suspend.    Device drivers' .resume() callbacks have
-                       been executed and tasks have been thawed.
+                       suspend.  Device drivers' resume callbacks have been
+                       executed and tasks have been thawed.
 
 It is generally assumed that whatever the notifiers do for
 PM_HIBERNATION_PREPARE, should be undone for PM_POST_HIBERNATION.  Analogously,
index 113085a..7aa4262 100644 (file)
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
-#if defined(CONFIG_PM)
+#ifdef CONFIG_PM
 /**
  * struct vic_device - VIC PM device
- * @sysdev: The system device which is registered.
  * @irq: The IRQ number for the base of the VIC.
  * @base: The register base for the VIC.
  * @resume_sources: A bitmask of interrupts for resume.
@@ -43,8 +42,6 @@
  * @protect: Save for VIC_PROTECT.
  */
 struct vic_device {
-       struct sys_device sysdev;
-
        void __iomem    *base;
        int             irq;
        u32             resume_sources;
@@ -59,11 +56,6 @@ struct vic_device {
 static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
 
 static int vic_id;
-
-static inline struct vic_device *to_vic(struct sys_device *sys)
-{
-       return container_of(sys, struct vic_device, sysdev);
-}
 #endif /* CONFIG_PM */
 
 /**
@@ -85,10 +77,9 @@ static void vic_init2(void __iomem *base)
        writel(32, base + VIC_PL190_DEF_VECT_ADDR);
 }
 
-#if defined(CONFIG_PM)
-static int vic_class_resume(struct sys_device *dev)
+#ifdef CONFIG_PM
+static void resume_one_vic(struct vic_device *vic)
 {
-       struct vic_device *vic = to_vic(dev);
        void __iomem *base = vic->base;
 
        printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
@@ -107,13 +98,18 @@ static int vic_class_resume(struct sys_device *dev)
 
        writel(vic->soft_int, base + VIC_INT_SOFT);
        writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR);
+}
 
-       return 0;
+static void vic_resume(void)
+{
+       int id;
+
+       for (id = vic_id - 1; id >= 0; id--)
+               resume_one_vic(vic_devices + id);
 }
 
-static int vic_class_suspend(struct sys_device *dev, pm_message_t state)
+static void suspend_one_vic(struct vic_device *vic)
 {
-       struct vic_device *vic = to_vic(dev);
        void __iomem *base = vic->base;
 
        printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base);
@@ -128,14 +124,21 @@ static int vic_class_suspend(struct sys_device *dev, pm_message_t state)
 
        writel(vic->resume_irqs, base + VIC_INT_ENABLE);
        writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static int vic_suspend(void)
+{
+       int id;
+
+       for (id = 0; id < vic_id; id++)
+               suspend_one_vic(vic_devices + id);
 
        return 0;
 }
 
-struct sysdev_class vic_class = {
-       .name           = "vic",
-       .suspend        = vic_class_suspend,
-       .resume         = vic_class_resume,
+struct syscore_ops vic_syscore_ops = {
+       .suspend        = vic_suspend,
+       .resume         = vic_resume,
 };
 
 /**
@@ -147,30 +150,8 @@ struct sysdev_class vic_class = {
 */
 static int __init vic_pm_init(void)
 {
-       struct vic_device *dev = vic_devices;
-       int err;
-       int id;
-
-       if (vic_id == 0)
-               return 0;
-
-       err = sysdev_class_register(&vic_class);
-       if (err) {
-               printk(KERN_ERR "%s: cannot register class\n", __func__);
-               return err;
-       }
-
-       for (id = 0; id < vic_id; id++, dev++) {
-               dev->sysdev.id = id;
-               dev->sysdev.cls = &vic_class;
-
-               err = sysdev_register(&dev->sysdev);
-               if (err) {
-                       printk(KERN_ERR "%s: failed to register device\n",
-                              __func__);
-                       return err;
-               }
-       }
+       if (vic_id > 0)
+               register_syscore_ops(&vic_syscore_ops);
 
        return 0;
 }
index 883f6be..d5adaae 100644 (file)
@@ -34,7 +34,6 @@
  *   timer interrupt which may be pending.
  */
 struct sys_timer {
-       struct sys_device       dev;
        void                    (*init)(void);
        void                    (*suspend)(void);
        void                    (*resume)(void);
index 31a316c..0f107dc 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/leds.h>
 
@@ -69,36 +70,37 @@ static ssize_t leds_store(struct sys_device *dev,
 
 static SYSDEV_ATTR(event, 0200, NULL, leds_store);
 
-static int leds_suspend(struct sys_device *dev, pm_message_t state)
+static struct sysdev_class leds_sysclass = {
+       .name           = "leds",
+};
+
+static struct sys_device leds_device = {
+       .id             = 0,
+       .cls            = &leds_sysclass,
+};
+
+static int leds_suspend(void)
 {
        leds_event(led_stop);
        return 0;
 }
 
-static int leds_resume(struct sys_device *dev)
+static void leds_resume(void)
 {
        leds_event(led_start);
-       return 0;
 }
 
-static int leds_shutdown(struct sys_device *dev)
+static void leds_shutdown(void)
 {
        leds_event(led_halted);
-       return 0;
 }
 
-static struct sysdev_class leds_sysclass = {
-       .name           = "leds",
+static struct syscore_ops leds_syscore_ops = {
        .shutdown       = leds_shutdown,
        .suspend        = leds_suspend,
        .resume         = leds_resume,
 };
 
-static struct sys_device leds_device = {
-       .id             = 0,
-       .cls            = &leds_sysclass,
-};
-
 static int __init leds_init(void)
 {
        int ret;
@@ -107,6 +109,8 @@ static int __init leds_init(void)
                ret = sysdev_register(&leds_device);
        if (ret == 0)
                ret = sysdev_create_file(&leds_device, &attr_event);
+       if (ret == 0)
+               register_syscore_ops(&leds_syscore_ops);
        return ret;
 }
 
index 1ff46ca..cb634c3 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/timex.h>
 #include <linux/errno.h>
 #include <linux/profile.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/timer.h>
 #include <linux/irq.h>
 
@@ -115,48 +115,37 @@ void timer_tick(void)
 #endif
 
 #if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
-static int timer_suspend(struct sys_device *dev, pm_message_t state)
+static int timer_suspend(void)
 {
-       struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
-
-       if (timer->suspend != NULL)
-               timer->suspend();
+       if (system_timer->suspend)
+               system_timer->suspend();
 
        return 0;
 }
 
-static int timer_resume(struct sys_device *dev)
+static void timer_resume(void)
 {
-       struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
-
-       if (timer->resume != NULL)
-               timer->resume();
-
-       return 0;
+       if (system_timer->resume)
+               system_timer->resume();
 }
 #else
 #define timer_suspend NULL
 #define timer_resume NULL
 #endif
 
-static struct sysdev_class timer_sysclass = {
-       .name           = "timer",
+static struct syscore_ops timer_syscore_ops = {
        .suspend        = timer_suspend,
        .resume         = timer_resume,
 };
 
-static int __init timer_init_sysfs(void)
+static int __init timer_init_syscore_ops(void)
 {
-       int ret = sysdev_class_register(&timer_sysclass);
-       if (ret == 0) {
-               system_timer->dev.cls = &timer_sysclass;
-               ret = sysdev_register(&system_timer->dev);
-       }
+       register_syscore_ops(&timer_syscore_ops);
 
-       return ret;
+       return 0;
 }
 
-device_initcall(timer_init_sysfs);
+device_initcall(timer_init_syscore_ops);
 
 void __init time_init(void)
 {
index 10d917d..8755ca8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/suspend.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
@@ -372,7 +373,27 @@ void exynos4_scu_enable(void __iomem *scu_base)
        flush_cache_all();
 }
 
-static int exynos4_pm_resume(struct sys_device *dev)
+static struct sysdev_driver exynos4_pm_driver = {
+       .add            = exynos4_pm_add,
+};
+
+static __init int exynos4_pm_drvinit(void)
+{
+       unsigned int tmp;
+
+       s3c_pm_init();
+
+       /* All wakeup disable */
+
+       tmp = __raw_readl(S5P_WAKEUP_MASK);
+       tmp |= ((0xFF << 8) | (0x1F << 1));
+       __raw_writel(tmp, S5P_WAKEUP_MASK);
+
+       return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
+}
+arch_initcall(exynos4_pm_drvinit);
+
+static void exynos4_pm_resume(void)
 {
        /* For release retention */
 
@@ -394,27 +415,15 @@ static int exynos4_pm_resume(struct sys_device *dev)
        /* enable L2X0*/
        writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
 #endif
-
-       return 0;
 }
 
-static struct sysdev_driver exynos4_pm_driver = {
-       .add            = exynos4_pm_add,
+static struct syscore_ops exynos4_pm_syscore_ops = {
        .resume         = exynos4_pm_resume,
 };
 
-static __init int exynos4_pm_drvinit(void)
+static __init int exynos4_pm_syscore_init(void)
 {
-       unsigned int tmp;
-
-       s3c_pm_init();
-
-       /* All wakeup disable */
-
-       tmp = __raw_readl(S5P_WAKEUP_MASK);
-       tmp |= ((0xFF << 8) | (0x1F << 1));
-       __raw_writel(tmp, S5P_WAKEUP_MASK);
-
-       return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
+       register_syscore_ops(&exynos4_pm_syscore_ops);
+       return 0;
 }
-arch_initcall(exynos4_pm_drvinit);
+arch_initcall(exynos4_pm_syscore_init);
index 980803f..d3e9645 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
 #include <linux/clocksource.h>
@@ -180,13 +180,13 @@ static void __init ap_init_irq(void)
 #ifdef CONFIG_PM
 static unsigned long ic_irq_enable;
 
-static int irq_suspend(struct sys_device *dev, pm_message_t state)
+static int irq_suspend(void)
 {
        ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
        return 0;
 }
 
-static int irq_resume(struct sys_device *dev)
+static void irq_resume(void)
 {
        /* disable all irq sources */
        writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
@@ -194,33 +194,25 @@ static int irq_resume(struct sys_device *dev)
        writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 
        writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
-       return 0;
 }
 #else
 #define irq_suspend NULL
 #define irq_resume NULL
 #endif
 
-static struct sysdev_class irq_class = {
-       .name           = "irq",
+static struct syscore_ops irq_syscore_ops = {
        .suspend        = irq_suspend,
        .resume         = irq_resume,
 };
 
-static struct sys_device irq_device = {
-       .id     = 0,
-       .cls    = &irq_class,
-};
-
-static int __init irq_init_sysfs(void)
+static int __init irq_syscore_init(void)
 {
-       int ret = sysdev_class_register(&irq_class);
-       if (ret == 0)
-               ret = sysdev_register(&irq_device);
-       return ret;
+       register_syscore_ops(&irq_syscore_ops);
+
+       return 0;
 }
 
-device_initcall(irq_init_sysfs);
+device_initcall(irq_syscore_init);
 
 /*
  * Flash handling.
index 6588c22..fe31d93 100644 (file)
 #ifdef CONFIG_PM_RUNTIME
 static int omap1_pm_runtime_suspend(struct device *dev)
 {
-       struct clk *iclk, *fclk;
-       int ret = 0;
+       int ret;
 
        dev_dbg(dev, "%s\n", __func__);
 
        ret = pm_generic_runtime_suspend(dev);
+       if (ret)
+               return ret;
 
-       fclk = clk_get(dev, "fck");
-       if (!IS_ERR(fclk)) {
-               clk_disable(fclk);
-               clk_put(fclk);
-       }
-
-       iclk = clk_get(dev, "ick");
-       if (!IS_ERR(iclk)) {
-               clk_disable(iclk);
-               clk_put(iclk);
+       ret = pm_runtime_clk_suspend(dev);
+       if (ret) {
+               pm_generic_runtime_resume(dev);
+               return ret;
        }
 
        return 0;
-};
+}
 
 static int omap1_pm_runtime_resume(struct device *dev)
 {
-       struct clk *iclk, *fclk;
-
        dev_dbg(dev, "%s\n", __func__);
 
-       iclk = clk_get(dev, "ick");
-       if (!IS_ERR(iclk)) {
-               clk_enable(iclk);
-               clk_put(iclk);
-       }
+       pm_runtime_clk_resume(dev);
+       return pm_generic_runtime_resume(dev);
+}
 
-       fclk = clk_get(dev, "fck");
-       if (!IS_ERR(fclk)) {
-               clk_enable(fclk);
-               clk_put(fclk);
-       }
+static struct dev_power_domain default_power_domain = {
+       .ops = {
+               .runtime_suspend = omap1_pm_runtime_suspend,
+               .runtime_resume = omap1_pm_runtime_resume,
+               USE_PLATFORM_PM_SLEEP_OPS
+       },
+};
 
-       return pm_generic_runtime_resume(dev);
+static struct pm_clk_notifier_block platform_bus_notifier = {
+       .pwr_domain = &default_power_domain,
+       .con_ids = { "ick", "fck", NULL, },
 };
 
 static int __init omap1_pm_runtime_init(void)
 {
-       const struct dev_pm_ops *pm;
-       struct dev_pm_ops *omap_pm;
-
        if (!cpu_class_is_omap1())
                return -ENODEV;
 
-       pm = platform_bus_get_pm_ops();
-       if (!pm) {
-               pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
-                       __func__);
-               return -ENODEV;
-       }
-
-       omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
-       if (!omap_pm) {
-               pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
-                       __func__);
-               return -ENOMEM;
-       }
-
-       omap_pm->runtime_suspend = omap1_pm_runtime_suspend;
-       omap_pm->runtime_resume = omap1_pm_runtime_resume;
-
-       platform_bus_set_pm_ops(omap_pm);
+       pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
 
        return 0;
 }
index 512b152..66dfbcc 100644 (file)
@@ -59,10 +59,10 @@ endif
 # Power Management
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)               += pm24xx.o
-obj-$(CONFIG_ARCH_OMAP2)               += sleep24xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP2)               += sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)               += pm34xx.o sleep34xx.o \
-                                          cpuidle34xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP4)               += pm44xx.o pm_bus.o
+                                          cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4)               += pm44xx.o
 obj-$(CONFIG_PM_DEBUG)                 += pm-debug.o
 obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
 obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)  += smartreflex-class3.o
diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
deleted file mode 100644 (file)
index 5acd2ab..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Runtime PM support code for OMAP
- *
- * Author: Kevin Hilman, Deep Root Systems, LLC
- *
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-
-#include <plat/omap_device.h>
-#include <plat/omap-pm.h>
-
-#ifdef CONFIG_PM_RUNTIME
-static int omap_pm_runtime_suspend(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       int r, ret = 0;
-
-       dev_dbg(dev, "%s\n", __func__);
-
-       ret = pm_generic_runtime_suspend(dev);
-
-       if (!ret && dev->parent == &omap_device_parent) {
-               r = omap_device_idle(pdev);
-               WARN_ON(r);
-       }
-
-       return ret;
-};
-
-static int omap_pm_runtime_resume(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       int r;
-
-       dev_dbg(dev, "%s\n", __func__);
-
-       if (dev->parent == &omap_device_parent) {
-               r = omap_device_enable(pdev);
-               WARN_ON(r);
-       }
-
-       return pm_generic_runtime_resume(dev);
-};
-#else
-#define omap_pm_runtime_suspend NULL
-#define omap_pm_runtime_resume NULL
-#endif /* CONFIG_PM_RUNTIME */
-
-static int __init omap_pm_runtime_init(void)
-{
-       const struct dev_pm_ops *pm;
-       struct dev_pm_ops *omap_pm;
-
-       pm = platform_bus_get_pm_ops();
-       if (!pm) {
-               pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
-                       __func__);
-               return -ENODEV;
-       }
-
-       omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
-       if (!omap_pm) {
-               pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
-                       __func__);
-               return -ENOMEM;
-       }
-
-       omap_pm->runtime_suspend = omap_pm_runtime_suspend;
-       omap_pm->runtime_resume = omap_pm_runtime_resume;
-
-       platform_bus_set_pm_ops(omap_pm);
-
-       return 0;
-}
-core_initcall(omap_pm_runtime_init);
index bfbecec..810a982 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
index 1ce0904..1d5859d 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/pxa2xx-regs.h>
 
@@ -33,32 +33,22 @@ const struct clkops clk_pxa2xx_cken_ops = {
 #ifdef CONFIG_PM
 static uint32_t saved_cken;
 
-static int pxa2xx_clock_suspend(struct sys_device *d, pm_message_t state)
+static int pxa2xx_clock_suspend(void)
 {
        saved_cken = CKEN;
        return 0;
 }
 
-static int pxa2xx_clock_resume(struct sys_device *d)
+static void pxa2xx_clock_resume(void)
 {
        CKEN = saved_cken;
-       return 0;
 }
 #else
 #define pxa2xx_clock_suspend   NULL
 #define pxa2xx_clock_resume    NULL
 #endif
 
-struct sysdev_class pxa2xx_clock_sysclass = {
-       .name           = "pxa2xx-clock",
+struct syscore_ops pxa2xx_clock_syscore_ops = {
        .suspend        = pxa2xx_clock_suspend,
        .resume         = pxa2xx_clock_resume,
 };
-
-static int __init pxa2xx_clock_init(void)
-{
-       if (cpu_is_pxa2xx())
-               return sysdev_class_register(&pxa2xx_clock_sysclass);
-       return 0;
-}
-postcore_initcall(pxa2xx_clock_init);
index 3f864cd..2a37a9a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/smemc.h>
 #include <mach/pxa3xx-regs.h>
@@ -182,7 +183,7 @@ const struct clkops clk_pxa3xx_pout_ops = {
 static uint32_t cken[2];
 static uint32_t accr;
 
-static int pxa3xx_clock_suspend(struct sys_device *d, pm_message_t state)
+static int pxa3xx_clock_suspend(void)
 {
        cken[0] = CKENA;
        cken[1] = CKENB;
@@ -190,28 +191,18 @@ static int pxa3xx_clock_suspend(struct sys_device *d, pm_message_t state)
        return 0;
 }
 
-static int pxa3xx_clock_resume(struct sys_device *d)
+static void pxa3xx_clock_resume(void)
 {
        ACCR = accr;
        CKENA = cken[0];
        CKENB = cken[1];
-       return 0;
 }
 #else
 #define pxa3xx_clock_suspend   NULL
 #define pxa3xx_clock_resume    NULL
 #endif
 
-struct sysdev_class pxa3xx_clock_sysclass = {
-       .name           = "pxa3xx-clock",
+struct syscore_ops pxa3xx_clock_syscore_ops = {
        .suspend        = pxa3xx_clock_suspend,
        .resume         = pxa3xx_clock_resume,
 };
-
-static int __init pxa3xx_clock_init(void)
-{
-       if (cpu_is_pxa3xx() || cpu_is_pxa95x())
-               return sysdev_class_register(&pxa3xx_clock_sysclass);
-       return 0;
-}
-postcore_initcall(pxa3xx_clock_init);
index f9f349a..1f2fb9c 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/clkdev.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 struct clkops {
        void                    (*enable)(struct clk *);
@@ -54,7 +54,7 @@ extern const struct clkops clk_pxa2xx_cken_ops;
 void clk_pxa2xx_cken_enable(struct clk *clk);
 void clk_pxa2xx_cken_disable(struct clk *clk);
 
-extern struct sysdev_class pxa2xx_clock_sysclass;
+extern struct syscore_ops pxa2xx_clock_syscore_ops;
 
 #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
 #define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay)  \
@@ -74,5 +74,6 @@ extern const struct clkops clk_pxa3xx_smemc_ops;
 extern void clk_pxa3xx_cken_enable(struct clk *);
 extern void clk_pxa3xx_cken_disable(struct clk *);
 
-extern struct sysdev_class pxa3xx_clock_sysclass;
+extern struct syscore_ops pxa3xx_clock_syscore_ops;
+
 #endif
index b88d601..13518a7 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
index 8225e2e..a109967 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
 
@@ -388,7 +388,7 @@ static inline void cmx2xx_init_display(void) {}
 #ifdef CONFIG_PM
 static unsigned long sleep_save_msc[10];
 
-static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state)
+static int cmx2xx_suspend(void)
 {
        cmx2xx_pci_suspend();
 
@@ -412,7 +412,7 @@ static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int cmx2xx_resume(struct sys_device *dev)
+static void cmx2xx_resume(void)
 {
        cmx2xx_pci_resume();
 
@@ -420,27 +420,18 @@ static int cmx2xx_resume(struct sys_device *dev)
        __raw_writel(sleep_save_msc[0], MSC0);
        __raw_writel(sleep_save_msc[1], MSC1);
        __raw_writel(sleep_save_msc[2], MSC2);
-
-       return 0;
 }
 
-static struct sysdev_class cmx2xx_pm_sysclass = {
-       .name = "pm",
+static struct syscore_ops cmx2xx_pm_syscore_ops = {
        .resume = cmx2xx_resume,
        .suspend = cmx2xx_suspend,
 };
 
-static struct sys_device cmx2xx_pm_device = {
-       .cls = &cmx2xx_pm_sysclass,
-};
-
 static int __init cmx2xx_pm_init(void)
 {
-       int error;
-       error = sysdev_class_register(&cmx2xx_pm_sysclass);
-       if (error == 0)
-               error = sysdev_register(&cmx2xx_pm_device);
-       return error;
+       register_syscore_ops(&cmx2xx_pm_syscore_ops);
+
+       return 0;
 }
 #else
 static int __init cmx2xx_pm_init(void) { return 0; }
index 81c3c43..d28e802 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <asm/mach-types.h>
index 44c1b77..80538b8 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/platform_device.h>
 #include <linux/pwm_backlight.h>
 #include <linux/i2c/pxa-i2c.h>
-#include <linux/sysdev.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
index 6fc5d32..7545a48 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/ucb1400.h>
 
 #include <asm/mach/arch.h>
index a079d8b..e6c9344 100644 (file)
@@ -61,10 +61,10 @@ extern unsigned pxa3xx_get_clk_frequency_khz(int);
 #define pxa3xx_get_clk_frequency_khz(x)                (0)
 #endif
 
-extern struct sysdev_class pxa_irq_sysclass;
-extern struct sysdev_class pxa_gpio_sysclass;
-extern struct sysdev_class pxa2xx_mfp_sysclass;
-extern struct sysdev_class pxa3xx_mfp_sysclass;
+extern struct syscore_ops pxa_irq_syscore_ops;
+extern struct syscore_ops pxa_gpio_syscore_ops;
+extern struct syscore_ops pxa2xx_mfp_syscore_ops;
+extern struct syscore_ops pxa3xx_mfp_syscore_ops;
 
 void __init pxa_set_ffuart_info(void *info);
 void __init pxa_set_btuart_info(void *info);
index 6251e3f..32ed551 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 
@@ -183,7 +183,7 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
 static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
 static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
 
-static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
+static int pxa_irq_suspend(void)
 {
        int i;
 
@@ -202,7 +202,7 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int pxa_irq_resume(struct sys_device *dev)
+static void pxa_irq_resume(void)
 {
        int i;
 
@@ -218,22 +218,13 @@ static int pxa_irq_resume(struct sys_device *dev)
                        __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
 
        __raw_writel(1, IRQ_BASE + ICCR);
-       return 0;
 }
 #else
 #define pxa_irq_suspend                NULL
 #define pxa_irq_resume         NULL
 #endif
 
-struct sysdev_class pxa_irq_sysclass = {
-       .name           = "irq",
+struct syscore_ops pxa_irq_syscore_ops = {
        .suspend        = pxa_irq_suspend,
        .resume         = pxa_irq_resume,
 };
-
-static int __init pxa_irq_init(void)
-{
-       return sysdev_class_register(&pxa_irq_sysclass);
-}
-
-core_initcall(pxa_irq_init);
index f5de541..6cf8180 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
@@ -159,30 +159,22 @@ static void __init lpd270_init_irq(void)
 
 
 #ifdef CONFIG_PM
-static int lpd270_irq_resume(struct sys_device *dev)
+static void lpd270_irq_resume(void)
 {
        __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
-       return 0;
 }
 
-static struct sysdev_class lpd270_irq_sysclass = {
-       .name = "cpld_irq",
+static struct syscore_ops lpd270_irq_syscore_ops = {
        .resume = lpd270_irq_resume,
 };
 
-static struct sys_device lpd270_irq_device = {
-       .cls = &lpd270_irq_sysclass,
-};
-
 static int __init lpd270_irq_device_init(void)
 {
-       int ret = -ENODEV;
        if (machine_is_logicpd_pxa270()) {
-               ret = sysdev_class_register(&lpd270_irq_sysclass);
-               if (ret == 0)
-                       ret = sysdev_register(&lpd270_irq_device);
+               register_syscore_ops(&lpd270_irq_syscore_ops);
+               return 0;
        }
-       return ret;
+       return -ENODEV;
 }
 
 device_initcall(lpd270_irq_device_init);
index 3ede978..e10ddb8 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/major.h>
 #include <linux/fb.h>
 #include <linux/interrupt.h>
@@ -176,31 +176,22 @@ static void __init lubbock_init_irq(void)
 
 #ifdef CONFIG_PM
 
-static int lubbock_irq_resume(struct sys_device *dev)
+static void lubbock_irq_resume(void)
 {
        LUB_IRQ_MASK_EN = lubbock_irq_enabled;
-       return 0;
 }
 
-static struct sysdev_class lubbock_irq_sysclass = {
-       .name = "cpld_irq",
+static struct syscore_ops lubbock_irq_syscore_ops = {
        .resume = lubbock_irq_resume,
 };
 
-static struct sys_device lubbock_irq_device = {
-       .cls = &lubbock_irq_sysclass,
-};
-
 static int __init lubbock_irq_device_init(void)
 {
-       int ret = -ENODEV;
-
        if (machine_is_lubbock()) {
-               ret = sysdev_class_register(&lubbock_irq_sysclass);
-               if (ret == 0)
-                       ret = sysdev_register(&lubbock_irq_device);
+               register_syscore_ops(&lubbock_irq_syscore_ops);
+               return 0;
        }
-       return ret;
+       return -ENODEV;
 }
 
 device_initcall(lubbock_irq_device_init);
index 95163ba..3479e2b 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
@@ -185,31 +185,21 @@ static void __init mainstone_init_irq(void)
 
 #ifdef CONFIG_PM
 
-static int mainstone_irq_resume(struct sys_device *dev)
+static void mainstone_irq_resume(void)
 {
        MST_INTMSKENA = mainstone_irq_enabled;
-       return 0;
 }
 
-static struct sysdev_class mainstone_irq_sysclass = {
-       .name = "cpld_irq",
+static struct syscore_ops mainstone_irq_syscore_ops = {
        .resume = mainstone_irq_resume,
 };
 
-static struct sys_device mainstone_irq_device = {
-       .cls = &mainstone_irq_sysclass,
-};
-
 static int __init mainstone_irq_device_init(void)
 {
-       int ret = -ENODEV;
+       if (machine_is_mainstone())
+               register_syscore_ops(&mainstone_irq_syscore_ops);
 
-       if (machine_is_mainstone()) {
-               ret = sysdev_class_register(&mainstone_irq_sysclass);
-               if (ret == 0)
-                       ret = sysdev_register(&mainstone_irq_device);
-       }
-       return ret;
+       return 0;
 }
 
 device_initcall(mainstone_irq_device_init);
index 1d1419b..87ae312 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/gpio.h>
 #include <mach/pxa2xx-regs.h>
@@ -338,7 +338,7 @@ static unsigned long saved_gafr[2][4];
 static unsigned long saved_gpdr[4];
 static unsigned long saved_pgsr[4];
 
-static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
+static int pxa2xx_mfp_suspend(void)
 {
        int i;
 
@@ -365,7 +365,7 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
        return 0;
 }
 
-static int pxa2xx_mfp_resume(struct sys_device *d)
+static void pxa2xx_mfp_resume(void)
 {
        int i;
 
@@ -376,15 +376,13 @@ static int pxa2xx_mfp_resume(struct sys_device *d)
                PGSR(i) = saved_pgsr[i];
        }
        PSSR = PSSR_RDH | PSSR_PH;
-       return 0;
 }
 #else
 #define pxa2xx_mfp_suspend     NULL
 #define pxa2xx_mfp_resume      NULL
 #endif
 
-struct sysdev_class pxa2xx_mfp_sysclass = {
-       .name           = "mfp",
+struct syscore_ops pxa2xx_mfp_syscore_ops = {
        .suspend        = pxa2xx_mfp_suspend,
        .resume         = pxa2xx_mfp_resume,
 };
@@ -409,6 +407,6 @@ static int __init pxa2xx_mfp_init(void)
        for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
                gpdr_lpm[i] = GPDR(i * 32);
 
-       return sysdev_class_register(&pxa2xx_mfp_sysclass);
+       return 0;
 }
 postcore_initcall(pxa2xx_mfp_init);
index 7a270ee..89863a0 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <mach/mfp-pxa3xx.h>
  * a pull-down mode if they're an active low chip select, and we're
  * just entering standby.
  */
-static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
+static int pxa3xx_mfp_suspend(void)
 {
        mfp_config_lpm();
        return 0;
 }
 
-static int pxa3xx_mfp_resume(struct sys_device *d)
+static void pxa3xx_mfp_resume(void)
 {
        mfp_config_run();
 
@@ -47,24 +47,13 @@ static int pxa3xx_mfp_resume(struct sys_device *d)
         * preserve them here in case they will be referenced later
         */
        ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
-       return 0;
 }
 #else
 #define pxa3xx_mfp_suspend     NULL
 #define pxa3xx_mfp_resume      NULL
 #endif
 
-struct sysdev_class pxa3xx_mfp_sysclass = {
-       .name           = "mfp",
+struct syscore_ops pxa3xx_mfp_syscore_ops = {
        .suspend        = pxa3xx_mfp_suspend,
-       .resume         = pxa3xx_mfp_resume,
+       .resume         = pxa3xx_mfp_resume,
 };
-
-static int __init mfp_init_devicefs(void)
-{
-       if (cpu_is_pxa3xx())
-               return sysdev_class_register(&pxa3xx_mfp_sysclass);
-
-       return 0;
-}
-postcore_initcall(mfp_init_devicefs);
index 23925db..e347013 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/gpio_keys.h>
@@ -488,7 +488,7 @@ static void install_bootstrap(void)
 }
 
 
-static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state)
+static int mioa701_sys_suspend(void)
 {
        int i = 0, is_bt_on;
        u32 *mem_resume_vector  = phys_to_virt(RESUME_VECTOR_ADDR);
@@ -514,7 +514,7 @@ static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state)
        return 0;
 }
 
-static int mioa701_sys_resume(struct sys_device *sysdev)
+static void mioa701_sys_resume(void)
 {
        int i = 0;
        u32 *mem_resume_vector  = phys_to_virt(RESUME_VECTOR_ADDR);
@@ -527,43 +527,18 @@ static int mioa701_sys_resume(struct sys_device *sysdev)
        *mem_resume_enabler = save_buffer[i++];
        *mem_resume_bt      = save_buffer[i++];
        *mem_resume_unknown = save_buffer[i++];
-
-       return 0;
 }
 
-static struct sysdev_class mioa701_sysclass = {
-       .name = "mioa701",
-};
-
-static struct sys_device sysdev_bootstrap = {
-       .cls            = &mioa701_sysclass,
-};
-
-static struct sysdev_driver driver_bootstrap = {
-       .suspend        = &mioa701_sys_suspend,
-       .resume         = &mioa701_sys_resume,
+static struct syscore_ops mioa701_syscore_ops = {
+       .suspend        = mioa701_sys_suspend,
+       .resume         = mioa701_sys_resume,
 };
 
 static int __init bootstrap_init(void)
 {
-       int rc;
        int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3);
 
-       rc = sysdev_class_register(&mioa701_sysclass);
-       if (rc) {
-               printk(KERN_ERR "Failed registering mioa701 sys class\n");
-               return -ENODEV;
-       }
-       rc = sysdev_register(&sysdev_bootstrap);
-       if (rc) {
-               printk(KERN_ERR "Failed registering mioa701 sys device\n");
-               return -ENODEV;
-       }
-       rc = sysdev_driver_register(&mioa701_sysclass, &driver_bootstrap);
-       if (rc) {
-               printk(KERN_ERR "Failed registering PMU sys driver\n");
-               return -ENODEV;
-       }
+       register_syscore_ops(&mioa701_syscore_ops);
 
        save_buffer = kmalloc(save_size, GFP_KERNEL);
        if (!save_buffer)
@@ -576,9 +551,7 @@ static int __init bootstrap_init(void)
 static void bootstrap_exit(void)
 {
        kfree(save_buffer);
-       sysdev_driver_unregister(&mioa701_sysclass, &driver_bootstrap);
-       sysdev_unregister(&sysdev_bootstrap);
-       sysdev_class_unregister(&mioa701_sysclass);
+       unregister_syscore_ops(&mioa701_syscore_ops);
 
        printk(KERN_CRIT "Unregistering mioa701 suspend will hang next"
               "resume !!!\n");
index a6f898c..4061ecd 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/gpio.h>
 #include <linux/wm97xx.h>
 #include <linux/power_supply.h>
-#include <linux/sysdev.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
index 8aadad5..20d1b18 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
 #include <linux/power_supply.h>
-#include <linux/sysdev.h>
 #include <linux/w1-gpio.h>
 
 #include <asm/mach-types.h>
index 3b8a4f3..65f24f0 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
@@ -233,9 +233,9 @@ static struct palmz72_resume_info palmz72_resume_info = {
 
 static unsigned long store_ptr;
 
-/* sys_device for Palm Zire 72 PM */
+/* syscore_ops for Palm Zire 72 PM */
 
-static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
+static int palmz72_pm_suspend(void)
 {
        /* setup the resume_info struct for the original bootloader */
        palmz72_resume_info.resume_addr = (u32) cpu_resume;
@@ -249,31 +249,23 @@ static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
        return 0;
 }
 
-static int palmz72_pm_resume(struct sys_device *dev)
+static void palmz72_pm_resume(void)
 {
        *PALMZ72_SAVE_DWORD = store_ptr;
-       return 0;
 }
 
-static struct sysdev_class palmz72_pm_sysclass = {
-       .name = "palmz72_pm",
+static struct syscore_ops palmz72_pm_syscore_ops = {
        .suspend = palmz72_pm_suspend,
        .resume = palmz72_pm_resume,
 };
 
-static struct sys_device palmz72_pm_device = {
-       .cls = &palmz72_pm_sysclass,
-};
-
 static int __init palmz72_pm_init(void)
 {
-       int ret = -ENODEV;
        if (machine_is_palmz72()) {
-               ret = sysdev_class_register(&palmz72_pm_sysclass);
-               if (ret == 0)
-                       ret = sysdev_register(&palmz72_pm_device);
+               register_syscore_ops(&palmz72_pm_syscore_ops);
+               return 0;
        }
-       return ret;
+       return -ENODEV;
 }
 
 device_initcall(palmz72_pm_init);
index a4af8c5..fed363c 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/suspend.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/irq.h>
 
 #include <asm/mach/map.h>
@@ -350,21 +350,9 @@ static struct platform_device *pxa25x_devices[] __initdata = {
        &pxa_device_asoc_platform,
 };
 
-static struct sys_device pxa25x_sysdev[] = {
-       {
-               .cls    = &pxa_irq_sysclass,
-       }, {
-               .cls    = &pxa2xx_mfp_sysclass,
-       }, {
-               .cls    = &pxa_gpio_sysclass,
-       }, {
-               .cls    = &pxa2xx_clock_sysclass,
-       }
-};
-
 static int __init pxa25x_init(void)
 {
-       int i, ret = 0;
+       int ret = 0;
 
        if (cpu_is_pxa25x()) {
 
@@ -377,11 +365,10 @@ static int __init pxa25x_init(void)
 
                pxa25x_init_pm();
 
-               for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) {
-                       ret = sysdev_register(&pxa25x_sysdev[i]);
-                       if (ret)
-                               pr_err("failed to register sysdev[%d]\n", i);
-               }
+               register_syscore_ops(&pxa_irq_syscore_ops);
+               register_syscore_ops(&pxa2xx_mfp_syscore_ops);
+               register_syscore_ops(&pxa_gpio_syscore_ops);
+               register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
                ret = platform_add_devices(pxa25x_devices,
                                           ARRAY_SIZE(pxa25x_devices));
index 909756e..2fecbec 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -428,21 +428,9 @@ static struct platform_device *devices[] __initdata = {
        &pxa27x_device_pwm1,
 };
 
-static struct sys_device pxa27x_sysdev[] = {
-       {
-               .cls    = &pxa_irq_sysclass,
-       }, {
-               .cls    = &pxa2xx_mfp_sysclass,
-       }, {
-               .cls    = &pxa_gpio_sysclass,
-       }, {
-               .cls    = &pxa2xx_clock_sysclass,
-       }
-};
-
 static int __init pxa27x_init(void)
 {
-       int i, ret = 0;
+       int ret = 0;
 
        if (cpu_is_pxa27x()) {
 
@@ -455,11 +443,10 @@ static int __init pxa27x_init(void)
 
                pxa27x_init_pm();
 
-               for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) {
-                       ret = sysdev_register(&pxa27x_sysdev[i]);
-                       if (ret)
-                               pr_err("failed to register sysdev[%d]\n", i);
-               }
+               register_syscore_ops(&pxa_irq_syscore_ops);
+               register_syscore_ops(&pxa2xx_mfp_syscore_ops);
+               register_syscore_ops(&pxa_gpio_syscore_ops);
+               register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
index 8dd1073..8521d7d 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/i2c/pxa-i2c.h>
 
 #include <asm/mach/map.h>
@@ -427,21 +427,9 @@ static struct platform_device *devices[] __initdata = {
        &pxa27x_device_pwm1,
 };
 
-static struct sys_device pxa3xx_sysdev[] = {
-       {
-               .cls    = &pxa_irq_sysclass,
-       }, {
-               .cls    = &pxa3xx_mfp_sysclass,
-       }, {
-               .cls    = &pxa_gpio_sysclass,
-       }, {
-               .cls    = &pxa3xx_clock_sysclass,
-       }
-};
-
 static int __init pxa3xx_init(void)
 {
-       int i, ret = 0;
+       int ret = 0;
 
        if (cpu_is_pxa3xx()) {
 
@@ -462,11 +450,10 @@ static int __init pxa3xx_init(void)
 
                pxa3xx_init_pm();
 
-               for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) {
-                       ret = sysdev_register(&pxa3xx_sysdev[i]);
-                       if (ret)
-                               pr_err("failed to register sysdev[%d]\n", i);
-               }
+               register_syscore_ops(&pxa_irq_syscore_ops);
+               register_syscore_ops(&pxa3xx_mfp_syscore_ops);
+               register_syscore_ops(&pxa_gpio_syscore_ops);
+               register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
index 23b229b..ecc82a3 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <mach/gpio.h>
@@ -260,16 +260,6 @@ static struct platform_device *devices[] __initdata = {
        &pxa27x_device_pwm1,
 };
 
-static struct sys_device pxa95x_sysdev[] = {
-       {
-               .cls    = &pxa_irq_sysclass,
-       }, {
-               .cls    = &pxa_gpio_sysclass,
-       }, {
-               .cls    = &pxa3xx_clock_sysclass,
-       }
-};
-
 static int __init pxa95x_init(void)
 {
        int ret = 0, i;
@@ -293,11 +283,9 @@ static int __init pxa95x_init(void)
                if ((ret = pxa_init_dma(IRQ_DMA, 32)))
                        return ret;
 
-               for (i = 0; i < ARRAY_SIZE(pxa95x_sysdev); i++) {
-                       ret = sysdev_register(&pxa95x_sysdev[i]);
-                       if (ret)
-                               pr_err("failed to register sysdev[%d]\n", i);
-               }
+               register_syscore_ops(&pxa_irq_syscore_ops);
+               register_syscore_ops(&pxa_gpio_syscore_ops);
+               register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
index cd18613..d130f77 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/sysdev.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
index 232b731..7992305 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <mach/smemc.h>
@@ -16,7 +16,7 @@ static unsigned long msc[2];
 static unsigned long sxcnfg, memclkcfg;
 static unsigned long csadrcfg[4];
 
-static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state)
+static int pxa3xx_smemc_suspend(void)
 {
        msc[0] = __raw_readl(MSC0);
        msc[1] = __raw_readl(MSC1);
@@ -30,7 +30,7 @@ static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int pxa3xx_smemc_resume(struct sys_device *dev)
+static void pxa3xx_smemc_resume(void)
 {
        __raw_writel(msc[0], MSC0);
        __raw_writel(msc[1], MSC1);
@@ -40,34 +40,19 @@ static int pxa3xx_smemc_resume(struct sys_device *dev)
        __raw_writel(csadrcfg[1], CSADRCFG1);
        __raw_writel(csadrcfg[2], CSADRCFG2);
        __raw_writel(csadrcfg[3], CSADRCFG3);
-
-       return 0;
 }
 
-static struct sysdev_class smemc_sysclass = {
-       .name           = "smemc",
+static struct syscore_ops smemc_syscore_ops = {
        .suspend        = pxa3xx_smemc_suspend,
        .resume         = pxa3xx_smemc_resume,
 };
 
-static struct sys_device smemc_sysdev = {
-       .id             = 0,
-       .cls            = &smemc_sysclass,
-};
-
 static int __init smemc_init(void)
 {
-       int ret = 0;
+       if (cpu_is_pxa3xx())
+               register_syscore_ops(&smemc_syscore_ops);
 
-       if (cpu_is_pxa3xx()) {
-               ret = sysdev_class_register(&smemc_sysclass);
-               if (ret)
-                       return ret;
-
-               ret = sysdev_register(&smemc_sysdev);
-       }
-
-       return ret;
+       return 0;
 }
 subsys_initcall(smemc_init);
 #endif
index b9cfbeb..687417a 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
index b523f11..903218e 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/pxa25x.h>
 #include <mach/audio.h>
@@ -130,20 +131,19 @@ static u8 viper_hw_version(void)
        return v1;
 }
 
-/* CPU sysdev */
-static int viper_cpu_suspend(struct sys_device *sysdev, pm_message_t state)
+/* CPU system core operations. */
+static int viper_cpu_suspend(void)
 {
        viper_icr_set_bit(VIPER_ICR_R_DIS);
        return 0;
 }
 
-static int viper_cpu_resume(struct sys_device *sysdev)
+static void viper_cpu_resume(void)
 {
        viper_icr_clear_bit(VIPER_ICR_R_DIS);
-       return 0;
 }
 
-static struct sysdev_driver viper_cpu_sysdev_driver = {
+static struct syscore_ops viper_cpu_syscore_ops = {
        .suspend        = viper_cpu_suspend,
        .resume         = viper_cpu_resume,
 };
@@ -945,7 +945,7 @@ static void __init viper_init(void)
        viper_init_vcore_gpios();
        viper_init_cpufreq();
 
-       sysdev_driver_register(&cpu_sysdev_class, &viper_cpu_sysdev_driver);
+       register_syscore_ops(&viper_cpu_syscore_ops);
 
        if (version) {
                pr_info("viper: hardware v%di%d detected. "
index f71d377..67bd414 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
-#include <linux/sysdev.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 5e2f353..2854129 100644 (file)
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
 
-static int s3c2410_irq_add(struct sys_device *sysdev)
-{
-       return 0;
-}
-
-static struct sysdev_driver s3c2410_irq_driver = {
-       .add            = s3c2410_irq_add,
+struct syscore_ops s3c24xx_irq_syscore_ops = {
        .suspend        = s3c24xx_irq_suspend,
        .resume         = s3c24xx_irq_resume,
 };
-
-static int __init s3c2410_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
-}
-
-arch_initcall(s3c2410_irq_init);
-
-static struct sysdev_driver s3c2410a_irq_driver = {
-       .add            = s3c2410_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
-};
-
-static int __init s3c2410a_irq_init(void)
-{
-       return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver);
-}
-
-arch_initcall(s3c2410a_irq_init);
index 2970ea9..1e2d536 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/dm9000.h>
@@ -214,17 +214,16 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
 /* NAND Flash on BAST board */
 
 #ifdef CONFIG_PM
-static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
+static int bast_pm_suspend(void)
 {
        /* ensure that an nRESET is not generated on resume. */
        gpio_direction_output(S3C2410_GPA(21), 1);
        return 0;
 }
 
-static int bast_pm_resume(struct sys_device *sd)
+static void bast_pm_resume(void)
 {
        s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
-       return 0;
 }
 
 #else
@@ -232,16 +231,11 @@ static int bast_pm_resume(struct sys_device *sd)
 #define bast_pm_resume NULL
 #endif
 
-static struct sysdev_class bast_pm_sysclass = {
-       .name           = "mach-bast",
+static struct syscore_ops bast_pm_syscore_ops = {
        .suspend        = bast_pm_suspend,
        .resume         = bast_pm_resume,
 };
 
-static struct sys_device bast_pm_sysdev = {
-       .cls            = &bast_pm_sysclass,
-};
-
 static int smartmedia_map[] = { 0 };
 static int chip0_map[] = { 1 };
 static int chip1_map[] = { 2 };
@@ -642,8 +636,7 @@ static void __init bast_map_io(void)
 
 static void __init bast_init(void)
 {
-       sysdev_class_register(&bast_pm_sysclass);
-       sysdev_register(&bast_pm_sysdev);
+       register_syscore_ops(&bast_pm_syscore_ops);
 
        s3c_i2c0_set_platdata(&bast_i2c_info);
        s3c_nand_set_platdata(&bast_nand_info);
index 725636f..4728f9a 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/time.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 
@@ -92,7 +93,7 @@ static void s3c2410_pm_prepare(void)
        }
 }
 
-static int s3c2410_pm_resume(struct sys_device *dev)
+static void s3c2410_pm_resume(void)
 {
        unsigned long tmp;
 
@@ -104,10 +105,12 @@ static int s3c2410_pm_resume(struct sys_device *dev)
 
        if ( machine_is_aml_m5900() )
                s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-
-       return 0;
 }
 
+struct syscore_ops s3c2410_pm_syscore_ops = {
+       .resume         = s3c2410_pm_resume,
+};
+
 static int s3c2410_pm_add(struct sys_device *dev)
 {
        pm_cpu_prep = s3c2410_pm_prepare;
@@ -119,7 +122,6 @@ static int s3c2410_pm_add(struct sys_device *dev)
 #if defined(CONFIG_CPU_S3C2410)
 static struct sysdev_driver s3c2410_pm_driver = {
        .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
 };
 
 /* register ourselves */
@@ -133,7 +135,6 @@ arch_initcall(s3c2410_pm_drvinit);
 
 static struct sysdev_driver s3c2410a_pm_driver = {
        .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
 };
 
 static int __init s3c2410a_pm_drvinit(void)
@@ -147,7 +148,6 @@ arch_initcall(s3c2410a_pm_drvinit);
 #if defined(CONFIG_CPU_S3C2440)
 static struct sysdev_driver s3c2440_pm_driver = {
        .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
 };
 
 static int __init s3c2440_pm_drvinit(void)
@@ -161,7 +161,6 @@ arch_initcall(s3c2440_pm_drvinit);
 #if defined(CONFIG_CPU_S3C2442)
 static struct sysdev_driver s3c2442_pm_driver = {
        .add            = s3c2410_pm_add,
-       .resume         = s3c2410_pm_resume,
 };
 
 static int __init s3c2442_pm_drvinit(void)
index adc90a3..f1d3bd8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -40,6 +41,7 @@
 #include <plat/devs.h>
 #include <plat/clock.h>
 #include <plat/pll.h>
+#include <plat/pm.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -168,6 +170,9 @@ int __init s3c2410_init(void)
 {
        printk("S3C2410: Initialising architecture\n");
 
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
        return sysdev_register(&s3c2410_sysdev);
 }
 
index f3355d2..1a1aa22 100644 (file)
@@ -202,8 +202,6 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
 
 static struct sysdev_driver s3c2412_irq_driver = {
        .add            = s3c2412_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
 };
 
 static int s3c2412_irq_init(void)
index 923e01b..85dcaeb 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
@@ -486,7 +486,7 @@ static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
 /* Jive power management device */
 
 #ifdef CONFIG_PM
-static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
+static int jive_pm_suspend(void)
 {
        /* Write the magic value u-boot uses to check for resume into
         * the INFORM0 register, and ensure INFORM1 is set to the
@@ -498,10 +498,9 @@ static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
        return 0;
 }
 
-static int jive_pm_resume(struct sys_device *sd)
+static void jive_pm_resume(void)
 {
        __raw_writel(0x0, S3C2412_INFORM0);
-       return 0;
 }
 
 #else
@@ -509,16 +508,11 @@ static int jive_pm_resume(struct sys_device *sd)
 #define jive_pm_resume NULL
 #endif
 
-static struct sysdev_class jive_pm_sysclass = {
-       .name           = "jive-pm",
+static struct syscore_ops jive_pm_syscore_ops = {
        .suspend        = jive_pm_suspend,
        .resume         = jive_pm_resume,
 };
 
-static struct sys_device jive_pm_sysdev = {
-       .cls            = &jive_pm_sysclass,
-};
-
 static void __init jive_map_io(void)
 {
        s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
@@ -536,10 +530,9 @@ static void jive_power_off(void)
 
 static void __init jive_machine_init(void)
 {
-       /* register system devices for managing low level suspend */
+       /* register system core operations for managing low level suspend */
 
-       sysdev_class_register(&jive_pm_sysclass);
-       sysdev_register(&jive_pm_sysdev);
+       register_syscore_ops(&jive_pm_syscore_ops);
 
        /* write our sleep configurations for the IO. Pull down all unused
         * IO, ensure that we have turned off all peripherals we do not
index a7417c4..752b13a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -86,13 +87,24 @@ static struct sleep_save s3c2412_sleep[] = {
        SAVE_ITEM(S3C2413_GPJSLPCON),
 };
 
-static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
+static struct sysdev_driver s3c2412_pm_driver = {
+       .add            = s3c2412_pm_add,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
+}
+
+arch_initcall(s3c2412_pm_init);
+
+static int s3c2412_pm_suspend(void)
 {
        s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
        return 0;
 }
 
-static int s3c2412_pm_resume(struct sys_device *dev)
+static void s3c2412_pm_resume(void)
 {
        unsigned long tmp;
 
@@ -102,18 +114,9 @@ static int s3c2412_pm_resume(struct sys_device *dev)
        __raw_writel(tmp, S3C2412_PWRCFG);
 
        s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-       return 0;
 }
 
-static struct sysdev_driver s3c2412_pm_driver = {
-       .add            = s3c2412_pm_add,
+struct syscore_ops s3c2412_pm_syscore_ops = {
        .suspend        = s3c2412_pm_suspend,
        .resume         = s3c2412_pm_resume,
 };
-
-static __init int s3c2412_pm_init(void)
-{
-       return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
-}
-
-arch_initcall(s3c2412_pm_init);
index 4c6df51..ef0958d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -244,5 +245,8 @@ int __init s3c2412_init(void)
 {
        printk("S3C2412: Initialising architecture\n");
 
+       register_syscore_ops(&s3c2412_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
        return sysdev_register(&s3c2412_sysdev);
 }
index 77b38f2..28ad20d 100644 (file)
@@ -236,8 +236,6 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev)
 
 static struct sysdev_driver s3c2416_irq_driver = {
        .add            = s3c2416_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
 };
 
 static int __init s3c2416_irq_init(void)
index 4a04205..41db2b2 100644 (file)
@@ -11,6 +11,7 @@
 */
 
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
@@ -55,30 +56,26 @@ static int s3c2416_pm_add(struct sys_device *sysdev)
        return 0;
 }
 
-static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state)
+static struct sysdev_driver s3c2416_pm_driver = {
+       .add            = s3c2416_pm_add,
+};
+
+static __init int s3c2416_pm_init(void)
 {
-       return 0;
+       return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
 }
 
-static int s3c2416_pm_resume(struct sys_device *dev)
+arch_initcall(s3c2416_pm_init);
+
+
+static void s3c2416_pm_resume(void)
 {
        /* unset the return-from-sleep amd inform flags */
        __raw_writel(0x0, S3C2443_PWRMODE);
        __raw_writel(0x0, S3C2412_INFORM0);
        __raw_writel(0x0, S3C2412_INFORM1);
-
-       return 0;
 }
 
-static struct sysdev_driver s3c2416_pm_driver = {
-       .add            = s3c2416_pm_add,
-       .suspend        = s3c2416_pm_suspend,
+struct syscore_ops s3c2416_pm_syscore_ops = {
        .resume         = s3c2416_pm_resume,
 };
-
-static __init int s3c2416_pm_init(void)
-{
-       return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
-}
-
-arch_initcall(s3c2416_pm_init);
index ba7fd87..494ce91 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -54,6 +55,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/sdhci.h>
+#include <plat/pm.h>
 
 #include <plat/iic-core.h>
 #include <plat/fb-core.h>
@@ -95,6 +97,9 @@ int __init s3c2416_init(void)
 
        s3c_fb_setname("s3c2443-fb");
 
+       register_syscore_ops(&s3c2416_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
        return sysdev_register(&s3c2416_sysdev);
 }
 
index 14dc678..d885363 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/clk.h>
 #include <linux/i2c.h>
@@ -284,7 +284,7 @@ static struct platform_device osiris_pcmcia = {
 #ifdef CONFIG_PM
 static unsigned char pm_osiris_ctrl0;
 
-static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
+static int osiris_pm_suspend(void)
 {
        unsigned int tmp;
 
@@ -304,7 +304,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
        return 0;
 }
 
-static int osiris_pm_resume(struct sys_device *sd)
+static void osiris_pm_resume(void)
 {
        if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
                __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
@@ -312,8 +312,6 @@ static int osiris_pm_resume(struct sys_device *sd)
        __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
 
        s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
-
-       return 0;
 }
 
 #else
@@ -321,16 +319,11 @@ static int osiris_pm_resume(struct sys_device *sd)
 #define osiris_pm_resume NULL
 #endif
 
-static struct sysdev_class osiris_pm_sysclass = {
-       .name           = "mach-osiris",
+static struct syscore_ops osiris_pm_syscore_ops = {
        .suspend        = osiris_pm_suspend,
        .resume         = osiris_pm_resume,
 };
 
-static struct sys_device osiris_pm_sysdev = {
-       .cls            = &osiris_pm_sysclass,
-};
-
 /* Link for DVS driver to TPS65011 */
 
 static void osiris_tps_release(struct device *dev)
@@ -439,8 +432,7 @@ static void __init osiris_map_io(void)
 
 static void __init osiris_init(void)
 {
-       sysdev_class_register(&osiris_pm_sysclass);
-       sysdev_register(&osiris_pm_sysdev);
+       register_syscore_ops(&osiris_pm_syscore_ops);
 
        s3c_i2c0_set_platdata(NULL);
        s3c_nand_set_platdata(&osiris_nand_info);
index f7663f7..ce99ff7 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -33,6 +34,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/s3c244x.h>
+#include <plat/pm.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -51,6 +53,12 @@ int __init s3c2440_init(void)
        s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
        s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
 
+       /* register suspend/resume handlers */
+
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+       register_syscore_ops(&s3c244x_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
        /* register our system device for everything else */
 
        return sysdev_register(&s3c2440_sysdev);
index ecf8135..6224bad 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/mutex.h>
@@ -45,6 +46,7 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/s3c244x.h>
+#include <plat/pm.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -167,6 +169,10 @@ int __init s3c2442_init(void)
 {
        printk("S3C2442: Initialising architecture\n");
 
+       register_syscore_ops(&s3c2410_pm_syscore_ops);
+       register_syscore_ops(&s3c244x_pm_syscore_ops);
+       register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
        return sysdev_register(&s3c2442_sysdev);
 }
 
index de07c2f..c63e8f2 100644 (file)
@@ -116,8 +116,6 @@ static int s3c244x_irq_add(struct sys_device *sysdev)
 
 static struct sysdev_driver s3c2440_irq_driver = {
        .add            = s3c244x_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
 };
 
 static int s3c2440_irq_init(void)
@@ -129,8 +127,6 @@ arch_initcall(s3c2440_irq_init);
 
 static struct sysdev_driver s3c2442_irq_driver = {
        .add            = s3c244x_irq_add,
-       .suspend        = s3c24xx_irq_suspend,
-       .resume         = s3c24xx_irq_resume,
 };
 
 
index 90c1707..7e8a23d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -134,45 +135,14 @@ void __init s3c244x_init_clocks(int xtal)
        s3c2410_baseclk_add();
 }
 
-#ifdef CONFIG_PM
-
-static struct sleep_save s3c244x_sleep[] = {
-       SAVE_ITEM(S3C2440_DSC0),
-       SAVE_ITEM(S3C2440_DSC1),
-       SAVE_ITEM(S3C2440_GPJDAT),
-       SAVE_ITEM(S3C2440_GPJCON),
-       SAVE_ITEM(S3C2440_GPJUP)
-};
-
-static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
-{
-       s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-       return 0;
-}
-
-static int s3c244x_resume(struct sys_device *dev)
-{
-       s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
-       return 0;
-}
-
-#else
-#define s3c244x_suspend NULL
-#define s3c244x_resume  NULL
-#endif
-
 /* Since the S3C2442 and S3C2440 share  items, put both sysclasses here */
 
 struct sysdev_class s3c2440_sysclass = {
        .name           = "s3c2440-core",
-       .suspend        = s3c244x_suspend,
-       .resume         = s3c244x_resume
 };
 
 struct sysdev_class s3c2442_sysclass = {
        .name           = "s3c2442-core",
-       .suspend        = s3c244x_suspend,
-       .resume         = s3c244x_resume
 };
 
 /* need to register class before we actually register the device, and
@@ -194,3 +164,33 @@ static int __init s3c2442_core_init(void)
 }
 
 core_initcall(s3c2442_core_init);
+
+
+#ifdef CONFIG_PM
+static struct sleep_save s3c244x_sleep[] = {
+       SAVE_ITEM(S3C2440_DSC0),
+       SAVE_ITEM(S3C2440_DSC1),
+       SAVE_ITEM(S3C2440_GPJDAT),
+       SAVE_ITEM(S3C2440_GPJCON),
+       SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(void)
+{
+       s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+       return 0;
+}
+
+static void s3c244x_resume(void)
+{
+       s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+}
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume  NULL
+#endif
+
+struct syscore_ops s3c244x_pm_syscore_ops = {
+       .suspend        = s3c244x_suspend,
+       .resume         = s3c244x_resume,
+};
index da1bec6..8bec61e 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/serial_core.h>
 #include <linux/irq.h>
@@ -54,7 +54,7 @@ static struct irq_grp_save {
 
 static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
 
-static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
+static int s3c64xx_irq_pm_suspend(void)
 {
        struct irq_grp_save *grp = eint_grp_save;
        int i;
@@ -75,7 +75,7 @@ static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int s3c64xx_irq_pm_resume(struct sys_device *dev)
+static void s3c64xx_irq_pm_resume(void)
 {
        struct irq_grp_save *grp = eint_grp_save;
        int i;
@@ -94,18 +94,18 @@ static int s3c64xx_irq_pm_resume(struct sys_device *dev)
        }
 
        S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
-       return 0;
 }
 
-static struct sysdev_driver s3c64xx_irq_driver = {
+struct syscore_ops s3c64xx_irq_syscore_ops = {
        .suspend = s3c64xx_irq_pm_suspend,
        .resume  = s3c64xx_irq_pm_resume,
 };
 
-static int __init s3c64xx_irq_pm_init(void)
+static __init int s3c64xx_syscore_init(void)
 {
-       return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
-}
+       register_syscore_ops(&s3c64xx_irq_syscore_ops);
 
-arch_initcall(s3c64xx_irq_pm_init);
+       return 0;
+}
 
+core_initcall(s3c64xx_syscore_init);
index 549d792..24febae 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/suspend.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 
 #include <plat/cpu.h>
@@ -140,7 +141,17 @@ static int s5pv210_pm_add(struct sys_device *sysdev)
        return 0;
 }
 
-static int s5pv210_pm_resume(struct sys_device *dev)
+static struct sysdev_driver s5pv210_pm_driver = {
+       .add            = s5pv210_pm_add,
+};
+
+static __init int s5pv210_pm_drvinit(void)
+{
+       return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+}
+arch_initcall(s5pv210_pm_drvinit);
+
+static void s5pv210_pm_resume(void)
 {
        u32 tmp;
 
@@ -150,17 +161,15 @@ static int s5pv210_pm_resume(struct sys_device *dev)
        __raw_writel(tmp , S5P_OTHERS);
 
        s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
-
-       return 0;
 }
 
-static struct sysdev_driver s5pv210_pm_driver = {
-       .add            = s5pv210_pm_add,
+static struct syscore_ops s5pv210_pm_syscore_ops = {
        .resume         = s5pv210_pm_resume,
 };
 
-static __init int s5pv210_pm_drvinit(void)
+static __init int s5pv210_pm_syscore_init(void)
 {
-       return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+       register_syscore_ops(&s5pv210_pm_syscore_ops);
+       return 0;
 }
-arch_initcall(s5pv210_pm_drvinit);
+arch_initcall(s5pv210_pm_syscore_init);
index 423ddb3..dfbf824 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/ioport.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/irq.h>
@@ -234,7 +234,7 @@ static struct sa1100irq_state {
        unsigned int    iccr;
 } sa1100irq_state;
 
-static int sa1100irq_suspend(struct sys_device *dev, pm_message_t state)
+static int sa1100irq_suspend(void)
 {
        struct sa1100irq_state *st = &sa1100irq_state;
 
@@ -264,7 +264,7 @@ static int sa1100irq_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int sa1100irq_resume(struct sys_device *dev)
+static void sa1100irq_resume(void)
 {
        struct sa1100irq_state *st = &sa1100irq_state;
 
@@ -277,24 +277,17 @@ static int sa1100irq_resume(struct sys_device *dev)
 
                ICMR = st->icmr;
        }
-       return 0;
 }
 
-static struct sysdev_class sa1100irq_sysclass = {
-       .name           = "sa11x0-irq",
+static struct syscore_ops sa1100irq_syscore_ops = {
        .suspend        = sa1100irq_suspend,
        .resume         = sa1100irq_resume,
 };
 
-static struct sys_device sa1100irq_device = {
-       .id             = 0,
-       .cls            = &sa1100irq_sysclass,
-};
-
 static int __init sa1100irq_init_devicefs(void)
 {
-       sysdev_class_register(&sa1100irq_sysclass);
-       return sysdev_register(&sa1100irq_device);
+       register_syscore_ops(&sa1100irq_syscore_ops);
+       return 0;
 }
 
 device_initcall(sa1100irq_init_devicefs);
index 94912d3..2d1b67a 100644 (file)
 #include <linux/clk.h>
 #include <linux/sh_clk.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PM_RUNTIME
-#define BIT_ONCE 0
-#define BIT_ACTIVE 1
-#define BIT_CLK_ENABLED 2
 
-struct pm_runtime_data {
-       unsigned long flags;
-       struct clk *clk;
-};
-
-static void __devres_release(struct device *dev, void *res)
-{
-       struct pm_runtime_data *prd = res;
-
-       dev_dbg(dev, "__devres_release()\n");
-
-       if (test_bit(BIT_CLK_ENABLED, &prd->flags))
-               clk_disable(prd->clk);
-
-       if (test_bit(BIT_ACTIVE, &prd->flags))
-               clk_put(prd->clk);
-}
-
-static struct pm_runtime_data *__to_prd(struct device *dev)
-{
-       return devres_find(dev, __devres_release, NULL, NULL);
-}
-
-static void platform_pm_runtime_init(struct device *dev,
-                                    struct pm_runtime_data *prd)
-{
-       if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) {
-               prd->clk = clk_get(dev, NULL);
-               if (!IS_ERR(prd->clk)) {
-                       set_bit(BIT_ACTIVE, &prd->flags);
-                       dev_info(dev, "clocks managed by runtime pm\n");
-               }
-       }
-}
-
-static void platform_pm_runtime_bug(struct device *dev,
-                                   struct pm_runtime_data *prd)
-{
-       if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags))
-               dev_err(dev, "runtime pm suspend before resume\n");
-}
-
-int platform_pm_runtime_suspend(struct device *dev)
-{
-       struct pm_runtime_data *prd = __to_prd(dev);
-
-       dev_dbg(dev, "platform_pm_runtime_suspend()\n");
-
-       platform_pm_runtime_bug(dev, prd);
-
-       if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
-               clk_disable(prd->clk);
-               clear_bit(BIT_CLK_ENABLED, &prd->flags);
-       }
-
-       return 0;
-}
-
-int platform_pm_runtime_resume(struct device *dev)
-{
-       struct pm_runtime_data *prd = __to_prd(dev);
-
-       dev_dbg(dev, "platform_pm_runtime_resume()\n");
-
-       platform_pm_runtime_init(dev, prd);
-
-       if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
-               clk_enable(prd->clk);
-               set_bit(BIT_CLK_ENABLED, &prd->flags);
-       }
-
-       return 0;
-}
-
-int platform_pm_runtime_idle(struct device *dev)
+static int default_platform_runtime_idle(struct device *dev)
 {
        /* suspend synchronously to disable clocks immediately */
        return pm_runtime_suspend(dev);
 }
 
-static int platform_bus_notify(struct notifier_block *nb,
-                              unsigned long action, void *data)
-{
-       struct device *dev = data;
-       struct pm_runtime_data *prd;
-
-       dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
-
-       if (action == BUS_NOTIFY_BIND_DRIVER) {
-               prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL);
-               if (prd)
-                       devres_add(dev, prd);
-               else
-                       dev_err(dev, "unable to alloc memory for runtime pm\n");
-       }
-
-       return 0;
-}
-
-#else /* CONFIG_PM_RUNTIME */
-
-static int platform_bus_notify(struct notifier_block *nb,
-                              unsigned long action, void *data)
-{
-       struct device *dev = data;
-       struct clk *clk;
+static struct dev_power_domain default_power_domain = {
+       .ops = {
+               .runtime_suspend = pm_runtime_clk_suspend,
+               .runtime_resume = pm_runtime_clk_resume,
+               .runtime_idle = default_platform_runtime_idle,
+               USE_PLATFORM_PM_SLEEP_OPS
+       },
+};
 
-       dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
+#define DEFAULT_PWR_DOMAIN_PTR (&default_power_domain)
 
-       switch (action) {
-       case BUS_NOTIFY_BIND_DRIVER:
-               clk = clk_get(dev, NULL);
-               if (!IS_ERR(clk)) {
-                       clk_enable(clk);
-                       clk_put(clk);
-                       dev_info(dev, "runtime pm disabled, clock forced on\n");
-               }
-               break;
-       case BUS_NOTIFY_UNBOUND_DRIVER:
-               clk = clk_get(dev, NULL);
-               if (!IS_ERR(clk)) {
-                       clk_disable(clk);
-                       clk_put(clk);
-                       dev_info(dev, "runtime pm disabled, clock forced off\n");
-               }
-               break;
-       }
+#else
 
-       return 0;
-}
+#define DEFAULT_PWR_DOMAIN_PTR NULL
 
 #endif /* CONFIG_PM_RUNTIME */
 
-static struct notifier_block platform_bus_notifier = {
-       .notifier_call = platform_bus_notify
+static struct pm_clk_notifier_block platform_bus_notifier = {
+       .pwr_domain = DEFAULT_PWR_DOMAIN_PTR,
+       .con_ids = { NULL, },
 };
 
 static int __init sh_pm_runtime_init(void)
 {
-       bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
+       pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
        return 0;
 }
 core_initcall(sh_pm_runtime_init);
index d2adcdd..bd9e321 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -1372,9 +1372,7 @@ static const struct dev_pm_ops omap_mpuio_dev_pm_ops = {
        .resume_noirq = omap_mpuio_resume_noirq,
 };
 
-/* use platform_driver for this, now that there's no longer any
- * point to sys_device (other than not disturbing old code).
- */
+/* use platform_driver for this. */
 static struct platform_driver omap_mpuio_driver = {
        .driver         = {
                .name   = "mpuio",
@@ -1745,7 +1743,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev)
 }
 
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
+static int omap_gpio_suspend(void)
 {
        int i;
 
@@ -1795,12 +1793,12 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
        return 0;
 }
 
-static int omap_gpio_resume(struct sys_device *dev)
+static void omap_gpio_resume(void)
 {
        int i;
 
        if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-               return 0;
+               return;
 
        for (i = 0; i < gpio_bank_count; i++) {
                struct gpio_bank *bank = &gpio_bank[i];
@@ -1836,21 +1834,13 @@ static int omap_gpio_resume(struct sys_device *dev)
                __raw_writel(bank->saved_wakeup, wake_set);
                spin_unlock_irqrestore(&bank->lock, flags);
        }
-
-       return 0;
 }
 
-static struct sysdev_class omap_gpio_sysclass = {
-       .name           = "gpio",
+static struct syscore_ops omap_gpio_syscore_ops = {
        .suspend        = omap_gpio_suspend,
        .resume         = omap_gpio_resume,
 };
 
-static struct sys_device omap_gpio_device = {
-       .id             = 0,
-       .cls            = &omap_gpio_sysclass,
-};
-
 #endif
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
@@ -2108,21 +2098,14 @@ postcore_initcall(omap_gpio_drv_reg);
 
 static int __init omap_gpio_sysinit(void)
 {
-       int ret = 0;
-
        mpuio_init();
 
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-       if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-               if (ret == 0) {
-                       ret = sysdev_class_register(&omap_gpio_sysclass);
-                       if (ret == 0)
-                               ret = sysdev_register(&omap_gpio_device);
-               }
-       }
+       if (cpu_is_omap16xx() || cpu_class_is_omap2())
+               register_syscore_ops(&omap_gpio_syscore_ops);
 #endif
 
-       return ret;
+       return 0;
 }
 
 arch_initcall(omap_gpio_sysinit);
index 9bbda9a..a37b8eb 100644 (file)
@@ -536,6 +536,28 @@ int omap_early_device_register(struct omap_device *od)
        return 0;
 }
 
+static int _od_runtime_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+
+       return omap_device_idle(pdev);
+}
+
+static int _od_runtime_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+
+       return omap_device_enable(pdev);
+}
+
+static struct dev_power_domain omap_device_power_domain = {
+       .ops = {
+               .runtime_suspend = _od_runtime_suspend,
+               .runtime_resume = _od_runtime_resume,
+               USE_PLATFORM_PM_SLEEP_OPS
+       }
+};
+
 /**
  * omap_device_register - register an omap_device with one omap_hwmod
  * @od: struct omap_device * to register
@@ -549,6 +571,7 @@ int omap_device_register(struct omap_device *od)
        pr_debug("omap_device: %s: registering\n", od->pdev.name);
 
        od->pdev.dev.parent = &omap_device_parent;
+       od->pdev.dev.pwr_domain = &omap_device_power_domain;
        return platform_device_register(&od->pdev);
 }
 
index dce088f..48ebb94 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/slab.h>
 
 #include <mach/gpio.h>
@@ -295,7 +295,7 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
 }
 
 #ifdef CONFIG_PM
-static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
+static int pxa_gpio_suspend(void)
 {
        struct pxa_gpio_chip *c;
        int gpio;
@@ -312,7 +312,7 @@ static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int pxa_gpio_resume(struct sys_device *dev)
+static void pxa_gpio_resume(void)
 {
        struct pxa_gpio_chip *c;
        int gpio;
@@ -326,22 +326,13 @@ static int pxa_gpio_resume(struct sys_device *dev)
                __raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET);
                __raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET);
        }
-       return 0;
 }
 #else
 #define pxa_gpio_suspend       NULL
 #define pxa_gpio_resume                NULL
 #endif
 
-struct sysdev_class pxa_gpio_sysclass = {
-       .name           = "gpio",
+struct syscore_ops pxa_gpio_syscore_ops = {
        .suspend        = pxa_gpio_suspend,
        .resume         = pxa_gpio_resume,
 };
-
-static int __init pxa_gpio_init(void)
-{
-       return sysdev_class_register(&pxa_gpio_sysclass);
-}
-
-core_initcall(pxa_gpio_init);
index a9aa5ad..be12ead 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
 
 #include <plat/mfp.h>
 
index 27ea852..c10d10c 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/io.h>
@@ -1195,19 +1195,12 @@ int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *d
 
 EXPORT_SYMBOL(s3c2410_dma_getposition);
 
-static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
-{
-       return container_of(dev, struct s3c2410_dma_chan, dev);
-}
-
-/* system device class */
+/* system core operations */
 
 #ifdef CONFIG_PM
 
-static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
+static void s3c2410_dma_suspend_chan(s3c2410_dma_chan *cp)
 {
-       struct s3c2410_dma_chan *cp = to_dma_chan(dev);
-
        printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
 
        if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
@@ -1222,13 +1215,21 @@ static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
 
                s3c2410_dma_dostop(cp);
        }
+}
+
+static int s3c2410_dma_suspend(void)
+{
+       struct s3c2410_dma_chan *cp = s3c2410_chans;
+       int channel;
+
+       for (channel = 0; channel < dma_channels; cp++, channel++)
+               s3c2410_dma_suspend_chan(cp);
 
        return 0;
 }
 
-static int s3c2410_dma_resume(struct sys_device *dev)
+static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
 {
-       struct s3c2410_dma_chan *cp = to_dma_chan(dev);
        unsigned int no = cp->number | DMACH_LOW_LEVEL;
 
        /* restore channel's hardware configuration */
@@ -1249,13 +1250,21 @@ static int s3c2410_dma_resume(struct sys_device *dev)
        return 0;
 }
 
+static void s3c2410_dma_resume(void)
+{
+       struct s3c2410_dma_chan *cp = s3c2410_chans + dma_channels - 1;
+       int channel;
+
+       for (channel = dma_channels - 1; channel >= 0; cp++, channel--)
+               s3c2410_dma_resume_chan(cp);
+}
+
 #else
 #define s3c2410_dma_suspend NULL
 #define s3c2410_dma_resume  NULL
 #endif /* CONFIG_PM */
 
-struct sysdev_class dma_sysclass = {
-       .name           = "s3c24xx-dma",
+struct syscore_ops dma_syscore_ops = {
        .suspend        = s3c2410_dma_suspend,
        .resume         = s3c2410_dma_resume,
 };
@@ -1269,39 +1278,14 @@ static void s3c2410_dma_cache_ctor(void *p)
 
 /* initialisation code */
 
-static int __init s3c24xx_dma_sysclass_init(void)
+static int __init s3c24xx_dma_syscore_init(void)
 {
-       int ret = sysdev_class_register(&dma_sysclass);
-
-       if (ret != 0)
-               printk(KERN_ERR "dma sysclass registration failed\n");
-
-       return ret;
-}
-
-core_initcall(s3c24xx_dma_sysclass_init);
-
-static int __init s3c24xx_dma_sysdev_register(void)
-{
-       struct s3c2410_dma_chan *cp = s3c2410_chans;
-       int channel, ret;
-
-       for (channel = 0; channel < dma_channels; cp++, channel++) {
-               cp->dev.cls = &dma_sysclass;
-               cp->dev.id  = channel;
-               ret = sysdev_register(&cp->dev);
-
-               if (ret) {
-                       printk(KERN_ERR "error registering dev for dma %d\n",
-                              channel);
-                       return ret;
-               }
-       }
+       register_syscore_ops(&dma_syscore_ops);
 
        return 0;
 }
 
-late_initcall(s3c24xx_dma_sysdev_register);
+late_initcall(s3c24xx_dma_syscore_init);
 
 int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
                            unsigned int stride)
index c3624d8..0efb2e2 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
 #include <linux/irq.h>
 
 #include <plat/cpu.h>
@@ -65,7 +64,7 @@ static unsigned long save_extint[3];
 static unsigned long save_eintflt[4];
 static unsigned long save_eintmask;
 
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+int s3c24xx_irq_suspend(void)
 {
        unsigned int i;
 
@@ -81,7 +80,7 @@ int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-int s3c24xx_irq_resume(struct sys_device *dev)
+void s3c24xx_irq_resume(void)
 {
        unsigned int i;
 
@@ -93,6 +92,4 @@ int s3c24xx_irq_resume(struct sys_device *dev)
 
        s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
        __raw_writel(save_eintmask, S3C24XX_EINTMASK);
-
-       return 0;
 }
index 5259ad4..327acb3 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
 
 #include <plat/cpu.h>
 #include <plat/irqs.h>
@@ -77,17 +76,15 @@ static struct sleep_save eint_save[] = {
        SAVE_ITEM(S5P_EINT_MASK(3)),
 };
 
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+int s3c24xx_irq_suspend(void)
 {
        s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
 
        return 0;
 }
 
-int s3c24xx_irq_resume(struct sys_device *dev)
+void s3c24xx_irq_resume(void)
 {
        s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
-
-       return 0;
 }
 
index cedfff5..3aedac0 100644 (file)
@@ -68,6 +68,12 @@ extern void s3c24xx_init_uartdevs(char *name,
 struct sys_timer;
 extern struct sys_timer s3c24xx_timer;
 
+extern struct syscore_ops s3c2410_pm_syscore_ops;
+extern struct syscore_ops s3c2412_pm_syscore_ops;
+extern struct syscore_ops s3c2416_pm_syscore_ops;
+extern struct syscore_ops s3c244x_pm_syscore_ops;
+extern struct syscore_ops s3c64xx_irq_syscore_ops;
+
 /* system device classes */
 
 extern struct sysdev_class s3c2410_sysclass;
index 937cc2a..7fb6f6b 100644 (file)
@@ -103,14 +103,16 @@ extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
 
 #ifdef CONFIG_PM
 extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
-extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
-extern int s3c24xx_irq_resume(struct sys_device *dev);
+extern int s3c24xx_irq_suspend(void);
+extern void s3c24xx_irq_resume(void);
 #else
 #define s3c_irqext_wake NULL
 #define s3c24xx_irq_suspend NULL
 #define s3c24xx_irq_resume  NULL
 #endif
 
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
 /* PM debug functions */
 
 #ifdef CONFIG_SAMSUNG_PM_DEBUG
index f746950..f25e7ec 100644 (file)
@@ -398,9 +398,9 @@ static void vfp_enable(void *unused)
 }
 
 #ifdef CONFIG_PM
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
-static int vfp_pm_suspend(struct sys_device *dev, pm_message_t state)
+static int vfp_pm_suspend(void)
 {
        struct thread_info *ti = current_thread_info();
        u32 fpexc = fmrx(FPEXC);
@@ -420,34 +420,25 @@ static int vfp_pm_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int vfp_pm_resume(struct sys_device *dev)
+static void vfp_pm_resume(void)
 {
        /* ensure we have access to the vfp */
        vfp_enable(NULL);
 
        /* and disable it to ensure the next usage restores the state */
        fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
-
-       return 0;
 }
 
-static struct sysdev_class vfp_pm_sysclass = {
-       .name           = "vfp",
+static struct syscore_ops vfp_pm_syscore_ops = {
        .suspend        = vfp_pm_suspend,
        .resume         = vfp_pm_resume,
 };
 
-static struct sys_device vfp_pm_sysdev = {
-       .cls    = &vfp_pm_sysclass,
-};
-
 static void vfp_pm_init(void)
 {
-       sysdev_class_register(&vfp_pm_sysclass);
-       sysdev_register(&vfp_pm_sysdev);
+       register_syscore_ops(&vfp_pm_syscore_ops);
 }
 
-
 #else
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
index 21ce35f..3e36461 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/io.h>
 
@@ -21,7 +21,6 @@
 struct intc {
        void __iomem            *regs;
        struct irq_chip         chip;
-       struct sys_device       sysdev;
 #ifdef CONFIG_PM
        unsigned long           suspend_ipr;
        unsigned long           saved_ipr[64];
@@ -146,9 +145,8 @@ void intc_set_suspend_handler(unsigned long offset)
        intc0.suspend_ipr = offset;
 }
 
-static int intc_suspend(struct sys_device *sdev, pm_message_t state)
+static int intc_suspend(void)
 {
-       struct intc *intc = container_of(sdev, struct intc, sysdev);
        int i;
 
        if (unlikely(!irqs_disabled())) {
@@ -156,28 +154,25 @@ static int intc_suspend(struct sys_device *sdev, pm_message_t state)
                return -EINVAL;
        }
 
-       if (unlikely(!intc->suspend_ipr)) {
+       if (unlikely(!intc0.suspend_ipr)) {
                pr_err("intc_suspend: suspend_ipr not initialized\n");
                return -EINVAL;
        }
 
        for (i = 0; i < 64; i++) {
-               intc->saved_ipr[i] = intc_readl(intc, INTPR0 + 4 * i);
-               intc_writel(intc, INTPR0 + 4 * i, intc->suspend_ipr);
+               intc0.saved_ipr[i] = intc_readl(&intc0, INTPR0 + 4 * i);
+               intc_writel(&intc0, INTPR0 + 4 * i, intc0.suspend_ipr);
        }
 
        return 0;
 }
 
-static int intc_resume(struct sys_device *sdev)
+static int intc_resume(void)
 {
-       struct intc *intc = container_of(sdev, struct intc, sysdev);
        int i;
 
-       WARN_ON(!irqs_disabled());
-
        for (i = 0; i < 64; i++)
-               intc_writel(intc, INTPR0 + 4 * i, intc->saved_ipr[i]);
+               intc_writel(&intc0, INTPR0 + 4 * i, intc0.saved_ipr[i]);
 
        return 0;
 }
@@ -186,27 +181,18 @@ static int intc_resume(struct sys_device *sdev)
 #define intc_resume    NULL
 #endif
 
-static struct sysdev_class intc_class = {
-       .name           = "intc",
+static struct syscore_ops intc_syscore_ops = {
        .suspend        = intc_suspend,
        .resume         = intc_resume,
 };
 
-static int __init intc_init_sysdev(void)
+static int __init intc_init_syscore(void)
 {
-       int ret;
-
-       ret = sysdev_class_register(&intc_class);
-       if (ret)
-               return ret;
+       register_syscore_ops(&intc_syscore_ops);
 
-       intc0.sysdev.id = 0;
-       intc0.sysdev.cls = &intc_class;
-       ret = sysdev_register(&intc0.sysdev);
-
-       return ret;
+       return 0;
 }
-device_initcall(intc_init_sysdev);
+device_initcall(intc_init_syscore);
 
 unsigned long intc_get_pending(unsigned int group)
 {
index 0b5f72f..401eb1d 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/bitops.h>
 #include <linux/hardirq.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/pm.h>
 #include <linux/nmi.h>
 #include <linux/smp.h>
@@ -196,43 +196,31 @@ void touch_nmi_watchdog(void)
 
 /* Suspend/resume support */
 #ifdef CONFIG_PM
-static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state)
+static int nmi_wdt_suspend(void)
 {
        nmi_wdt_stop();
        return 0;
 }
 
-static int nmi_wdt_resume(struct sys_device *dev)
+static void nmi_wdt_resume(void)
 {
        if (nmi_active)
                nmi_wdt_start();
-       return 0;
 }
 
-static struct sysdev_class nmi_sysclass = {
-       .name           = DRV_NAME,
+static struct syscore_ops nmi_syscore_ops = {
        .resume         = nmi_wdt_resume,
        .suspend        = nmi_wdt_suspend,
 };
 
-static struct sys_device device_nmi_wdt = {
-       .id     = 0,
-       .cls    = &nmi_sysclass,
-};
-
-static int __init init_nmi_wdt_sysfs(void)
+static int __init init_nmi_wdt_syscore(void)
 {
-       int error;
-
-       if (!nmi_active)
-               return 0;
+       if (nmi_active)
+               register_syscore_ops(&nmi_syscore_ops);
 
-       error = sysdev_class_register(&nmi_sysclass);
-       if (!error)
-               error = sysdev_register(&device_nmi_wdt);
-       return error;
+       return 0;
 }
-late_initcall(init_nmi_wdt_sysfs);
+late_initcall(init_nmi_wdt_syscore);
 
 #endif /* CONFIG_PM */
 
index 7005ee0..49baddc 100644 (file)
@@ -3,7 +3,6 @@
 #ifdef __KERNEL__
 
 #include <linux/irq.h>
-#include <linux/sysdev.h>
 #include <asm/dcr.h>
 #include <asm/msi_bitmap.h>
 
@@ -320,8 +319,6 @@ struct mpic
        /* link */
        struct mpic             *next;
 
-       struct sys_device       sysdev;
-
 #ifdef CONFIG_PM
        struct mpic_irq_save    *save_data;
 #endif
index acfacce..3675da7 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/linux_logo.h>
+#include <linux/syscore_ops.h>
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
 #include <asm/spu_csa.h>
@@ -521,18 +522,8 @@ void spu_init_channels(struct spu *spu)
 }
 EXPORT_SYMBOL_GPL(spu_init_channels);
 
-static int spu_shutdown(struct sys_device *sysdev)
-{
-       struct spu *spu = container_of(sysdev, struct spu, sysdev);
-
-       spu_free_irqs(spu);
-       spu_destroy_spu(spu);
-       return 0;
-}
-
 static struct sysdev_class spu_sysdev_class = {
        .name = "spu",
-       .shutdown = spu_shutdown,
 };
 
 int spu_add_sysdev_attr(struct sysdev_attribute *attr)
@@ -797,6 +788,22 @@ static inline void crash_register_spus(struct list_head *list)
 }
 #endif
 
+static void spu_shutdown(void)
+{
+       struct spu *spu;
+
+       mutex_lock(&spu_full_list_mutex);
+       list_for_each_entry(spu, &spu_full_list, full_list) {
+               spu_free_irqs(spu);
+               spu_destroy_spu(spu);
+       }
+       mutex_unlock(&spu_full_list_mutex);
+}
+
+static struct syscore_ops spu_syscore_ops = {
+       .shutdown = spu_shutdown,
+};
+
 static int __init init_spu_base(void)
 {
        int i, ret = 0;
@@ -830,6 +837,7 @@ static int __init init_spu_base(void)
        crash_register_spus(&spu_full_list);
        mutex_unlock(&spu_full_list_mutex);
        spu_add_sysdev_attr(&attr_stat);
+       register_syscore_ops(&spu_syscore_ops);
 
        spu_init_affinity();
 
index 023f240..7c18a16 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/signal.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/module.h>
@@ -677,7 +677,7 @@ not_found:
        return viaint;
 }
 
-static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
+static int pmacpic_suspend(void)
 {
        int viaint = pmacpic_find_viaint();
 
@@ -698,7 +698,7 @@ static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
         return 0;
 }
 
-static int pmacpic_resume(struct sys_device *sysdev)
+static void pmacpic_resume(void)
 {
        int i;
 
@@ -709,39 +709,19 @@ static int pmacpic_resume(struct sys_device *sysdev)
        for (i = 0; i < max_real_irqs; ++i)
                if (test_bit(i, sleep_save_mask))
                        pmac_unmask_irq(irq_get_irq_data(i));
-
-       return 0;
 }
 
-#endif /* CONFIG_PM && CONFIG_PPC32 */
-
-static struct sysdev_class pmacpic_sysclass = {
-       .name = "pmac_pic",
+static struct syscore_ops pmacpic_syscore_ops = {
+       .suspend        = pmacpic_suspend,
+       .resume         = pmacpic_resume,
 };
 
-static struct sys_device device_pmacpic = {
-       .id             = 0,
-       .cls            = &pmacpic_sysclass,
-};
-
-static struct sysdev_driver driver_pmacpic = {
-#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
-       .suspend        = &pmacpic_suspend,
-       .resume         = &pmacpic_resume,
-#endif /* CONFIG_PM && CONFIG_PPC32 */
-};
-
-static int __init init_pmacpic_sysfs(void)
+static int __init init_pmacpic_syscore(void)
 {
-#ifdef CONFIG_PPC32
-       if (max_irqs == 0)
-               return -ENODEV;
-#endif
-       printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
-       sysdev_class_register(&pmacpic_sysclass);
-       sysdev_register(&device_pmacpic);
-       sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
+       register_syscore_ops(&pmacpic_syscore_ops);
        return 0;
 }
-machine_subsys_initcall(powermac, init_pmacpic_sysfs);
 
+machine_subsys_initcall(powermac, init_pmacpic_syscore);
+
+#endif /* CONFIG_PM && CONFIG_PPC32 */
index fa438be..596554a 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/stddef.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/device.h>
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
@@ -902,7 +902,7 @@ static struct {
        u32 sercr;
 } ipic_saved_state;
 
-static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
+static int ipic_suspend(void)
 {
        struct ipic *ipic = primary_ipic;
 
@@ -933,7 +933,7 @@ static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
        return 0;
 }
 
-static int ipic_resume(struct sys_device *sdev)
+static void ipic_resume(void)
 {
        struct ipic *ipic = primary_ipic;
 
@@ -949,44 +949,26 @@ static int ipic_resume(struct sys_device *sdev)
        ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
        ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
        ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
-
-       return 0;
 }
 #else
 #define ipic_suspend NULL
 #define ipic_resume NULL
 #endif
 
-static struct sysdev_class ipic_sysclass = {
-       .name = "ipic",
+static struct syscore_ops ipic_syscore_ops = {
        .suspend = ipic_suspend,
        .resume = ipic_resume,
 };
 
-static struct sys_device device_ipic = {
-       .id             = 0,
-       .cls            = &ipic_sysclass,
-};
-
-static int __init init_ipic_sysfs(void)
+static int __init init_ipic_syscore(void)
 {
-       int rc;
-
        if (!primary_ipic || !primary_ipic->regs)
                return -ENODEV;
-       printk(KERN_DEBUG "Registering ipic with sysfs...\n");
 
-       rc = sysdev_class_register(&ipic_sysclass);
-       if (rc) {
-               printk(KERN_ERR "Failed registering ipic sys class\n");
-               return -ENODEV;
-       }
-       rc = sysdev_register(&device_ipic);
-       if (rc) {
-               printk(KERN_ERR "Failed registering ipic sys device\n");
-               return -ENODEV;
-       }
+       printk(KERN_DEBUG "Registering ipic system core operations\n");
+       register_syscore_ops(&ipic_syscore_ops);
+
        return 0;
 }
 
-subsys_initcall(init_ipic_sysfs);
+subsys_initcall(init_ipic_syscore);
index f91c065..7e5dc8f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/ptrace.h>
 #include <asm/signal.h>
@@ -1702,9 +1703,8 @@ void mpic_reset_core(int cpu)
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_PM
-static int mpic_suspend(struct sys_device *dev, pm_message_t state)
+static void mpic_suspend_one(struct mpic *mpic)
 {
-       struct mpic *mpic = container_of(dev, struct mpic, sysdev);
        int i;
 
        for (i = 0; i < mpic->num_sources; i++) {
@@ -1713,13 +1713,22 @@ static int mpic_suspend(struct sys_device *dev, pm_message_t state)
                mpic->save_data[i].dest =
                        mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION));
        }
+}
+
+static int mpic_suspend(void)
+{
+       struct mpic *mpic = mpics;
+
+       while (mpic) {
+               mpic_suspend_one(mpic);
+               mpic = mpic->next;
+       }
 
        return 0;
 }
 
-static int mpic_resume(struct sys_device *dev)
+static void mpic_resume_one(struct mpic *mpic)
 {
-       struct mpic *mpic = container_of(dev, struct mpic, sysdev);
        int i;
 
        for (i = 0; i < mpic->num_sources; i++) {
@@ -1746,33 +1755,28 @@ static int mpic_resume(struct sys_device *dev)
        }
 #endif
        } /* end for loop */
+}
 
-       return 0;
+static void mpic_resume(void)
+{
+       struct mpic *mpic = mpics;
+
+       while (mpic) {
+               mpic_resume_one(mpic);
+               mpic = mpic->next;
+       }
 }
-#endif
 
-static struct sysdev_class mpic_sysclass = {
-#ifdef CONFIG_PM
+static struct syscore_ops mpic_syscore_ops = {
        .resume = mpic_resume,
        .suspend = mpic_suspend,
-#endif
-       .name = "mpic",
 };
 
 static int mpic_init_sys(void)
 {
-       struct mpic *mpic = mpics;
-       int error, id = 0;
-
-       error = sysdev_class_register(&mpic_sysclass);
-
-       while (mpic && !error) {
-               mpic->sysdev.cls = &mpic_sysclass;
-               mpic->sysdev.id = id++;
-               error = sysdev_register(&mpic->sysdev);
-               mpic = mpic->next;
-       }
-       return error;
+       register_syscore_ops(&mpic_syscore_ops);
+       return 0;
 }
 
 device_initcall(mpic_init_sys);
+#endif
index 4b89da2..bc439de 100644 (file)
@@ -24,7 +24,6 @@ config SUPERH
        select RTC_LIB
        select GENERIC_ATOMIC64
        select GENERIC_IRQ_SHOW
-       select ARCH_NO_SYSDEV_OPS
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
index e71a531..77ec0e7 100644 (file)
@@ -48,7 +48,6 @@ CONFIG_PREEMPT=y
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
-CONFIG_PM_VERBOSE=y
 CONFIG_PM_RUNTIME=y
 CONFIG_CPU_IDLE=y
 CONFIG_NET=y
index dc4a2eb..c416505 100644 (file)
@@ -83,7 +83,6 @@ CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
-CONFIG_PM_VERBOSE=y
 CONFIG_PM_RUNTIME=y
 CONFIG_CPU_IDLE=y
 CONFIG_NET=y
index 6dcb816..22db127 100644 (file)
@@ -139,7 +139,7 @@ void platform_pm_runtime_suspend_idle(void)
        queue_work(pm_wq, &hwblk_work);
 }
 
-int platform_pm_runtime_suspend(struct device *dev)
+static int default_platform_runtime_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct pdev_archdata *ad = &pdev->archdata;
@@ -147,7 +147,7 @@ int platform_pm_runtime_suspend(struct device *dev)
        int hwblk = ad->hwblk_id;
        int ret = 0;
 
-       dev_dbg(dev, "platform_pm_runtime_suspend() [%d]\n", hwblk);
+       dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
 
        /* ignore off-chip platform devices */
        if (!hwblk)
@@ -183,20 +183,20 @@ int platform_pm_runtime_suspend(struct device *dev)
        mutex_unlock(&ad->mutex);
 
 out:
-       dev_dbg(dev, "platform_pm_runtime_suspend() [%d] returns %d\n",
-               hwblk, ret);
+       dev_dbg(dev, "%s() [%d] returns %d\n",
+                __func__, hwblk, ret);
 
        return ret;
 }
 
-int platform_pm_runtime_resume(struct device *dev)
+static int default_platform_runtime_resume(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct pdev_archdata *ad = &pdev->archdata;
        int hwblk = ad->hwblk_id;
        int ret = 0;
 
-       dev_dbg(dev, "platform_pm_runtime_resume() [%d]\n", hwblk);
+       dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
 
        /* ignore off-chip platform devices */
        if (!hwblk)
@@ -228,19 +228,19 @@ int platform_pm_runtime_resume(struct device *dev)
         */
        mutex_unlock(&ad->mutex);
 out:
-       dev_dbg(dev, "platform_pm_runtime_resume() [%d] returns %d\n",
-               hwblk, ret);
+       dev_dbg(dev, "%s() [%d] returns %d\n",
+               __func__, hwblk, ret);
 
        return ret;
 }
 
-int platform_pm_runtime_idle(struct device *dev)
+static int default_platform_runtime_idle(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        int hwblk = pdev->archdata.hwblk_id;
        int ret = 0;
 
-       dev_dbg(dev, "platform_pm_runtime_idle() [%d]\n", hwblk);
+       dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
 
        /* ignore off-chip platform devices */
        if (!hwblk)
@@ -252,10 +252,19 @@ int platform_pm_runtime_idle(struct device *dev)
        /* suspend synchronously to disable clocks immediately */
        ret = pm_runtime_suspend(dev);
 out:
-       dev_dbg(dev, "platform_pm_runtime_idle() [%d] done!\n", hwblk);
+       dev_dbg(dev, "%s() [%d] done!\n", __func__, hwblk);
        return ret;
 }
 
+static struct dev_power_domain default_power_domain = {
+       .ops = {
+               .runtime_suspend = default_platform_runtime_suspend,
+               .runtime_resume = default_platform_runtime_resume,
+               .runtime_idle = default_platform_runtime_idle,
+               USE_PLATFORM_PM_SLEEP_OPS
+       },
+};
+
 static int platform_bus_notify(struct notifier_block *nb,
                               unsigned long action, void *data)
 {
@@ -276,6 +285,7 @@ static int platform_bus_notify(struct notifier_block *nb,
                hwblk_disable(hwblk_info, hwblk);
                /* make sure driver re-inits itself once */
                __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+               dev->pwr_domain = &default_power_domain;
                break;
        /* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
        case BUS_NOTIFY_BOUND_DRIVER:
@@ -289,6 +299,7 @@ static int platform_bus_notify(struct notifier_block *nb,
                __set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
                break;
        case BUS_NOTIFY_DEL_DEVICE:
+               dev->pwr_domain = NULL;
                break;
        }
        return 0;
index 2aa30a3..d4efa7d 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/list.h>
 #include <linux/kallsyms.h>
 #include <linux/proc_fs.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/gpio.h>
 
 #include <asm/system.h>
@@ -237,7 +237,7 @@ static struct puv3_irq_state {
        unsigned int    iccr;
 } puv3_irq_state;
 
-static int puv3_irq_suspend(struct sys_device *dev, pm_message_t state)
+static int puv3_irq_suspend(void)
 {
        struct puv3_irq_state *st = &puv3_irq_state;
 
@@ -265,7 +265,7 @@ static int puv3_irq_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int puv3_irq_resume(struct sys_device *dev)
+static void puv3_irq_resume(void)
 {
        struct puv3_irq_state *st = &puv3_irq_state;
 
@@ -278,27 +278,20 @@ static int puv3_irq_resume(struct sys_device *dev)
 
                writel(st->icmr, INTC_ICMR);
        }
-       return 0;
 }
 
-static struct sysdev_class puv3_irq_sysclass = {
-       .name           = "pkunity-irq",
+static struct syscore_ops puv3_irq_syscore_ops = {
        .suspend        = puv3_irq_suspend,
        .resume         = puv3_irq_resume,
 };
 
-static struct sys_device puv3_irq_device = {
-       .id             = 0,
-       .cls            = &puv3_irq_sysclass,
-};
-
-static int __init puv3_irq_init_devicefs(void)
+static int __init puv3_irq_init_syscore(void)
 {
-       sysdev_class_register(&puv3_irq_sysclass);
-       return sysdev_register(&puv3_irq_device);
+       register_syscore_ops(&puv3_irq_syscore_ops);
+       return 0;
 }
 
-device_initcall(puv3_irq_init_devicefs);
+device_initcall(puv3_irq_init_syscore);
 
 void __init init_IRQ(void)
 {
index e7f94a5..b9ea9a8 100644 (file)
@@ -71,7 +71,6 @@ config X86
        select GENERIC_IRQ_SHOW
        select IRQ_FORCED_THREADING
        select USE_GENERIC_SMP_HELPERS if SMP
-       select ARCH_NO_SYSDEV_OPS
 
 config INSTRUCTION_DECODER
        def_bool (KPROBES || PERF_EVENTS)
index ff93bc1..18a857b 100644 (file)
@@ -112,11 +112,6 @@ static int __init acpi_sleep_setup(char *str)
 #ifdef CONFIG_HIBERNATION
                if (strncmp(str, "s4_nohwsig", 10) == 0)
                        acpi_no_s4_hw_signature();
-               if (strncmp(str, "s4_nonvs", 8) == 0) {
-                       pr_warning("ACPI: acpi_sleep=s4_nonvs is deprecated, "
-                                       "please use acpi_sleep=nonvs instead");
-                       acpi_nvs_nosave();
-               }
 #endif
                if (strncmp(str, "nonvs", 5) == 0)
                        acpi_nvs_nosave();
index adee12e..3bfa022 100644 (file)
@@ -1238,7 +1238,6 @@ static int suspend(int vetoable)
        dpm_suspend_noirq(PMSG_SUSPEND);
 
        local_irq_disable();
-       sysdev_suspend(PMSG_SUSPEND);
        syscore_suspend();
 
        local_irq_enable();
@@ -1258,7 +1257,6 @@ static int suspend(int vetoable)
        err = (err == APM_SUCCESS) ? 0 : -EIO;
 
        syscore_resume();
-       sysdev_resume();
        local_irq_enable();
 
        dpm_resume_noirq(PMSG_RESUME);
@@ -1282,7 +1280,6 @@ static void standby(void)
        dpm_suspend_noirq(PMSG_SUSPEND);
 
        local_irq_disable();
-       sysdev_suspend(PMSG_SUSPEND);
        syscore_suspend();
        local_irq_enable();
 
@@ -1292,7 +1289,6 @@ static void standby(void)
 
        local_irq_disable();
        syscore_resume();
-       sysdev_resume();
        local_irq_enable();
 
        dpm_resume_noirq(PMSG_RESUME);
index e9e5238..d57e8d0 100644 (file)
@@ -168,11 +168,4 @@ config SYS_HYPERVISOR
        bool
        default n
 
-config ARCH_NO_SYSDEV_OPS
-       bool
-       ---help---
-         To be selected by architectures that don't use sysdev class or
-         sysdev driver power management (suspend/resume) and shutdown
-         operations.
-
 endmenu
index 19f49e4..a34dca0 100644 (file)
@@ -111,8 +111,6 @@ static inline int driver_match_device(struct device_driver *drv,
        return drv->bus->match ? drv->bus->match(dev, drv) : 1;
 }
 
-extern void sysdev_shutdown(void);
-
 extern char *make_class_name(const char *name, struct kobject *kobj);
 
 extern int devres_release_all(struct device *dev);
index da57ee9..29917c7 100644 (file)
@@ -316,8 +316,7 @@ static void __device_release_driver(struct device *dev)
 
        drv = dev->driver;
        if (drv) {
-               pm_runtime_get_noresume(dev);
-               pm_runtime_barrier(dev);
+               pm_runtime_get_sync(dev);
 
                driver_sysfs_remove(dev);
 
@@ -326,6 +325,8 @@ static void __device_release_driver(struct device *dev)
                                                     BUS_NOTIFY_UNBIND_DRIVER,
                                                     dev);
 
+               pm_runtime_put_sync(dev);
+
                if (dev->bus && dev->bus->remove)
                        dev->bus->remove(dev);
                else if (drv->remove)
@@ -338,7 +339,6 @@ static void __device_release_driver(struct device *dev)
                                                     BUS_NOTIFY_UNBOUND_DRIVER,
                                                     dev);
 
-               pm_runtime_put_sync(dev);
        }
 }
 
index 8c798ef..bbb03e6 100644 (file)
@@ -521,6 +521,11 @@ static int _request_firmware(const struct firmware **firmware_p,
        if (!firmware_p)
                return -EINVAL;
 
+       if (WARN_ON(usermodehelper_is_disabled())) {
+               dev_err(device, "firmware: %s will not be loaded\n", name);
+               return -EBUSY;
+       }
+
        *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
        if (!firmware) {
                dev_err(device, "%s: kmalloc(struct firmware) failed\n",
index 9e0e4fc..48425f1 100644 (file)
@@ -667,7 +667,7 @@ static int platform_legacy_resume(struct device *dev)
        return ret;
 }
 
-static int platform_pm_prepare(struct device *dev)
+int platform_pm_prepare(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -678,7 +678,7 @@ static int platform_pm_prepare(struct device *dev)
        return ret;
 }
 
-static void platform_pm_complete(struct device *dev)
+void platform_pm_complete(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
 
@@ -686,16 +686,11 @@ static void platform_pm_complete(struct device *dev)
                drv->pm->complete(dev);
 }
 
-#else /* !CONFIG_PM_SLEEP */
-
-#define platform_pm_prepare            NULL
-#define platform_pm_complete           NULL
-
-#endif /* !CONFIG_PM_SLEEP */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_SUSPEND
 
-int __weak platform_pm_suspend(struct device *dev)
+int platform_pm_suspend(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -713,7 +708,7 @@ int __weak platform_pm_suspend(struct device *dev)
        return ret;
 }
 
-int __weak platform_pm_suspend_noirq(struct device *dev)
+int platform_pm_suspend_noirq(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -729,7 +724,7 @@ int __weak platform_pm_suspend_noirq(struct device *dev)
        return ret;
 }
 
-int __weak platform_pm_resume(struct device *dev)
+int platform_pm_resume(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -747,7 +742,7 @@ int __weak platform_pm_resume(struct device *dev)
        return ret;
 }
 
-int __weak platform_pm_resume_noirq(struct device *dev)
+int platform_pm_resume_noirq(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -763,18 +758,11 @@ int __weak platform_pm_resume_noirq(struct device *dev)
        return ret;
 }
 
-#else /* !CONFIG_SUSPEND */
-
-#define platform_pm_suspend            NULL
-#define platform_pm_resume             NULL
-#define platform_pm_suspend_noirq      NULL
-#define platform_pm_resume_noirq       NULL
-
-#endif /* !CONFIG_SUSPEND */
+#endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATE_CALLBACKS
 
-static int platform_pm_freeze(struct device *dev)
+int platform_pm_freeze(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -792,7 +780,7 @@ static int platform_pm_freeze(struct device *dev)
        return ret;
 }
 
-static int platform_pm_freeze_noirq(struct device *dev)
+int platform_pm_freeze_noirq(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -808,7 +796,7 @@ static int platform_pm_freeze_noirq(struct device *dev)
        return ret;
 }
 
-static int platform_pm_thaw(struct device *dev)
+int platform_pm_thaw(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -826,7 +814,7 @@ static int platform_pm_thaw(struct device *dev)
        return ret;
 }
 
-static int platform_pm_thaw_noirq(struct device *dev)
+int platform_pm_thaw_noirq(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -842,7 +830,7 @@ static int platform_pm_thaw_noirq(struct device *dev)
        return ret;
 }
 
-static int platform_pm_poweroff(struct device *dev)
+int platform_pm_poweroff(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -860,7 +848,7 @@ static int platform_pm_poweroff(struct device *dev)
        return ret;
 }
 
-static int platform_pm_poweroff_noirq(struct device *dev)
+int platform_pm_poweroff_noirq(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -876,7 +864,7 @@ static int platform_pm_poweroff_noirq(struct device *dev)
        return ret;
 }
 
-static int platform_pm_restore(struct device *dev)
+int platform_pm_restore(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -894,7 +882,7 @@ static int platform_pm_restore(struct device *dev)
        return ret;
 }
 
-static int platform_pm_restore_noirq(struct device *dev)
+int platform_pm_restore_noirq(struct device *dev)
 {
        struct device_driver *drv = dev->driver;
        int ret = 0;
@@ -910,62 +898,13 @@ static int platform_pm_restore_noirq(struct device *dev)
        return ret;
 }
 
-#else /* !CONFIG_HIBERNATE_CALLBACKS */
-
-#define platform_pm_freeze             NULL
-#define platform_pm_thaw               NULL
-#define platform_pm_poweroff           NULL
-#define platform_pm_restore            NULL
-#define platform_pm_freeze_noirq       NULL
-#define platform_pm_thaw_noirq         NULL
-#define platform_pm_poweroff_noirq     NULL
-#define platform_pm_restore_noirq      NULL
-
-#endif /* !CONFIG_HIBERNATE_CALLBACKS */
-
-#ifdef CONFIG_PM_RUNTIME
-
-int __weak platform_pm_runtime_suspend(struct device *dev)
-{
-       return pm_generic_runtime_suspend(dev);
-};
-
-int __weak platform_pm_runtime_resume(struct device *dev)
-{
-       return pm_generic_runtime_resume(dev);
-};
-
-int __weak platform_pm_runtime_idle(struct device *dev)
-{
-       return pm_generic_runtime_idle(dev);
-};
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define platform_pm_runtime_suspend NULL
-#define platform_pm_runtime_resume NULL
-#define platform_pm_runtime_idle NULL
-
-#endif /* !CONFIG_PM_RUNTIME */
+#endif /* CONFIG_HIBERNATE_CALLBACKS */
 
 static const struct dev_pm_ops platform_dev_pm_ops = {
-       .prepare = platform_pm_prepare,
-       .complete = platform_pm_complete,
-       .suspend = platform_pm_suspend,
-       .resume = platform_pm_resume,
-       .freeze = platform_pm_freeze,
-       .thaw = platform_pm_thaw,
-       .poweroff = platform_pm_poweroff,
-       .restore = platform_pm_restore,
-       .suspend_noirq = platform_pm_suspend_noirq,
-       .resume_noirq = platform_pm_resume_noirq,
-       .freeze_noirq = platform_pm_freeze_noirq,
-       .thaw_noirq = platform_pm_thaw_noirq,
-       .poweroff_noirq = platform_pm_poweroff_noirq,
-       .restore_noirq = platform_pm_restore_noirq,
-       .runtime_suspend = platform_pm_runtime_suspend,
-       .runtime_resume = platform_pm_runtime_resume,
-       .runtime_idle = platform_pm_runtime_idle,
+       .runtime_suspend = pm_generic_runtime_suspend,
+       .runtime_resume = pm_generic_runtime_resume,
+       .runtime_idle = pm_generic_runtime_idle,
+       USE_PLATFORM_PM_SLEEP_OPS
 };
 
 struct bus_type platform_bus_type = {
@@ -977,41 +916,6 @@ struct bus_type platform_bus_type = {
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
 
-/**
- * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
- *
- * This function can be used by platform code to get the current
- * set of dev_pm_ops functions used by the platform_bus_type.
- */
-const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
-{
-       return platform_bus_type.pm;
-}
-
-/**
- * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
- *
- * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
- *
- * Platform code can override the dev_pm_ops methods of
- * platform_bus_type by using this function.  It is expected that
- * platform code will first do a platform_bus_get_pm_ops(), then
- * kmemdup it, then customize selected methods and pass a pointer to
- * the new struct dev_pm_ops to this function.
- *
- * Since platform-specific code is customizing methods for *all*
- * devices (not just platform-specific devices) it is expected that
- * any custom overrides of these functions will keep existing behavior
- * and simply extend it.  For example, any customization of the
- * runtime PM methods should continue to call the pm_generic_*
- * functions as the default ones do in addition to the
- * platform-specific behavior.
- */
-void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
-{
-       platform_bus_type.pm = pm;
-}
-
 int __init platform_bus_init(void)
 {
        int error;
index 118c1b9..3647e11 100644 (file)
@@ -3,6 +3,6 @@ obj-$(CONFIG_PM_SLEEP)  += main.o wakeup.o
 obj-$(CONFIG_PM_RUNTIME)       += runtime.o
 obj-$(CONFIG_PM_TRACE_RTC)     += trace.o
 obj-$(CONFIG_PM_OPP)   += opp.o
+obj-$(CONFIG_HAVE_CLK) += clock_ops.o
 
-ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
-ccflags-$(CONFIG_PM_VERBOSE)   += -DDEBUG
+ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
\ No newline at end of file
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c
new file mode 100644 (file)
index 0000000..c0dd09d
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks
+ *
+ * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#ifdef CONFIG_PM_RUNTIME
+
+struct pm_runtime_clk_data {
+       struct list_head clock_list;
+       struct mutex lock;
+};
+
+enum pce_status {
+       PCE_STATUS_NONE = 0,
+       PCE_STATUS_ACQUIRED,
+       PCE_STATUS_ENABLED,
+       PCE_STATUS_ERROR,
+};
+
+struct pm_clock_entry {
+       struct list_head node;
+       char *con_id;
+       struct clk *clk;
+       enum pce_status status;
+};
+
+static struct pm_runtime_clk_data *__to_prd(struct device *dev)
+{
+       return dev ? dev->power.subsys_data : NULL;
+}
+
+/**
+ * pm_runtime_clk_add - Start using a device clock for runtime PM.
+ * @dev: Device whose clock is going to be used for runtime PM.
+ * @con_id: Connection ID of the clock.
+ *
+ * Add the clock represented by @con_id to the list of clocks used for
+ * the runtime PM of @dev.
+ */
+int pm_runtime_clk_add(struct device *dev, const char *con_id)
+{
+       struct pm_runtime_clk_data *prd = __to_prd(dev);
+       struct pm_clock_entry *ce;
+
+       if (!prd)
+               return -EINVAL;
+
+       ce = kzalloc(sizeof(*ce), GFP_KERNEL);
+       if (!ce) {
+               dev_err(dev, "Not enough memory for clock entry.\n");
+               return -ENOMEM;
+       }
+
+       if (con_id) {
+               ce->con_id = kstrdup(con_id, GFP_KERNEL);
+               if (!ce->con_id) {
+                       dev_err(dev,
+                               "Not enough memory for clock connection ID.\n");
+                       kfree(ce);
+                       return -ENOMEM;
+               }
+       }
+
+       mutex_lock(&prd->lock);
+       list_add_tail(&ce->node, &prd->clock_list);
+       mutex_unlock(&prd->lock);
+       return 0;
+}
+
+/**
+ * __pm_runtime_clk_remove - Destroy runtime PM clock entry.
+ * @ce: Runtime PM clock entry to destroy.
+ *
+ * This routine must be called under the mutex protecting the runtime PM list
+ * of clocks corresponding the the @ce's device.
+ */
+static void __pm_runtime_clk_remove(struct pm_clock_entry *ce)
+{
+       if (!ce)
+               return;
+
+       list_del(&ce->node);
+
+       if (ce->status < PCE_STATUS_ERROR) {
+               if (ce->status == PCE_STATUS_ENABLED)
+                       clk_disable(ce->clk);
+
+               if (ce->status >= PCE_STATUS_ACQUIRED)
+                       clk_put(ce->clk);
+       }
+
+       if (ce->con_id)
+               kfree(ce->con_id);
+
+       kfree(ce);
+}
+
+/**
+ * pm_runtime_clk_remove - Stop using a device clock for runtime PM.
+ * @dev: Device whose clock should not be used for runtime PM any more.
+ * @con_id: Connection ID of the clock.
+ *
+ * Remove the clock represented by @con_id from the list of clocks used for
+ * the runtime PM of @dev.
+ */
+void pm_runtime_clk_remove(struct device *dev, const char *con_id)
+{
+       struct pm_runtime_clk_data *prd = __to_prd(dev);
+       struct pm_clock_entry *ce;
+
+       if (!prd)
+               return;
+
+       mutex_lock(&prd->lock);
+
+       list_for_each_entry(ce, &prd->clock_list, node) {
+               if (!con_id && !ce->con_id) {
+                       __pm_runtime_clk_remove(ce);
+                       break;
+               } else if (!con_id || !ce->con_id) {
+                       continue;
+               } else if (!strcmp(con_id, ce->con_id)) {
+                       __pm_runtime_clk_remove(ce);
+                       break;
+               }
+       }
+
+       mutex_unlock(&prd->lock);
+}
+
+/**
+ * pm_runtime_clk_init - Initialize a device's list of runtime PM clocks.
+ * @dev: Device to initialize the list of runtime PM clocks for.
+ *
+ * Allocate a struct pm_runtime_clk_data object, initialize its lock member and
+ * make the @dev's power.subsys_data field point to it.
+ */
+int pm_runtime_clk_init(struct device *dev)
+{
+       struct pm_runtime_clk_data *prd;
+
+       prd = kzalloc(sizeof(*prd), GFP_KERNEL);
+       if (!prd) {
+               dev_err(dev, "Not enough memory fo runtime PM data.\n");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&prd->clock_list);
+       mutex_init(&prd->lock);
+       dev->power.subsys_data = prd;
+       return 0;
+}
+
+/**
+ * pm_runtime_clk_destroy - Destroy a device's list of runtime PM clocks.
+ * @dev: Device to destroy the list of runtime PM clocks for.
+ *
+ * Clear the @dev's power.subsys_data field, remove the list of clock entries
+ * from the struct pm_runtime_clk_data object pointed to by it before and free
+ * that object.
+ */
+void pm_runtime_clk_destroy(struct device *dev)
+{
+       struct pm_runtime_clk_data *prd = __to_prd(dev);
+       struct pm_clock_entry *ce, *c;
+
+       if (!prd)
+               return;
+
+       dev->power.subsys_data = NULL;
+
+       mutex_lock(&prd->lock);
+
+       list_for_each_entry_safe_reverse(ce, c, &prd->clock_list, node)
+               __pm_runtime_clk_remove(ce);
+
+       mutex_unlock(&prd->lock);
+
+       kfree(prd);
+}
+
+/**
+ * pm_runtime_clk_acquire - Acquire a device clock.
+ * @dev: Device whose clock is to be acquired.
+ * @con_id: Connection ID of the clock.
+ */
+static void pm_runtime_clk_acquire(struct device *dev,
+                                   struct pm_clock_entry *ce)
+{
+       ce->clk = clk_get(dev, ce->con_id);
+       if (IS_ERR(ce->clk)) {
+               ce->status = PCE_STATUS_ERROR;
+       } else {
+               ce->status = PCE_STATUS_ACQUIRED;
+               dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
+       }
+}
+
+/**
+ * pm_runtime_clk_suspend - Disable clocks in a device's runtime PM clock list.
+ * @dev: Device to disable the clocks for.
+ */
+int pm_runtime_clk_suspend(struct device *dev)
+{
+       struct pm_runtime_clk_data *prd = __to_prd(dev);
+       struct pm_clock_entry *ce;
+
+       dev_dbg(dev, "%s()\n", __func__);
+
+       if (!prd)
+               return 0;
+
+       mutex_lock(&prd->lock);
+
+       list_for_each_entry_reverse(ce, &prd->clock_list, node) {
+               if (ce->status == PCE_STATUS_NONE)
+                       pm_runtime_clk_acquire(dev, ce);
+
+               if (ce->status < PCE_STATUS_ERROR) {
+                       clk_disable(ce->clk);
+                       ce->status = PCE_STATUS_ACQUIRED;
+               }
+       }
+
+       mutex_unlock(&prd->lock);
+
+       return 0;
+}
+
+/**
+ * pm_runtime_clk_resume - Enable clocks in a device's runtime PM clock list.
+ * @dev: Device to enable the clocks for.
+ */
+int pm_runtime_clk_resume(struct device *dev)
+{
+       struct pm_runtime_clk_data *prd = __to_prd(dev);
+       struct pm_clock_entry *ce;
+
+       dev_dbg(dev, "%s()\n", __func__);
+
+       if (!prd)
+               return 0;
+
+       mutex_lock(&prd->lock);
+
+       list_for_each_entry(ce, &prd->clock_list, node) {
+               if (ce->status == PCE_STATUS_NONE)
+                       pm_runtime_clk_acquire(dev, ce);
+
+               if (ce->status < PCE_STATUS_ERROR) {
+                       clk_enable(ce->clk);
+                       ce->status = PCE_STATUS_ENABLED;
+               }
+       }
+
+       mutex_unlock(&prd->lock);
+
+       return 0;
+}
+
+/**
+ * pm_runtime_clk_notify - Notify routine for device addition and removal.
+ * @nb: Notifier block object this function is a member of.
+ * @action: Operation being carried out by the caller.
+ * @data: Device the routine is being run for.
+ *
+ * For this function to work, @nb must be a member of an object of type
+ * struct pm_clk_notifier_block containing all of the requisite data.
+ * Specifically, the pwr_domain member of that object is copied to the device's
+ * pwr_domain field and its con_ids member is used to populate the device's list
+ * of runtime PM clocks, depending on @action.
+ *
+ * If the device's pwr_domain field is already populated with a value different
+ * from the one stored in the struct pm_clk_notifier_block object, the function
+ * does nothing.
+ */
+static int pm_runtime_clk_notify(struct notifier_block *nb,
+                                unsigned long action, void *data)
+{
+       struct pm_clk_notifier_block *clknb;
+       struct device *dev = data;
+       char *con_id;
+       int error;
+
+       dev_dbg(dev, "%s() %ld\n", __func__, action);
+
+       clknb = container_of(nb, struct pm_clk_notifier_block, nb);
+
+       switch (action) {
+       case BUS_NOTIFY_ADD_DEVICE:
+               if (dev->pwr_domain)
+                       break;
+
+               error = pm_runtime_clk_init(dev);
+               if (error)
+                       break;
+
+               dev->pwr_domain = clknb->pwr_domain;
+               if (clknb->con_ids[0]) {
+                       for (con_id = clknb->con_ids[0]; *con_id; con_id++)
+                               pm_runtime_clk_add(dev, con_id);
+               } else {
+                       pm_runtime_clk_add(dev, NULL);
+               }
+
+               break;
+       case BUS_NOTIFY_DEL_DEVICE:
+               if (dev->pwr_domain != clknb->pwr_domain)
+                       break;
+
+               dev->pwr_domain = NULL;
+               pm_runtime_clk_destroy(dev);
+               break;
+       }
+
+       return 0;
+}
+
+#else /* !CONFIG_PM_RUNTIME */
+
+/**
+ * enable_clock - Enable a device clock.
+ * @dev: Device whose clock is to be enabled.
+ * @con_id: Connection ID of the clock.
+ */
+static void enable_clock(struct device *dev, const char *con_id)
+{
+       struct clk *clk;
+
+       clk = clk_get(dev, con_id);
+       if (!IS_ERR(clk)) {
+               clk_enable(clk);
+               clk_put(clk);
+               dev_info(dev, "Runtime PM disabled, clock forced on.\n");
+       }
+}
+
+/**
+ * disable_clock - Disable a device clock.
+ * @dev: Device whose clock is to be disabled.
+ * @con_id: Connection ID of the clock.
+ */
+static void disable_clock(struct device *dev, const char *con_id)
+{
+       struct clk *clk;
+
+       clk = clk_get(dev, con_id);
+       if (!IS_ERR(clk)) {
+               clk_disable(clk);
+               clk_put(clk);
+               dev_info(dev, "Runtime PM disabled, clock forced off.\n");
+       }
+}
+
+/**
+ * pm_runtime_clk_notify - Notify routine for device addition and removal.
+ * @nb: Notifier block object this function is a member of.
+ * @action: Operation being carried out by the caller.
+ * @data: Device the routine is being run for.
+ *
+ * For this function to work, @nb must be a member of an object of type
+ * struct pm_clk_notifier_block containing all of the requisite data.
+ * Specifically, the con_ids member of that object is used to enable or disable
+ * the device's clocks, depending on @action.
+ */
+static int pm_runtime_clk_notify(struct notifier_block *nb,
+                                unsigned long action, void *data)
+{
+       struct pm_clk_notifier_block *clknb;
+       struct device *dev = data;
+       char *con_id;
+
+       dev_dbg(dev, "%s() %ld\n", __func__, action);
+
+       clknb = container_of(nb, struct pm_clk_notifier_block, nb);
+
+       switch (action) {
+       case BUS_NOTIFY_ADD_DEVICE:
+               if (clknb->con_ids[0]) {
+                       for (con_id = clknb->con_ids[0]; *con_id; con_id++)
+                               enable_clock(dev, con_id);
+               } else {
+                       enable_clock(dev, NULL);
+               }
+               break;
+       case BUS_NOTIFY_DEL_DEVICE:
+               if (clknb->con_ids[0]) {
+                       for (con_id = clknb->con_ids[0]; *con_id; con_id++)
+                               disable_clock(dev, con_id);
+               } else {
+                       disable_clock(dev, NULL);
+               }
+               break;
+       }
+
+       return 0;
+}
+
+#endif /* !CONFIG_PM_RUNTIME */
+
+/**
+ * pm_runtime_clk_add_notifier - Add bus type notifier for runtime PM clocks.
+ * @bus: Bus type to add the notifier to.
+ * @clknb: Notifier to be added to the given bus type.
+ *
+ * The nb member of @clknb is not expected to be initialized and its
+ * notifier_call member will be replaced with pm_runtime_clk_notify().  However,
+ * the remaining members of @clknb should be populated prior to calling this
+ * routine.
+ */
+void pm_runtime_clk_add_notifier(struct bus_type *bus,
+                                struct pm_clk_notifier_block *clknb)
+{
+       if (!bus || !clknb)
+               return;
+
+       clknb->nb.notifier_call = pm_runtime_clk_notify;
+       bus_register_notifier(bus, &clknb->nb);
+}
index 42f97f9..cb3bb36 100644 (file)
@@ -73,6 +73,23 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
 #endif /* CONFIG_PM_RUNTIME */
 
 #ifdef CONFIG_PM_SLEEP
+/**
+ * pm_generic_prepare - Generic routine preparing a device for power transition.
+ * @dev: Device to prepare.
+ *
+ * Prepare a device for a system-wide power transition.
+ */
+int pm_generic_prepare(struct device *dev)
+{
+       struct device_driver *drv = dev->driver;
+       int ret = 0;
+
+       if (drv && drv->pm && drv->pm->prepare)
+               ret = drv->pm->prepare(dev);
+
+       return ret;
+}
+
 /**
  * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback.
  * @dev: Device to handle.
@@ -213,16 +230,38 @@ int pm_generic_restore(struct device *dev)
        return __pm_generic_resume(dev, PM_EVENT_RESTORE);
 }
 EXPORT_SYMBOL_GPL(pm_generic_restore);
+
+/**
+ * pm_generic_complete - Generic routine competing a device power transition.
+ * @dev: Device to handle.
+ *
+ * Complete a device power transition during a system-wide power transition.
+ */
+void pm_generic_complete(struct device *dev)
+{
+       struct device_driver *drv = dev->driver;
+
+       if (drv && drv->pm && drv->pm->complete)
+               drv->pm->complete(dev);
+
+       /*
+        * Let runtime PM try to suspend devices that haven't been in use before
+        * going into the system-wide sleep state we're resuming from.
+        */
+       pm_runtime_idle(dev);
+}
 #endif /* CONFIG_PM_SLEEP */
 
 struct dev_pm_ops generic_subsys_pm_ops = {
 #ifdef CONFIG_PM_SLEEP
+       .prepare = pm_generic_prepare,
        .suspend = pm_generic_suspend,
        .resume = pm_generic_resume,
        .freeze = pm_generic_freeze,
        .thaw = pm_generic_thaw,
        .poweroff = pm_generic_poweroff,
        .restore = pm_generic_restore,
+       .complete = pm_generic_complete,
 #endif
 #ifdef CONFIG_PM_RUNTIME
        .runtime_suspend = pm_generic_runtime_suspend,
index abe3ab7..aa63202 100644 (file)
@@ -426,10 +426,8 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
 
        if (dev->pwr_domain) {
                pm_dev_dbg(dev, state, "EARLY power domain ");
-               pm_noirq_op(dev, &dev->pwr_domain->ops, state);
-       }
-
-       if (dev->type && dev->type->pm) {
+               error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
+       } else if (dev->type && dev->type->pm) {
                pm_dev_dbg(dev, state, "EARLY type ");
                error = pm_noirq_op(dev, dev->type->pm, state);
        } else if (dev->class && dev->class->pm) {
@@ -517,7 +515,8 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
 
        if (dev->pwr_domain) {
                pm_dev_dbg(dev, state, "power domain ");
-               pm_op(dev, &dev->pwr_domain->ops, state);
+               error = pm_op(dev, &dev->pwr_domain->ops, state);
+               goto End;
        }
 
        if (dev->type && dev->type->pm) {
@@ -580,11 +579,13 @@ static bool is_async(struct device *dev)
  * Execute the appropriate "resume" callback for all devices whose status
  * indicates that they are suspended.
  */
-static void dpm_resume(pm_message_t state)
+void dpm_resume(pm_message_t state)
 {
        struct device *dev;
        ktime_t starttime = ktime_get();
 
+       might_sleep();
+
        mutex_lock(&dpm_list_mtx);
        pm_transition = state;
        async_error = 0;
@@ -629,12 +630,11 @@ static void device_complete(struct device *dev, pm_message_t state)
 {
        device_lock(dev);
 
-       if (dev->pwr_domain && dev->pwr_domain->ops.complete) {
+       if (dev->pwr_domain) {
                pm_dev_dbg(dev, state, "completing power domain ");
-               dev->pwr_domain->ops.complete(dev);
-       }
-
-       if (dev->type && dev->type->pm) {
+               if (dev->pwr_domain->ops.complete)
+                       dev->pwr_domain->ops.complete(dev);
+       } else if (dev->type && dev->type->pm) {
                pm_dev_dbg(dev, state, "completing type ");
                if (dev->type->pm->complete)
                        dev->type->pm->complete(dev);
@@ -658,10 +658,12 @@ static void device_complete(struct device *dev, pm_message_t state)
  * Execute the ->complete() callbacks for all devices whose PM status is not
  * DPM_ON (this allows new devices to be registered).
  */
-static void dpm_complete(pm_message_t state)
+void dpm_complete(pm_message_t state)
 {
        struct list_head list;
 
+       might_sleep();
+
        INIT_LIST_HEAD(&list);
        mutex_lock(&dpm_list_mtx);
        while (!list_empty(&dpm_prepared_list)) {
@@ -690,7 +692,6 @@ static void dpm_complete(pm_message_t state)
  */
 void dpm_resume_end(pm_message_t state)
 {
-       might_sleep();
        dpm_resume(state);
        dpm_complete(state);
 }
@@ -732,7 +733,12 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
 {
        int error;
 
-       if (dev->type && dev->type->pm) {
+       if (dev->pwr_domain) {
+               pm_dev_dbg(dev, state, "LATE power domain ");
+               error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
+               if (error)
+                       return error;
+       } else if (dev->type && dev->type->pm) {
                pm_dev_dbg(dev, state, "LATE type ");
                error = pm_noirq_op(dev, dev->type->pm, state);
                if (error)
@@ -749,11 +755,6 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
                        return error;
        }
 
-       if (dev->pwr_domain) {
-               pm_dev_dbg(dev, state, "LATE power domain ");
-               pm_noirq_op(dev, &dev->pwr_domain->ops, state);
-       }
-
        return 0;
 }
 
@@ -841,21 +842,27 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
                goto End;
        }
 
+       if (dev->pwr_domain) {
+               pm_dev_dbg(dev, state, "power domain ");
+               error = pm_op(dev, &dev->pwr_domain->ops, state);
+               goto End;
+       }
+
        if (dev->type && dev->type->pm) {
                pm_dev_dbg(dev, state, "type ");
                error = pm_op(dev, dev->type->pm, state);
-               goto Domain;
+               goto End;
        }
 
        if (dev->class) {
                if (dev->class->pm) {
                        pm_dev_dbg(dev, state, "class ");
                        error = pm_op(dev, dev->class->pm, state);
-                       goto Domain;
+                       goto End;
                } else if (dev->class->suspend) {
                        pm_dev_dbg(dev, state, "legacy class ");
                        error = legacy_suspend(dev, state, dev->class->suspend);
-                       goto Domain;
+                       goto End;
                }
        }
 
@@ -869,12 +876,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
                }
        }
 
- Domain:
-       if (!error && dev->pwr_domain) {
-               pm_dev_dbg(dev, state, "power domain ");
-               pm_op(dev, &dev->pwr_domain->ops, state);
-       }
-
  End:
        device_unlock(dev);
        complete_all(&dev->power.completion);
@@ -914,11 +915,13 @@ static int device_suspend(struct device *dev)
  * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
  * @state: PM transition of the system being carried out.
  */
-static int dpm_suspend(pm_message_t state)
+int dpm_suspend(pm_message_t state)
 {
        ktime_t starttime = ktime_get();
        int error = 0;
 
+       might_sleep();
+
        mutex_lock(&dpm_list_mtx);
        pm_transition = state;
        async_error = 0;
@@ -965,7 +968,14 @@ static int device_prepare(struct device *dev, pm_message_t state)
 
        device_lock(dev);
 
-       if (dev->type && dev->type->pm) {
+       if (dev->pwr_domain) {
+               pm_dev_dbg(dev, state, "preparing power domain ");
+               if (dev->pwr_domain->ops.prepare)
+                       error = dev->pwr_domain->ops.prepare(dev);
+               suspend_report_result(dev->pwr_domain->ops.prepare, error);
+               if (error)
+                       goto End;
+       } else if (dev->type && dev->type->pm) {
                pm_dev_dbg(dev, state, "preparing type ");
                if (dev->type->pm->prepare)
                        error = dev->type->pm->prepare(dev);
@@ -984,13 +994,6 @@ static int device_prepare(struct device *dev, pm_message_t state)
                if (dev->bus->pm->prepare)
                        error = dev->bus->pm->prepare(dev);
                suspend_report_result(dev->bus->pm->prepare, error);
-               if (error)
-                       goto End;
-       }
-
-       if (dev->pwr_domain && dev->pwr_domain->ops.prepare) {
-               pm_dev_dbg(dev, state, "preparing power domain ");
-               dev->pwr_domain->ops.prepare(dev);
        }
 
  End:
@@ -1005,10 +1008,12 @@ static int device_prepare(struct device *dev, pm_message_t state)
  *
  * Execute the ->prepare() callback(s) for all devices.
  */
-static int dpm_prepare(pm_message_t state)
+int dpm_prepare(pm_message_t state)
 {
        int error = 0;
 
+       might_sleep();
+
        mutex_lock(&dpm_list_mtx);
        while (!list_empty(&dpm_list)) {
                struct device *dev = to_device(dpm_list.next);
@@ -1057,7 +1062,6 @@ int dpm_suspend_start(pm_message_t state)
 {
        int error;
 
-       might_sleep();
        error = dpm_prepare(state);
        if (!error)
                error = dpm_suspend(state);
index 3172c60..0d4587b 100644 (file)
@@ -168,7 +168,6 @@ static int rpm_check_suspend_allowed(struct device *dev)
 static int rpm_idle(struct device *dev, int rpmflags)
 {
        int (*callback)(struct device *);
-       int (*domain_callback)(struct device *);
        int retval;
 
        retval = rpm_check_suspend_allowed(dev);
@@ -214,7 +213,9 @@ static int rpm_idle(struct device *dev, int rpmflags)
 
        dev->power.idle_notification = true;
 
-       if (dev->type && dev->type->pm)
+       if (dev->pwr_domain)
+               callback = dev->pwr_domain->ops.runtime_idle;
+       else if (dev->type && dev->type->pm)
                callback = dev->type->pm->runtime_idle;
        else if (dev->class && dev->class->pm)
                callback = dev->class->pm->runtime_idle;
@@ -223,19 +224,10 @@ static int rpm_idle(struct device *dev, int rpmflags)
        else
                callback = NULL;
 
-       if (dev->pwr_domain)
-               domain_callback = dev->pwr_domain->ops.runtime_idle;
-       else
-               domain_callback = NULL;
-
-       if (callback || domain_callback) {
+       if (callback) {
                spin_unlock_irq(&dev->power.lock);
 
-               if (domain_callback)
-                       retval = domain_callback(dev);
-
-               if (!retval && callback)
-                       callback(dev);
+               callback(dev);
 
                spin_lock_irq(&dev->power.lock);
        }
@@ -382,7 +374,9 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 
        __update_runtime_status(dev, RPM_SUSPENDING);
 
-       if (dev->type && dev->type->pm)
+       if (dev->pwr_domain)
+               callback = dev->pwr_domain->ops.runtime_suspend;
+       else if (dev->type && dev->type->pm)
                callback = dev->type->pm->runtime_suspend;
        else if (dev->class && dev->class->pm)
                callback = dev->class->pm->runtime_suspend;
@@ -400,8 +394,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                else
                        pm_runtime_cancel_pending(dev);
        } else {
-               if (dev->pwr_domain)
-                       rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev);
  no_callback:
                __update_runtime_status(dev, RPM_SUSPENDED);
                pm_runtime_deactivate_timer(dev);
@@ -582,9 +574,8 @@ static int rpm_resume(struct device *dev, int rpmflags)
        __update_runtime_status(dev, RPM_RESUMING);
 
        if (dev->pwr_domain)
-               rpm_callback(dev->pwr_domain->ops.runtime_resume, dev);
-
-       if (dev->type && dev->type->pm)
+               callback = dev->pwr_domain->ops.runtime_resume;
+       else if (dev->type && dev->type->pm)
                callback = dev->type->pm->runtime_resume;
        else if (dev->class && dev->class->pm)
                callback = dev->class->pm->runtime_resume;
index fff49be..a9f5b89 100644 (file)
@@ -212,8 +212,9 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev,
 static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show,
                autosuspend_delay_ms_store);
 
-#endif
+#endif /* CONFIG_PM_RUNTIME */
 
+#ifdef CONFIG_PM_SLEEP
 static ssize_t
 wake_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
@@ -248,7 +249,6 @@ wake_store(struct device * dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
 
-#ifdef CONFIG_PM_SLEEP
 static ssize_t wakeup_count_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
index abbbd33..84f7c7d 100644 (file)
@@ -110,7 +110,6 @@ void wakeup_source_add(struct wakeup_source *ws)
        spin_lock_irq(&events_lock);
        list_add_rcu(&ws->entry, &wakeup_sources);
        spin_unlock_irq(&events_lock);
-       synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(wakeup_source_add);
 
index acde9b5..9dff77b 100644 (file)
@@ -328,203 +328,8 @@ void sysdev_unregister(struct sys_device *sysdev)
        kobject_put(&sysdev->kobj);
 }
 
-
-#ifndef CONFIG_ARCH_NO_SYSDEV_OPS
-/**
- *     sysdev_shutdown - Shut down all system devices.
- *
- *     Loop over each class of system devices, and the devices in each
- *     of those classes. For each device, we call the shutdown method for
- *     each driver registered for the device - the auxiliaries,
- *     and the class driver.
- *
- *     Note: The list is iterated in reverse order, so that we shut down
- *     child devices before we shut down their parents. The list ordering
- *     is guaranteed by virtue of the fact that child devices are registered
- *     after their parents.
- */
-void sysdev_shutdown(void)
-{
-       struct sysdev_class *cls;
-
-       pr_debug("Shutting Down System Devices\n");
-
-       mutex_lock(&sysdev_drivers_lock);
-       list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
-               struct sys_device *sysdev;
-
-               pr_debug("Shutting down type '%s':\n",
-                        kobject_name(&cls->kset.kobj));
-
-               list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-                       struct sysdev_driver *drv;
-                       pr_debug(" %s\n", kobject_name(&sysdev->kobj));
-
-                       /* Call auxiliary drivers first */
-                       list_for_each_entry(drv, &cls->drivers, entry) {
-                               if (drv->shutdown)
-                                       drv->shutdown(sysdev);
-                       }
-
-                       /* Now call the generic one */
-                       if (cls->shutdown)
-                               cls->shutdown(sysdev);
-               }
-       }
-       mutex_unlock(&sysdev_drivers_lock);
-}
-
-static void __sysdev_resume(struct sys_device *dev)
-{
-       struct sysdev_class *cls = dev->cls;
-       struct sysdev_driver *drv;
-
-       /* First, call the class-specific one */
-       if (cls->resume)
-               cls->resume(dev);
-       WARN_ONCE(!irqs_disabled(),
-               "Interrupts enabled after %pF\n", cls->resume);
-
-       /* Call auxiliary drivers next. */
-       list_for_each_entry(drv, &cls->drivers, entry) {
-               if (drv->resume)
-                       drv->resume(dev);
-               WARN_ONCE(!irqs_disabled(),
-                       "Interrupts enabled after %pF\n", drv->resume);
-       }
-}
-
-/**
- *     sysdev_suspend - Suspend all system devices.
- *     @state:         Power state to enter.
- *
- *     We perform an almost identical operation as sysdev_shutdown()
- *     above, though calling ->suspend() instead. Interrupts are disabled
- *     when this called. Devices are responsible for both saving state and
- *     quiescing or powering down the device.
- *
- *     This is only called by the device PM core, so we let them handle
- *     all synchronization.
- */
-int sysdev_suspend(pm_message_t state)
-{
-       struct sysdev_class *cls;
-       struct sys_device *sysdev, *err_dev;
-       struct sysdev_driver *drv, *err_drv;
-       int ret;
-
-       pr_debug("Checking wake-up interrupts\n");
-
-       /* Return error code if there are any wake-up interrupts pending */
-       ret = check_wakeup_irqs();
-       if (ret)
-               return ret;
-
-       WARN_ONCE(!irqs_disabled(),
-               "Interrupts enabled while suspending system devices\n");
-
-       pr_debug("Suspending System Devices\n");
-
-       list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
-               pr_debug("Suspending type '%s':\n",
-                        kobject_name(&cls->kset.kobj));
-
-               list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-                       pr_debug(" %s\n", kobject_name(&sysdev->kobj));
-
-                       /* Call auxiliary drivers first */
-                       list_for_each_entry(drv, &cls->drivers, entry) {
-                               if (drv->suspend) {
-                                       ret = drv->suspend(sysdev, state);
-                                       if (ret)
-                                               goto aux_driver;
-                               }
-                               WARN_ONCE(!irqs_disabled(),
-                                       "Interrupts enabled after %pF\n",
-                                       drv->suspend);
-                       }
-
-                       /* Now call the generic one */
-                       if (cls->suspend) {
-                               ret = cls->suspend(sysdev, state);
-                               if (ret)
-                                       goto cls_driver;
-                               WARN_ONCE(!irqs_disabled(),
-                                       "Interrupts enabled after %pF\n",
-                                       cls->suspend);
-                       }
-               }
-       }
-       return 0;
-       /* resume current sysdev */
-cls_driver:
-       drv = NULL;
-       printk(KERN_ERR "Class suspend failed for %s: %d\n",
-               kobject_name(&sysdev->kobj), ret);
-
-aux_driver:
-       if (drv)
-               printk(KERN_ERR "Class driver suspend failed for %s: %d\n",
-                               kobject_name(&sysdev->kobj), ret);
-       list_for_each_entry(err_drv, &cls->drivers, entry) {
-               if (err_drv == drv)
-                       break;
-               if (err_drv->resume)
-                       err_drv->resume(sysdev);
-       }
-
-       /* resume other sysdevs in current class */
-       list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
-               if (err_dev == sysdev)
-                       break;
-               pr_debug(" %s\n", kobject_name(&err_dev->kobj));
-               __sysdev_resume(err_dev);
-       }
-
-       /* resume other classes */
-       list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) {
-               list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
-                       pr_debug(" %s\n", kobject_name(&err_dev->kobj));
-                       __sysdev_resume(err_dev);
-               }
-       }
-       return ret;
-}
-EXPORT_SYMBOL_GPL(sysdev_suspend);
-
-/**
- *     sysdev_resume - Bring system devices back to life.
- *
- *     Similar to sysdev_suspend(), but we iterate the list forwards
- *     to guarantee that parent devices are resumed before their children.
- *
- *     Note: Interrupts are disabled when called.
- */
-int sysdev_resume(void)
-{
-       struct sysdev_class *cls;
-
-       WARN_ONCE(!irqs_disabled(),
-               "Interrupts enabled while resuming system devices\n");
-
-       pr_debug("Resuming System Devices\n");
-
-       list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
-               struct sys_device *sysdev;
-
-               pr_debug("Resuming type '%s':\n",
-                        kobject_name(&cls->kset.kobj));
-
-               list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-                       pr_debug(" %s\n", kobject_name(&sysdev->kobj));
-
-                       __sysdev_resume(sysdev);
-               }
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(sysdev_resume);
-#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */
+EXPORT_SYMBOL_GPL(sysdev_register);
+EXPORT_SYMBOL_GPL(sysdev_unregister);
 
 int __init system_bus_init(void)
 {
@@ -534,9 +339,6 @@ int __init system_bus_init(void)
        return 0;
 }
 
-EXPORT_SYMBOL_GPL(sysdev_register);
-EXPORT_SYMBOL_GPL(sysdev_unregister);
-
 #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
 
 ssize_t sysdev_store_ulong(struct sys_device *sysdev,
index a2eee57..0b5366b 100644 (file)
@@ -70,12 +70,7 @@ static int xen_suspend(void *data)
 
        BUG_ON(!irqs_disabled());
 
-       err = sysdev_suspend(PMSG_FREEZE);
-       if (!err) {
-               err = syscore_suspend();
-               if (err)
-                       sysdev_resume();
-       }
+       err = syscore_suspend();
        if (err) {
                printk(KERN_ERR "xen_suspend: system core suspend failed: %d\n",
                        err);
@@ -102,7 +97,6 @@ static int xen_suspend(void *data)
        }
 
        syscore_resume();
-       sysdev_resume();
 
        return 0;
 }
index d08399d..0d75350 100644 (file)
@@ -632,13 +632,6 @@ static inline int devtmpfs_mount(const char *mountpoint) { return 0; }
 /* drivers/base/power/shutdown.c */
 extern void device_shutdown(void);
 
-#ifndef CONFIG_ARCH_NO_SYSDEV_OPS
-/* drivers/base/sys.c */
-extern void sysdev_shutdown(void);
-#else
-static inline void sysdev_shutdown(void) { }
-#endif
-
 /* debugging and troubleshooting/diagnostic helpers. */
 extern const char *dev_driver_string(const struct device *dev);
 
index 6efd7a7..3102318 100644 (file)
@@ -113,5 +113,6 @@ extern void usermodehelper_init(void);
 
 extern int usermodehelper_disable(void);
 extern void usermodehelper_enable(void);
+extern bool usermodehelper_is_disabled(void);
 
 #endif /* __LINUX_KMOD_H__ */
index 744942c..ede1a80 100644 (file)
@@ -150,9 +150,6 @@ extern struct platform_device *platform_create_bundle(struct platform_driver *dr
                                        struct resource *res, unsigned int n_res,
                                        const void *data, size_t size);
 
-extern const struct dev_pm_ops * platform_bus_get_pm_ops(void);
-extern void platform_bus_set_pm_ops(const struct dev_pm_ops *pm);
-
 /* early platform driver interface */
 struct early_platform_driver {
        const char *class_str;
@@ -205,4 +202,64 @@ static inline char *early_platform_driver_setup_func(void)         \
 }
 #endif /* MODULE */
 
+#ifdef CONFIG_PM_SLEEP
+extern int platform_pm_prepare(struct device *dev);
+extern void platform_pm_complete(struct device *dev);
+#else
+#define platform_pm_prepare    NULL
+#define platform_pm_complete   NULL
+#endif
+
+#ifdef CONFIG_SUSPEND
+extern int platform_pm_suspend(struct device *dev);
+extern int platform_pm_suspend_noirq(struct device *dev);
+extern int platform_pm_resume(struct device *dev);
+extern int platform_pm_resume_noirq(struct device *dev);
+#else
+#define platform_pm_suspend            NULL
+#define platform_pm_resume             NULL
+#define platform_pm_suspend_noirq      NULL
+#define platform_pm_resume_noirq       NULL
+#endif
+
+#ifdef CONFIG_HIBERNATE_CALLBACKS
+extern int platform_pm_freeze(struct device *dev);
+extern int platform_pm_freeze_noirq(struct device *dev);
+extern int platform_pm_thaw(struct device *dev);
+extern int platform_pm_thaw_noirq(struct device *dev);
+extern int platform_pm_poweroff(struct device *dev);
+extern int platform_pm_poweroff_noirq(struct device *dev);
+extern int platform_pm_restore(struct device *dev);
+extern int platform_pm_restore_noirq(struct device *dev);
+#else
+#define platform_pm_freeze             NULL
+#define platform_pm_thaw               NULL
+#define platform_pm_poweroff           NULL
+#define platform_pm_restore            NULL
+#define platform_pm_freeze_noirq       NULL
+#define platform_pm_thaw_noirq         NULL
+#define platform_pm_poweroff_noirq     NULL
+#define platform_pm_restore_noirq      NULL
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+#define USE_PLATFORM_PM_SLEEP_OPS \
+       .prepare = platform_pm_prepare, \
+       .complete = platform_pm_complete, \
+       .suspend = platform_pm_suspend, \
+       .resume = platform_pm_resume, \
+       .freeze = platform_pm_freeze, \
+       .thaw = platform_pm_thaw, \
+       .poweroff = platform_pm_poweroff, \
+       .restore = platform_pm_restore, \
+       .suspend_noirq = platform_pm_suspend_noirq, \
+       .resume_noirq = platform_pm_resume_noirq, \
+       .freeze_noirq = platform_pm_freeze_noirq, \
+       .thaw_noirq = platform_pm_thaw_noirq, \
+       .poweroff_noirq = platform_pm_poweroff_noirq, \
+       .restore_noirq = platform_pm_restore_noirq,
+#else
+#define USE_PLATFORM_PM_SLEEP_OPS
+#endif
+
 #endif /* _PLATFORM_DEVICE_H_ */
index 512e091..3160648 100644 (file)
@@ -460,6 +460,7 @@ struct dev_pm_info {
        unsigned long           active_jiffies;
        unsigned long           suspended_jiffies;
        unsigned long           accounting_timestamp;
+       void                    *subsys_data;  /* Owned by the subsystem. */
 #endif
 };
 
@@ -529,21 +530,17 @@ struct dev_power_domain {
  */
 
 #ifdef CONFIG_PM_SLEEP
-#ifndef CONFIG_ARCH_NO_SYSDEV_OPS
-extern int sysdev_suspend(pm_message_t state);
-extern int sysdev_resume(void);
-#else
-static inline int sysdev_suspend(pm_message_t state) { return 0; }
-static inline int sysdev_resume(void) { return 0; }
-#endif
-
 extern void device_pm_lock(void);
 extern void dpm_resume_noirq(pm_message_t state);
 extern void dpm_resume_end(pm_message_t state);
+extern void dpm_resume(pm_message_t state);
+extern void dpm_complete(pm_message_t state);
 
 extern void device_pm_unlock(void);
 extern int dpm_suspend_noirq(pm_message_t state);
 extern int dpm_suspend_start(pm_message_t state);
+extern int dpm_suspend(pm_message_t state);
+extern int dpm_prepare(pm_message_t state);
 
 extern void __suspend_report_result(const char *function, void *fn, int ret);
 
@@ -553,6 +550,16 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
        } while (0)
 
 extern int device_pm_wait_for_dev(struct device *sub, struct device *dev);
+
+extern int pm_generic_prepare(struct device *dev);
+extern int pm_generic_suspend(struct device *dev);
+extern int pm_generic_resume(struct device *dev);
+extern int pm_generic_freeze(struct device *dev);
+extern int pm_generic_thaw(struct device *dev);
+extern int pm_generic_restore(struct device *dev);
+extern int pm_generic_poweroff(struct device *dev);
+extern void pm_generic_complete(struct device *dev);
+
 #else /* !CONFIG_PM_SLEEP */
 
 #define device_pm_lock() do {} while (0)
@@ -569,6 +576,15 @@ static inline int device_pm_wait_for_dev(struct device *a, struct device *b)
 {
        return 0;
 }
+
+#define pm_generic_prepare     NULL
+#define pm_generic_suspend     NULL
+#define pm_generic_resume      NULL
+#define pm_generic_freeze      NULL
+#define pm_generic_thaw                NULL
+#define pm_generic_restore     NULL
+#define pm_generic_poweroff    NULL
+#define pm_generic_complete    NULL
 #endif /* !CONFIG_PM_SLEEP */
 
 /* How to reorder dpm_list after device_move() */
@@ -579,11 +595,4 @@ enum dpm_order {
        DPM_ORDER_DEV_LAST,
 };
 
-extern int pm_generic_suspend(struct device *dev);
-extern int pm_generic_resume(struct device *dev);
-extern int pm_generic_freeze(struct device *dev);
-extern int pm_generic_thaw(struct device *dev);
-extern int pm_generic_restore(struct device *dev);
-extern int pm_generic_poweroff(struct device *dev);
-
 #endif /* _LINUX_PM_H */
index 8de9aa6..878cf84 100644 (file)
@@ -245,4 +245,46 @@ static inline void pm_runtime_dont_use_autosuspend(struct device *dev)
        __pm_runtime_use_autosuspend(dev, false);
 }
 
+struct pm_clk_notifier_block {
+       struct notifier_block nb;
+       struct dev_power_domain *pwr_domain;
+       char *con_ids[];
+};
+
+#ifdef CONFIG_PM_RUNTIME_CLK
+extern int pm_runtime_clk_init(struct device *dev);
+extern void pm_runtime_clk_destroy(struct device *dev);
+extern int pm_runtime_clk_add(struct device *dev, const char *con_id);
+extern void pm_runtime_clk_remove(struct device *dev, const char *con_id);
+extern int pm_runtime_clk_suspend(struct device *dev);
+extern int pm_runtime_clk_resume(struct device *dev);
+#else
+static inline int pm_runtime_clk_init(struct device *dev)
+{
+       return -EINVAL;
+}
+static inline void pm_runtime_clk_destroy(struct device *dev)
+{
+}
+static inline int pm_runtime_clk_add(struct device *dev, const char *con_id)
+{
+       return -EINVAL;
+}
+static inline void pm_runtime_clk_remove(struct device *dev, const char *con_id)
+{
+}
+#define pm_runtime_clock_suspend       NULL
+#define pm_runtime_clock_resume                NULL
+#endif
+
+#ifdef CONFIG_HAVE_CLK
+extern void pm_runtime_clk_add_notifier(struct bus_type *bus,
+                                       struct pm_clk_notifier_block *clknb);
+#else
+static inline void pm_runtime_clk_add_notifier(struct bus_type *bus,
+                                       struct pm_clk_notifier_block *clknb)
+{
+}
+#endif
+
 #endif
index dfb078d..d35e783 100644 (file)
@@ -34,12 +34,6 @@ struct sysdev_class {
        struct list_head        drivers;
        struct sysdev_class_attribute **attrs;
        struct kset             kset;
-#ifndef CONFIG_ARCH_NO_SYSDEV_OPS
-       /* Default operations for these types of devices */
-       int     (*shutdown)(struct sys_device *);
-       int     (*suspend)(struct sys_device *, pm_message_t state);
-       int     (*resume)(struct sys_device *);
-#endif
 };
 
 struct sysdev_class_attribute {
@@ -77,11 +71,6 @@ struct sysdev_driver {
        struct list_head        entry;
        int     (*add)(struct sys_device *);
        int     (*remove)(struct sys_device *);
-#ifndef CONFIG_ARCH_NO_SYSDEV_OPS
-       int     (*shutdown)(struct sys_device *);
-       int     (*suspend)(struct sys_device *, pm_message_t state);
-       int     (*resume)(struct sys_device *);
-#endif
 };
 
 
index 66ecd2e..7b01de9 100644 (file)
@@ -17,7 +17,7 @@ static inline void frozen_process(void)
 {
        if (!unlikely(current->flags & PF_NOFREEZE)) {
                current->flags |= PF_FROZEN;
-               wmb();
+               smp_wmb();
        }
        clear_freeze_flag(current);
 }
@@ -93,7 +93,7 @@ bool freeze_task(struct task_struct *p, bool sig_only)
         * the task as frozen and next clears its TIF_FREEZE.
         */
        if (!freezing(p)) {
-               rmb();
+               smp_rmb();
                if (frozen(p))
                        return false;
 
index 87b77de..8d814cb 100644 (file)
@@ -1531,13 +1531,7 @@ int kernel_kexec(void)
                if (error)
                        goto Enable_cpus;
                local_irq_disable();
-               /* Suspend system devices */
-               error = sysdev_suspend(PMSG_FREEZE);
-               if (!error) {
-                       error = syscore_suspend();
-                       if (error)
-                               sysdev_resume();
-               }
+               error = syscore_suspend();
                if (error)
                        goto Enable_irqs;
        } else
@@ -1553,7 +1547,6 @@ int kernel_kexec(void)
 #ifdef CONFIG_KEXEC_JUMP
        if (kexec_image->preserve_context) {
                syscore_resume();
-               sysdev_resume();
  Enable_irqs:
                local_irq_enable();
  Enable_cpus:
index 9cd0591..5ae0ff3 100644 (file)
@@ -245,7 +245,6 @@ static void __call_usermodehelper(struct work_struct *work)
        }
 }
 
-#ifdef CONFIG_PM_SLEEP
 /*
  * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY
  * (used for preventing user land processes from being created after the user
@@ -301,6 +300,15 @@ void usermodehelper_enable(void)
        usermodehelper_disabled = 0;
 }
 
+/**
+ * usermodehelper_is_disabled - check if new helpers are allowed to be started
+ */
+bool usermodehelper_is_disabled(void)
+{
+       return usermodehelper_disabled;
+}
+EXPORT_SYMBOL_GPL(usermodehelper_is_disabled);
+
 static void helper_lock(void)
 {
        atomic_inc(&running_helpers);
@@ -312,12 +320,6 @@ static void helper_unlock(void)
        if (atomic_dec_and_test(&running_helpers))
                wake_up(&running_helpers_waitq);
 }
-#else /* CONFIG_PM_SLEEP */
-#define usermodehelper_disabled        0
-
-static inline void helper_lock(void) {}
-static inline void helper_unlock(void) {}
-#endif /* CONFIG_PM_SLEEP */
 
 /**
  * call_usermodehelper_setup - prepare to call a usermode helper
index 6de9a8f..87f4d24 100644 (file)
@@ -125,12 +125,6 @@ config PM_DEBUG
        code. This is helpful when debugging and reporting PM bugs, like
        suspend support.
 
-config PM_VERBOSE
-       bool "Verbose Power Management debugging"
-       depends on PM_DEBUG
-       ---help---
-       This option enables verbose messages from the Power Management code.
-
 config PM_ADVANCED_DEBUG
        bool "Extra PM attributes in sysfs for low-level debugging/testing"
        depends on PM_DEBUG
@@ -229,3 +223,7 @@ config PM_OPP
          representing individual voltage domains and provides SOC
          implementations a ready to use framework to manage OPPs.
          For more information, read <file:Documentation/power/opp.txt>
+
+config PM_RUNTIME_CLK
+       def_bool y
+       depends on PM_RUNTIME && HAVE_CLK
index 50aae66..f9bec56 100644 (file)
@@ -272,12 +272,7 @@ static int create_image(int platform_mode)
 
        local_irq_disable();
 
-       error = sysdev_suspend(PMSG_FREEZE);
-       if (!error) {
-               error = syscore_suspend();
-               if (error)
-                       sysdev_resume();
-       }
+       error = syscore_suspend();
        if (error) {
                printk(KERN_ERR "PM: Some system devices failed to power down, "
                        "aborting hibernation\n");
@@ -302,7 +297,6 @@ static int create_image(int platform_mode)
 
  Power_up:
        syscore_resume();
-       sysdev_resume();
        /* NOTE:  dpm_resume_noirq() is just a resume() for devices
         * that suspended with irqs off ... no overall powerup.
         */
@@ -333,20 +327,25 @@ static int create_image(int platform_mode)
 
 int hibernation_snapshot(int platform_mode)
 {
+       pm_message_t msg = PMSG_RECOVER;
        int error;
 
        error = platform_begin(platform_mode);
        if (error)
                goto Close;
 
+       error = dpm_prepare(PMSG_FREEZE);
+       if (error)
+               goto Complete_devices;
+
        /* Preallocate image memory before shutting down devices. */
        error = hibernate_preallocate_memory();
        if (error)
-               goto Close;
+               goto Complete_devices;
 
        suspend_console();
        pm_restrict_gfp_mask();
-       error = dpm_suspend_start(PMSG_FREEZE);
+       error = dpm_suspend(PMSG_FREEZE);
        if (error)
                goto Recover_platform;
 
@@ -364,13 +363,17 @@ int hibernation_snapshot(int platform_mode)
        if (error || !in_suspend)
                swsusp_free();
 
-       dpm_resume_end(in_suspend ?
-               (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
+       msg = in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE;
+       dpm_resume(msg);
 
        if (error || !in_suspend)
                pm_restore_gfp_mask();
 
        resume_console();
+
+ Complete_devices:
+       dpm_complete(msg);
+
  Close:
        platform_end(platform_mode);
        return error;
@@ -409,12 +412,7 @@ static int resume_target_kernel(bool platform_mode)
 
        local_irq_disable();
 
-       error = sysdev_suspend(PMSG_QUIESCE);
-       if (!error) {
-               error = syscore_suspend();
-               if (error)
-                       sysdev_resume();
-       }
+       error = syscore_suspend();
        if (error)
                goto Enable_irqs;
 
@@ -442,7 +440,6 @@ static int resume_target_kernel(bool platform_mode)
        touch_softlockup_watchdog();
 
        syscore_resume();
-       sysdev_resume();
 
  Enable_irqs:
        local_irq_enable();
@@ -528,7 +525,6 @@ int hibernation_platform_enter(void)
                goto Platform_finish;
 
        local_irq_disable();
-       sysdev_suspend(PMSG_HIBERNATE);
        syscore_suspend();
        if (pm_wakeup_pending()) {
                error = -EAGAIN;
@@ -541,7 +537,6 @@ int hibernation_platform_enter(void)
 
  Power_up:
        syscore_resume();
-       sysdev_resume();
        local_irq_enable();
        enable_nonboot_cpus();
 
@@ -982,10 +977,33 @@ static ssize_t image_size_store(struct kobject *kobj, struct kobj_attribute *att
 
 power_attr(image_size);
 
+static ssize_t reserved_size_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%lu\n", reserved_size);
+}
+
+static ssize_t reserved_size_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned long size;
+
+       if (sscanf(buf, "%lu", &size) == 1) {
+               reserved_size = size;
+               return n;
+       }
+
+       return -EINVAL;
+}
+
+power_attr(reserved_size);
+
 static struct attribute * g[] = {
        &disk_attr.attr,
        &resume_attr.attr,
        &image_size_attr.attr,
+       &reserved_size_attr.attr,
        NULL,
 };
 
index de9aef8..2981af4 100644 (file)
@@ -337,6 +337,7 @@ static int __init pm_init(void)
        if (error)
                return error;
        hibernate_image_size_init();
+       hibernate_reserved_size_init();
        power_kobj = kobject_create_and_add("power", NULL);
        if (!power_kobj)
                return -ENOMEM;
index 03634be..9a00a0a 100644 (file)
@@ -15,6 +15,7 @@ struct swsusp_info {
 
 #ifdef CONFIG_HIBERNATION
 /* kernel/power/snapshot.c */
+extern void __init hibernate_reserved_size_init(void);
 extern void __init hibernate_image_size_init(void);
 
 #ifdef CONFIG_ARCH_HIBERNATION_HEADER
@@ -55,6 +56,7 @@ extern int hibernation_platform_enter(void);
 
 #else /* !CONFIG_HIBERNATION */
 
+static inline void hibernate_reserved_size_init(void) {}
 static inline void hibernate_image_size_init(void) {}
 #endif /* !CONFIG_HIBERNATION */
 
@@ -72,6 +74,8 @@ static struct kobj_attribute _name##_attr = { \
 
 /* Preferred image size in bytes (default 500 MB) */
 extern unsigned long image_size;
+/* Size of memory reserved for drivers (default SPARE_PAGES x PAGE_SIZE) */
+extern unsigned long reserved_size;
 extern int in_suspend;
 extern dev_t swsusp_resume_device;
 extern sector_t swsusp_resume_block;
index ca0aacc..ace5588 100644 (file)
@@ -40,17 +40,29 @@ static int swsusp_page_is_free(struct page *);
 static void swsusp_set_page_forbidden(struct page *);
 static void swsusp_unset_page_forbidden(struct page *);
 
+/*
+ * Number of bytes to reserve for memory allocations made by device drivers
+ * from their ->freeze() and ->freeze_noirq() callbacks so that they don't
+ * cause image creation to fail (tunable via /sys/power/reserved_size).
+ */
+unsigned long reserved_size;
+
+void __init hibernate_reserved_size_init(void)
+{
+       reserved_size = SPARE_PAGES * PAGE_SIZE;
+}
+
 /*
  * Preferred image size in bytes (tunable via /sys/power/image_size).
- * When it is set to N, the image creating code will do its best to
- * ensure the image size will not exceed N bytes, but if that is
- * impossible, it will try to create the smallest image possible.
+ * When it is set to N, swsusp will do its best to ensure the image
+ * size will not exceed N bytes, but if that is impossible, it will
+ * try to create the smallest image possible.
  */
 unsigned long image_size;
 
 void __init hibernate_image_size_init(void)
 {
-       image_size = (totalram_pages / 3) * PAGE_SIZE;
+       image_size = ((totalram_pages * 2) / 5) * PAGE_SIZE;
 }
 
 /* List of PBEs needed for restoring the pages that were allocated before
@@ -1263,11 +1275,13 @@ static unsigned long minimum_image_size(unsigned long saveable)
  * frame in use.  We also need a number of page frames to be free during
  * hibernation for allocations made while saving the image and for device
  * drivers, in case they need to allocate memory from their hibernation
- * callbacks (these two numbers are given by PAGES_FOR_IO and SPARE_PAGES,
- * respectively, both of which are rough estimates).  To make this happen, we
- * compute the total number of available page frames and allocate at least
+ * callbacks (these two numbers are given by PAGES_FOR_IO (which is a rough
+ * estimate) and reserverd_size divided by PAGE_SIZE (which is tunable through
+ * /sys/power/reserved_size, respectively).  To make this happen, we compute the
+ * total number of available page frames and allocate at least
  *
- * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2 + 2 * SPARE_PAGES
+ * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2
+ *  + 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
  *
  * of them, which corresponds to the maximum size of a hibernation image.
  *
@@ -1322,7 +1336,8 @@ int hibernate_preallocate_memory(void)
        count -= totalreserve_pages;
 
        /* Compute the maximum number of saveable pages to leave in memory. */
-       max_size = (count - (size + PAGES_FOR_IO)) / 2 - 2 * SPARE_PAGES;
+       max_size = (count - (size + PAGES_FOR_IO)) / 2
+                       - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE);
        /* Compute the desired number of image pages specified by image_size. */
        size = DIV_ROUND_UP(image_size, PAGE_SIZE);
        if (size > max_size)
index 6275970..1c41ba2 100644 (file)
@@ -163,19 +163,13 @@ static int suspend_enter(suspend_state_t state)
        arch_suspend_disable_irqs();
        BUG_ON(!irqs_disabled());
 
-       error = sysdev_suspend(PMSG_SUSPEND);
-       if (!error) {
-               error = syscore_suspend();
-               if (error)
-                       sysdev_resume();
-       }
+       error = syscore_suspend();
        if (!error) {
                if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) {
                        error = suspend_ops->enter(state);
                        events_check_enabled = false;
                }
                syscore_resume();
-               sysdev_resume();
        }
 
        arch_suspend_enable_irqs();
@@ -226,7 +220,7 @@ int suspend_devices_and_enter(suspend_state_t state)
        if (suspend_test(TEST_DEVICES))
                goto Recover_platform;
 
-       suspend_enter(state);
+       error = suspend_enter(state);
 
  Resume_devices:
        suspend_test_start();
index af468ed..f0c1038 100644 (file)
@@ -315,7 +315,6 @@ void kernel_restart_prepare(char *cmd)
        blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
        system_state = SYSTEM_RESTART;
        device_shutdown();
-       sysdev_shutdown();
        syscore_shutdown();
 }
 
@@ -354,7 +353,6 @@ static void kernel_shutdown_prepare(enum system_states state)
 void kernel_halt(void)
 {
        kernel_shutdown_prepare(SYSTEM_HALT);
-       sysdev_shutdown();
        syscore_shutdown();
        printk(KERN_EMERG "System halted.\n");
        kmsg_dump(KMSG_DUMP_HALT);
@@ -374,7 +372,6 @@ void kernel_power_off(void)
        if (pm_power_off_prepare)
                pm_power_off_prepare();
        disable_nonboot_cpus();
-       sysdev_shutdown();
        syscore_shutdown();
        printk(KERN_EMERG "Power down.\n");
        kmsg_dump(KMSG_DUMP_POWEROFF);