Commit b1d03b7e authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'acpi-cppc', 'acpi-pcc', 'acpi-apei' and 'acpi-osi'

Merge new material related to CPPC, PCC, APEI and OSI strings handling
for 6.1-rc1:

 - Disable frequency invariance in the CPPC library if registers used
   by cppc_get_perf_ctrs() are accessed via PCC (Jeremy Linton).

 - Add ACPI disabled check to acpi_cpc_valid() (Perry Yuan).

 - Fix Tx acknowledge in the PCC address space handler (Huisong Li).

 - Use wait_for_completion_timeout() for PCC mailbox operations (Huisong
   Li).

 - Release resources on PCC address space setup failure path (Rafael
   Mendonca).

 - Remove unneeded result variables from APEI code (ye xingchen).

 - Print total number of records found during BERT log parsing (Dmitry
   Monakhov).

 - Drop support for 3 _OSI strings that should not be necessary any
   more and update documentation on custom _OSI strings so that adding
   new ones is not encouraged any more (Mario Limonciello).

* acpi-cppc:
  ACPI: CPPC: Disable FIE if registers in PCC regions
  ACPI: CPPC: Add ACPI disabled check to acpi_cpc_valid()

* acpi-pcc:
  ACPI: PCC: Fix Tx acknowledge in the PCC address space handler
  ACPI: PCC: replace wait_for_completion()
  ACPI: PCC: Release resources on address space setup failure path

* acpi-apei:
  ACPI: APEI: Remove unneeded result variables
  ACPI: APEI: Add BERT error log footer

* acpi-osi:
  ACPI: OSI: Update Documentation on custom _OSI strings
  ACPI: OSI: Remove Linux-HPI-Hybrid-Graphics _OSI string
  ACPI: OSI: Remove Linux-Lenovo-NV-HDMI-Audio _OSI string
  ACPI: OSI: Remove Linux-Dell-Video _OSI string
Loading
Loading
Loading
Loading
+11 −14
Original line number Original line Diff line number Diff line
@@ -41,26 +41,23 @@ But it is likely that they will all eventually be added.
What should an OEM do if they want to support Linux and Windows
What should an OEM do if they want to support Linux and Windows
using the same BIOS image?  Often they need to do something different
using the same BIOS image?  Often they need to do something different
for Linux to deal with how Linux is different from Windows.
for Linux to deal with how Linux is different from Windows.
Here the BIOS should ask exactly what it wants to know:


In this case, the OEM should create custom ASL to be executed by the
Linux kernel and changes to Linux kernel drivers to execute this custom
ASL.  The easiest way to accomplish this is to introduce a device specific
method (_DSM) that is called from the Linux kernel.

In the past the kernel used to support something like:
_OSI("Linux-OEM-my_interface_name")
_OSI("Linux-OEM-my_interface_name")
where 'OEM' is needed if this is an OEM-specific hook,
where 'OEM' is needed if this is an OEM-specific hook,
and 'my_interface_name' describes the hook, which could be a
and 'my_interface_name' describes the hook, which could be a
quirk, a bug, or a bug-fix.
quirk, a bug, or a bug-fix.


In addition, the OEM should send a patch to upstream Linux
However this was discovered to be abused by other BIOS vendors to change
via the linux-acpi@vger.kernel.org mailing list.  When that patch
completely unrelated code on completely unrelated systems.  This prompted
is checked into Linux, the OS will answer "YES" when the BIOS
an evaluation of all of it's uses. This uncovered that they aren't needed
on the OEM's system uses _OSI to ask if the interface is supported
for any of the original reasons. As such, the kernel will not respond to
by the OS.  Linux distributors can back-port that patch for Linux
any custom Linux-* strings by default.
pre-installs, and it will be included by all distributions that
re-base to upstream.  If the distribution can not update the kernel binary,
they can also add an acpi_osi=Linux-OEM-my_interface_name
cmdline parameter to the boot loader, as needed.

If the string refers to a feature where the upstream kernel
eventually grows support, a patch should be sent to remove
the string when that support is added to the kernel.


That was easy.  Read on, to find out how to do it wrong.
That was easy.  Read on, to find out how to do it wrong.


+25 −3
Original line number Original line Diff line number Diff line
@@ -23,6 +23,12 @@


#include <acpi/pcc.h>
#include <acpi/pcc.h>


/*
 * Arbitrary retries in case the remote processor is slow to respond
 * to PCC commands
 */
