Skip to content

Commit

Permalink
ACPI / platform: Use struct acpi_scan_handler for creating devices
Browse files Browse the repository at this point in the history
Currently, the ACPI namespace scanning code creates platform device
objects for ACPI device nodes whose IDs match the contents of the
acpi_platform_device_ids[] table.  However, this adds a superfluous
special case into acpi_bus_device_attach() and makes it more
difficult to follow than it has to be.  It also will make it more
difficult to implement removal code for those platform device objects
in the future.

For the above reasons, introduce a struct acpi_scan_handler object
for creating platform devices and move the code related to that from
acpi_bus_device_attach() to the .attach() callback of that object.
Also move the acpi_platform_device_ids[] table to acpi_platform.c.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Acked-by: Toshi Kani <toshi.kani@hp.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
  • Loading branch information
Rafael J. Wysocki committed Jan 30, 2013
1 parent 4daeaf6 commit 141a297
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 46 deletions.
59 changes: 48 additions & 11 deletions drivers/acpi/acpi_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,18 +63,18 @@ 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
* 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,
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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}
7 changes: 1 addition & 6 deletions drivers/acpi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ int init_acpi_device_notify(void);
int acpi_scan_init(void);
void acpi_pci_root_init(void);
void acpi_pci_link_init(void);
void acpi_platform_init(void);
int acpi_sysfs_init(void);
void acpi_csrt_init(void);

Expand Down Expand Up @@ -119,10 +120,4 @@ static inline void suspend_nvs_restore(void) {}
-------------------------------------------------------------------------- */
struct platform_device;

/* 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_ */
30 changes: 1 addition & 29 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,6 @@ extern struct acpi_device *acpi_root;

static const char *dummy_hid = "device";

/*
* 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 LIST_HEAD(acpi_device_list);
static LIST_HEAD(acpi_bus_id_list);
static DEFINE_MUTEX(acpi_scan_lock);
Expand Down Expand Up @@ -1606,7 +1585,6 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
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;
struct acpi_device *device;
unsigned long long sta_not_used;
int ret;
Expand All @@ -1621,13 +1599,6 @@ 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;

id = __acpi_match_device(device, acpi_platform_device_ids);
if (id) {
/* This is a known good platform device. */
acpi_create_platform_device(device, id->driver_data);
return AE_OK;
}

ret = acpi_scan_attach_handler(device);
if (ret)
return ret > 0 ? AE_OK : AE_CTRL_DEPTH;
Expand Down Expand Up @@ -1775,6 +1746,7 @@ int __init acpi_scan_init(void)

acpi_pci_root_init();
acpi_pci_link_init();
acpi_platform_init();
acpi_csrt_init();

/*
Expand Down

0 comments on commit 141a297

Please sign in to comment.