diff mbox series

PCI: rcar-gen2: Ensure the mandatory clock is enabled

Message ID 1553271070-7509-1-git-send-email-gareth.williams.jx@renesas.com
State Rejected
Delegated to: Lorenzo Pieralisi
Headers show
Series PCI: rcar-gen2: Ensure the mandatory clock is enabled | expand

Commit Message

Gareth Williams March 22, 2019, 4:11 p.m. UTC
From: Phil Edworthy <phil.edworthy@renesas.com>

All SoC devices that use this driver have a module stop clock associated
with it that we must ensure is enabled. All SoCs enabled this clock
by default, so I guess no one noticed that the driver didn't enable it.

Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
Signed-off-by: Gareth Williams <gareth.williams.jx@renesas.com>
---
Note: This change was tested on RZN1 and R-Car M2 hardware. NULL is
passed to devm_clk_get for backwards compatibility reasons with R-Car gen2
devices which do not name the clock.

DTS files for Renesas devices that use this driver have been checked to
ensure they specify a clock and do not name that clock.  
---
 drivers/pci/controller/pci-rcar-gen2.c | 35 +++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

Comments

Geert Uytterhoeven March 22, 2019, 7:14 p.m. UTC | #1
Hi Gareth, Phil,

Thanks for your patch!

On Fri, Mar 22, 2019 at 5:11 PM Gareth Williams
<gareth.williams.jx@renesas.com> wrote:
> From: Phil Edworthy <phil.edworthy@renesas.com>
>
> All SoC devices that use this driver have a module stop clock associated
> with it that we must ensure is enabled. All SoCs enabled this clock
> by default, so I guess no one noticed that the driver didn't enable it.

This is not really correct: the module clock has always been controlled
through the clock domain the device is part of, either through the
"power-domains" property in DT, or through the legacy clock domain
before that, combined with Runtime PM (see also commit fb178d8b2fab3f2a
("PCI: rcar: Add runtime PM support")).

Furthermore adding explicit clock management (with a mandatory clock)
makes it harder to use the device with virtualization and VFIO, and to
reuse the driver on other SoCs where no module clock may be present.
Using Runtime PM allows to abstract the presence of the module clock,
or whatever power saving feature that may be present (e.g. a power area),
which is an integration feature, and not a feature of the actual device.

So I don't think this change is needed or wanted.

NAKed-by: Geert Uytterhoeven <geert+renesas@glider.be>

> Note: This change was tested on RZN1 and R-Car M2 hardware. NULL is
> passed to devm_clk_get for backwards compatibility reasons with R-Car gen2
> devices which do not name the clock.
>
> DTS files for Renesas devices that use this driver have been checked to
> ensure they specify a clock and do not name that clock.

I understand RZ/N1 has the same PCI controller, and you're trying to add
support for it?  I think the solution there is to add clock domain support to
drivers/clk/renesas/r9a06g032-clocks.c.

Gr{oetje,eeting}s,

                        Geert
Gareth Williams March 25, 2019, 9:49 a.m. UTC | #2
Hi Geert,

I will take a look into how I can do this. Thanks for taking the time to give
some background and pointers.

Kind Regards,

Gareth

