From: "Rafael J. Wysocki" <rafael@kernel.org>
To: Linux ACPI <linux-acpi@vger.kernel.org>,
Jonathan Cameron <jonathan.cameron@huawei.com>
Cc: LKML <linux-kernel@vger.kernel.org>,
Linux PCI <linux-pci@vger.kernel.org>,
Bjorn Helgaas <helgaas@kernel.org>,
Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,
Hans de Goede <hansg@kernel.org>,
Mario Limonciello <mario.limonciello@amd.com>
Subject: [PATCH v2.1 6/8] ACPI: bus: Rework the handling of \_SB._OSC platform features
Date: Mon, 22 Dec 2025 20:21:19 +0100 [thread overview]
Message-ID: <1966378.CQOukoFCf9@rafael.j.wysocki> (raw)
In-Reply-To: <2413407.ElGaqSPkdT@rafael.j.wysocki>
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Both acpi_bus_osc_negotiate_platform_control() and
acpi_bus_osc_negotiate_usb_control() first call acpi_run_osc() to
evaluate _OSC in "query mode", with OSC_QUERY_ENABLE set in the
capabilities buffer, and then use the resultant feature mask as
the input buffer for requesting control of those features by
calling acpi_run_osc() to evaluate _OSC with OSC_QUERY_ENABLE clear.
This involves some code duplication and unnecessary memory
allocations, so introduce a new helper function carrying out an
_OSC handshake along the lines of the above description in a simpler
way and update acpi_bus_osc_negotiate_platform_control() to use it.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v1 -> v2.1:
* Add printing error messages regarding unexpected _OSC errors when
processing a feature mask acknowledged previously (Jonathan).
* Update the changelog after moving the essential change to patch [1/8].
---
drivers/acpi/bus.c | 141 +++++++++++++++++++++++++++++++++++++----------------
1 file changed, 101 insertions(+), 40 deletions(-)
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -325,6 +325,92 @@ out:
}
EXPORT_SYMBOL(acpi_run_osc);
+static int acpi_osc_handshake(acpi_handle handle, const char *uuid_str,
+ int rev, struct acpi_buffer *cap)
+{
+ union acpi_object in_params[4], *out_obj;
+ size_t bufsize = cap->length / sizeof(u32);
+ struct acpi_object_list input;
+ struct acpi_buffer output;
+ u32 *capbuf, *retbuf, test;
+ guid_t guid;
+ int ret, i;
+
+ if (!cap || cap->length < 2 * sizeof(32) || guid_parse(uuid_str, &guid))
+ return -EINVAL;
+
+ /* First evaluate _OSC with OSC_QUERY_ENABLE set. */
+ capbuf = cap->pointer;
+ capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;
+
+ ret = acpi_eval_osc(handle, &guid, rev, cap, in_params, &output);
+ if (ret)
+ return ret;
+
+ out_obj = output.pointer;
+ retbuf = (u32 *)out_obj->buffer.pointer;
+
+ if (acpi_osc_error_check(handle, &guid, rev, cap, retbuf)) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ /*
+ * Clear the feature bits in the capabilities buffer that have not been
+ * acknowledged and clear the return buffer.
+ */
+ for (i = OSC_QUERY_DWORD + 1, test = 0; i < bufsize; i++) {
+ capbuf[i] &= retbuf[i];
+ test |= capbuf[i];
+ retbuf[i] = 0;
+ }
+ /*
+ * If none of the feature bits have been acknowledged, there's nothing
+ * more to do. capbuf[] contains a feature mask of all zeros.
+ */
+ if (!test)
+ goto out;
+
+ retbuf[OSC_QUERY_DWORD] = 0;
+ /*
+ * Now evaluate _OSC again (directly) with OSC_QUERY_ENABLE clear and
+ * the updated input and output buffers used before. Since the feature
+ * bits that were clear in the return buffer from the previous _OSC
+ * evaluation are also clear in the capabilities buffer now, this _OSC
+ * evaluation is not expected to fail.
+ */
+ capbuf[OSC_QUERY_DWORD] = 0;
+ /* Reuse in_params[] populated by acpi_eval_osc(). */
+ input.pointer = in_params;
+ input.count = 4;
+
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_OSC", &input, &output))) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ /*
+ * Clear the feature bits in capbuf[] that have not been acknowledged.
+ * After that, capbuf[] contains the resultant feature mask.
+ */
+ for (i = OSC_QUERY_DWORD + 1; i < bufsize; i++)
+ capbuf[i] &= retbuf[i];
+
+ if (retbuf[OSC_QUERY_DWORD] & OSC_ERROR_MASK) {
+ /*
+ * Complain about the unexpected errors and print diagnostic
+ * information related to them.
+ */
+ acpi_handle_err(handle, "_OSC: errors while processing control request\n");
+ acpi_handle_err(handle, "_OSC: some features may be missing\n");
+ acpi_osc_error_check(handle, &guid, rev, cap, retbuf);
+ }
+
+out:
+ ACPI_FREE(out_obj);
+ return ret;
+}
+
bool osc_sb_apei_support_acked;
/*
@@ -356,19 +442,16 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_sup
bool osc_sb_cppc2_support_acked;
-static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
static void acpi_bus_osc_negotiate_platform_control(void)
{
- u32 capbuf[2], *capbuf_ret;
- struct acpi_osc_context context = {
- .uuid_str = sb_uuid_str,
- .rev = 1,
- .cap.length = 8,
- .cap.pointer = capbuf,
+ static const u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
+ u32 capbuf[2];
+ struct acpi_buffer cap = {
+ .pointer = capbuf,
+ .length = sizeof(capbuf),
};
acpi_handle handle;
- capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;
capbuf[OSC_SUPPORT_DWORD] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
if (IS_ENABLED(CONFIG_ACPI_PROCESSOR_AGGREGATOR))
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT;
@@ -414,43 +497,21 @@ static void acpi_bus_osc_negotiate_platf
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
return;
- if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
- return;
-
- capbuf_ret = context.ret.pointer;
- if (context.ret.length <= OSC_SUPPORT_DWORD) {
- kfree(context.ret.pointer);
+ if (acpi_osc_handshake(handle, sb_uuid_str, 1, &cap))
return;
- }
-
- /*
- * Now run _OSC again with query flag clear and with the caps
- * supported by both the OS and the platform.
- */
- capbuf[OSC_QUERY_DWORD] = 0;
- capbuf[OSC_SUPPORT_DWORD] = capbuf_ret[OSC_SUPPORT_DWORD];
- kfree(context.ret.pointer);
- if (ACPI_FAILURE(acpi_run_osc(handle, &context)))
- return;
-
- capbuf_ret = context.ret.pointer;
- if (context.ret.length > OSC_SUPPORT_DWORD) {
#ifdef CONFIG_ACPI_CPPC_LIB
- osc_sb_cppc2_support_acked = capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;
+ osc_sb_cppc2_support_acked = capbuf[OSC_SUPPORT_DWORD] & OSC_SB_CPCV2_SUPPORT;
#endif
- osc_sb_apei_support_acked =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
- osc_pc_lpi_support_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
- osc_sb_native_usb4_support_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
- osc_cpc_flexible_adr_space_confirmed =
- capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
- }
-
- kfree(context.ret.pointer);
+ osc_sb_apei_support_acked =
+ capbuf[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
+ osc_pc_lpi_support_confirmed =
+ capbuf[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
+ osc_sb_native_usb4_support_confirmed =
+ capbuf[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
+ osc_cpc_flexible_adr_space_confirmed =
+ capbuf[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
}
/*
next prev parent reply other threads:[~2025-12-22 19:26 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-22 18:58 [PATCH v2.1 0/8] ACPI: bus: Rework of the \_SB._OSC handling Rafael J. Wysocki
2025-12-22 19:05 ` [PATCH v2.1 1/8] ACPI: bus: Fix handling of _OSC errors in acpi_run_osc() Rafael J. Wysocki
2025-12-23 11:12 ` Jonathan Cameron
2025-12-23 16:13 ` Rafael J. Wysocki
2025-12-22 19:11 ` [PATCH v2.1 2/8] ACPI: bus: Rework printing debug messages on _OSC errors Rafael J. Wysocki
2025-12-23 11:13 ` Jonathan Cameron
2025-12-22 19:14 ` [PATCH v2.1 3/8] ACPI: bus: Split _OSC evaluation out of acpi_run_osc() Rafael J. Wysocki
2025-12-23 11:18 ` Jonathan Cameron
2025-12-22 19:17 ` [PATCH v2.1 4/8] ACPI: bus: Split _OSC error processing " Rafael J. Wysocki
2025-12-22 19:18 ` [PATCH v2.1 5/8] ACPI: bus: Rename label and use ACPI_FREE() in acpi_run_osc() Rafael J. Wysocki
2025-12-22 19:21 ` Rafael J. Wysocki [this message]
2025-12-23 11:25 ` [PATCH v2.1 6/8] ACPI: bus: Rework the handling of \_SB._OSC platform features Jonathan Cameron
2025-12-22 19:23 ` [PATCH v2.1 7/8] ACPI: bus: Adjust feature mask creation for \_SB._OSC Rafael J. Wysocki
2025-12-23 11:26 ` Jonathan Cameron
2025-12-22 19:26 ` [PATCH v2.1 8/8] ACPI: bus: Rework the handling of \_SB._OSC USB4 features Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1966378.CQOukoFCf9@rafael.j.wysocki \
--to=rafael@kernel.org \
--cc=hansg@kernel.org \
--cc=helgaas@kernel.org \
--cc=jonathan.cameron@huawei.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=srinivas.pandruvada@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.