// SPDX-License-Identifier: GPL-2.0-only
/*
 * acpi_processor.c - ACPI processor enumeration support
 *
 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 * Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
 * Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
 * Copyright (C) 2013, Intel Corporation
 *                     Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 */

#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>

#include <acpi/processor.h>

#include <asm/cpu.h>

#include "internal.h"

#define _COMPONENT	ACPI_PROCESSOR_COMPONENT

ACPI_MODULE_NAME("processor");

DEFINE_PER_CPU(struct acpi_processor *, processors);
EXPORT_PER_CPU_SYMBOL(processors);

/* --------------------------------------------------------------------------
                                Errata Handling
   -------------------------------------------------------------------------- */

struct acpi_processor_errata errata __read_mostly;
EXPORT_SYMBOL_GPL(errata);

static int acpi_processor_errata_piix4(struct pci_dev *dev)
{
	u8 value1 = 0;
	u8 value2 = 0;


	if (!dev)
		return -EINVAL;

	/*
	 * Note that 'dev' references the PIIX4 ACPI Controller.
	 */

	switch (dev->revision) {
	case 0:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
		break;
	case 1:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
		break;
	case 2:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
		break;
	case 3:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
		break;
	default:
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
		break;
	}

	switch (dev->revision) {

	case 0:		/* PIIX4 A-step */
	case 1:		/* PIIX4 B-step */
		/*
		 * See specification changes #13 ("Manual Throttle Duty Cycle")
		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
		 * erratum #5 ("STPCLK# Deassertion Time") from the January
		 * 2002 PIIX4 specification update.  Applies to only older
		 * PIIX4 models.
		 */
		errata.piix4.throttle = 1;
		fallthrough;

	case 2:		/* PIIX4E */
	case 3:		/* PIIX4M */
		/*
		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
		 * Livelock") from the January 2002 PIIX4 specification update.
		 * Applies to all PIIX4 models.
		 */

		/*
		 * BM-IDE
		 * ------
		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
		 * Status register address.  We'll use this later to read
		 * each IDE controller's DMA status to make sure we catch all
		 * DMA activity.
		 */
		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
				     PCI_DEVICE_ID_INTEL_82371AB,
				     PCI_ANY_ID, PCI_ANY_ID, NULL);
		if (dev) {
			errata.piix4.bmisx = pci_resource_start(dev, 4);
			pci_dev_put(dev);
		}

		/*
		 * Type-F DMA
		 * ----------
		 * Find the PIIX4 ISA Controller and read the Motherboard
		 * DMA controller's status to see if Type-F (Fast) DMA mode
		 * is enabled (bit 7) on either channel.  Note that we'll
		 * disable C3 support if this is enabled, as some legacy
		 * devices won't operate well if fast DMA is disabled.
		 */
		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
				     PCI_DEVICE_ID_INTEL_82371AB_0,
				     PCI_ANY_ID, PCI_ANY_ID, NULL);
		if (dev) {
			pci_read_config_byte(dev, 0x76, &value1);
			pci_read_config_byte(dev, 0x77, &value2);
			if ((value1 & 0x80) || (value2 & 0x80))
				errata.piix4.fdma = 1;
			pci_dev_put(dev);
		}

		break;
	}

	if (errata.piix4.bmisx)
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Bus master activity detection (BM-IDE) erratum enabled\n"));
	if (errata.piix4.fdma)
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Type-F DMA livelock erratum (C3 disabled)\n"));

	return 0;
}

static int acpi_processor_errata(void)
{
	int result = 0;
	struct pci_dev *dev = NULL;

	/*
	 * PIIX4
	 */
	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
			     PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
			     PCI_ANY_ID, NULL);
	if (dev) {
		result = acpi_processor_errata_piix4(dev);
		pci_dev_put(dev);
	}

	return result;
}

/* --------------------------------------------------------------------------
                                Initialization
   -------------------------------------------------------------------------- */

#ifdef CONFIG_ACPI_HOTPLUG_CPU
int __weak acpi_map_cpu(acpi_handle handle,
		phys_cpuid_t physid, u32 acpi_id, int *pcpu)
{
	return -ENODEV;
}

int __weak acpi_unmap_cpu(int cpu)
{
	return -ENODEV;
}

