On Thu, Jun 23, 2022 at 10:52:13AM -0500, Bjorn Helgaas wrote: > On Thu, May 19, 2022 at 11:46:46AM +0200, Johan Hovold wrote: > > Allow the Qualcomm PCIe controller driver to be built as a module, which > > is useful for multi-platform kernels as well as during development. > > > > Signed-off-by: Johan Hovold <johan+linaro@xxxxxxxxxx> > > --- > > +static void qcom_pcie_host_deinit(struct qcom_pcie *pcie) > > +{ > > + qcom_ep_reset_assert(pcie); > > + if (pcie->cfg->ops->post_deinit) > > + pcie->cfg->ops->post_deinit(pcie); > > + phy_power_off(pcie->phy); > > + pcie->cfg->ops->deinit(pcie); > > These post_deinit/deinit names look backwards. Why would we call a > "post_deinit()" method *before* the "deinit()" method? It would make > sense if we called "pre_deinit()" followed by "deinit()". Yeah, that annoys me as well, but those are the names the driver currently use. I considered renaming the deinit callback but instead sent a follow up patch to remove both of these callbacks now that the pipe clock rework that depends on them has been merged, but seems like the post_init one will be needed for the DBI accesses. I can respin the above mentioned patch to drop or or rename the badly named one when things settle down a bit. > > static const struct dw_pcie_host_ops qcom_pcie_dw_ops = { > > .host_init = qcom_pcie_host_init, > > }; > > @@ -1651,6 +1660,22 @@ static int qcom_pcie_probe(struct platform_device *pdev) > > return ret; > > } > > > > +static int qcom_pcie_remove(struct platform_device *pdev) > > +{ > > + struct qcom_pcie *pcie = platform_get_drvdata(pdev); > > + struct device *dev = &pdev->dev; > > + > > + dw_pcie_host_deinit(&pcie->pci->pp); > > + qcom_pcie_host_deinit(pcie); > > + > > + phy_exit(pcie->phy); > > + > > + pm_runtime_put_sync(dev); > > + pm_runtime_disable(dev); > > Why is this not more symmetric with qcom_pcie_probe()? Maybe struct > dw_pcie_host_ops needs a new .host_deinit() pointer that would be > called from dw_pcie_host_deinit()? Yeah, I considered that too but decided it's not needed to implement modular builds for this driver. Instead I did the ground work by adding a deinit helper function so that it's easier to track any additions to the host_init() callback and which can later be called by core if someone decides to clean up core and add a deinit callback. Looks like someone just posted something along these lines, but this would conflict with the split MSI series which is otherwise ready to be merged: https://lore.kernel.org/r/20220624143947.8991-9-Sergey.Semin@xxxxxxxxxxxxxxxxxxxx Also note that there are other drivers that implement remove() without this callback already today. > In the probe path, we have this: > > qcom_pcie_probe > pm_runtime_enable > pm_runtime_get_sync > phy_init(pcie->phy) > dw_pcie_host_init > pp->ops->host_init > qcom_pcie_host_init # .host_init() > pcie->cfg->ops->init(pcie) > phy_power_on(pcie->phy) > pcie->cfg->ops->post_init(pcie) > qcom_ep_reset_deassert(pcie) > > The remove path does do things in the opposite order, which makes > sense, but the call to qcom_pcie_host_deinit() breaks the symmetry: > > qcom_pcie_remove > dw_pcie_host_deinit > qcom_pcie_host_deinit > qcom_ep_reset_assert > pcie->cfg->ops->post_deinit > phy_power_off(pcie->phy) > pcie->cfg->ops->deinit > phy_exit(pcie->phy) > pm_runtime_put_sync > pm_runtime_disable Yeah, I didn't want to go rewrite core just for this basic driver functionality. Especially with so many things already in flux. As mentioned above, everything is instead prepared to move over to such a callback if and when it materialises. Johan