Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[firefly-linux-kernel-4.4.55.git] / drivers / base / platform.c
index dfcbfe504867e9db43ea944c55cda9eae9328556..d2198f64ad4e3d8acccf61599b32fa620b916175 100644 (file)
@@ -24,7 +24,7 @@
                                 driver))
 
 struct device platform_bus = {
-       .bus_id         = "platform",
+       .init_name      = "platform",
 };
 EXPORT_SYMBOL_GPL(platform_bus);
 
@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
        if (d) {
                memcpy(d, data, size);
                pdev->dev.platform_data = d;
+               pdev->platform_data = d;
        }
        return d ? 0 : -ENOMEM;
 }
@@ -242,16 +243,30 @@ int platform_device_add(struct platform_device *pdev)
        pdev->dev.bus = &platform_bus_type;
 
        if (pdev->id != -1)
-               snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,
-                        pdev->id);
+               dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
        else
-               strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
+               dev_set_name(&pdev->dev, pdev->name);
+
+       /* We will remove platform_data field from struct device
+       * if all platform devices pass its platform specific data
+       * from platform_device. The conversion is going to be a
+       * long time, so we allow the two cases coexist to make
+       * this kind of fix more easily*/
+       if (pdev->platform_data && pdev->dev.platform_data) {
+               printk(KERN_ERR
+                              "%s: use which platform_data?\n",
+                              dev_name(&pdev->dev));
+       } else if (pdev->platform_data) {
+               pdev->dev.platform_data = pdev->platform_data;
+       } else if (pdev->dev.platform_data) {
+               pdev->platform_data = pdev->dev.platform_data;
+       }
 
        for (i = 0; i < pdev->num_resources; i++) {
                struct resource *p, *r = &pdev->resource[i];
 
                if (r->name == NULL)
-                       r->name = pdev->dev.bus_id;
+                       r->name = dev_name(&pdev->dev);
 
                p = r->parent;
                if (!p) {
@@ -264,14 +279,14 @@ int platform_device_add(struct platform_device *pdev)
                if (p && insert_resource(p, r)) {
                        printk(KERN_ERR
                               "%s: failed to claim resource %d\n",
-                              pdev->dev.bus_id, i);
+                              dev_name(&pdev->dev), i);
                        ret = -EBUSY;
                        goto failed;
                }
        }
 
        pr_debug("Registering platform device '%s'. Parent at %s\n",
-                pdev->dev.bus_id, pdev->dev.parent->bus_id);
+                dev_name(&pdev->dev), dev_name(pdev->dev.parent));
 
        ret = device_add(&pdev->dev);
        if (ret == 0)
@@ -503,8 +518,6 @@ int platform_driver_register(struct platform_driver *drv)
                drv->driver.suspend = platform_drv_suspend;
        if (drv->resume)
                drv->driver.resume = platform_drv_resume;
-       if (drv->pm)
-               drv->driver.pm = &drv->pm->base;
        return driver_register(&drv->driver);
 }
 EXPORT_SYMBOL_GPL(platform_driver_register);
@@ -587,10 +600,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        struct platform_device  *pdev = to_platform_device(dev);
 
-       add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+       add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+               (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
        return 0;
 }
 
