[net-next v32 1/2] mailbox: pcc: functions for reading and writing PCC extended data
From: Adam Young <hidden>
Date: 2026-03-03 21:37:07
Also in:
lkml
Subsystem:
acpi, acpi component architecture (acpica), acpi pcc(platform communication channel) mailbox driver, mailbox api, the rest · Maintainers:
"Rafael J. Wysocki", Saket Dumbre, Sudeep Holla, Jassi Brar, Linus Torvalds
Adds a function that allows a client to query the number of bytes available to read in order to preallocate buffers for reading. Adds a function that reads from the shared buffer into memory provided by the client. Adds a function that writes from client memory into the shared buffer. Signed-off-by: Adam Young <redacted> --- drivers/mailbox/pcc.c | 86 +++++++++++++++++++++++++++++++++++++++++++ include/acpi/pcc.h | 22 +++++++++++ 2 files changed, 108 insertions(+)
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index 22e70af1ae5d..a8b377a64e05 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c@@ -419,6 +419,92 @@ void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan) } EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); +/** + * pcc_mbox_query_bytes_available - count of bytes cwreadable in the shared buffer + * + * @pchan: pointer to channel associated with buffer + * Return: the number of bytes available to read from the shared buffer + */ +int pcc_mbox_query_bytes_available(struct pcc_mbox_chan *pchan) +{ + struct acpi_pcct_ext_pcc_shared_memory pcc_header; + struct pcc_chan_info *pinfo = pchan->mchan->con_priv; + int data_len; + u64 val; + + pcc_chan_reg_read(&pinfo->cmd_complete, &val); + if (val) { + pr_info("%s Buffer not enabled for reading", __func__); + return -1; + } + memcpy_fromio(&pcc_header, pchan->shmem, + sizeof(pcc_header)); + data_len = pcc_header.length - sizeof(u32) + sizeof(pcc_header); + return data_len; +} +EXPORT_SYMBOL_GPL(pcc_mbox_query_bytes_available); + +/** + * pcc_mbox_read_from_buffer - Copy bytes from shared buffer into data + * + * @pchan: channel associated with the shared buffer + * @len: number of bytes to read + * @data: pointer to memory in which to write the data from the + * shared buffer + * + * Return: number of bytes read and written into daa + */ +int pcc_mbox_read_from_buffer(struct pcc_mbox_chan *pchan, int len, void *data) +{ + struct pcc_chan_info *pinfo = pchan->mchan->con_priv; + int data_len; + u64 val; + + pcc_chan_reg_read(&pinfo->cmd_complete, &val); + if (val) { + pr_info("%s buffer not enabled for reading", __func__); + return -1; + } + data_len = pcc_mbox_query_bytes_available(pchan); + if (len < data_len) + data_len = len; + memcpy_fromio(data, pchan->shmem, len); + return len; +} +EXPORT_SYMBOL_GPL(pcc_mbox_read_from_buffer); + +/** + * pcc_mbox_write_to_buffer - copy the contents of the data + * pointer to the shared buffer. Confirms that the command + * flag has been set prior to writing. Data should be a + * properly formatted extended data buffer. + * pcc_mbox_write_to_buffer + * @pchan: channel + * @len: Length of the overall buffer passed in, including the + * Entire header. The length value in the shared buffer header + * Will be calculated from len. + * @data: Client specific data to be written to the shared buffer. + * Return: number of bytes written to the buffer. + */ +int pcc_mbox_write_to_buffer(struct pcc_mbox_chan *pchan, int len, void *data) +{ + struct acpi_pcct_ext_pcc_shared_memory *pcc_header = data; + /* + * The PCC header length includes the command field + * but not the other values from the header. + */ + pcc_header->length = len - sizeof(struct acpi_pcct_ext_pcc_shared_memory) + sizeof(u32); + + if (len > pchan->shmem_size) + return 0; + + memcpy_toio(pchan->shmem, data, len); + + return len; +} +EXPORT_SYMBOL_GPL(pcc_mbox_write_to_buffer); + + /** * pcc_send_data - Called from Mailbox Controller code. Used * here only to ring the channel doorbell. The PCC client
diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
index 840bfc95bae3..9be1ae358056 100644
--- a/include/acpi/pcc.h
+++ b/include/acpi/pcc.h@@ -37,6 +37,14 @@ struct pcc_mbox_chan { extern struct pcc_mbox_chan * pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id); extern void pcc_mbox_free_channel(struct pcc_mbox_chan *chan); +extern +int pcc_mbox_write_to_buffer(struct pcc_mbox_chan *pchan, int len, void *data); +extern +int pcc_mbox_query_bytes_available(struct pcc_mbox_chan *pchan); +extern +int pcc_mbox_read_from_buffer(struct pcc_mbox_chan *pchan, int len, + void *data); + #else static inline struct pcc_mbox_chan * pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
@@ -44,6 +52,20 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) return ERR_PTR(-ENODEV); } static inline void pcc_mbox_free_channel(struct pcc_mbox_chan *chan) { } +static inline +int pcc_mbox_write_to_buffer(struct pcc_mbox_chan *pchan, int len, void *data) +{ + return 0; +} +static inline int pcc_mbox_query_bytes_available(struct pcc_mbox_chan *pchan); +{ + return 0; +} +static inline +int pcc_mbox_read_from_buffer(struct pcc_mbox_chan *pchan, int len, void *data) +{ + return 0; +} #endif #endif /* _PCC_H */
--
2.43.0