All of lore.kernel.org
 help / color / mirror / Atom feed
From: Geert Uytterhoeven <geert@linux-m68k.org>
To: Marek Vasut <marek.vasut@gmail.com>
Cc: linux-pci <linux-pci@vger.kernel.org>,
	"Marek Vasut" <marek.vasut+renesas@gmail.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Geert Uytterhoeven" <geert+renesas@glider.be>,
	"Krzysztof Wilczyński" <kw@linux.com>,
	"Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
	"Wolfram Sang" <wsa@the-dreams.de>,
	"Yoshihiro Shimoda" <yoshihiro.shimoda.uh@renesas.com>,
	Linux-Renesas <linux-renesas-soc@vger.kernel.org>
Subject: Re: [PATCH 1/2] PCI: rcar: Finish transition to L1 state in rcar_pcie_config_access()
Date: Sun, 16 Jan 2022 11:39:16 +0100	[thread overview]
Message-ID: <CAMuHMdXUteqOinkCNH8L-dC=W82DChQSupAXv_Uhjq5M=T5uxQ@mail.gmail.com> (raw)
In-Reply-To: <20220116022549.456486-1-marek.vasut@gmail.com>

Hi Marek,

On Sun, Jan 16, 2022 at 3:26 AM <marek.vasut@gmail.com> wrote:
> From: Marek Vasut <marek.vasut+renesas@gmail.com>
>
> In case the controller is transitioning to L1 in rcar_pcie_config_access(),
> any read/write access to PCIECDR triggers asynchronous external abort. This
> is because the transition to L1 link state must be manually finished by the
> driver. The PCIe IP can transition back from L1 state to L0 on its own.
>
> Avoid triggering the abort in rcar_pcie_config_access() by checking whether
> the controller is in the transition state, and if so, finish the transition
> right away. This prevents a lot of unnecessary exceptions, although not all
> of them.
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>

Thanks for your patch!

