]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/base/platform.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[karo-tx-linux.git] / drivers / base / platform.c
index 456594bd97bc5f13f9189854a73b84dfef157bd8..4fa954b07ac4ada384d27ffba6b293c22651febd 100644 (file)
@@ -10,6 +10,7 @@
  * information.
  */
 
+#include <linux/string.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -17,6 +18,7 @@
 #include <linux/bootmem.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
 #include "base.h"
 
@@ -212,14 +214,13 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
 int platform_device_add_data(struct platform_device *pdev, const void *data,
                             size_t size)
 {
-       void *d;
+       void *d = kmemdup(data, size, GFP_KERNEL);
 
-       d = kmalloc(size, GFP_KERNEL);
        if (d) {
-               memcpy(d, data, size);
                pdev->dev.platform_data = d;
+               return 0;
        }
-       return d ? 0 : -ENOMEM;
+       return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(platform_device_add_data);
 
@@ -520,11 +521,15 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv,
 {
        int retval, code;
 
+       /* make sure driver won't have bind/unbind attributes */
+       drv->driver.suppress_bind_attrs = true;
+
        /* temporary section violation during probe() */
        drv->probe = probe;
        retval = code = platform_driver_register(drv);
 
-       /* Fixup that section violation, being paranoid about code scanning
+       /*
+        * Fixup that section violation, being paranoid about code scanning
         * the list of drivers in order to probe new devices.  Check to see
         * if the probe was successful, and make sure any forced probes of
         * new devices fail.
@@ -625,30 +630,6 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
        return ret;
 }
 
-static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
-{
-       struct platform_driver *pdrv = to_platform_driver(dev->driver);
-       struct platform_device *pdev = to_platform_device(dev);
-       int ret = 0;
-
-       if (dev->driver && pdrv->suspend_late)
-               ret = pdrv->suspend_late(pdev, mesg);
-
-       return ret;
-}
-
-static int platform_legacy_resume_early(struct device *dev)
-{
-       struct platform_driver *pdrv = to_platform_driver(dev->driver);
-       struct platform_device *pdev = to_platform_device(dev);
-       int ret = 0;
-
-       if (dev->driver && pdrv->resume_early)
-               ret = pdrv->resume_early(pdev);
-
-       return ret;
-}
-
 static int platform_legacy_resume(struct device *dev)
 {
        struct platform_driver *pdrv = to_platform_driver(dev->driver);
@@ -680,6 +661,13 @@ 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 */
+
 #ifdef CONFIG_SUSPEND
 
 static int platform_pm_suspend(struct device *dev)
@@ -711,8 +699,6 @@ static int platform_pm_suspend_noirq(struct device *dev)
        if (drv->pm) {
                if (drv->pm->suspend_noirq)
                        ret = drv->pm->suspend_noirq(dev);
-       } else {
-               ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND);
        }
 
        return ret;
@@ -747,8 +733,6 @@ static int platform_pm_resume_noirq(struct device *dev)
        if (drv->pm) {
                if (drv->pm->resume_noirq)
                        ret = drv->pm->resume_noirq(dev);
-       } else {
-               ret = platform_legacy_resume_early(dev);
        }
 
        return ret;
@@ -794,8 +778,6 @@ static int platform_pm_freeze_noirq(struct device *dev)
        if (drv->pm) {
                if (drv->pm->freeze_noirq)
                        ret = drv->pm->freeze_noirq(dev);
-       } else {
-               ret = platform_legacy_suspend_late(dev, PMSG_FREEZE);
        }
 
        return ret;
@@ -830,8 +812,6 @@ static int platform_pm_thaw_noirq(struct device *dev)
        if (drv->pm) {
                if (drv->pm->thaw_noirq)
                        ret = drv->pm->thaw_noirq(dev);
-       } else {
-               ret = platform_legacy_resume_early(dev);
        }
 
        return ret;
@@ -866,8 +846,6 @@ static int platform_pm_poweroff_noirq(struct device *dev)
        if (drv->pm) {
                if (drv->pm->poweroff_noirq)
                        ret = drv->pm->poweroff_noirq(dev);
-       } else {
-               ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE);
        }
 
        return ret;
@@ -902,8 +880,6 @@ static int platform_pm_restore_noirq(struct device *dev)
        if (drv->pm) {
                if (drv->pm->restore_noirq)
                        ret = drv->pm->restore_noirq(dev);
-       } else {
-               ret = platform_legacy_resume_early(dev);
        }
 
        return ret;
@@ -922,7 +898,32 @@ static int platform_pm_restore_noirq(struct device *dev)
 
 #endif /* !CONFIG_HIBERNATION */
 
-static struct dev_pm_ops platform_dev_pm_ops = {
+#ifdef CONFIG_PM_RUNTIME
+
+int __weak platform_pm_runtime_suspend(struct device *dev)
+{
+       return -ENOSYS;
+};
+
+int __weak platform_pm_runtime_resume(struct device *dev)
+{
+       return -ENOSYS;
+};
+
+int __weak platform_pm_runtime_idle(struct device *dev)
+{
+       return -ENOSYS;
+};
+
+#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 */
+
+static const struct dev_pm_ops platform_dev_pm_ops = {
        .prepare = platform_pm_prepare,
        .complete = platform_pm_complete,
        .suspend = platform_pm_suspend,
@@ -937,22 +938,17 @@ static struct dev_pm_ops platform_dev_pm_ops = {
        .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,
 };
 
-#define PLATFORM_PM_OPS_PTR    (&platform_dev_pm_ops)
-
-#else /* !CONFIG_PM_SLEEP */
-
-#define PLATFORM_PM_OPS_PTR    NULL
-
-#endif /* !CONFIG_PM_SLEEP */
-
 struct bus_type platform_bus_type = {
        .name           = "platform",
        .dev_attrs      = platform_dev_attrs,
        .match          = platform_match,
        .uevent         = platform_uevent,
-       .pm             = PLATFORM_PM_OPS_PTR,
+       .pm             = &platform_dev_pm_ops,
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);