/*
 * ACPI support for platform bus type.
 *
 * Copyright (C) 2012, Intel Corporation
 * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
 *          Mathias Nyman <mathias.nyman@linux.intel.com>
 *          Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#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>

#include "internal.h"

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;

	/* 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.
 * @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.
 */
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;
	struct resource_list_entry *rentry;
	struct list_head resource_list;
	struct resource *resources;
	int count;

	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 0;

	INIT_LIST_HEAD(&resource_list);
	count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
	if (count <= 0)
		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 -ENOMEM;
	}
	count = 0;
	list_for_each_entry(rentry, &resource_list, node)
		resources[count++] = rentry->res;

	acpi_dev_free_resource_list(&resource_list);

	memset(&pdevinfo, 0, sizeof(pdevinfo));
	/*
	 * If the ACPI node has a parent and that parent has a physical device
	 * attached to it, that physical device should be the parent of the
	 * platform device we are about to create.
	 */
	pdevinfo.parent = NULL;
	acpi_parent = adev->parent;
	if (acpi_parent) {
		struct acpi_device_physical_node *entry;
		struct list_head *list;

		mutex_lock(&acpi_parent->physical_node_lock);
		list = &acpi_parent->physical_node_list;
		if (!list_empty(list)) {
			entry = list_first_entry(list,
					struct acpi_device_physical_node,
					node);
			pdevinfo.parent = entry->dev;
		}
		mutex_unlock(&acpi_parent->physical_node_lock);
	}
	pdevinfo.name = dev_name(&adev->dev);
	pdevinfo.id = -1;
	pdevinfo.res = resources;
	pdevinfo.num_res = count;
	pdevinfo.acpi_node.handle = adev->handle;
	pdev = platform_device_register_full(&pdevinfo);
	if (IS_ERR(pdev)) {
		dev_err(&adev->dev, "platform device creation failed: %ld\n",
			PTR_ERR(pdev));
		pdev = NULL;
	} else {
		dev_dbg(&adev->dev, "created platform device %s\n",
			dev_name(&pdev->dev));
	}

	kfree(resources);
	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);
}
