#include <linux/acpi.h>
#include <linux/device.h>
+#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
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
*
* 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;
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;
-------------------------------------------------------------------------- */
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_ */
{ "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 },
{ }
};
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;
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;
}