]> Pileus Git - ~andy/linux/blobdiff - drivers/base/platform.c
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[~andy/linux] / drivers / base / platform.c
index 72c776f2a1f528db39398a0983ae86730ebf24c1..c0b8df38402ba5b9a12a5c136aefea146c497c8f 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
 #include <linux/idr.h>
+#include <linux/acpi.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -44,7 +45,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
  * be setup before the platform_notifier is called.  So if a user needs to
  * manipulate any relevant information in the pdev_archdata they can do:
  *
- *     platform_devic_alloc()
+ *     platform_device_alloc()
  *     ... manipulate ...
  *     platform_device_add()
  *
@@ -122,7 +123,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
 EXPORT_SYMBOL_GPL(platform_get_resource_byname);
 
 /**
- * platform_get_irq - get an IRQ for a device
+ * platform_get_irq_byname - get an IRQ for a device by name
  * @dev: platform device
  * @name: IRQ name
  */
@@ -436,6 +437,7 @@ struct platform_device *platform_device_register_full(
                goto err_alloc;
 
        pdev->dev.parent = pdevinfo->parent;
+       ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle);
 
        if (pdevinfo->dma_mask) {
                /*
@@ -466,6 +468,7 @@ struct platform_device *platform_device_register_full(
        ret = platform_device_add(pdev);
        if (ret) {
 err:
+               ACPI_HANDLE_SET(&pdev->dev, NULL);
                kfree(pdev->dev.dma_mask);
 
 err_alloc:
@@ -481,8 +484,16 @@ static int platform_drv_probe(struct device *_dev)
 {
        struct platform_driver *drv = to_platform_driver(_dev->driver);
        struct platform_device *dev = to_platform_device(_dev);
+       int ret;
+
+       if (ACPI_HANDLE(_dev))
+               acpi_dev_pm_attach(_dev, true);
 
-       return drv->probe(dev);
+       ret = drv->probe(dev);
+       if (ret && ACPI_HANDLE(_dev))
+               acpi_dev_pm_detach(_dev, true);
+
+       return ret;
 }
 
 static int platform_drv_probe_fail(struct device *_dev)
@@ -494,8 +505,13 @@ static int platform_drv_remove(struct device *_dev)
 {
        struct platform_driver *drv = to_platform_driver(_dev->driver);
        struct platform_device *dev = to_platform_device(_dev);
+       int ret;
 
-       return drv->remove(dev);
+       ret = drv->remove(dev);
+       if (ACPI_HANDLE(_dev))
+               acpi_dev_pm_detach(_dev, true);
+
+       return ret;
 }
 
 static void platform_drv_shutdown(struct device *_dev)
@@ -504,6 +520,8 @@ static void platform_drv_shutdown(struct device *_dev)
        struct platform_device *dev = to_platform_device(_dev);
 
        drv->shutdown(dev);
+       if (ACPI_HANDLE(_dev))
+               acpi_dev_pm_detach(_dev, true);
 }
 
 /**
@@ -709,6 +727,10 @@ static int platform_match(struct device *dev, struct device_driver *drv)
        if (of_driver_match_device(dev, drv))
                return 1;
 
+       /* Then try ACPI style match */
+       if (acpi_driver_match_device(dev, drv))
+               return 1;
+
        /* Then try to match against the id table */
        if (pdrv->id_table)
                return platform_match_id(pdrv->id_table, pdev) != NULL;