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>
This commit is contained in:
parent
701190fd74
commit
e375325ce5
@ -13,6 +13,7 @@
|
||||
|
||||
#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>
|
||||
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user