Skip to content

Commit 7f9e19f

Browse files
Adam YoungJassi Brar
authored andcommitted
mailbox: pcc: Check before sending MCTP PCC response ACK
Type 4 PCC channels have an option to send back a response to the platform when they are done processing the request. The flag to indicate whether or not to respond is inside the message body, and thus is not available to the pcc mailbox. If the flag is not set, still set command completion bit after processing message. In order to read the flag, this patch maps the shared buffer to virtual memory. To avoid duplication of mapping the shared buffer is then made available to be used by the driver that uses the mailbox. Signed-off-by: Adam Young <[email protected]> Cc: Sudeep Holla <[email protected]> Signed-off-by: Jassi Brar <[email protected]>
1 parent 81f939d commit 7f9e19f

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed

drivers/mailbox/pcc.c

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,35 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
269269
return !!val;
270270
}
271271

272+
static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
273+
{
274+
struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
275+
276+
if (pchan->type != ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
277+
return;
278+
/* If the memory region has not been mapped, we cannot
279+
* determine if we need to send the message, but we still
280+
* need to set the cmd_update flag before returning.
281+
*/
282+
if (pchan->chan.shmem == NULL) {
283+
pcc_chan_reg_read_modify_write(&pchan->cmd_update);
284+
return;
285+
}
286+
memcpy_fromio(&pcc_hdr, pchan->chan.shmem,
287+
sizeof(struct acpi_pcct_ext_pcc_shared_memory));
288+
/*
289+
* The PCC slave subspace channel needs to set the command complete bit
290+
* after processing message. If the PCC_ACK_FLAG is set, it should also
291+
* ring the doorbell.
292+
*
293+
* The PCC master subspace channel clears chan_in_use to free channel.
294+
*/
295+
if (le32_to_cpup(&pcc_hdr.flags) & PCC_ACK_FLAG_MASK)
296+
pcc_send_data(chan, NULL);
297+
else
298+
pcc_chan_reg_read_modify_write(&pchan->cmd_update);
299+
}
300+
272301
/**
273302
* pcc_mbox_irq - PCC mailbox interrupt handler
274303
* @irq: interrupt number
@@ -306,14 +335,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
306335

307336
mbox_chan_received_data(chan, NULL);
308337

309-
/*
310-
* The PCC slave subspace channel needs to set the command complete bit
311-
* and ring doorbell after processing message.
312-
*
313-
* The PCC master subspace channel clears chan_in_use to free channel.
314-
*/
315-
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
316-
pcc_send_data(chan, NULL);
338+
check_and_ack(pchan, chan);
317339
pchan->chan_in_use = false;
318340

319341
return IRQ_HANDLED;
@@ -365,14 +387,37 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
365387
void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
366388
{
367389
struct mbox_chan *chan = pchan->mchan;
390+
struct pcc_chan_info *pchan_info;
391+
struct pcc_mbox_chan *pcc_mbox_chan;
368392

369393
if (!chan || !chan->cl)
370394
return;
395+
pchan_info = chan->con_priv;
396+
pcc_mbox_chan = &pchan_info->chan;
397+
if (pcc_mbox_chan->shmem) {
398+
iounmap(pcc_mbox_chan->shmem);
399+
pcc_mbox_chan->shmem = NULL;
400+
}
371401

372402
mbox_free_channel(chan);
373403
}
374404
EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
375405

406+
int pcc_mbox_ioremap(struct mbox_chan *chan)
407+
{
408+
struct pcc_chan_info *pchan_info;
409+
struct pcc_mbox_chan *pcc_mbox_chan;
410+
411+
if (!chan || !chan->cl)
412+
return -1;
413+
pchan_info = chan->con_priv;
414+
pcc_mbox_chan = &pchan_info->chan;
415+
pcc_mbox_chan->shmem = ioremap(pcc_mbox_chan->shmem_base_addr,
416+
pcc_mbox_chan->shmem_size);
417+
return 0;
418+
}
419+
EXPORT_SYMBOL_GPL(pcc_mbox_ioremap);
420+
376421
/**
377422
* pcc_send_data - Called from Mailbox Controller code. Used
378423
* here only to ring the channel doorbell. The PCC client

include/acpi/pcc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
struct pcc_mbox_chan {
1313
struct mbox_chan *mchan;
1414
u64 shmem_base_addr;
15+
void __iomem *shmem;
1516
u64 shmem_size;
1617
u32 latency;
1718
u32 max_access_rate;
@@ -31,18 +32,24 @@ struct pcc_mbox_chan {
3132
#define PCC_CMD_COMPLETION_NOTIFY BIT(0)
3233

3334
#define MAX_PCC_SUBSPACES 256
35+
#define PCC_ACK_FLAG_MASK 0x1
3436

3537
#ifdef CONFIG_PCC
3638
extern struct pcc_mbox_chan *
3739
pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);
3840
extern void pcc_mbox_free_channel(struct pcc_mbox_chan *chan);
41+
extern int pcc_mbox_ioremap(struct mbox_chan *chan);
3942
#else
4043
static inline struct pcc_mbox_chan *
4144
pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
4245
{
4346
return ERR_PTR(-ENODEV);
4447
}
4548
static inline void pcc_mbox_free_channel(struct pcc_mbox_chan *chan) { }
49+
static inline int pcc_mbox_ioremap(struct mbox_chan *chan)
50+
{
51+
return 0;
52+
};
4653
#endif
4754

4855
#endif /* _PCC_H */

0 commit comments

Comments
 (0)