#define PCC_CMD_WAIT_RETRIES_NUM	500

struct pcc_data {
struct pcc_data {
	struct pcc_mbox_chan *pcc_chan;
	struct pcc_mbox_chan *pcc_chan;
	void __iomem *pcc_comm_addr;
	void __iomem *pcc_comm_addr;
@@ -63,6 +69,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
	if (IS_ERR(data->pcc_chan)) {
	if (IS_ERR(data->pcc_chan)) {
		pr_err("Failed to find PCC channel for subspace %d\n",
		pr_err("Failed to find PCC channel for subspace %d\n",
		       ctx->subspace_id);
		       ctx->subspace_id);
		kfree(data);
		return AE_NOT_FOUND;
		return AE_NOT_FOUND;
	}
	}


@@ -72,6 +79,8 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
	if (!data->pcc_comm_addr) {
	if (!data->pcc_comm_addr) {
		pr_err("Failed to ioremap PCC comm region mem for %d\n",
		pr_err("Failed to ioremap PCC comm region mem for %d\n",
		       ctx->subspace_id);
		       ctx->subspace_id);
		pcc_mbox_free_channel(data->pcc_chan);
		kfree(data);
		return AE_NO_MEMORY;
		return AE_NO_MEMORY;
	}
	}


@@ -86,6 +95,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
{
{
	int ret;
	int ret;
	struct pcc_data *data = region_context;
	struct pcc_data *data = region_context;
	u64 usecs_lat;


	reinit_completion(&data->done);
	reinit_completion(&data->done);


@@ -96,10 +106,22 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
	if (ret < 0)
	if (ret < 0)
		return AE_ERROR;
		return AE_ERROR;


	if (data->pcc_chan->mchan->mbox->txdone_irq)
	if (data->pcc_chan->mchan->mbox->txdone_irq) {
		wait_for_completion(&data->done);
		/*
		 * pcc_chan->latency is just a Nominal value. In reality the remote
		 * processor could be much slower to reply. So add an arbitrary
		 * amount of wait on top of Nominal.
		 */
		usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
		ret = wait_for_completion_timeout(&data->done,
						  usecs_to_jiffies(usecs_lat));
		if (ret == 0) {
			pr_err("PCC command executed timeout!\n");
			return AE_TIME;
		}
	}


	mbox_client_txdone(data->pcc_chan->mchan, ret);
	mbox_chan_txdone(data->pcc_chan->mchan, ret);


	memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length);
	memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length);


+1 −4
Original line number Original line Diff line number Diff line
@@ -125,12 +125,9 @@ EXPORT_SYMBOL_GPL(apei_exec_write_register);
int apei_exec_write_register_value(struct apei_exec_context *ctx,
int apei_exec_write_register_value(struct apei_exec_context *ctx,
				   struct acpi_whea_header *entry)
				   struct acpi_whea_header *entry)
{
{
	int rc;

	ctx->value = entry->value;
	ctx->value = entry->value;
	rc = apei_exec_write_register(ctx, entry);


	return rc;
	return apei_exec_write_register(ctx, entry);
}
}
EXPORT_SYMBOL_GPL(apei_exec_write_register_value);
EXPORT_SYMBOL_GPL(apei_exec_write_register_value);


+3 −0
Original line number Original line Diff line number Diff line
@@ -90,6 +90,9 @@ static void __init bert_print_all(struct acpi_bert_region *region,


	if (skipped)
	if (skipped)
		pr_info(HW_ERR "Skipped %d error records\n", skipped);
		pr_info(HW_ERR "Skipped %d error records\n", skipped);

	if (printed + skipped)
		pr_info("Total records found: %d\n", printed + skipped);
}
}


static int __init setup_bert_disable(char *str)
static int __init setup_bert_disable(char *str)
+1 −5
Original line number Original line Diff line number Diff line
@@ -1020,14 +1020,10 @@ static int reader_pos;


static int erst_open_pstore(struct pstore_info *psi)
static int erst_open_pstore(struct pstore_info *psi)
{
{
	int rc;

	if (erst_disable)
	if (erst_disable)
		return -ENODEV;
		return -ENODEV;


	rc = erst_get_record_id_begin(&reader_pos);
	return erst_get_record_id_begin(&reader_pos);

	return rc;
}
}


static int erst_close_pstore(struct pstore_info *psi)
static int erst_close_pstore(struct pstore_info *psi)
Loading