/*
 * File:	pci-acpi.c
 * Purpose:	Provide PCI support in ACPI
 *
 * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com>
 * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com>
 * Copyright (C) 2004 Intel Corp.
 */

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/pci-aspm.h>
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acresrc.h>
#include <acpi/acpi_bus.h>

#include <linux/pci-acpi.h>
#include "pci.h"

struct acpi_osc_data {
	acpi_handle handle;
	u32 support_set;
	u32 control_set;
	u32 control_query;
	int is_queried;
	struct list_head sibiling;
};
static LIST_HEAD(acpi_osc_data_list);

struct acpi_osc_args {
	u32 capbuf[3];
};

static DEFINE_MUTEX(pci_acpi_lock);

static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
{
	struct acpi_osc_data *data;

	list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
		if (data->handle == handle)
			return data;
	}
	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return NULL;
	INIT_LIST_HEAD(&data->sibiling);
	data->handle = handle;
	list_add_tail(&data->sibiling, &acpi_osc_data_list);
	return data;
}

static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
			  0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};

static acpi_status acpi_run_osc(acpi_handle handle,
				struct acpi_osc_args *osc_args, u32 *retval)
{
	acpi_status status;
	struct acpi_object_list input;
	union acpi_object in_params[4];
	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
	union acpi_object *out_obj;
	u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE];

	/* Setting up input parameters */
	input.count = 4;
	input.pointer = in_params;
	in_params[0].type 		= ACPI_TYPE_BUFFER;
	in_params[0].buffer.length 	= 16;
	in_params[0].buffer.pointer	= OSC_UUID;
	in_params[1].type 		= ACPI_TYPE_INTEGER;
	in_params[1].integer.value 	= 1;
	in_params[2].type 		= ACPI_TYPE_INTEGER;
	in_params[2].integer.value	= 3;
	in_params[3].type		= ACPI_TYPE_BUFFER;
	in_params[3].buffer.length 	= 12;
	in_params[3].buffer.pointer 	= (u8 *)osc_args->capbuf;

	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
	if (ACPI_FAILURE(status))
		return status;

	if (!output.length)
		return AE_NULL_OBJECT;

	out_obj = output.pointer;
	if (out_obj->type != ACPI_TYPE_BUFFER) {
		printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");
		status = AE_TYPE;
		goto out_kfree;
	}
	/* Need to ignore the bit0 in result code */
	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
	if (errors) {
		if (errors & OSC_REQUEST_ERROR)
			printk(KERN_DEBUG "_OSC request fails\n"); 
		if (errors & OSC_INVALID_UUID_ERROR)
			printk(KERN_DEBUG "_OSC invalid UUID\n"); 
		if (errors & OSC_INVALID_REVISION_ERROR)
			printk(KERN_DEBUG "_OSC invalid revision\n"); 
		if (errors & OSC_CAPABILITIES_MASK_ERROR) {
			if (flags & OSC_QUERY_ENABLE)
				goto out_success;
			printk(KERN_DEBUG "_OSC FW not grant req. control\n");
			status = AE_SUPPORT;
			goto out_kfree;
		}
		status = AE_ERROR;
		goto out_kfree;
	}
out_success:
	*retval = *((u32 *)(out_obj->buffer.pointer + 8));
	status = AE_OK;

out_kfree:
	kfree(output.pointer);
	return status;
}

static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data)
{
	acpi_status status;
	u32 support_set, result;
	struct acpi_osc_args osc_args;

	/* do _OSC query for all possible controls */
	support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
	osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
	osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
	osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;

	status = acpi_run_osc(osc_data->handle, &osc_args, &result);
	if (ACPI_SUCCESS(status)) {
		osc_data->support_set = support_set;
		osc_data->control_query = result;
		osc_data->is_queried = 1;
	}

	return status;
}

/*
 * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature
 * @flags: Bitmask of flags to support
 *
 * See the ACPI spec for the definition of the flags
 */
int pci_acpi_osc_support(acpi_handle handle, u32 flags)
{
	acpi_status status;
	acpi_handle tmp;
	struct acpi_osc_data *osc_data;
	int rc = 0;

	status = acpi_get_handle(handle, "_OSC", &tmp);
	if (ACPI_FAILURE(status))
		return -ENOTTY;

	mutex_lock(&pci_acpi_lock);
	osc_data = acpi_get_osc_data(handle);
	if (!osc_data) {
		printk(KERN_ERR "acpi osc data array is full\n");
		rc = -ENOMEM;
		goto out;
	}

	__acpi_query_osc(flags, osc_data);
out:
	mutex_unlock(&pci_acpi_lock);
	return rc;
}

/**
 * pci_osc_control_set - commit requested control to Firmware
 * @handle: acpi_handle for the target ACPI object
 * @flags: driver's requested control bits
 *
 * Attempt to take control from Firmware on requested control bits.
 **/
acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
{
	acpi_status status;
	u32 control_req, control_set, result;
	acpi_handle tmp;
	struct acpi_osc_data *osc_data;
	struct acpi_osc_args osc_args;

	status = acpi_get_handle(handle, "_OSC", &tmp);
	if (ACPI_FAILURE(status))
		return status;

	mutex_lock(&pci_acpi_lock);
	osc_data = acpi_get_osc_data(handle);
	if (!osc_data) {
		printk(KERN_ERR "acpi osc data array is full\n");
		status = AE_ERROR;
		goto out;
	}

	control_req = (flags & OSC_CONTROL_MASKS);
	if (!control_req) {
		status = AE_TYPE;
		goto out;
	}

	/* No need to evaluate _OSC if the control was already granted. */
	if ((osc_data->control_set & control_req) == control_req)
		goto out;

	if (!osc_data->is_queried) {
		status = __acpi_query_osc(osc_data->support_set, osc_data);
		if (ACPI_FAILURE(status))
			goto out;
	}

	if ((osc_data->control_query & control_req) != control_req) {
		status = AE_SUPPORT;
		goto out;
	}

	control_set = osc_data->control_set | control_req;
	osc_args.capbuf[OSC_QUERY_TYPE] = 0;
	osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set;
	osc_args.capbuf[OSC_CONTROL_TYPE] = control_set;
	status = acpi_run_osc(handle, &osc_args, &result);
	if (ACPI_SUCCESS(status))
		osc_data->control_set = result;
out:
	mutex_unlock(&pci_acpi_lock);
	return status;
}
EXPORT_SYMBOL(pci_osc_control_set);

/*
 * _SxD returns the D-state with the highest power
 * (lowest D-state number) supported in the S-state "x".
 *
 * If the devices does not have a _PRW
 * (Power Resources for Wake) supporting system wakeup from "x"
 * then the OS is free to choose a lower power (higher number
 * D-state) than the return value from _SxD.
 *
 * But if _PRW is enabled at S-state "x", the OS
 * must not choose a power lower than _SxD --
 * unless the device has an _SxW method specifying
 * the lowest power (highest D-state number) the device
 * may enter while still able to wake the system.
 *
 * ie. depending on global OS policy:
 *
 * if (_PRW at S-state x)
 *	choose from highest power _SxD to lowest power _SxW
 * else // no _PRW at S-state x
 * 	choose highest power _SxD or any lower power
 */

static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
{
	int acpi_state;

	acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL);
	if (acpi_state < 0)
		return PCI_POWER_ERROR;

	switch (acpi_state) {
	case ACPI_STATE_D0:
		return PCI_D0;
	case ACPI_STATE_D1:
		return PCI_D1;
	case ACPI_STATE_D2:
		return PCI_D2;
	case ACPI_STATE_D3:
		return PCI_D3hot;
	}
	return PCI_POWER_ERROR;
}

static bool acpi_pci_power_manageable(struct pci_dev *dev)
{
	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);

	return handle ? acpi_bus_power_manageable(handle) : false;
}

static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{
	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
	acpi_handle tmp;
	static const u8 state_conv[] = {
		[PCI_D0] = ACPI_STATE_D0,
		[PCI_D1] = ACPI_STATE_D1,
		[PCI_D2] = ACPI_STATE_D2,
		[PCI_D3hot] = ACPI_STATE_D3,
		[PCI_D3cold] = ACPI_STATE_D3
	};
	int error = -EINVAL;

	/* If the ACPI device has _EJ0, ignore the device */
	if (!handle || ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp)))
		return -ENODEV;

	switch (state) {
	case PCI_D0:
	case PCI_D1:
	case PCI_D2:
	case PCI_D3hot:
	case PCI_D3cold:
		error = acpi_bus_set_power(handle, state_conv[state]);
	}

	if (!error)
		dev_printk(KERN_INFO, &dev->dev,
				"power state changed by ACPI to D%d\n", state);

	return error;
}

static bool acpi_pci_can_wakeup(struct pci_dev *dev)
{
	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);

	return handle ? acpi_bus_can_wakeup(handle) : false;
}

static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
{
	int error = acpi_pm_device_sleep_wake(&dev->dev, enable);

	if (!error)
		dev_printk(KERN_INFO, &dev->dev,
				"wake-up capability %s by ACPI\n",
				enable ? "enabled" : "disabled");
	return error;
}

static struct pci_platform_pm_ops acpi_pci_platform_pm = {
	.is_manageable = acpi_pci_power_manageable,
	.set_state = acpi_pci_set_power_state,
	.choose_state = acpi_pci_choose_state,
	.can_wakeup = acpi_pci_can_wakeup,
	.sleep_wake = acpi_pci_sleep_wake,
};

/* ACPI bus type */
static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
{
	struct pci_dev * pci_dev;
	acpi_integer	addr;

	pci_dev = to_pci_dev(dev);
	/* Please ref to ACPI spec for the syntax of _ADR */
	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
	if (!*handle)
		return -ENODEV;
	return 0;
}

static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
{
	int num;
	unsigned int seg, bus;

	/*
	 * The string should be the same as root bridge's name
	 * Please look at 'pci_scan_bus_parented'
	 */
	num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus);
	if (num != 2)
		return -ENODEV;
	*handle = acpi_get_pci_rootbridge_handle(seg, bus);
	if (!*handle)
		return -ENODEV;
	return 0;
}

static struct acpi_bus_type acpi_pci_bus = {
	.bus = &pci_bus_type,
	.find_device = acpi_pci_find_device,
	.find_bridge = acpi_pci_find_root_bridge,
};

static int __init acpi_pci_init(void)
{
	int ret;

	if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
		printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
		pci_no_msi();
	}

	if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
		printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
		pcie_no_aspm();
	}

	ret = register_acpi_bus_type(&acpi_pci_bus);
	if (ret)
		return 0;
	pci_set_platform_pm(&acpi_pci_platform_pm);
	return 0;
}
arch_initcall(acpi_pci_init);