+static const struct platform_device_id *platform_match_id(
+                       struct platform_device_id *id,
+                       struct platform_device *pdev)
+{
+       while (id->name[0]) {
+               if (strcmp(pdev->name, id->name) == 0) {
+                       pdev->id_entry = id;
+                       return id;
+               }
+               id++;
+       }
+       return NULL;
+}
+
 /**
  * platform_match - bind platform device to platform driver.
  * @dev: device.
@@ -606,10 +634,15 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
  */
 static int platform_match(struct device *dev, struct device_driver *drv)
 {
-       struct platform_device *pdev;
+       struct platform_device *pdev = to_platform_device(dev);
+       struct platform_driver *pdrv = to_platform_driver(drv);
+
+       /* match against the id table first */
+       if (pdrv->id_table)
+               return platform_match_id(pdrv->id_table, pdev) != NULL;
 
-       pdev = container_of(dev, struct platform_device, dev);
-       return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
+       /* fall-back to driver name match */
+       return (strcmp(pdev->name, drv->name) == 0);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -626,26 +659,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
 
 static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
 {
-       struct platform_driver *drv = to_platform_driver(dev->driver);
-       struct platform_device *pdev;
+       struct platform_driver *pdrv = to_platform_driver(dev->driver);
+       struct platform_device *pdev = to_platform_device(dev);
        int ret = 0;
 
-       pdev = container_of(dev, struct platform_device, dev);
-       if (dev->driver && drv->suspend_late)
-               ret = drv->suspend_late(pdev, mesg);
+       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 *drv = to_platform_driver(dev->driver);
-       struct platform_device *pdev;
+       struct platform_driver *pdrv = to_platform_driver(dev->driver);
+       struct platform_device *pdev = to_platform_device(dev);
        int ret = 0;
 
-       pdev = container_of(dev, struct platform_device, dev);
-       if (dev->driver && drv->resume_early)
-               ret = drv->resume_early(pdev);
+       if (dev->driver && pdrv->resume_early)
+               ret = pdrv->resume_early(pdev);
 
        return ret;
 }
@@ -686,7 +717,10 @@ static int platform_pm_suspend(struct device *dev)
        struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (drv && drv->pm) {
+       if (!drv)
+               return 0;
+
+       if (drv->pm) {
                if (drv->pm->suspend)
                        ret = drv->pm->suspend(dev);
        } else {
@@ -698,16 +732,15 @@ static int platform_pm_suspend(struct device *dev)
 
 static int platform_pm_suspend_noirq(struct device *dev)
 {
-       struct platform_driver *pdrv;
+       struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (!dev->driver)
+       if (!drv)
                return 0;
 
-       pdrv = to_platform_driver(dev->driver);
-       if (pdrv->pm) {
-               if (pdrv->pm->suspend_noirq)
-                       ret = pdrv->pm->suspend_noirq(dev);
+       if (drv->pm) {
+               if (drv->pm->suspend_noirq)
+                       ret = drv->pm->suspend_noirq(dev);
        } else {
                ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND);
        }
@@ -720,7 +753,10 @@ static int platform_pm_resume(struct device *dev)
        struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (drv && drv->pm) {
+       if (!drv)
+               return 0;
+
+       if (drv->pm) {
                if (drv->pm->resume)
                        ret = drv->pm->resume(dev);
        } else {
@@ -732,16 +768,15 @@ static int platform_pm_resume(struct device *dev)
 
 static int platform_pm_resume_noirq(struct device *dev)
 {
-       struct platform_driver *pdrv;
+       struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (!dev->driver)
+       if (!drv)
                return 0;
 
-       pdrv = to_platform_driver(dev->driver);
-       if (pdrv->pm) {
-               if (pdrv->pm->resume_noirq)
-                       ret = pdrv->pm->resume_noirq(dev);
+       if (drv->pm) {
+               if (drv->pm->resume_noirq)
+                       ret = drv->pm->resume_noirq(dev);
        } else {
                ret = platform_legacy_resume_early(dev);
        }
@@ -780,16 +815,15 @@ static int platform_pm_freeze(struct device *dev)
 
 static int platform_pm_freeze_noirq(struct device *dev)
 {
-       struct platform_driver *pdrv;
+       struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (!dev->driver)
+       if (!drv)
                return 0;
 
-       pdrv = to_platform_driver(dev->driver);
-       if (pdrv->pm) {
-               if (pdrv->pm->freeze_noirq)
-                       ret = pdrv->pm->freeze_noirq(dev);
+       if (drv->pm) {
+               if (drv->pm->freeze_noirq)
+                       ret = drv->pm->freeze_noirq(dev);
        } else {
                ret = platform_legacy_suspend_late(dev, PMSG_FREEZE);
        }
@@ -802,7 +836,10 @@ static int platform_pm_thaw(struct device *dev)
        struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (drv && drv->pm) {
+       if (!drv)
+               return 0;
+
+       if (drv->pm) {
                if (drv->pm->thaw)
                        ret = drv->pm->thaw(dev);
        } else {
@@ -814,16 +851,15 @@ static int platform_pm_thaw(struct device *dev)
 
 static int platform_pm_thaw_noirq(struct device *dev)
 {
-       struct platform_driver *pdrv;
+       struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (!dev->driver)
+       if (!drv)
                return 0;
 
-       pdrv = to_platform_driver(dev->driver);
-       if (pdrv->pm) {
-               if (pdrv->pm->thaw_noirq)
-                       ret = pdrv->pm->thaw_noirq(dev);
+       if (drv->pm) {
+               if (drv->pm->thaw_noirq)
+                       ret = drv->pm->thaw_noirq(dev);
        } else {
                ret = platform_legacy_resume_early(dev);
        }
@@ -836,7 +872,10 @@ static int platform_pm_poweroff(struct device *dev)
        struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (drv && drv->pm) {
+       if (!drv)
+               return 0;
+
+       if (drv->pm) {
                if (drv->pm->poweroff)
                        ret = drv->pm->poweroff(dev);
        } else {
@@ -848,16 +887,15 @@ static int platform_pm_poweroff(struct device *dev)
 
 static int platform_pm_poweroff_noirq(struct device *dev)
 {
-       struct platform_driver *pdrv;
+       struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (!dev->driver)
+       if (!drv)
                return 0;
 
-       pdrv = to_platform_driver(dev->driver);
-       if (pdrv->pm) {
-               if (pdrv->pm->poweroff_noirq)
-                       ret = pdrv->pm->poweroff_noirq(dev);
+       if (drv->pm) {
+               if (drv->pm->poweroff_noirq)
+                       ret = drv->pm->poweroff_noirq(dev);
        } else {
                ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE);
        }
@@ -870,7 +908,10 @@ static int platform_pm_restore(struct device *dev)
        struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (drv && drv->pm) {
+       if (!drv)
+               return 0;
+
+       if (drv->pm) {
                if (drv->pm->restore)
                        ret = drv->pm->restore(dev);
        } else {
@@ -882,16 +923,15 @@ static int platform_pm_restore(struct device *dev)
 
 static int platform_pm_restore_noirq(struct device *dev)
 {
-       struct platform_driver *pdrv;
+       struct device_driver *drv = dev->driver;
        int ret = 0;
 
-       if (!dev->driver)
+       if (!drv)
                return 0;
 
-       pdrv = to_platform_driver(dev->driver);
-       if (pdrv->pm) {
-               if (pdrv->pm->restore_noirq)
-                       ret = pdrv->pm->restore_noirq(dev);
+       if (drv->pm) {
+               if (drv->pm->restore_noirq)
+                       ret = drv->pm->restore_noirq(dev);
        } else {
                ret = platform_legacy_resume_early(dev);
        }
@@ -912,17 +952,15 @@ static int platform_pm_restore_noirq(struct device *dev)
 
 #endif /* !CONFIG_HIBERNATION */
 
-static struct pm_ext_ops platform_pm_ops = {
-       .base = {
-               .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,
-       },
+static 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,
@@ -931,7 +969,7 @@ static struct pm_ext_ops platform_pm_ops = {
        .restore_noirq = platform_pm_restore_noirq,
 };
 
-#define PLATFORM_PM_OPS_PTR    &platform_pm_ops
+#define PLATFORM_PM_OPS_PTR    (&platform_dev_pm_ops)
 
 #else /* !CONFIG_PM_SLEEP */