[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6d00d240-0c86-d593-6efe-44fec21421a8@huawei.com>
Date: Wed, 26 Oct 2022 14:10:13 +0800
From: "lihuisong (C)" <lihuisong@...wei.com>
To: <linux-acpi@...r.kernel.org>, <linux-kernel@...r.kernel.org>
CC: <rafael@...nel.org>, <sudeep.holla@....com>,
<rafael.j.wysocki@...el.com>, <wanghuiqiang@...wei.com>,
<huangdaode@...wei.com>, <tanxiaofei@...wei.com>,
Loc Ho <lho@....com>, Hoan Tran <hotran@....com>
Subject: Re: [RFC] ACPI: PCC: Support shared interrupt for multiple subspaces
Kindly ping.
在 2022/10/16 11:40, Huisong Li 写道:
> As ACPI protocol descripted, if interrupts are level, a GSIV may
> be shared by multiple subspaces, but each one must have unique
> platform interrupt ack preserve and ack set masks. Therefore, need
> set to shared interrupt for types that can distinguish interrupt
> response channel if platform interrupt mode is level triggered.
>
> The distinguishing point isn't definitely command complete register.
> Because the two status values of command complete indicate that
> there is no interrupt in a subspace('1' means subspace is free for
> use, and '0' means platform is processing the command). On the whole,
> the platform interrupt ack register is more suitable for this role.
> As ACPI protocol said, If the subspace does support interrupts, and
> these are level, this register must be supplied. And is used to clear
> the interrupt by using a read, modify, write sequence. This register
> is a 'WR' register, the bit corresponding to the subspace is '1' when
> the command is completed, or is '0'.
>
> Therefore, register shared interrupt for multiple subspaces if support
> platform interrupt ack register and interrupts are level, and read the
> ack register to ensure the idle or unfinished command channels to
> quickly return IRQ_NONE.
>
> Signed-off-by: Huisong Li <lihuisong@...wei.com>
> ---
> drivers/mailbox/pcc.c | 27 +++++++++++++++++++++++++--
> 1 file changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
> index 3c2bc0ca454c..86c6cc44c73d 100644
> --- a/drivers/mailbox/pcc.c
> +++ b/drivers/mailbox/pcc.c
> @@ -100,6 +100,7 @@ struct pcc_chan_info {
> struct pcc_chan_reg cmd_update;
> struct pcc_chan_reg error;
> int plat_irq;
> + u8 plat_irq_trigger;
> };
>
> #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
> @@ -236,6 +237,15 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
> int ret;
>
> pchan = chan->con_priv;
> + ret = pcc_chan_reg_read(&pchan->plat_irq_ack, &val);
> + if (ret)
> + return IRQ_NONE;
> + /* Irq ack GAS exist and check if this interrupt has the channel. */
> + if (pchan->plat_irq_ack.gas) {
> + val &= pchan->plat_irq_ack.set_mask;
> + if (val == 0)
> + return IRQ_NONE;
> + }
>
> ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
> if (ret)
> @@ -309,10 +319,21 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
> spin_unlock_irqrestore(&chan->lock, flags);
>
> if (pchan->plat_irq > 0) {
> + unsigned long irqflags;
> int rc;
>
> - rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq, 0,
> - MBOX_IRQ_NAME, chan);
> + /*
> + * As ACPI protocol descripted, if interrupts are level, a GSIV
> + * may be shared by multiple subspaces.
> + * Therefore, register shared interrupt for multiple subspaces
> + * if support platform interrupt ack register and interrupts
> + * are level.
> + */
> + irqflags = (pchan->plat_irq_ack.gas &&
> + pchan->plat_irq_trigger == ACPI_LEVEL_SENSITIVE) ?
> + IRQF_SHARED : 0;
> + rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq,
> + irqflags, MBOX_IRQ_NAME, chan);
> if (unlikely(rc)) {
> dev_err(dev, "failed to register PCC interrupt %d\n",
> pchan->plat_irq);
> @@ -457,6 +478,8 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
> pcct_ss->platform_interrupt);
> return -EINVAL;
> }
> + pchan->plat_irq_trigger = (pcct_ss->flags & ACPI_PCCT_INTERRUPT_MODE) ?
> + ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
>
> if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
> struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
Powered by blists - more mailing lists