hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/acpi/acpi_processor.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * acpi_processor.c - ACPI processor enumeration support
34 *
....@@ -7,10 +8,6 @@
78 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
89 * Copyright (C) 2013, Intel Corporation
910 * Rafael J. Wysocki <rafael.j.wysocki@intel.com>
10
- *
11
- * This program is free software; you can redistribute it and/or modify it
12
- * under the terms of the GNU General Public License version 2 as published
13
- * by the Free Software Foundation.
1411 */
1512
1613 #include <linux/acpi.h>
....@@ -82,7 +79,7 @@
8279 * PIIX4 models.
8380 */
8481 errata.piix4.throttle = 1;
85
- /* fall through*/
82
+ fallthrough;
8683
8784 case 2: /* PIIX4E */
8885 case 3: /* PIIX4M */
....@@ -267,7 +264,6 @@
267264 } else {
268265 /*
269266 * Declared with "Device" statement; match _UID.
270
- * Note that we don't handle string _UIDs yet.
271267 */
272268 status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
273269 NULL, &value);
....@@ -708,3 +704,207 @@
708704 acpi_scan_add_handler_with_hotplug(&processor_handler, "processor");
709705 acpi_scan_add_handler(&processor_container_handler);
710706 }
707
+
708
+#ifdef CONFIG_ACPI_PROCESSOR_CSTATE
709
+/**
710
+ * acpi_processor_claim_cst_control - Request _CST control from the platform.
711
+ */
712
+bool acpi_processor_claim_cst_control(void)
713
+{
714
+ static bool cst_control_claimed;
715
+ acpi_status status;
716
+
717
+ if (!acpi_gbl_FADT.cst_control || cst_control_claimed)
718
+ return true;
719
+
720
+ status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
721
+ acpi_gbl_FADT.cst_control, 8);
722
+ if (ACPI_FAILURE(status)) {
723
+ pr_warn("ACPI: Failed to claim processor _CST control\n");
724
+ return false;
725
+ }
726
+
727
+ cst_control_claimed = true;
728
+ return true;
729
+}
730
+EXPORT_SYMBOL_GPL(acpi_processor_claim_cst_control);
731
+
732
+/**
733
+ * acpi_processor_evaluate_cst - Evaluate the processor _CST control method.
734
+ * @handle: ACPI handle of the processor object containing the _CST.
735
+ * @cpu: The numeric ID of the target CPU.
736
+ * @info: Object write the C-states information into.
737
+ *
738
+ * Extract the C-state information for the given CPU from the output of the _CST
739
+ * control method under the corresponding ACPI processor object (or processor
740
+ * device object) and populate @info with it.
741
+ *
742
+ * If any ACPI_ADR_SPACE_FIXED_HARDWARE C-states are found, invoke
743
+ * acpi_processor_ffh_cstate_probe() to verify them and update the
744
+ * cpu_cstate_entry data for @cpu.
745
+ */
746
+int acpi_processor_evaluate_cst(acpi_handle handle, u32 cpu,
747
+ struct acpi_processor_power *info)
748
+{
749
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
750
+ union acpi_object *cst;
751
+ acpi_status status;
752
+ u64 count;
753
+ int last_index = 0;
754
+ int i, ret = 0;
755
+
756
+ status = acpi_evaluate_object(handle, "_CST", NULL, &buffer);
757
+ if (ACPI_FAILURE(status)) {
758
+ acpi_handle_debug(handle, "No _CST\n");
759
+ return -ENODEV;
760
+ }
761
+
762
+ cst = buffer.pointer;
763
+
764
+ /* There must be at least 2 elements. */
765
+ if (!cst || cst->type != ACPI_TYPE_PACKAGE || cst->package.count < 2) {
766
+ acpi_handle_warn(handle, "Invalid _CST output\n");
767
+ ret = -EFAULT;
768
+ goto end;
769
+ }
770
+
771
+ count = cst->package.elements[0].integer.value;
772
+
773
+ /* Validate the number of C-states. */
774
+ if (count < 1 || count != cst->package.count - 1) {
775
+ acpi_handle_warn(handle, "Inconsistent _CST data\n");
776
+ ret = -EFAULT;
777
+ goto end;
778
+ }
779
+
780
+ for (i = 1; i <= count; i++) {
781
+ union acpi_object *element;
782
+ union acpi_object *obj;
783
+ struct acpi_power_register *reg;
784
+ struct acpi_processor_cx cx;
785
+
786
+ /*
787
+ * If there is not enough space for all C-states, skip the
788
+ * excess ones and log a warning.
789
+ */
790
+ if (last_index >= ACPI_PROCESSOR_MAX_POWER - 1) {
791
+ acpi_handle_warn(handle,
792
+ "No room for more idle states (limit: %d)\n",
793
+ ACPI_PROCESSOR_MAX_POWER - 1);
794
+ break;
795
+ }
796
+
797
+ memset(&cx, 0, sizeof(cx));
798
+
799
+ element = &cst->package.elements[i];
800
+ if (element->type != ACPI_TYPE_PACKAGE) {
801
+ acpi_handle_info(handle, "_CST C%d type(%x) is not package, skip...\n",
802
+ i, element->type);
803
+ continue;
804
+ }
805
+
806
+ if (element->package.count != 4) {
807
+ acpi_handle_info(handle, "_CST C%d package count(%d) is not 4, skip...\n",
808
+ i, element->package.count);
809
+ continue;
810
+ }
811
+
812
+ obj = &element->package.elements[0];
813
+
814
+ if (obj->type != ACPI_TYPE_BUFFER) {
815
+ acpi_handle_info(handle, "_CST C%d package element[0] type(%x) is not buffer, skip...\n",
816
+ i, obj->type);
817
+ continue;
818
+ }
819
+
820
+ reg = (struct acpi_power_register *)obj->buffer.pointer;
821
+
822
+ obj = &element->package.elements[1];
823
+ if (obj->type != ACPI_TYPE_INTEGER) {
824
+ acpi_handle_info(handle, "_CST C[%d] package element[1] type(%x) is not integer, skip...\n",
825
+ i, obj->type);
826
+ continue;
827
+ }
828
+
829
+ cx.type = obj->integer.value;
830
+ /*
831
+ * There are known cases in which the _CST output does not
832
+ * contain C1, so if the type of the first state found is not
833
+ * C1, leave an empty slot for C1 to be filled in later.
834
+ */
835
+ if (i == 1 && cx.type != ACPI_STATE_C1)
836
+ last_index = 1;
837
+
838
+ cx.address = reg->address;
839
+ cx.index = last_index + 1;
840
+
841
+ if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
842
+ if (!acpi_processor_ffh_cstate_probe(cpu, &cx, reg)) {
843
+ /*
844
+ * In the majority of cases _CST describes C1 as
845
+ * a FIXED_HARDWARE C-state, but if the command
846
+ * line forbids using MWAIT, use CSTATE_HALT for
847
+ * C1 regardless.
848
+ */
849
+ if (cx.type == ACPI_STATE_C1 &&
850
+ boot_option_idle_override == IDLE_NOMWAIT) {
851
+ cx.entry_method = ACPI_CSTATE_HALT;
852
+ snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");
853
+ } else {
854
+ cx.entry_method = ACPI_CSTATE_FFH;
855
+ }
856
+ } else if (cx.type == ACPI_STATE_C1) {
857
+ /*
858
+ * In the special case of C1, FIXED_HARDWARE can
859
+ * be handled by executing the HLT instruction.
860
+ */
861
+ cx.entry_method = ACPI_CSTATE_HALT;
862
+ snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");
863
+ } else {
864
+ acpi_handle_info(handle, "_CST C%d declares FIXED_HARDWARE C-state but not supported in hardware, skip...\n",
865
+ i);
866
+ continue;
867
+ }
868
+ } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
869
+ cx.entry_method = ACPI_CSTATE_SYSTEMIO;
870
+ snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x",
871
+ cx.address);
872
+ } else {
873
+ acpi_handle_info(handle, "_CST C%d space_id(%x) neither FIXED_HARDWARE nor SYSTEM_IO, skip...\n",
874
+ i, reg->space_id);
875
+ continue;
876
+ }
877
+
878
+ if (cx.type == ACPI_STATE_C1)
879
+ cx.valid = 1;
880
+
881
+ obj = &element->package.elements[2];
882
+ if (obj->type != ACPI_TYPE_INTEGER) {
883
+ acpi_handle_info(handle, "_CST C%d package element[2] type(%x) not integer, skip...\n",
884
+ i, obj->type);
885
+ continue;
886
+ }
887
+
888
+ cx.latency = obj->integer.value;
889
+
890
+ obj = &element->package.elements[3];
891
+ if (obj->type != ACPI_TYPE_INTEGER) {
892
+ acpi_handle_info(handle, "_CST C%d package element[3] type(%x) not integer, skip...\n",
893
+ i, obj->type);
894
+ continue;
895
+ }
896
+
897
+ memcpy(&info->states[++last_index], &cx, sizeof(cx));
898
+ }
899
+
900
+ acpi_handle_info(handle, "Found %d idle states\n", last_index);
901
+
902
+ info->count = last_index;
903
+
904
+ end:
905
+ kfree(buffer.pointer);
906
+
907
+ return ret;
908
+}
909
+EXPORT_SYMBOL_GPL(acpi_processor_evaluate_cst);
910
+#endif /* CONFIG_ACPI_PROCESSOR_CSTATE */