On Fri, Mar 22, 2019 at 19:14 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote: 
> Hi Gareth, Phil,
> 
> Thanks for your patch!
> 
> On Fri, Mar 22, 2019 at 5:11 PM Gareth Williams
> <gareth.williams.jx@renesas.com> wrote:
> > From: Phil Edworthy <phil.edworthy@renesas.com>
> >
> > All SoC devices that use this driver have a module stop clock
> > associated with it that we must ensure is enabled. All SoCs enabled
> > this clock by default, so I guess no one noticed that the driver didn't enable
> it.
> 
> This is not really correct: the module clock has always been controlled
> through the clock domain the device is part of, either through the "power-
> domains" property in DT, or through the legacy clock domain before that,
> combined with Runtime PM (see also commit fb178d8b2fab3f2a
> ("PCI: rcar: Add runtime PM support")).
> 
> Furthermore adding explicit clock management (with a mandatory clock)
> makes it harder to use the device with virtualization and VFIO, and to reuse
> the driver on other SoCs where no module clock may be present.
> Using Runtime PM allows to abstract the presence of the module clock, or
> whatever power saving feature that may be present (e.g. a power area),
> which is an integration feature, and not a feature of the actual device.
> 
> So I don't think this change is needed or wanted.
> 
> NAKed-by: Geert Uytterhoeven <geert+renesas@glider.be>
> 
> > Note: This change was tested on RZN1 and R-Car M2 hardware. NULL is
> > passed to devm_clk_get for backwards compatibility reasons with R-Car
> > gen2 devices which do not name the clock.
> >
> > DTS files for Renesas devices that use this driver have been checked
> > to ensure they specify a clock and do not name that clock.
> 
> I understand RZ/N1 has the same PCI controller, and you're trying to add
> support for it?  I think the solution there is to add clock domain support to
> drivers/clk/renesas/r9a06g032-clocks.c.
> 
> 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
diff mbox series

Patch

diff --git a/drivers/pci/controller/pci-rcar-gen2.c b/drivers/pci/controller/pci-rcar-gen2.c
index 326171c..4c94860 100644
--- a/drivers/pci/controller/pci-rcar-gen2.c
+++ b/drivers/pci/controller/pci-rcar-gen2.c
@@ -8,6 +8,7 @@ 
  * Author: Valentine Barshak <valentine.barshak@cogentembedded.com>
  */
 
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -95,6 +96,7 @@ 
 
 struct rcar_pci_priv {
 	struct device *dev;
+	struct clk *clk;
 	void __iomem *reg;
 	struct resource mem_res;
 	struct resource *cfg_res;
@@ -340,6 +342,8 @@  static int rcar_pci_probe(struct platform_device *pdev)
 	void __iomem *reg;
 	struct hw_pci hw;
 	void *hw_private[1];
+	struct clk *clk;
+	int ret;
 
 	cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	reg = devm_ioremap_resource(dev, cfg_res);
@@ -376,7 +380,6 @@  static int rcar_pci_probe(struct platform_device *pdev)
 
 	if (dev->of_node) {
 		struct resource busnr;
-		int ret;
 
 		ret = of_pci_parse_bus_range(dev->of_node, &busnr);
 		if (ret < 0) {
@@ -397,6 +400,14 @@  static int rcar_pci_probe(struct platform_device *pdev)
 		priv->busnr = pdev->id;
 	}
 
+	clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		return ret;
+	priv->clk = clk;
+
 	hw_private[0] = priv;
 	memset(&hw, 0, sizeof(hw));
 	hw.nr_controllers = ARRAY_SIZE(hw_private);
@@ -409,6 +420,27 @@  static int rcar_pci_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __maybe_unused pci_rcar_gen2_suspend_noirq(struct device *dev)
+{
+	struct rcar_pci_priv *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->clk);
+	return 0;
+}
+
+static int __maybe_unused pci_rcar_gen2_resume_noirq(struct device *dev)
+{
+	struct rcar_pci_priv *priv = dev_get_drvdata(dev);
+
+	clk_prepare_enable(priv->clk);
+	return 0;
+}
+
+static const struct dev_pm_ops pci_rcar_gen2_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pci_rcar_gen2_suspend_noirq,
+				      pci_rcar_gen2_resume_noirq)
+};
+
 static const struct of_device_id rcar_pci_of_match[] = {
 	{ .compatible = "renesas,pci-r8a7790", },
 	{ .compatible = "renesas,pci-r8a7791", },
@@ -422,6 +454,7 @@  static struct platform_driver rcar_pci_driver = {
 		.name = "pci-rcar-gen2",
 		.suppress_bind_attrs = true,
 		.of_match_table = rcar_pci_of_match,
+		.pm = &pci_rcar_gen2_pm_ops,
 	},
 	.probe = rcar_pci_probe,
 };