int __weak arch_register_cpu(int cpu)
{
	return -ENODEV;
}

void __weak arch_unregister_cpu(int cpu) {}

static int acpi_processor_hotadd_init(struct acpi_processor *pr)
{
	unsigned long long sta;
	acpi_status status;
	int ret;

	if (invalid_phys_cpuid(pr->phys_id))
		return -ENODEV;

	status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
		return -ENODEV;

	cpu_maps_update_begin();
	cpu_hotplug_begin();

	ret = acpi_map_cpu(pr->handle, pr->phys_id, pr->acpi_id, &pr->id);
	if (ret)
		goto out;

	ret = arch_register_cpu(pr->id);
	if (ret) {
		acpi_unmap_cpu(pr->id);
		goto out;
	}

	/*
	 * CPU got hot-added, but cpu_data is not initialized yet.  Set a flag
	 * to delay cpu_idle/throttling initialization and do it when the CPU
	 * gets online for the first time.
	 */
	pr_info("CPU%d has been hot-added\n", pr->id);
	pr->flags.need_hotplug_init = 1;

out:
	cpu_hotplug_done();
	cpu_maps_update_done();
	return ret;
}
#else
static inline int acpi_processor_hotadd_init(struct acpi_processor *pr)
{
	return -ENODEV;
}
#endif /* CONFIG_ACPI_HOTPLUG_CPU */

static int acpi_processor_get_info(struct acpi_device *device)
{
	union acpi_object object = { 0 };
	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
	struct acpi_processor *pr = acpi_driver_data(device);
	int device_declaration = 0;
	acpi_status status = AE_OK;
	static int cpu0_initialized;
	unsigned long long value;

	acpi_processor_errata();

	/*
	 * Check to see if we have bus mastering arbitration control.  This
	 * is required for proper C3 usage (to maintain cache coherency).
	 */
	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
		pr->flags.bm_control = 1;
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "Bus mastering arbitration control present\n"));
	} else
		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "No bus mastering arbitration control\n"));

	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
		/* Declared with "Processor" statement; match ProcessorID */
		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
		if (ACPI_FAILURE(status)) {
			dev_err(&device->dev,
				"Failed to evaluate processor object (0x%x)\n",
				status);
			return -ENODEV;
		}

		pr->acpi_id = object.processor.proc_id;
	} else {
		/*
		 * Declared with "Device" statement; match _UID.
		 */
		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
						NULL, &value);
		if (ACPI_FAILURE(status)) {
			dev_err(&device->dev,
				"Failed to evaluate processor _UID (0x%x)\n",
				status);
			return -ENODEV;
		}
		device_declaration = 1;
		pr->acpi_id = value;
	}

	if (acpi_duplicate_processor_id(pr->acpi_id)) {
		if (pr->acpi_id == 0xff)
			dev_info_once(&device->dev,
				"Entry not well-defined, consider updating BIOS\n");
		else
			dev_err(&device->dev,
				"Failed to get unique processor _UID (0x%x)\n",
				pr->acpi_id);
		return -ENODEV;
	}

	pr->phys_id = acpi_get_phys_id(pr->handle, device_declaration,
					pr->acpi_id);
	if (invalid_phys_cpuid(pr->phys_id))
		acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n");

	pr->id = acpi_map_cpuid(pr->phys_id, pr->acpi_id);
	if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
		cpu0_initialized = 1;
		/*
		 * Handle UP system running SMP kernel, with no CPU
		 * entry in MADT
		 */
		if (invalid_logical_cpuid(pr->id) && (num_online_cpus() == 1))
			pr->id = 0;
	}

	/*
	 *  Extra Processor objects may be enumerated on MP systems with
	 *  less than the max # of CPUs. They should be ignored _iff
	 *  they are physically not present.
	 *
	 *  NOTE: Even if the processor has a cpuid, it may not be present
	 *  because cpuid <-> apicid mapping is persistent now.
	 */
	if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
		int ret = acpi_processor_hotadd_init(pr);
		if (ret)
			return ret;
	}

	/*
	 * On some boxes several processors use the same processor bus id.
	 * But they are located in different scope. For example:
	 * \_SB.SCK0.CPU0
	 * \_SB.SCK1.CPU0
	 * Rename the processor device bus id. And the new bus id will be
	 * generated as the following format:
	 * CPU+CPU ID.
	 */
	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
			  pr->acpi_id));

	if (!object.processor.pblk_address)
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
	else if (object.processor.pblk_length != 6)
		dev_err(&device->dev, "Invalid PBLK length [%d]\n",
			    object.processor.pblk_length);
	else {
		pr->throttling.address = object.processor.pblk_address;
		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;

		pr->pblk = object.processor.pblk_address;
	}

	/*
	 * If ACPI describes a slot number for this CPU, we can use it to
	 * ensure we get the right value in the "physical id" field
	 * of /proc/cpuinfo
	 */
	status = acpi_evaluate_integer(pr->handle, "_SUN", NULL, &value);
	if (ACPI_SUCCESS(status))
		arch_fix_phys_package_id(pr->id, value);

	return 0;
}

