aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-30 08:27:40 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-30 08:27:40 -0500
commit141a297bd02e8ddc5ab625cc3a1a5926b1ff929a (patch)
treef89584c92cf7593fe8f52b28f2f80c97aa590721
parent4daeaf68379f75dedd120582add5206c7c5ad72e (diff)
ACPI / platform: Use struct acpi_scan_handler for creating devices
Currently, the ACPI namespace scanning code creates platform device objects for ACPI device nodes whose IDs match the contents of the acpi_platform_device_ids[] table. However, this adds a superfluous special case into acpi_bus_device_attach() and makes it more difficult to follow than it has to be. It also will make it more difficult to implement removal code for those platform device objects in the future. For the above reasons, introduce a struct acpi_scan_handler object for creating platform devices and move the code related to that from acpi_bus_device_attach() to the .attach() callback of that object. Also move the acpi_platform_device_ids[] table to acpi_platform.c. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-rw-r--r--drivers/acpi/acpi_platform.c59
-rw-r--r--drivers/acpi/internal.h7
-rw-r--r--drivers/acpi/scan.c30
3 files changed, 50 insertions, 46 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 2d1fb4c21605..26fce4b8a632 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -22,6 +22,30 @@
22 22
23ACPI_MODULE_NAME("platform"); 23ACPI_MODULE_NAME("platform");
24 24
25/* Flags for acpi_create_platform_device */
26#define ACPI_PLATFORM_CLK BIT(0)
27
28/*
29 * The following ACPI IDs are known to be suitable for representing as
30 * platform devices.
31 */
32static const struct acpi_device_id acpi_platform_device_ids[] = {
33
34 { "PNP0D40" },
35
36 /* Haswell LPSS devices */
37 { "INT33C0", ACPI_PLATFORM_CLK },
38 { "INT33C1", ACPI_PLATFORM_CLK },
39 { "INT33C2", ACPI_PLATFORM_CLK },
40 { "INT33C3", ACPI_PLATFORM_CLK },
41 { "INT33C4", ACPI_PLATFORM_CLK },
42 { "INT33C5", ACPI_PLATFORM_CLK },
43 { "INT33C6", ACPI_PLATFORM_CLK },
44 { "INT33C7", ACPI_PLATFORM_CLK },
45
46 { }
47};
48
25static int acpi_create_platform_clks(struct acpi_device *adev) 49static int acpi_create_platform_clks(struct acpi_device *adev)
26{ 50{
27 static struct platform_device *pdev; 51 static struct platform_device *pdev;
@@ -39,8 +63,7 @@ static int acpi_create_platform_clks(struct acpi_device *adev)
39/** 63/**
40 * acpi_create_platform_device - Create platform device for ACPI device node 64 * acpi_create_platform_device - Create platform device for ACPI device node
41 * @adev: ACPI device node to create a platform device for. 65 * @adev: ACPI device node to create a platform device for.
42 * @flags: ACPI_PLATFORM_* flags that affect the creation of the platform 66 * @id: ACPI device ID used to match @adev.
43 * devices.
44 * 67 *
45 * Check if the given @adev can be represented as a platform device and, if 68 * Check if the given @adev can be represented as a platform device and, if
46 * that's the case, create and register a platform device, populate its common 69 * that's the case, create and register a platform device, populate its common
@@ -48,9 +71,10 @@ static int acpi_create_platform_clks(struct acpi_device *adev)
48 * 71 *
49 * Name of the platform device will be the same as @adev's. 72 * Name of the platform device will be the same as @adev's.
50 */ 73 */
51struct platform_device *acpi_create_platform_device(struct acpi_device *adev, 74static int acpi_create_platform_device(struct acpi_device *adev,
52 unsigned long flags) 75 const struct acpi_device_id *id)
53{ 76{
77 unsigned long flags = id->driver_data;
54 struct platform_device *pdev = NULL; 78 struct platform_device *pdev = NULL;
55 struct acpi_device *acpi_parent; 79 struct acpi_device *acpi_parent;
56 struct platform_device_info pdevinfo; 80 struct platform_device_info pdevinfo;
@@ -59,25 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
59 struct resource *resources; 83 struct resource *resources;
60 int count; 84 int count;
61 85
62 if ((flags & ACPI_PLATFORM_CLK) && acpi_create_platform_clks(adev)) { 86 if (flags & ACPI_PLATFORM_CLK) {
63 dev_err(&adev->dev, "failed to create clocks\n"); 87 int ret = acpi_create_platform_clks(adev);
64 return NULL; 88 if (ret) {
89 dev_err(&adev->dev, "failed to create clocks\n");
90 return ret;
91 }
65 } 92 }
66 93
67 /* If the ACPI node already has a physical device attached, skip it. */ 94 /* If the ACPI node already has a physical device attached, skip it. */
68 if (adev->physical_node_count) 95 if (adev->physical_node_count)
69 return NULL; 96 return 0;
70 97
71 INIT_LIST_HEAD(&resource_list); 98 INIT_LIST_HEAD(&resource_list);
72 count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); 99 count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
73 if (count <= 0) 100 if (count <= 0)
74 return NULL; 101 return 0;
75 102
76 resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); 103 resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
77 if (!resources) { 104 if (!resources) {
78 dev_err(&adev->dev, "No memory for resources\n"); 105 dev_err(&adev->dev, "No memory for resources\n");
79 acpi_dev_free_resource_list(&resource_list); 106 acpi_dev_free_resource_list(&resource_list);
80 return NULL; 107 return -ENOMEM;
81 } 108 }
82 count = 0; 109 count = 0;
83 list_for_each_entry(rentry, &resource_list, node) 110 list_for_each_entry(rentry, &resource_list, node)
@@ -123,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
123 } 150 }
124 151
125 kfree(resources); 152 kfree(resources);
126 return pdev; 153 return 1;
154}
155
156static struct acpi_scan_handler platform_handler = {
157 .ids = acpi_platform_device_ids,
158 .attach = acpi_create_platform_device,
159};
160
161void __init acpi_platform_init(void)
162{
163 acpi_scan_add_handler(&platform_handler);
127} 164}
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index e5a65217e480..0d1397dc7003 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -27,6 +27,7 @@ int init_acpi_device_notify(void);
27int acpi_scan_init(void); 27int acpi_scan_init(void);
28void acpi_pci_root_init(void); 28void acpi_pci_root_init(void);
29void acpi_pci_link_init(void); 29void acpi_pci_link_init(void);
30void acpi_platform_init(void);
30int acpi_sysfs_init(void); 31int acpi_sysfs_init(void);
31void acpi_csrt_init(void); 32void acpi_csrt_init(void);
32 33
@@ -119,10 +120,4 @@ static inline void suspend_nvs_restore(void) {}
119 -------------------------------------------------------------------------- */ 120 -------------------------------------------------------------------------- */
120struct platform_device; 121struct platform_device;
121 122
122/* Flags for acpi_create_platform_device */
123#define ACPI_PLATFORM_CLK BIT(0)
124
125struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
126 unsigned long flags);
127
128#endif /* _ACPI_INTERNAL_H_ */ 123#endif /* _ACPI_INTERNAL_H_ */
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c2821699bc49..a849d2430dff 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -29,27 +29,6 @@ extern struct acpi_device *acpi_root;
29 29
30static const char *dummy_hid = "device"; 30static const char *dummy_hid = "device";
31 31
32/*
33 * The following ACPI IDs are known to be suitable for representing as
34 * platform devices.
35 */
36static const struct acpi_device_id acpi_platform_device_ids[] = {
37
38 { "PNP0D40" },
39
40 /* Haswell LPSS devices */
41 { "INT33C0", ACPI_PLATFORM_CLK },
42 { "INT33C1", ACPI_PLATFORM_CLK },
43 { "INT33C2", ACPI_PLATFORM_CLK },
44 { "INT33C3", ACPI_PLATFORM_CLK },
45 { "INT33C4", ACPI_PLATFORM_CLK },
46 { "INT33C5", ACPI_PLATFORM_CLK },
47 { "INT33C6", ACPI_PLATFORM_CLK },
48 { "INT33C7", ACPI_PLATFORM_CLK },
49
50 { }
51};
52
53static LIST_HEAD(acpi_device_list); 32static LIST_HEAD(acpi_device_list);
54static LIST_HEAD(acpi_bus_id_list); 33static LIST_HEAD(acpi_bus_id_list);
55static DEFINE_MUTEX(acpi_scan_lock); 34static DEFINE_MUTEX(acpi_scan_lock);
@@ -1606,7 +1585,6 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
1606static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, 1585static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
1607 void *not_used, void **ret_not_used) 1586 void *not_used, void **ret_not_used)
1608{ 1587{
1609 const struct acpi_device_id *id;
1610 struct acpi_device *device; 1588 struct acpi_device *device;
1611 unsigned long long sta_not_used; 1589 unsigned long long sta_not_used;
1612 int ret; 1590 int ret;
@@ -1621,13 +1599,6 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
1621 if (acpi_bus_get_device(handle, &device)) 1599 if (acpi_bus_get_device(handle, &device))
1622 return AE_CTRL_DEPTH; 1600 return AE_CTRL_DEPTH;
1623 1601
1624 id = __acpi_match_device(device, acpi_platform_device_ids);
1625 if (id) {
1626 /* This is a known good platform device. */
1627 acpi_create_platform_device(device, id->driver_data);
1628 return AE_OK;
1629 }
1630
1631 ret = acpi_scan_attach_handler(device); 1602 ret = acpi_scan_attach_handler(device);
1632 if (ret) 1603 if (ret)
1633 return ret > 0 ? AE_OK : AE_CTRL_DEPTH; 1604 return ret > 0 ? AE_OK : AE_CTRL_DEPTH;
@@ -1775,6 +1746,7 @@ int __init acpi_scan_init(void)
1775 1746
1776 acpi_pci_root_init(); 1747 acpi_pci_root_init();
1777 acpi_pci_link_init(); 1748 acpi_pci_link_init();
1749 acpi_platform_init();
1778 acpi_csrt_init(); 1750 acpi_csrt_init();
1779 1751
1780 /* 1752 /*