Skip to content

Commit aa2e505

Browse files
committed
Merge tag 'acpi-pcc-updates-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux
Merge ACPI PCC changes for v6.7 from Sudeep Holla: "ACPI: PCC: Mailbox and generic updates for v6.7 Main updates include: 1. Addition of support for Type 4 PCC subspace that enables platform notification handling (Huisong Li). 2. Support for the shared interrupt amongst multiple PCC subspaces/ channels (Huisong Li). 3. Consolidation of PCC shared memory region command and status bitfields definitions that were duplicated and scattered across multiple PCC client drivers (Sudeep Holla)." * tag 'acpi-pcc-updates-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: soc: kunpeng_hccs: Migrate to use generic PCC shmem related macros hwmon: (xgene) Migrate to use generic PCC shmem related macros i2c: xgene-slimpro: Migrate to use generic PCC shmem related macros ACPI: PCC: Add PCC shared memory region command and status bitfields mailbox: pcc: Support shared interrupt for multiple subspaces mailbox: pcc: Add support for platform notification handling
2 parents 8a749fd + a46e42c commit aa2e505

File tree

5 files changed

+104
-40
lines changed

5 files changed

+104
-40
lines changed

drivers/hwmon/xgene-hwmon.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@
5757
(MSG_TYPE_SET(MSG_TYPE_PWRMGMT) | \
5858
MSG_SUBTYPE_SET(hndl) | TPC_CMD_SET(cmd) | type)
5959

60-
/* PCC defines */
61-
#define PCC_SIGNATURE_MASK 0x50424300
62-
#define PCCC_GENERATE_DB_INT BIT(15)
63-
#define PCCS_CMD_COMPLETE BIT(0)
64-
#define PCCS_SCI_DOORBEL BIT(1)
65-
#define PCCS_PLATFORM_NOTIFICATION BIT(3)
6660
/*
6761
* Arbitrary retries in case the remote processor is slow to respond
6862
* to PCC commands
@@ -142,15 +136,15 @@ static int xgene_hwmon_pcc_rd(struct xgene_hwmon_dev *ctx, u32 *msg)
142136

143137
/* Write signature for subspace */
144138
WRITE_ONCE(generic_comm_base->signature,
145-
cpu_to_le32(PCC_SIGNATURE_MASK | ctx->mbox_idx));
139+
cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx));
146140

147141
/* Write to the shared command region */
148142
WRITE_ONCE(generic_comm_base->command,
149-
cpu_to_le16(MSG_TYPE(msg[0]) | PCCC_GENERATE_DB_INT));
143+
cpu_to_le16(MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR));
150144

151145
/* Flip CMD COMPLETE bit */
152146
val = le16_to_cpu(READ_ONCE(generic_comm_base->status));
153-
val &= ~PCCS_CMD_COMPLETE;
147+
val &= ~PCC_STATUS_CMD_COMPLETE;
154148
WRITE_ONCE(generic_comm_base->status, cpu_to_le16(val));
155149

156150
/* Copy the message to the PCC comm space */
@@ -544,7 +538,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
544538
msg = generic_comm_base + 1;
545539
/* Check if platform sends interrupt */
546540
if (!xgene_word_tst_and_clr(&generic_comm_base->status,
547-
PCCS_SCI_DOORBEL))
541+
PCC_STATUS_SCI_DOORBELL))
548542
return;
549543

550544
/*
@@ -566,7 +560,7 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
566560
TPC_CMD(((u32 *)msg)[0]) == TPC_ALARM))) {
567561
/* Check if platform completes command */
568562
if (xgene_word_tst_and_clr(&generic_comm_base->status,
569-
PCCS_CMD_COMPLETE)) {
563+
PCC_STATUS_CMD_COMPLETE)) {
570564
ctx->sync_msg.msg = ((u32 *)msg)[0];
571565
ctx->sync_msg.param1 = ((u32 *)msg)[1];
572566
ctx->sync_msg.param2 = ((u32 *)msg)[2];

drivers/i2c/busses/i2c-xgene-slimpro.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,6 @@
9191

9292
#define SLIMPRO_IIC_MSG_DWORD_COUNT 3
9393

94-
/* PCC related defines */
95-
#define PCC_SIGNATURE 0x50424300
96-
#define PCC_STS_CMD_COMPLETE BIT(0)
97-
#define PCC_STS_SCI_DOORBELL BIT(1)
98-
#define PCC_STS_ERR BIT(2)
99-
#define PCC_STS_PLAT_NOTIFY BIT(3)
100-
#define PCC_CMD_GENERATE_DB_INT BIT(15)
101-
10294
struct slimpro_i2c_dev {
10395
struct i2c_adapter adapter;
10496
struct device *dev;
@@ -160,11 +152,11 @@ static void slimpro_i2c_pcc_rx_cb(struct mbox_client *cl, void *msg)
160152

161153
/* Check if platform sends interrupt */
162154
if (!xgene_word_tst_and_clr(&generic_comm_base->status,
163-
PCC_STS_SCI_DOORBELL))
155+
PCC_STATUS_SCI_DOORBELL))
164156
return;
165157