/*
 * Do not put anything in here which needs the core to be online.
 * For example MSR access or setting up things which check for cpuinfo_x86
 * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
 * Such things have to be put in and set up by the processor driver's .probe().
 */
static DEFINE_PER_CPU(void *, processor_device_array);

static int acpi_processor_add(struct acpi_device *device,
					const struct acpi_device_id *id)
{
	struct acpi_processor *pr;
	struct device *dev;
	int result = 0;

	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
	if (!pr)
		return -ENOMEM;

	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
		result = -ENOMEM;
		goto err_free_pr;
	}

	pr->handle = device->handle;
	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
	device->driver_data = pr;

	result = acpi_processor_get_info(device);
	if (result) /* Processor is not physically present or unavailable */
		return 0;

	BUG_ON(pr->id >= nr_cpu_ids);

	/*
	 * Buggy BIOS check.
	 * ACPI id of processors can be reported wrongly by the BIOS.
	 * Don't trust it blindly
	 */
	if (per_cpu(processor_device_array, pr->id) != NULL &&
	    per_cpu(processor_device_array, pr->id) != device) {
		dev_warn(&device->dev,
			"BIOS reported wrong ACPI id %d for the processor\n",
			pr->id);
		/* Give up, but do not abort the namespace scan. */
		goto err;
	}
	/*
	 * processor_device_array is not cleared on errors to allow buggy BIOS
	 * checks.
	 */
	per_cpu(processor_device_array, pr->id) = device;
	per_cpu(processors, pr->id) = pr;

	dev = get_cpu_device(pr->id);
	if (!dev) {
		result = -ENODEV;
		goto err;
	}

	result = acpi_bind_one(dev, device);
	if (result)
		goto err;

	pr->dev = dev;

	/* Trigger the processor driver's .probe() if present. */
	if (device_attach(dev) >= 0)
		return 1;

	dev_err(dev, "Processor driver could not be attached\n");
	acpi_unbind_one(dev);

 err:
	free_cpumask_var(pr->throttling.shared_cpu_map);
	device->driver_data = NULL;
	per_cpu(processors, pr->id) = NULL;
 err_free_pr:
	kfree(pr);
	return result;
}

#ifdef CONFIG_ACPI_HOTPLUG_CPU
/* --------------------------------------------------------------------------
                                    Removal
   -------------------------------------------------------------------------- */

static void acpi_processor_remove(struct acpi_device *device)
{
	struct acpi_processor *pr;

	if (!device || !acpi_driver_data(device))
		return;

	pr = acpi_driver_data(device);
	if (pr->id >= nr_cpu_ids)
		goto out;

	/*
	 * The only reason why we ever get here is CPU hot-removal.  The CPU is
	 * already offline and the ACPI device removal locking prevents it from
	 * being put back online at this point.
	 *
	 * Unbind the driver from the processor device and detach it from the
	 * ACPI companion object.
	 */
	device_release_driver(pr->dev);
	acpi_unbind_one(pr->dev);

	/* Clean up. */
	per_cpu(processor_device_array, pr->id) = NULL;
	per_cpu(processors, pr->id) = NULL;

	cpu_maps_update_begin();
	cpu_hotplug_begin();

	/* Remove the CPU. */
	arch_unregister_cpu(pr->id);
	acpi_unmap_cpu(pr->id);

	cpu_hotplug_done();
	cpu_maps_update_done();

	try_offline_node(cpu_to_node(pr->id));

 out:
	free_cpumask_var(pr->throttling.shared_cpu_map);
	kfree(pr);
}
#endif /* CONFIG_ACPI_HOTPLUG_CPU */

