brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · 994091b Raw
121 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2005 Intel Corporation4 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.5 *6 *      Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>7 *      - Added _PDC for platforms with Intel CPUs8 */9 10#define pr_fmt(fmt) "ACPI: " fmt11 12#include <linux/slab.h>13#include <linux/acpi.h>14#include <acpi/processor.h>15 16#include "internal.h"17 18static void acpi_set_pdc_bits(u32 *buf)19{20	buf[0] = ACPI_PDC_REVISION_ID;21	buf[1] = 1;22	buf[2] = 0;23 24	/* Twiddle arch-specific bits needed for _PDC */25	arch_acpi_set_proc_cap_bits(&buf[2]);26}27 28static struct acpi_object_list *acpi_processor_alloc_pdc(void)29{30	struct acpi_object_list *obj_list;31	union acpi_object *obj;32	u32 *buf;33 34	/* allocate and initialize pdc. It will be used later. */35	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);36	if (!obj_list)37		goto out;38 39	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);40	if (!obj) {41		kfree(obj_list);42		goto out;43	}44 45	buf = kmalloc(12, GFP_KERNEL);46	if (!buf) {47		kfree(obj);48		kfree(obj_list);49		goto out;50	}51 52	acpi_set_pdc_bits(buf);53 54	obj->type = ACPI_TYPE_BUFFER;55	obj->buffer.length = 12;56	obj->buffer.pointer = (u8 *) buf;57	obj_list->count = 1;58	obj_list->pointer = obj;59 60	return obj_list;61out:62	pr_err("Memory allocation error\n");63	return NULL;64}65 66/*67 * _PDC is required for a BIOS-OS handshake for most of the newer68 * ACPI processor features.69 */70static acpi_status71acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)72{73	acpi_status status = AE_OK;74 75	status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);76 77	if (ACPI_FAILURE(status))78		acpi_handle_debug(handle,79		    "Could not evaluate _PDC, using legacy perf control\n");80 81	return status;82}83 84void acpi_processor_set_pdc(acpi_handle handle)85{86	struct acpi_object_list *obj_list;87 88	if (arch_has_acpi_pdc() == false)89		return;90 91	obj_list = acpi_processor_alloc_pdc();92	if (!obj_list)93		return;94 95	acpi_processor_eval_pdc(handle, obj_list);96 97	kfree(obj_list->pointer->buffer.pointer);98	kfree(obj_list->pointer);99	kfree(obj_list);100}101 102static acpi_status __init103early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)104{105	if (processor_physically_present(handle) == false)106		return AE_OK;107 108	acpi_processor_set_pdc(handle);109	return AE_OK;110}111 112void __init acpi_early_processor_set_pdc(void)113{114	acpi_proc_quirk_mwait_check();115 116	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,117			    ACPI_UINT32_MAX,118			    early_init_pdc, NULL, NULL, NULL);119	acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);120}121