aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8727e9c5eea4..c0b8df38402b 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23#include <linux/idr.h> 23#include <linux/idr.h>
24#include <linux/acpi.h>
24 25
25#include "base.h" 26#include "base.h"
26#include "power/power.h" 27#include "power/power.h"
@@ -44,7 +45,7 @@ EXPORT_SYMBOL_GPL(platform_bus);
44 * be setup before the platform_notifier is called. So if a user needs to 45 * be setup before the platform_notifier is called. So if a user needs to
45 * manipulate any relevant information in the pdev_archdata they can do: 46 * manipulate any relevant information in the pdev_archdata they can do:
46 * 47 *
47 * platform_devic_alloc() 48 * platform_device_alloc()
48 * ... manipulate ... 49 * ... manipulate ...
49 * platform_device_add() 50 * platform_device_add()
50 * 51 *
@@ -83,9 +84,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource);
83 */ 84 */
84int platform_get_irq(struct platform_device *dev, unsigned int num) 85int platform_get_irq(struct platform_device *dev, unsigned int num)
85{ 86{
87#ifdef CONFIG_SPARC
88 /* sparc does not have irqs represented as IORESOURCE_IRQ resources */
89 if (!dev || num >= dev->archdata.num_irqs)
90 return -ENXIO;
91 return dev->archdata.irqs[num];
92#else
86 struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); 93 struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
87 94
88 return r ? r->start : -ENXIO; 95 return r ? r->start : -ENXIO;
96#endif
89} 97}
90EXPORT_SYMBOL_GPL(platform_get_irq); 98EXPORT_SYMBOL_GPL(platform_get_irq);
91 99
@@ -115,7 +123,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
115EXPORT_SYMBOL_GPL(platform_get_resource_byname); 123EXPORT_SYMBOL_GPL(platform_get_resource_byname);
116 124
117/** 125/**
118 * platform_get_irq - get an IRQ for a device 126 * platform_get_irq_byname - get an IRQ for a device by name
119 * @dev: platform device 127 * @dev: platform device
120 * @name: IRQ name 128 * @name: IRQ name
121 */ 129 */
@@ -429,6 +437,7 @@ struct platform_device *platform_device_register_full(
429 goto err_alloc; 437 goto err_alloc;
430 438
431 pdev->dev.parent = pdevinfo->parent; 439 pdev->dev.parent = pdevinfo->parent;
440 ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle);
432 441
433 if (pdevinfo->dma_mask) { 442 if (pdevinfo->dma_mask) {
434 /* 443 /*
@@ -459,6 +468,7 @@ struct platform_device *platform_device_register_full(
459 ret = platform_device_add(pdev); 468 ret = platform_device_add(pdev);
460 if (ret) { 469 if (ret) {
461err: 470err:
471 ACPI_HANDLE_SET(&pdev->dev, NULL);
462 kfree(pdev->dev.dma_mask); 472 kfree(pdev->dev.dma_mask);
463 473
464err_alloc: 474err_alloc:
@@ -474,8 +484,16 @@ static int platform_drv_probe(struct device *_dev)
474{ 484{
475 struct platform_driver *drv = to_platform_driver(_dev->driver); 485 struct platform_driver *drv = to_platform_driver(_dev->driver);
476 struct platform_device *dev = to_platform_device(_dev); 486 struct platform_device *dev = to_platform_device(_dev);
487 int ret;
488
489 if (ACPI_HANDLE(_dev))
490 acpi_dev_pm_attach(_dev, true);
477 491
478 return drv->probe(dev); 492 ret = drv->probe(dev);
493 if (ret && ACPI_HANDLE(_dev))
494 acpi_dev_pm_detach(_dev, true);
495
496 return ret;
479} 497}
480 498
481static int platform_drv_probe_fail(struct device *_dev) 499static int platform_drv_probe_fail(struct device *_dev)
@@ -487,8 +505,13 @@ static int platform_drv_remove(struct device *_dev)
487{ 505{
488 struct platform_driver *drv = to_platform_driver(_dev->driver); 506 struct platform_driver *drv = to_platform_driver(_dev->driver);
489 struct platform_device *dev = to_platform_device(_dev); 507 struct platform_device *dev = to_platform_device(_dev);
508 int ret;
490 509
491 return drv->remove(dev); 510 ret = drv->remove(dev);
511 if (ACPI_HANDLE(_dev))
512 acpi_dev_pm_detach(_dev, true);
513
514 return ret;
492} 515}
493 516
494static void platform_drv_shutdown(struct device *_dev) 517static void platform_drv_shutdown(struct device *_dev)
@@ -497,6 +520,8 @@ static void platform_drv_shutdown(struct device *_dev)
497 struct platform_device *dev = to_platform_device(_dev); 520 struct platform_device *dev = to_platform_device(_dev);
498 521
499 drv->shutdown(dev); 522 drv->shutdown(dev);
523 if (ACPI_HANDLE(_dev))
524 acpi_dev_pm_detach(_dev, true);
500} 525}
501 526
502/** 527/**
@@ -702,6 +727,10 @@ static int platform_match(struct device *dev, struct device_driver *drv)
702 if (of_driver_match_device(dev, drv)) 727 if (of_driver_match_device(dev, drv))
703 return 1; 728 return 1;
704 729
730 /* Then try ACPI style match */
731 if (acpi_driver_match_device(dev, drv))
732 return 1;
733
705 /* Then try to match against the id table */ 734 /* Then try to match against the id table */
706 if (pdrv->id_table) 735 if (pdrv->id_table)
707 return platform_match_id(pdrv->id_table, pdev) != NULL; 736 return platform_match_id(pdrv->id_table, pdev) != NULL;