#ifdef CONFIG_X86
static bool acpi_hwp_native_thermal_lvt_set;
static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
							  u32 lvl,
							  void *context,
							  void **rv)
{
	u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
	u32 capbuf[2];
	struct acpi_osc_context osc_context = {
		.uuid_str = sb_uuid_str,
		.rev = 1,
		.cap.length = 8,
		.cap.pointer = capbuf,
	};

	if (acpi_hwp_native_thermal_lvt_set)
		return AE_CTRL_TERMINATE;

	capbuf[0] = 0x0000;
	capbuf[1] = 0x1000; /* set bit 12 */

	if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) {
		if (osc_context.ret.pointer && osc_context.ret.length > 1) {
			u32 *capbuf_ret = osc_context.ret.pointer;

			if (capbuf_ret[1] & 0x1000) {
				acpi_handle_info(handle,
					"_OSC native thermal LVT Acked\n");
				acpi_hwp_native_thermal_lvt_set = true;
			}
		}
		kfree(osc_context.ret.pointer);
	}

	return AE_OK;
}

void __init acpi_early_processor_osc(void)
{
	if (boot_cpu_has(X86_FEATURE_HWP)) {
		acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
				    ACPI_UINT32_MAX,
				    acpi_hwp_native_thermal_lvt_osc,
				    NULL, NULL, NULL);
		acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID,
				 acpi_hwp_native_thermal_lvt_osc,
				 NULL, NULL);
	}
}
#endif

/*
 * The following ACPI IDs are known to be suitable for representing as
 * processor devices.
 */
static const struct acpi_device_id processor_device_ids[] = {

	{ ACPI_PROCESSOR_OBJECT_HID, },
	{ ACPI_PROCESSOR_DEVICE_HID, },

	{ }
};

static struct acpi_scan_handler processor_handler = {
	.ids = processor_device_ids,
	.attach = acpi_processor_add,
#ifdef CONFIG_ACPI_HOTPLUG_CPU
	.detach = acpi_processor_remove,
#endif
	.hotplug = {
		.enabled = true,
	},
};

static int acpi_processor_container_attach(struct acpi_device *dev,
					   const struct acpi_device_id *id)
{
	return 1;
}

static const struct acpi_device_id processor_container_ids[] = {
	{ ACPI_PROCESSOR_CONTAINER_HID, },
	{ }
};

static struct acpi_scan_handler processor_container_handler = {
	.ids = processor_container_ids,
	.attach = acpi_processor_container_attach,
};

/* The number of the unique processor IDs */
static int nr_unique_ids __initdata;

/* The number of the duplicate processor IDs */
static int nr_duplicate_ids;

/* Used to store the unique processor IDs */
static int unique_processor_ids[] __initdata = {
	[0 ... NR_CPUS - 1] = -1,
};

/* Used to store the duplicate processor IDs */
static int duplicate_processor_ids[] = {
	[0 ... NR_CPUS - 1] = -1,
};

static void __init processor_validated_ids_update(int proc_id)
{
	int i;

	if (nr_unique_ids == NR_CPUS||nr_duplicate_ids == NR_CPUS)
		return;

	/*
	 * Firstly, compare the proc_id with duplicate IDs, if the proc_id is
	 * already in the IDs, do nothing.
	 */
	for (i = 0; i < nr_duplicate_ids; i++) {
		if (duplicate_processor_ids[i] == proc_id)
			return;
	}

	/*
	 * Secondly, compare the proc_id with unique IDs, if the proc_id is in
	 * the IDs, put it in the duplicate IDs.
	 */
	for (i = 0; i < nr_unique_ids; i++) {
		if (unique_processor_ids[i] == proc_id) {
			duplicate_processor_ids[nr_duplicate_ids] = proc_id;
			nr_duplicate_ids++;
			return;
		}
	}

	/*
	 * Lastly, the proc_id is a unique ID, put it in the unique IDs.
	 */
	unique_processor_ids[nr_unique_ids] = proc_id;
	nr_unique_ids++;
}

