diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/platform.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 72c776f2a1f5..b2ee3bcd5a41 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -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" @@ -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; - return drv->probe(dev); + if (ACPI_HANDLE(_dev)) + acpi_dev_pm_attach(_dev, true); + + 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; + + ret = drv->remove(dev); + if (ACPI_HANDLE(_dev)) + acpi_dev_pm_detach(_dev, true); - return drv->remove(dev); + 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; |