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 @@ #include #include +#include #include #include #include @@ -21,9 +22,25 @@ ACPI_MODULE_NAME("platform"); +static int acpi_create_platform_clks(struct acpi_device *adev) +{ + static struct platform_device *pdev; + + /* Create Lynxpoint LPSS clocks */ + if (!pdev && !strncmp(acpi_device_hid(adev), "INT33C", 6)) { + pdev = platform_device_register_simple("clk-lpt", -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + } + + return 0; +} + /** * 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. * * 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 @@ -31,7 +48,8 @@ ACPI_MODULE_NAME("platform"); * * Name of the platform device will be the same as @adev's. */ -struct platform_device *acpi_create_platform_device(struct acpi_device *adev) +struct platform_device *acpi_create_platform_device(struct acpi_device *adev, + unsigned long flags) { struct platform_device *pdev = NULL; struct acpi_device *acpi_parent; @@ -41,6 +59,11 @@ 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 the ACPI node already has a physical device attached, skip it. */ if (adev->physical_node_count) 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) {} -------------------------------------------------------------------------- */ struct platform_device; -struct platform_device *acpi_create_platform_device(struct acpi_device *adev); +/* Flags for acpi_create_platform_device */ +#define ACPI_PLATFORM_CLK BIT(0) + +struct platform_device *acpi_create_platform_device(struct acpi_device *adev, + unsigned long flags); #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[] = { { "PNP0D40" }, /* Haswell LPSS devices */ - { "INT33C0", 0 }, - { "INT33C1", 0 }, - { "INT33C2", 0 }, - { "INT33C3", 0 }, - { "INT33C4", 0 }, - { "INT33C5", 0 }, - { "INT33C6", 0 }, - { "INT33C7", 0 }, + { "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 }, { } }; @@ -1553,6 +1553,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, void *not_used, void **ret_not_used) { + const struct acpi_device_id *id; acpi_status status = AE_OK; struct acpi_device *device; unsigned long long sta_not_used; @@ -1568,9 +1569,10 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, if (acpi_bus_get_device(handle, &device)) return AE_CTRL_DEPTH; - if (!acpi_match_device_ids(device, acpi_platform_device_ids)) { + id = __acpi_match_device(device, acpi_platform_device_ids); + if (id) { /* This is a known good platform device. */ - acpi_create_platform_device(device); + acpi_create_platform_device(device, id->driver_data); } else if (device_attach(&device->dev) < 0) { status = AE_CTRL_DEPTH; }