static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,
						  u32 lvl,
						  void *context,
						  void **rv)
{
	acpi_status status;
	acpi_object_type acpi_type;
	unsigned long long uid;
	union acpi_object object = { 0 };
	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };

	status = acpi_get_type(handle, &acpi_type);
	if (ACPI_FAILURE(status))
		return status;

	switch (acpi_type) {
	case ACPI_TYPE_PROCESSOR:
		status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
		if (ACPI_FAILURE(status))
			goto err;
		uid = object.processor.proc_id;
		break;

	case ACPI_TYPE_DEVICE:
		status = acpi_evaluate_integer(handle, "_UID", NULL, &uid);
		if (ACPI_FAILURE(status))
			goto err;
		break;
	default:
		goto err;
	}

	processor_validated_ids_update(uid);
	return AE_OK;

err:
	/* Exit on error, but don't abort the namespace walk */
	acpi_handle_info(handle, "Invalid processor object\n");
	return AE_OK;

}

static void __init acpi_processor_check_duplicates(void)
{
	/* check the correctness for all processors in ACPI namespace */
	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
						ACPI_UINT32_MAX,
						acpi_processor_ids_walk,
						NULL, NULL, NULL);
	acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, acpi_processor_ids_walk,
						NULL, NULL);
}

bool acpi_duplicate_processor_id(int proc_id)
{
	int i;

	/*
	 * compare the proc_id with duplicate IDs, if the proc_id is already
	 * in the duplicate IDs, return true, otherwise, return false.
	 */
	for (i = 0; i < nr_duplicate_ids; i++) {
		if (duplicate_processor_ids[i] == proc_id)
			return true;
	}
	return false;
}

void __init acpi_processor_init(void)
{
	acpi_processor_check_duplicates();
	acpi_scan_add_handler_with_hotplug(&processor_handler, "processor");
	acpi_scan_add_handler(&processor_container_handler);
}

#ifdef CONFIG_ACPI_PROCESSOR_CSTATE
/**
 * acpi_processor_claim_cst_control - Request _CST control from the platform.
 */
bool acpi_processor_claim_cst_control(void)
{
	static bool cst_control_claimed;
	acpi_status status;

	if (!acpi_gbl_FADT.cst_control || cst_control_claimed)
		return true;

	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
				    acpi_gbl_FADT.cst_control, 8);
	if (ACPI_FAILURE(status)) {
		pr_warn("ACPI: Failed to claim processor _CST control\n");
		return false;
	}

	cst_control_claimed = true;
	return true;
}
EXPORT_SYMBOL_GPL(acpi_processor_claim_cst_control);

/**
 * acpi_processor_evaluate_cst - Evaluate the processor _CST control method.
 * @handle: ACPI handle of the processor object containing the _CST.
 * @cpu: The numeric ID of the target CPU.
 * @info: Object write the C-states information into.
 *
 * Extract the C-state information for the given CPU from the output of the _CST
 * control method under the corresponding ACPI processor object (or processor
 * device object) and populate @info with it.
 *
 * If any ACPI_ADR_SPACE_FIXED_HARDWARE C-states are found, invoke
 * acpi_processor_ffh_cstate_probe() to verify them and update the
 * cpu_cstate_entry data for @cpu.
 */
int acpi_processor_evaluate_cst(acpi_handle handle, u32 cpu,
				struct acpi_processor_power *info)
{
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *cst;
	acpi_status status;
	u64 count;
	int last_index = 0;
	int i, ret = 0;

	status = acpi_evaluate_object(handle, "_CST", NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_handle_debug(handle, "No _CST\n");
		return -ENODEV;
	}

	cst = buffer.pointer;

	/* There must be at least 2 elements. */
	if (!cst || cst->type != ACPI_TYPE_PACKAGE || cst->package.count < 2) {
		acpi_handle_warn(handle, "Invalid _CST output\n");
		ret = -EFAULT;
		goto end;
	}

	count = cst->package.elements[0].integer.value;

	/* Validate the number of C-states. */
	if (count < 1 || count != cst->package.count - 1) {
		acpi_handle_warn(handle, "Inconsistent _CST data\n");
		ret = -EFAULT;
		goto end;
	}

