aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-01-18 08:46:01 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-23 15:14:22 -0500
commite375325ce55eb841ccda54a4472cf3b0139ea5f2 (patch)
tree79a9a12a6d18d86d24011909904f82d476a304da /drivers
parent701190fd7419f6757c19cdc6473830c79debb3ae (diff)
ACPI / platform: create LPSS clocks if Lynxpoint devices are found during scan
Intel Lynxpoint LPSS peripheral drivers depend on LPSS clock tree being created in order to function properly. The clock tree is exposed as a platform driver that binds to a device named 'clk-lpt'. To support this we modify the acpi_create_platform_device() to take one additional parameter called flags. This is passed from acpi_platform_device_ids[] array when acpi_create_platform_device() is called. We then introduce a new flag ACPI_PLATFORM_CLK which is used to tell acpi_create_platform_device() to create the platform clocks as well. Finally we set the ACPI_PLATFORM_CLK flags for all the Lynxpoint LPSS devices and make sure that when this flag is set we create the corresponding clock tree platform device. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpi_platform.c25
-rw-r--r--drivers/acpi/internal.h6
-rw-r--r--drivers/acpi/scan.c22
3 files changed, 41 insertions, 12 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 5554aea4bb0e..2d1fb4c21605 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/err.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -21,9 +22,25 @@
21 22
22ACPI_MODULE_NAME("platform"); 23ACPI_MODULE_NAME("platform");
23 24
25static int acpi_create_platform_clks(struct acpi_device *adev)
26{
27 static struct platform_device *pdev;
28
29 /* Create Lynxpoint LPSS clocks */
30 if (!pdev && !strncmp(acpi_device_hid(adev), "INT33C", 6)) {
31 pdev = platform_device_register_simple("clk-lpt", -1, NULL, 0);
32 if (IS_ERR(pdev))
33 return PTR_ERR(pdev);
34 }
35
36 return 0;
37}
38
24/** 39/**
25 * acpi_create_platform_device - Create platform device for ACPI device node 40 * acpi_create_platform_device - Create platform device for ACPI device node
26 * @adev: ACPI device node to create a platform device for. 41 * @adev: ACPI device node to create a platform device for.
42 * @flags: ACPI_PLATFORM_* flags that affect the creation of the platform
43 * devices.
27 * 44 *
28 * Check if the given @adev can be represented as a platform device and, if 45 * Check if the given @adev can be represented as a platform device and, if
29 * that's the case, create and register a platform device, populate its common 46 * that's the case, create and register a platform device, populate its common
@@ -31,7 +48,8 @@ ACPI_MODULE_NAME("platform");
31 * 48 *
32 * Name of the platform device will be the same as @adev's. 49 * Name of the platform device will be the same as @adev's.
33 */ 50 */
34struct platform_device *acpi_create_platform_device(struct acpi_device *adev) 51struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
52 unsigned long flags)
35{ 53{
36 struct platform_device *pdev = NULL; 54 struct platform_device *pdev = NULL;
37 struct acpi_device *acpi_parent; 55 struct acpi_device *acpi_parent;
@@ -41,6 +59,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
41 struct resource *resources; 59 struct resource *resources;
42 int count; 60 int count;
43 61
62 if ((flags & ACPI_PLATFORM_CLK) && acpi_create_platform_clks(adev)) {
63 dev_err(&adev->dev, "failed to create clocks\n");
64 return NULL;
65 }
66
44 /* If the ACPI node already has a physical device attached, skip it. */ 67 /* If the ACPI node already has a physical device attached, skip it. */
45 if (adev->physical_node_count) 68 if (adev->physical_node_count)
46 return NULL; 69 return NULL;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 4d2e4bf5f88d..4b68373473de 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -100,6 +100,10 @@ static inline void suspend_nvs_restore(void) {}
100 -------------------------------------------------------------------------- */ 100 -------------------------------------------------------------------------- */
101struct platform_device; 101struct platform_device;
102 102
103struct platform_device *acpi_create_platform_device(struct acpi_device *adev); 103/* Flags for acpi_create_platform_device */
104#define ACPI_PLATFORM_CLK BIT(0)
105
106struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
107 unsigned long flags);
104 108
105#endif /* _ACPI_INTERNAL_H_ */ 109#endif /* _ACPI_INTERNAL_H_ */
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a85b4080c3ca..fe171aa7a98c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -38,14 +38,14 @@ static const struct acpi_device_id acpi_platform_device_ids[] = {
38 { "PNP0D40" }, 38 { "PNP0D40" },
39 39
40 /* Haswell LPSS devices */ 40 /* Haswell LPSS devices */
41 { "INT33C0", 0 }, 41 { "INT33C0", ACPI_PLATFORM_CLK },
42 { "INT33C1", 0 }, 42 { "INT33C1", ACPI_PLATFORM_CLK },
43 { "INT33C2", 0 }, 43 { "INT33C2", ACPI_PLATFORM_CLK },
44 { "INT33C3", 0 }, 44 { "INT33C3", ACPI_PLATFORM_CLK },
45 { "INT33C4", 0 }, 45 { "INT33C4", ACPI_PLATFORM_CLK },
46 { "INT33C5", 0 }, 46 { "INT33C5", ACPI_PLATFORM_CLK },
47 { "INT33C6", 0 }, 47 { "INT33C6", ACPI_PLATFORM_CLK },
48 { "INT33C7", 0 }, 48 { "INT33C7", ACPI_PLATFORM_CLK },
49 49
50 { } 50 { }
51}; 51};
@@ -1553,6 +1553,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
1553static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, 1553static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
1554 void *not_used, void **ret_not_used) 1554 void *not_used, void **ret_not_used)
1555{ 1555{
1556 const struct acpi_device_id *id;
1556 acpi_status status = AE_OK; 1557 acpi_status status = AE_OK;
1557 struct acpi_device *device; 1558 struct acpi_device *device;
1558 unsigned long long sta_not_used; 1559 unsigned long long sta_not_used;
@@ -1568,9 +1569,10 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
1568 if (acpi_bus_get_device(handle, &device)) 1569 if (acpi_bus_get_device(handle, &device))
1569 return AE_CTRL_DEPTH; 1570 return AE_CTRL_DEPTH;
1570 1571
1571 if (!acpi_match_device_ids(device, acpi_platform_device_ids)) { 1572 id = __acpi_match_device(device, acpi_platform_device_ids);
1573 if (id) {
1572 /* This is a known good platform device. */ 1574 /* This is a known good platform device. */
1573 acpi_create_platform_device(device); 1575 acpi_create_platform_device(device, id->driver_data);
1574 } else if (device_attach(&device->dev) < 0) { 1576 } else if (device_attach(&device->dev) < 0) {
1575 status = AE_CTRL_DEPTH; 1577 status = AE_CTRL_DEPTH;
1576 } 1578 }