166158
if (xgene_word_tst_and_clr(&generic_comm_base->status,
167-
PCC_STS_CMD_COMPLETE)) {
159+
PCC_STATUS_CMD_COMPLETE)) {
168160
msg = generic_comm_base + 1;
169161

170162
/* Response message msg[1] contains the return value. */
@@ -186,10 +178,10 @@ static void slimpro_i2c_pcc_tx_prepare(struct slimpro_i2c_dev *ctx, u32 *msg)
186178
cpu_to_le32(PCC_SIGNATURE | ctx->mbox_idx));
187179

188180
WRITE_ONCE(generic_comm_base->command,
189-
cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INT));
181+
cpu_to_le16(SLIMPRO_MSG_TYPE(msg[0]) | PCC_CMD_GENERATE_DB_INTR));
190182

191183
status = le16_to_cpu(READ_ONCE(generic_comm_base->status));
192-
status &= ~PCC_STS_CMD_COMPLETE;
184+
status &= ~PCC_STATUS_CMD_COMPLETE;
193185
WRITE_ONCE(generic_comm_base->status, cpu_to_le16(status));
194186

195187
/* Copy the message to the PCC comm space */

drivers/mailbox/pcc.c

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ 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
95+
* @plat_irq_flags: platform interrupt flags
96+
* @chan_in_use: this flag is used just to check if the interrupt needs
97+
* handling when it is shared. Since only one transfer can occur
98+
* at a time and mailbox takes care of locking, this flag can be
99+
* accessed without a lock. Note: the type only support the
100+
* communication from OSPM to Platform, like type3, use it, and
101+
* other types completely ignore it.
94102
*/
95103
struct pcc_chan_info {
96104
struct pcc_mbox_chan chan;
@@ -100,12 +108,17 @@ struct pcc_chan_info {
100108
struct pcc_chan_reg cmd_update;
101109
struct pcc_chan_reg error;
102110
int plat_irq;
111+
u8 type;
112+
unsigned int plat_irq_flags;
113+
bool chan_in_use;
103114
};
104115

105116
#define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
106117
static struct pcc_chan_info *chan_info;
107118
static int pcc_chan_count;
108119

120+
static int pcc_send_data(struct mbox_chan *chan, void *data);
121+
109122
/*
110123
* PCC can be used with perf critical drivers such as CPPC
111124
* So it makes sense to locally cache the virtual address and
@@ -221,6 +234,41 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags)
221234
return acpi_register_gsi(NULL, interrupt, trigger, polarity);
222235
}
223236

237+
static bool pcc_chan_plat_irq_can_be_shared(struct pcc_chan_info *pchan)
238+
{
239+
return (pchan->plat_irq_flags & ACPI_PCCT_INTERRUPT_MODE) ==
240+
ACPI_LEVEL_SENSITIVE;
241+
}
242+
243+
static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan)
244+
{
245+
u64 val;
246+
int ret;
247+
248+
ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
249+
if (ret)
250+
return false;
251+
252+
if (!pchan->cmd_complete.gas)
253+
return true;
254+
255+
/*
256+
* Judge if the channel respond the interrupt based on the value of
257+
* command complete.
258+
*/
259+
val &= pchan->cmd_complete.status_mask;
260+
261+
/*
262+
* If this is PCC slave subspace channel, and the command complete
263+
* bit 0 indicates that Platform is sending a notification and OSPM
264+
* needs to respond this interrupt to process this command.
265+
*/
266+
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
267+
return !val;
268+
269+
return !!val;
270+
}
271+
224272
/**
225273
* pcc_mbox_irq - PCC mailbox interrupt handler
226274
* @irq: interrupt number
@@ -236,16 +284,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
236284
int ret;
237285

238286
pchan = chan->con_priv;
239-
240-
ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
241-
if (ret)
287+
if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE &&
288+
!pchan->chan_in_use)
242289
return IRQ_NONE;
243290

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-
}
291+
if (!pcc_mbox_cmd_complete_check(pchan))
292+
return IRQ_NONE;
249293

250294
ret = pcc_chan_reg_read(&pchan->error, &val);
251295
if (ret)
@@ -262,6 +306,16 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
262306

263307
mbox_chan_received_data(chan, NULL);
264308

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);
317+
pchan->chan_in_use = false;
318+
265319
return IRQ_HANDLED;
266320
}
267321

@@ -340,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
340394
if (ret)
341395
return ret;
342396

343-
return pcc_chan_reg_read_modify_write(&pchan->db);
397+
ret = pcc_chan_reg_read_modify_write(&pchan->db);
398+
if (!ret && pchan->plat_irq > 0)
399+
pchan->chan_in_use = true;
400+
401+
return ret;
344402
}
345403

346404
/**
@@ -353,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data)
353411
static int pcc_startup(struct mbox_chan *chan)
354412
{
355413
struct pcc_chan_info *pchan = chan->con_priv;
414+
unsigned long irqflags;
356415
int rc;
357416

358417
if (pchan->plat_irq > 0) {
359-
rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0,
360-
MBOX_IRQ_NAME, chan);
418+
irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ?
419+
IRQF_SHARED | IRQF_ONESHOT : 0;
420+
rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq,
421+
irqflags, MBOX_IRQ_NAME, chan);
361422
if (unlikely(rc)) {
362423
dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n",
363424
pchan->plat_irq);
@@ -463,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
463524
pcct_ss->platform_interrupt);
464525
return -EINVAL;
465526
}
527+
pchan->plat_irq_flags = pcct_ss->flags;
466528

467529
if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
468530
struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
@@ -484,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
484546
"PLAT IRQ ACK");
485547
}
486548

549+
if (pcc_chan_plat_irq_can_be_shared(pchan) &&
550+
!pchan->plat_irq_ack.gas) {
551+
pr_err("PCC subspace has level IRQ with no ACK register\n");
552+
return -EINVAL;
553+
}
554+
487555
return ret;
488556
}
489557

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

699767
pcc_parse_subspace_shmem(pchan, pcct_entry);
700768

769+
pchan->type = pcct_entry->type;
701770
pcct_entry = (struct acpi_subtable_header *)
702771
((unsigned long) pcct_entry + pcct_entry->length);
703772
}

drivers/soc/hisilicon/kunpeng_hccs.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@
3131

3232
#include "kunpeng_hccs.h"
3333

34-
/* PCC defines */
35-
#define HCCS_PCC_SIGNATURE_MASK 0x50434300
36-
#define HCCS_PCC_STATUS_CMD_COMPLETE BIT(0)
37-
3834
/*
3935
* Arbitrary retries in case the remote processor is slow to respond
4036
* to PCC commands
@@ -187,7 +183,7 @@ static int hccs_check_chan_cmd_complete(struct hccs_dev *hdev)
187183
* deadline_us(timeout_us) until PCC command complete bit is set(cond)
188184
*/
189185
ret = readw_poll_timeout(&comm_base->status, status,
190-
status & HCCS_PCC_STATUS_CMD_COMPLETE,
186+
status & PCC_STATUS_CMD_COMPLETE,
191187
HCCS_POLL_STATUS_TIME_INTERVAL_US,
192188
cl_info->deadline_us);
193189
if (unlikely(ret))
@@ -208,7 +204,7 @@ static int hccs_pcc_cmd_send(struct hccs_dev *hdev, u8 cmd,
208204
int ret;
209205

210206
/* Write signature for this subspace */
211-
tmp.signature = HCCS_PCC_SIGNATURE_MASK | hdev->chan_id;
207+
tmp.signature = PCC_SIGNATURE | hdev->chan_id;
212208
/* Write to the shared command region */
213209
tmp.command = cmd;
214210
/* Clear cmd complete bit */

include/acpi/pcc.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,20 @@ struct pcc_mbox_chan {
1818
u16 min_turnaround_time;
1919
};
2020

21+
/* Generic Communications Channel Shared Memory Region */
22+
#define PCC_SIGNATURE 0x50434300
23+
/* Generic Communications Channel Command Field */
24+
#define PCC_CMD_GENERATE_DB_INTR BIT(15)
25+
/* Generic Communications Channel Status Field */
26+
#define PCC_STATUS_CMD_COMPLETE BIT(0)
27+
#define PCC_STATUS_SCI_DOORBELL BIT(1)
28+
#define PCC_STATUS_ERROR BIT(2)
29+
#define PCC_STATUS_PLATFORM_NOTIFY BIT(3)
30+
/* Initiator Responder Communications Channel Flags */
31+
#define PCC_CMD_COMPLETION_NOTIFY BIT(0)
32+
2133
#define MAX_PCC_SUBSPACES 256
34+
2235
#ifdef CONFIG_PCC
2336
extern struct pcc_mbox_chan *
2437
pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id);

0 commit comments

Comments
 (0)