[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251202101215.2240024-1-andrea.tomassetti@sipearl.com>
Date: Tue, 2 Dec 2025 11:12:14 +0100
From: Andrea Tomassetti <andrea.tomassetti@...earl.com>
To: <sudeep.holla@....com>
CC: <andrea.tomassetti@...earl.com>, <jassisinghbrar@...il.com>,
<lenb@...nel.org>, <linux-acpi@...r.kernel.org>,
<linux-kernel@...r.kernel.org>, <lkp@...el.com>,
<oe-kbuild-all@...ts.linux.dev>, <olivier.dautricourt@...earl.com>,
<olivierdautricourt@...il.com>, <rafael@...nel.org>,
<thibault.cantori@...earl.com>
Subject: [PATCH v3 1/2] mailbox: pcc: support polling mode when there is no platform IRQ
The goal is to allow clients to submit a message in both irq and polling
mode of the pcc mailbox. The ACPI specification does not require a
platform irq for pcc channels. Let's implement the case where it is not
available.
Tested-by: Thibault Cantori <thibault.cantori@...earl.com>
Co-developed-by: Olivier Dautricourt <olivier.dautricourt@...earl.com>
Signed-off-by: Olivier Dautricourt <olivier.dautricourt@...earl.com>
Signed-off-by: Andrea Tomassetti <andrea.tomassetti@...earl.com>
Reported-by: kernel test robot <lkp@...el.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202511120243.soxAFpqQ-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202511120558.Cln7LF6M-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202511120729.R3XQNSnx-lkp@intel.com/
---
v3: Thank you very much for the feedback Sudeep! Here there are the changes
implemented in this latest version:
- separate the changes to the PCC OpRegion handler and the PCC mailbox
driver into individual patches
- rebased the changes on top of the ongoing cleanup work
v2: Fix issues reported by the kernel test robot
- sparse: incorrect type in argument 2 (different address spaces)
- acpi_pcc.c:(.text+0x69): undefined reference to `__udivdi3'
drivers/acpi/acpi_pcc.c | 78 ++++++++++++++++++++++++++++-------------
1 file changed, 53 insertions(+), 25 deletions(-)
diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c
index 97064e943768..37f94fa4c424 100644
--- a/drivers/acpi/acpi_pcc.c
+++ b/drivers/acpi/acpi_pcc.c
@@ -51,7 +51,6 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
{
struct pcc_data *data;
struct acpi_pcc_info *ctx = handler_context;
- struct pcc_mbox_chan *pcc_chan;
static acpi_status ret;
data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -59,7 +58,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
return AE_NO_MEMORY;
data->cl.rx_callback = pcc_rx_callback;
- data->cl.knows_txdone = true;
+ data->cl.knows_txdone = false;
data->ctx.length = ctx->length;
data->ctx.subspace_id = ctx->subspace_id;
data->ctx.internal_buffer = ctx->internal_buffer;
@@ -73,61 +72,90 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
goto err_free_data;
}
- pcc_chan = data->pcc_chan;
- if (!pcc_chan->mchan->mbox->txdone_irq) {
- pr_err("This channel-%d does not support interrupt.\n",
- ctx->subspace_id);
- ret = AE_SUPPORT;
- goto err_free_channel;
- }
-
*region_context = data;
return AE_OK;
-err_free_channel:
- pcc_mbox_free_channel(data->pcc_chan);
err_free_data:
kfree(data);
return ret;
}
+static acpi_status
+acpi_pcc_send_msg_polling(struct pcc_data *data)
+{
+ int ret;
+
+ ret = mbox_send_message(data->pcc_chan->mchan,
+ (__force void *)data->pcc_chan->shmem);
+ if (ret == -ETIME) {
+ pr_err("PCC command executed timeout!\n");
+ return AE_TIME;
+ }
+
+ if (ret < 0)
+ return AE_ERROR;
+
+ if (!mbox_client_peek_data(data->pcc_chan->mchan))
+ return AE_ERROR;
+
+ return AE_OK;
+}
+
+static acpi_status
+acpi_pcc_send_msg_irq(struct pcc_data *data)
+{
+ int ret;
+
+ ret = mbox_send_message(data->pcc_chan->mchan, NULL);
+ if (ret < 0)
+ return AE_ERROR;
+
+ ret = wait_for_completion_timeout(&data->done,
+ usecs_to_jiffies(data->cl.tx_tout * USEC_PER_MSEC));
+ if (ret == 0) {
+ pr_err("PCC command executed timeout!\n");
+ return AE_TIME;
+ }
+
+ mbox_chan_txdone(data->pcc_chan->mchan, ret);
+
+ return AE_OK;
+}
+
static acpi_status
acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
u32 bits, acpi_integer *value,
void *handler_context, void *region_context)
{
- int ret;
+ acpi_status ret;
struct pcc_data *data = region_context;
u64 usecs_lat;
+ bool use_polling = data->pcc_chan->mchan->mbox->txdone_poll;
reinit_completion(&data->done);
/* Write to Shared Memory */
memcpy_toio(data->pcc_chan->shmem, (void *)value, data->ctx.length);
- ret = mbox_send_message(data->pcc_chan->mchan, NULL);
- if (ret < 0)
- return AE_ERROR;
-
/*
* 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_chan_txdone(data->pcc_chan->mchan, ret);
+ data->cl.tx_block = use_polling;
+ data->cl.tx_tout = div_u64(usecs_lat, USEC_PER_MSEC);
+
+ if (use_polling)
+ ret = acpi_pcc_send_msg_polling(data);
+ else
+ ret = acpi_pcc_send_msg_irq(data);
memcpy_fromio(value, data->pcc_chan->shmem, data->ctx.length);
- return AE_OK;
+ return ret;
}
void __init acpi_init_pcc(void)
--
2.51.2
Powered by blists - more mailing lists