|
@@ -22,6 +22,30 @@
|
|
|
|
|
|
ACPI_MODULE_NAME("platform");
|
|
|
|
|
|
+/* Flags for acpi_create_platform_device */
|
|
|
+#define ACPI_PLATFORM_CLK BIT(0)
|
|
|
+
|
|
|
+/*
|
|
|
+ * The following ACPI IDs are known to be suitable for representing as
|
|
|
+ * platform devices.
|
|
|
+ */
|
|
|
+static const struct acpi_device_id acpi_platform_device_ids[] = {
|
|
|
+
|
|
|
+ { "PNP0D40" },
|
|
|
+
|
|
|
+ /* Haswell LPSS devices */
|
|
|
+ { "INT33C0", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C1", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C2", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C3", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C4", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C5", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C6", ACPI_PLATFORM_CLK },
|
|
|
+ { "INT33C7", ACPI_PLATFORM_CLK },
|
|
|
+
|
|
|
+ { }
|
|
|
+};
|
|
|
+
|
|
|
static int acpi_create_platform_clks(struct acpi_device *adev)
|
|
|
{
|
|
|
static struct platform_device *pdev;
|
|
@@ -39,8 +63,7 @@ static int acpi_create_platform_clks(struct acpi_device *adev)
|
|
|
/**
|
|
|
* acpi_create_platform_device - Create platform device for ACPI device node
|
|
|
* @adev: ACPI device node to create a platform device for.
|
|
|
- * @flags: ACPI_PLATFORM_* flags that affect the creation of the platform
|
|
|
- * devices.
|
|
|
+ * @id: ACPI device ID used to match @adev.
|
|
|
*
|
|
|
* Check if the given @adev can be represented as a platform device and, if
|
|
|
* 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)
|
|
|
*
|
|
|
* Name of the platform device will be the same as @adev's.
|
|
|
*/
|
|
|
-struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
|
|
- unsigned long flags)
|
|
|
+static int acpi_create_platform_device(struct acpi_device *adev,
|
|
|
+ const struct acpi_device_id *id)
|
|
|
{
|
|
|
+ unsigned long flags = id->driver_data;
|
|
|
struct platform_device *pdev = NULL;
|
|
|
struct acpi_device *acpi_parent;
|
|
|
struct platform_device_info pdevinfo;
|
|
@@ -59,25 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
|
|
struct resource *resources;
|
|
|
int count;
|
|
|
|
|
|
- if ((flags & ACPI_PLATFORM_CLK) && acpi_create_platform_clks(adev)) {
|
|
|
- dev_err(&adev->dev, "failed to create clocks\n");
|
|
|
- return NULL;
|
|
|
+ if (flags & ACPI_PLATFORM_CLK) {
|
|
|
+ int ret = acpi_create_platform_clks(adev);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&adev->dev, "failed to create clocks\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* If the ACPI node already has a physical device attached, skip it. */
|
|
|
if (adev->physical_node_count)
|
|
|
- return NULL;
|
|
|
+ return 0;
|
|
|
|
|
|
INIT_LIST_HEAD(&resource_list);
|
|
|
count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
|
|
if (count <= 0)
|
|
|
- return NULL;
|
|
|
+ return 0;
|
|
|
|
|
|
resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
|
|
|
if (!resources) {
|
|
|
dev_err(&adev->dev, "No memory for resources\n");
|
|
|
acpi_dev_free_resource_list(&resource_list);
|
|
|
- return NULL;
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
count = 0;
|
|
|
list_for_each_entry(rentry, &resource_list, node)
|
|
@@ -123,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
|
|
|
}
|
|
|
|
|
|
kfree(resources);
|
|
|
- return pdev;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+static struct acpi_scan_handler platform_handler = {
|
|
|
+ .ids = acpi_platform_device_ids,
|
|
|
+ .attach = acpi_create_platform_device,
|
|
|
+};
|
|
|
+
|
|
|
+void __init acpi_platform_init(void)
|
|
|
+{
|
|
|
+ acpi_scan_add_handler(&platform_handler);
|
|
|
}
|