Re: [PATCH v2 1/2] PCI: dwc: Perform host_init() before registering msi
From: Bjorn Helgaas
Date: Tue Aug 24 2021 - 15:05:34 EST
On Mon, Aug 23, 2021 at 08:49:57AM -0700, Bjorn Andersson wrote:
> On the Qualcomm sc8180x platform the bootloader does something related
> to PCI that leaves a pending "msi" interrupt, which with the current
> ordering often fires before init has a chance to enable the clocks that
> are necessary for the interrupt handler to access the hardware.
>
> Move the host_init() call before the registration of the "msi" interrupt
> handler to ensure the host driver has a chance to enable the clocks.
Did you audit other drivers for similar issues? If they do, we should
fix them all at once.
> The assignment of the bridge's ops and child_ops is moved along, because
> at least the TI Keystone driver overwrites these in its host_init
> callback.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx>
> ---
>
> Changes since v1:
> - New patch, instead of enabling resources in the qcom driver before jumping to
> dw_pcie_host_init(), per Rob Herring's suggestion.
>
> .../pci/controller/dwc/pcie-designware-host.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index d1d9b8344ec9..f4755f3a03be 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -335,6 +335,16 @@ int dw_pcie_host_init(struct pcie_port *pp)
> if (pci->link_gen < 1)
> pci->link_gen = of_pci_get_max_link_speed(np);
>
> + /* Set default bus ops */
> + bridge->ops = &dw_pcie_ops;
> + bridge->child_ops = &dw_child_pcie_ops;
> +
> + if (pp->ops->host_init) {
> + ret = pp->ops->host_init(pp);
> + if (ret)
> + return ret;
> + }
> +
> if (pci_msi_enabled()) {
> pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
> of_property_read_bool(np, "msi-parent") ||
> @@ -388,15 +398,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
> }
> }
>
> - /* Set default bus ops */
> - bridge->ops = &dw_pcie_ops;
> - bridge->child_ops = &dw_child_pcie_ops;
> -
> - if (pp->ops->host_init) {
> - ret = pp->ops->host_init(pp);
> - if (ret)
> - goto err_free_msi;
> - }
> dw_pcie_iatu_detect(pci);
>
> dw_pcie_setup_rc(pp);
> --
> 2.29.2
>