Skip to content

Commit

Permalink
ACPI / platform: create LPSS clocks if Lynxpoint devices are found du…
Browse files Browse the repository at this point in the history
…ring 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>
  • Loading branch information
Mika Westerberg authored and Rafael J. Wysocki committed Jan 23, 2013
1 parent 701190f commit e375325
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
25 changes: 24 additions & 1 deletion drivers/acpi/acpi_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -21,17 +22,34 @@

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
* resources and returns a pointer to it. Otherwise, return %NULL.
*
* 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;
Expand All @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
22 changes: 12 additions & 10 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },

{ }
};
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit e375325

Please sign in to comment.