Skip to content

Commit 60c40b0

Browse files
LiHuiSong1sudeep-holla
authored andcommitted
mailbox: pcc: Add support for platform notification handling
Currently, PCC driver doesn't support the processing of platform notification for type 4 PCC subspaces. According to ACPI specification, if platform sends a notification to OSPM, it must clear the command complete bit and trigger platform interrupt. OSPM needs to check whether the command complete bit is cleared, clear platform interrupt, process command, and then set the command complete and ring doorbell to the Platform. Let us stash the value of the pcc type and use the same while processing the interrupt of the channel. We also need to set the command complete bit and ring doorbell in the interrupt handler for the type 4 channel to complete the communication flow after processing the notification from the Platform. Signed-off-by: Huisong Li <[email protected]> Reviewed-by: Hanjun Guo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sudeep Holla <[email protected]>
1 parent 0bb80ec commit 60c40b0

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

drivers/mailbox/pcc.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ struct pcc_chan_reg {
9191
* @cmd_update: PCC register bundle for the command complete update register
9292
* @error: PCC register bundle for the error status register
9393
* @plat_irq: platform interrupt
94+
* @type: PCC subspace type
9495
*/
9596
struct pcc_chan_info {
9697
struct pcc_mbox_chan chan;
@@ -100,12 +101,15 @@ struct pcc_chan_info {
100101
struct pcc_chan_reg cmd_update;
101102
struct pcc_chan_reg error;
102103
int plat_irq;
104+
u8 type;
103105
};
104106

105107
#define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
106108
static struct pcc_chan_info *chan_info;
107109
static int pcc_chan_count;
108110

111+
static int pcc_send_data(struct mbox_chan *chan, void *data);
112+
109113
/*
110114
* PCC can be used with perf critical drivers such as CPPC
111115
* So it makes sense to locally cache the virtual address and
@@ -221,6 +225,34 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
221225
return acpi_register_gsi(NULL, interrupt, trigger, polarity);
222226
}
223227

228+
static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
229+
{
230+
u64 val;
231+
int ret;
232+
233+
ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
234+
if (ret)
235+
return false;
236+
237+
if (!pchan->cmd_complete.gas)
238+
return true;
239+
240+
/*
241+
* Judge if the channel respond the interrupt based on the value of
242+
* command complete.
243+
*/
244+
val &= pchan->cmd_complete.status_mask;
245+
/*
246+
* If this is PCC slave subspace channel, and the command complete
247+
* bit 0 indicates that Platform is sending a notification and OSPM
248+
* needs to respond this interrupt to process this command.
249+
*/
250+
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
251+
return !val;
252+
253+
return !!val;
254+
}
255+
224256
/**
225257
* pcc_mbox_irq - PCC mailbox interrupt handler
226258
* @irq: interrupt number
@@ -236,17 +268,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
236268
int ret;
237269

238270
pchan = chan->con_priv;
239-
240-
ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
241-
if (ret)
271+
if (!pcc_mbox_cmd_complete_check(pchan))
242272
return IRQ_NONE;
243273

244-
if (val) { /* Ensure GAS exists and value is non-zero */
245-
val &= pchan->cmd_complete.status_mask;
246-
if (!val)
247-
return IRQ_NONE;
248-
}
249-
250274
ret = pcc_chan_reg_read(&pchan->error, &val);
251275
if (ret)
252276
return IRQ_NONE;
@@ -262,6 +286,13 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
262286

263287
mbox_chan_received_data(chan, NULL);
264288

289+
/*
290+
* The PCC slave subspace channel needs to set the command complete bit
291+
* and ring doorbell after processing message.
292+
*/
293+
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
294+
pcc_send_data(chan, NULL);
295+
265296
return IRQ_HANDLED;
266297
}
267298

@@ -698,6 +729,7 @@ static int pcc_mbox_probe(struct platform_device *pdev)
698729

699730
pcc_parse_subspace_shmem(pchan, pcct_entry);
700731

732+
pchan->type = pcct_entry->type;
701733
pcct_entry = (struct acpi_subtable_header *)
702734
((unsigned long) pcct_entry + pcct_entry->length);
703735
}

0 commit comments

Comments
 (0)