> --- a/drivers/pci/controller/pcie-rcar-host.c
> +++ b/drivers/pci/controller/pcie-rcar-host.c
> @@ -54,6 +54,34 @@ static void __iomem *pcie_base;
>   * device is runtime suspended or not.
>   */
>  static struct device *pcie_dev;
> +
> +static DEFINE_SPINLOCK(pmsr_lock);
> +static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base)
> +{
> +       u32 pmsr, val;
> +       int ret = 0;
> +
> +       if (!pcie_base || pm_runtime_suspended(pcie_dev))
> +               return 1;

This is not a suitable return code to be propagated in
rcar_pcie_config_access(). But probably this cannot happen anyway
when called from rcar_pcie_config_access()?

> +
> +       pmsr = readl(pcie_base + PMSR);
> +
> +       /*
> +        * Test if the PCIe controller received PM_ENTER_L1 DLLP and
> +        * the PCIe controller is not in L1 link state. If true, apply
> +        * fix, which will put the controller into L1 link state, from
> +        * which it can return to L0s/L0 on its own.
> +        */
> +       if ((pmsr & PMEL1RX) && ((pmsr & PMSTATE) != PMSTATE_L1)) {
> +               writel(L1IATN, pcie_base + PMCTLR);
> +               ret = readl_poll_timeout_atomic(pcie_base + PMSR, val,
> +                                               val & L1FAEG, 10, 1000);
> +               WARN(ret, "Timeout waiting for L1 link state, ret=%d\n", ret);
> +               writel(L1FAEG | PMEL1RX, pcie_base + PMSR);
> +       }
> +
> +       return ret;
> +}
>  #endif
>
>  /* Structure representing the PCIe interface */
> @@ -85,6 +113,15 @@ static int rcar_pcie_config_access(struct rcar_pcie_host *host,
>  {
>         struct rcar_pcie *pcie = &host->pcie;
>         unsigned int dev, func, reg, index;
> +       unsigned long flags;
> +       int ret;
> +
> +       /* Wake the bus up in case it is in L1 state. */
> +       spin_lock_irqsave(&pmsr_lock, flags);
> +       ret = rcar_pcie_wakeup(pcie->dev, pcie->base);
> +       spin_unlock_irqrestore(&pmsr_lock, flags);

Move the spinlock handling in the caller?

> +       if (ret)
> +               return ret;
>
>         dev = PCI_SLOT(devfn);
>         func = PCI_FUNC(devfn);
> @@ -1050,36 +1087,18 @@ static struct platform_driver rcar_pcie_driver = {
>  };
>
>  #ifdef CONFIG_ARM
> -static DEFINE_SPINLOCK(pmsr_lock);
>  static int rcar_pcie_aarch32_abort_handler(unsigned long addr,
>                 unsigned int fsr, struct pt_regs *regs)
>  {
>         unsigned long flags;
> -       u32 pmsr, val;
>         int ret = 0;
>
>         spin_lock_irqsave(&pmsr_lock, flags);
>
> -       if (!pcie_base || pm_runtime_suspended(pcie_dev)) {
> -               ret = 1;
> +       ret = rcar_pcie_wakeup(pcie_dev, pcie_base);
> +       spin_unlock_irqrestore(&pmsr_lock, flags);

Move the spinlock handling in the caller?

> +       if (ret)
>                 goto unlock_exit;
> -       }
> -
> -       pmsr = readl(pcie_base + PMSR);
> -
> -       /*
> -        * Test if the PCIe controller received PM_ENTER_L1 DLLP and
> -        * the PCIe controller is not in L1 link state. If true, apply
> -        * fix, which will put the controller into L1 link state, from
> -        * which it can return to L0s/L0 on its own.
> -        */
> -       if ((pmsr & PMEL1RX) && ((pmsr & PMSTATE) != PMSTATE_L1)) {
> -               writel(L1IATN, pcie_base + PMCTLR);
> -               ret = readl_poll_timeout_atomic(pcie_base + PMSR, val,
> -                                               val & L1FAEG, 10, 1000);
> -               WARN(ret, "Timeout waiting for L1 link state, ret=%d\n", ret);
> -               writel(L1FAEG | PMEL1RX, pcie_base + PMSR);
> -       }
>
>  unlock_exit:
>         spin_unlock_irqrestore(&pmsr_lock, flags);

Whoops, double unlock.

As there's nothing to be done below, the goto and label can be removed.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

  parent reply	other threads:[~2022-01-16 10:39 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-16  2:25 [PATCH 1/2] PCI: rcar: Finish transition to L1 state in rcar_pcie_config_access() marek.vasut
2022-01-16  2:25 ` [PATCH 2/2] PCI: rcar: Return all Fs from read which triggered an exception marek.vasut
2022-01-16 18:30   ` kernel test robot
2022-01-16 18:30     ` kernel test robot
2022-01-16 18:51   ` kernel test robot
2022-01-16 18:51     ` kernel test robot
2022-01-16 20:43   ` kernel test robot
2022-01-16 20:43     ` kernel test robot
2022-01-16 10:39 ` Geert Uytterhoeven [this message]
2022-01-16 18:41 ` [PATCH 1/2] PCI: rcar: Finish transition to L1 state in rcar_pcie_config_access() kernel test robot
2022-01-16 18:41   ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAMuHMdXUteqOinkCNH8L-dC=W82DChQSupAXv_Uhjq5M=T5uxQ@mail.gmail.com' \
    --to=geert@linux-m68k.org \
    --cc=arnd@arndb.de \
    --cc=bhelgaas@google.com \
    --cc=geert+renesas@glider.be \
    --cc=kw@linux.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=marek.vasut+renesas@gmail.com \
    --cc=marek.vasut@gmail.com \
    --cc=wsa@the-dreams.de \
    --cc=yoshihiro.shimoda.uh@renesas.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.