	for (i = 1; i <= count; i++) {
		union acpi_object *element;
		union acpi_object *obj;
		struct acpi_power_register *reg;
		struct acpi_processor_cx cx;

		/*
		 * If there is not enough space for all C-states, skip the
		 * excess ones and log a warning.
		 */
		if (last_index >= ACPI_PROCESSOR_MAX_POWER - 1) {
			acpi_handle_warn(handle,
					 "No room for more idle states (limit: %d)\n",
					 ACPI_PROCESSOR_MAX_POWER - 1);
			break;
		}

		memset(&cx, 0, sizeof(cx));

		element = &cst->package.elements[i];
		if (element->type != ACPI_TYPE_PACKAGE) {
			acpi_handle_info(handle, "_CST C%d type(%x) is not package, skip...\n",
					 i, element->type);
			continue;
		}

		if (element->package.count != 4) {
			acpi_handle_info(handle, "_CST C%d package count(%d) is not 4, skip...\n",
					 i, element->package.count);
			continue;
		}

		obj = &element->package.elements[0];

		if (obj->type != ACPI_TYPE_BUFFER) {
			acpi_handle_info(handle, "_CST C%d package element[0] type(%x) is not buffer, skip...\n",
					 i, obj->type);
			continue;
		}

		reg = (struct acpi_power_register *)obj->buffer.pointer;

		obj = &element->package.elements[1];
		if (obj->type != ACPI_TYPE_INTEGER) {
			acpi_handle_info(handle, "_CST C[%d] package element[1] type(%x) is not integer, skip...\n",
					 i, obj->type);
			continue;
		}

		cx.type = obj->integer.value;
		/*
		 * There are known cases in which the _CST output does not
		 * contain C1, so if the type of the first state found is not
		 * C1, leave an empty slot for C1 to be filled in later.
		 */
		if (i == 1 && cx.type != ACPI_STATE_C1)
			last_index = 1;

		cx.address = reg->address;
		cx.index = last_index + 1;

		if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
			if (!acpi_processor_ffh_cstate_probe(cpu, &cx, reg)) {
				/*
				 * In the majority of cases _CST describes C1 as
				 * a FIXED_HARDWARE C-state, but if the command
				 * line forbids using MWAIT, use CSTATE_HALT for
				 * C1 regardless.
				 */
				if (cx.type == ACPI_STATE_C1 &&
				    boot_option_idle_override == IDLE_NOMWAIT) {
					cx.entry_method = ACPI_CSTATE_HALT;
					snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");
				} else {
					cx.entry_method = ACPI_CSTATE_FFH;
				}
			} else if (cx.type == ACPI_STATE_C1) {
				/*
				 * In the special case of C1, FIXED_HARDWARE can
				 * be handled by executing the HLT instruction.
				 */
				cx.entry_method = ACPI_CSTATE_HALT;
				snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");
			} else {
				acpi_handle_info(handle, "_CST C%d declares FIXED_HARDWARE C-state but not supported in hardware, skip...\n",
						 i);
				continue;
			}
		} else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
			cx.entry_method = ACPI_CSTATE_SYSTEMIO;
			snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x",
				 cx.address);
		} else {
			acpi_handle_info(handle, "_CST C%d space_id(%x) neither FIXED_HARDWARE nor SYSTEM_IO, skip...\n",
					 i, reg->space_id);
			continue;
		}

		if (cx.type == ACPI_STATE_C1)
			cx.valid = 1;

		obj = &element->package.elements[2];
		if (obj->type != ACPI_TYPE_INTEGER) {
			acpi_handle_info(handle, "_CST C%d package element[2] type(%x) not integer, skip...\n",
					 i, obj->type);
			continue;
		}

		cx.latency = obj->integer.value;

		obj = &element->package.elements[3];
		if (obj->type != ACPI_TYPE_INTEGER) {
			acpi_handle_info(handle, "_CST C%d package element[3] type(%x) not integer, skip...\n",
					 i, obj->type);
			continue;
		}

		memcpy(&info->states[++last_index], &cx, sizeof(cx));
	}

	acpi_handle_info(handle, "Found %d idle states\n", last_index);

	info->count = last_index;

      end:
	kfree(buffer.pointer);

	return ret;
}
EXPORT_SYMBOL_GPL(acpi_processor_evaluate_cst);
#endif /* CONFIG_ACPI_PROCESSOR_CSTATE */
