/*
 * 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 <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 ctrlset_buf[3];
	u32 global_ctrlsets;
	struct list_head sibiling;
};
static LIST_HEAD(acpi_osc_data_list);

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_query_osc (
	acpi_handle	handle,
	u32		level,
	void		*context,
	void		**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			osc_dw0;
	acpi_status *ret_status = (acpi_status *)retval;
	struct acpi_osc_data *osc_data;
	u32 flags = (unsigned long)context, temp;
	acpi_handle tmp;

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

	osc_data = acpi_get_osc_data(handle);
	if (!osc_data) {
		printk(KERN_ERR "acpi osc data array is full\n");
		return AE_ERROR;
	}

	osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS);

	/* do _OSC query for all possible controls */
	temp = osc_data->ctrlset_buf[OSC_CONTROL_TYPE];
	osc_data->ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;

	/* 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_data->ctrlset_buf;

	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
	if (ACPI_FAILURE(status))
		goto out_nofree;
	out_obj = output.pointer;

	if (out_obj->type != ACPI_TYPE_BUFFER) {
		printk(KERN_DEBUG  
			"Evaluate _OSC returns wrong type\n");
		status = AE_TYPE;
		goto query_osc_out;
	}
	osc_dw0 = *((u32 *) out_obj->buffer.pointer);
	if (osc_dw0) {
		if (osc_dw0 & OSC_REQUEST_ERROR)
			printk(KERN_DEBUG "_OSC request fails\n"); 
		if (osc_dw0 & OSC_INVALID_UUID_ERROR)
			printk(KERN_DEBUG "_OSC invalid UUID\n"); 
		if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
			printk(KERN_DEBUG "_OSC invalid revision\n"); 
		if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
			/* Update Global Control Set */
			osc_data->global_ctrlsets =
				*((u32 *)(out_obj->buffer.pointer + 8));
			status = AE_OK;
			goto query_osc_out;
		}
		status = AE_ERROR;
		goto query_osc_out;
	}

	/* Update Global Control Set */
	osc_data->global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
	status = AE_OK;

query_osc_out:
	kfree(output.pointer);
out_nofree:
	*ret_status = status;

	osc_data->ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE;
	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] = temp;
	if (ACPI_FAILURE(status)) {
		/* no osc support at all */
		osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] = 0;
	}

	return status;
}


static acpi_status  
acpi_run_osc (
	acpi_handle	handle,
	void		*context)
{
	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			osc_dw0;

	/* 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 *)context;

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

	out_obj = output.pointer;
	if (out_obj->type != ACPI_TYPE_BUFFER) {
		printk(KERN_DEBUG  
			"Evaluate _OSC returns wrong type\n");
		status = AE_TYPE;
		goto run_osc_out;
	}
	osc_dw0 = *((u32 *) out_obj->buffer.pointer);
	if (osc_dw0) {
		if (osc_dw0 & OSC_REQUEST_ERROR)
			printk(KERN_DEBUG "_OSC request fails\n"); 
		if (osc_dw0 & OSC_INVALID_UUID_ERROR)
			printk(KERN_DEBUG "_OSC invalid UUID\n"); 
		if (osc_dw0 & OSC_INVALID_REVISION_ERROR)
			printk(KERN_DEBUG "_OSC invalid revision\n"); 
		if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
			printk(KERN_DEBUG "_OSC FW not grant req. control\n");
			status = AE_SUPPORT;
			goto run_osc_out;
		}
		status = AE_ERROR;
		goto run_osc_out;
	}
	status = AE_OK;

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

/**
 * __pci_osc_support_set - register OS support to Firmware
 * @flags: OS support bits
 * @hid: hardware ID
 *
 * Update OS support fields and doing a _OSC Query to obtain an update
 * from Firmware on supported control bits.
 **/
acpi_status __pci_osc_support_set(u32 flags, const char *hid)
{
	acpi_status retval = AE_NOT_FOUND;

	if (!(flags & OSC_SUPPORT_MASKS)) {
		return AE_TYPE;
	}
	acpi_get_devices(hid,
			acpi_query_osc,
			(void *)(unsigned long)flags,
			(void **) &retval );
	return AE_OK;
}

/**
 * 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		ctrlset;
	acpi_handle tmp;
	struct acpi_osc_data *osc_data;

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

	osc_data = acpi_get_osc_data(handle);
	if (!osc_data) {
		printk(KERN_ERR "acpi osc data array is full\n");
		return AE_ERROR;
	}

	ctrlset = (flags & OSC_CONTROL_MASKS);
	if (!ctrlset) {
		return AE_TYPE;
	}
	if (osc_data->ctrlset_buf[OSC_SUPPORT_TYPE] &&
		((osc_data->global_ctrlsets & ctrlset) != ctrlset)) {
		return AE_SUPPORT;
	}
	osc_data->ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
	status = acpi_run_osc(handle, osc_data->ctrlset_buf);
	if (ACPI_FAILURE (status)) {
		osc_data->ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
	}
	
	return status;
}
EXPORT_SYMBOL(pci_osc_control_set);

#ifdef CONFIG_ACPI_SLEEP
/*
 * _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,
	pm_message_t state)
{
	int acpi_state;

	acpi_state = acpi_pm_device_sleep_state(&pdev->dev,
		device_may_wakeup(&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;
}
#endif

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

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

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


/* 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->bus_id, "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();
	}
	ret = register_acpi_bus_type(&acpi_pci_bus);
	if (ret)
		return 0;
#ifdef	CONFIG_ACPI_SLEEP
	platform_pci_choose_state = acpi_pci_choose_state;
#endif
	platform_pci_set_power_state = acpi_pci_set_power_state;
	return 0;
}
arch_initcall(acpi_pci_init);
