diff mbox series

[v5,2/2] PCI: brcmstb: Use reset/rearm instead of deassert/assert

Message ID 20210312204556.5387-3-jim2101024@gmail.com (mailing list archive)
State Superseded
Delegated to: Lorenzo Pieralisi
Headers show
Series ata: ahci_brcm: Fix use of BCM7216 reset controller | expand

Commit Message

Jim Quinlan March 12, 2021, 8:45 p.m. UTC
The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
The "rescal" implements a "pulse reset" so using assert/deassert is wrong
for this device.  Instead, we use reset/rearm.  We need to use rearm so
that we can reset it after a suspend/resume cycle; w/o using "rearm", the
"rescal" device will only ever fire once.

Of course for suspend/resume to work we also need to put the reset/rearm
calls in the suspend and resume routines.

Fixes: 740d6c3708a9 ("PCI: brcmstb: Add control of rescal reset")
Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

Comments

Lorenzo Pieralisi March 29, 2021, 4:06 p.m. UTC | #1
On Fri, Mar 12, 2021 at 03:45:55PM -0500, Jim Quinlan wrote:
> The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
> The "rescal" implements a "pulse reset" so using assert/deassert is wrong
> for this device.  Instead, we use reset/rearm.  We need to use rearm so
> that we can reset it after a suspend/resume cycle; w/o using "rearm", the
> "rescal" device will only ever fire once.
> 
> Of course for suspend/resume to work we also need to put the reset/rearm
> calls in the suspend and resume routines.
> 
> Fixes: 740d6c3708a9 ("PCI: brcmstb: Add control of rescal reset")
> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
> Acked-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/pci/controller/pcie-brcmstb.c | 19 +++++++++++++------
>  1 file changed, 13 insertions(+), 6 deletions(-)

Should I take this patch in the PCI queue ?

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
> index e330e6811f0b..3b35d629035e 100644
> --- a/drivers/pci/controller/pcie-brcmstb.c
> +++ b/drivers/pci/controller/pcie-brcmstb.c
> @@ -1148,6 +1148,7 @@ static int brcm_pcie_suspend(struct device *dev)
>  
>  	brcm_pcie_turn_off(pcie);
>  	ret = brcm_phy_stop(pcie);
> +	reset_control_rearm(pcie->rescal);
>  	clk_disable_unprepare(pcie->clk);
>  
>  	return ret;
> @@ -1163,9 +1164,13 @@ static int brcm_pcie_resume(struct device *dev)
>  	base = pcie->base;
>  	clk_prepare_enable(pcie->clk);
>  
> +	ret = reset_control_reset(pcie->rescal);
> +	if (ret)
> +		goto err_disable_clk;
> +
>  	ret = brcm_phy_start(pcie);
>  	if (ret)
> -		goto err;
> +		goto err_reset;
>  
>  	/* Take bridge out of reset so we can access the SERDES reg */
>  	pcie->bridge_sw_init_set(pcie, 0);
> @@ -1180,14 +1185,16 @@ static int brcm_pcie_resume(struct device *dev)
>  
>  	ret = brcm_pcie_setup(pcie);
>  	if (ret)
> -		goto err;
> +		goto err_reset;
>  
>  	if (pcie->msi)
>  		brcm_msi_set_regs(pcie->msi);
>  
>  	return 0;
>  
> -err:
> +err_reset:
> +	reset_control_rearm(pcie->rescal);
> +err_disable_clk:
>  	clk_disable_unprepare(pcie->clk);
>  	return ret;
>  }
> @@ -1197,7 +1204,7 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
>  	brcm_msi_remove(pcie);
>  	brcm_pcie_turn_off(pcie);
>  	brcm_phy_stop(pcie);
> -	reset_control_assert(pcie->rescal);
> +	reset_control_rearm(pcie->rescal);
>  	clk_disable_unprepare(pcie->clk);
>  }
>  
> @@ -1278,13 +1285,13 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>  		return PTR_ERR(pcie->perst_reset);
>  	}
>  
> -	ret = reset_control_deassert(pcie->rescal);
> +	ret = reset_control_reset(pcie->rescal);
>  	if (ret)
>  		dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
>  
>  	ret = brcm_phy_start(pcie);
>  	if (ret) {
> -		reset_control_assert(pcie->rescal);
> +		reset_control_rearm(pcie->rescal);
>  		clk_disable_unprepare(pcie->clk);
>  		return ret;
>  	}
> -- 
> 2.17.1
>
Lorenzo Pieralisi March 29, 2021, 4:10 p.m. UTC | #2
On Fri, Mar 12, 2021 at 03:45:55PM -0500, Jim Quinlan wrote:
> The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
> The "rescal" implements a "pulse reset" so using assert/deassert is wrong
> for this device.  Instead, we use reset/rearm.  We need to use rearm so
> that we can reset it after a suspend/resume cycle; w/o using "rearm", the
> "rescal" device will only ever fire once.
> 
> Of course for suspend/resume to work we also need to put the reset/rearm
> calls in the suspend and resume routines.

Actually - I am sorry but it looks like you will have to split the patch
in two since this is two logical changes.

Thanks,
Lorenzo

> Fixes: 740d6c3708a9 ("PCI: brcmstb: Add control of rescal reset")
> Signed-off-by: Jim Quinlan <jim2101024@gmail.com>
> Acked-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/pci/controller/pcie-brcmstb.c | 19 +++++++++++++------
>  1 file changed, 13 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
> index e330e6811f0b..3b35d629035e 100644
> --- a/drivers/pci/controller/pcie-brcmstb.c
> +++ b/drivers/pci/controller/pcie-brcmstb.c
> @@ -1148,6 +1148,7 @@ static int brcm_pcie_suspend(struct device *dev)
>  
>  	brcm_pcie_turn_off(pcie);
>  	ret = brcm_phy_stop(pcie);
> +	reset_control_rearm(pcie->rescal);
>  	clk_disable_unprepare(pcie->clk);
>  
>  	return ret;
> @@ -1163,9 +1164,13 @@ static int brcm_pcie_resume(struct device *dev)
>  	base = pcie->base;
>  	clk_prepare_enable(pcie->clk);
>  
> +	ret = reset_control_reset(pcie->rescal);
> +	if (ret)
> +		goto err_disable_clk;
> +
>  	ret = brcm_phy_start(pcie);
>  	if (ret)
> -		goto err;
> +		goto err_reset;
>  
>  	/* Take bridge out of reset so we can access the SERDES reg */
>  	pcie->bridge_sw_init_set(pcie, 0);
> @@ -1180,14 +1185,16 @@ static int brcm_pcie_resume(struct device *dev)
>  
>  	ret = brcm_pcie_setup(pcie);
>  	if (ret)
> -		goto err;
> +		goto err_reset;
>  
>  	if (pcie->msi)
>  		brcm_msi_set_regs(pcie->msi);
>  
>  	return 0;
>  
> -err:
> +err_reset:
> +	reset_control_rearm(pcie->rescal);
> +err_disable_clk:
>  	clk_disable_unprepare(pcie->clk);
>  	return ret;
>  }
> @@ -1197,7 +1204,7 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
>  	brcm_msi_remove(pcie);
>  	brcm_pcie_turn_off(pcie);
>  	brcm_phy_stop(pcie);
> -	reset_control_assert(pcie->rescal);
> +	reset_control_rearm(pcie->rescal);
>  	clk_disable_unprepare(pcie->clk);
>  }
>  
> @@ -1278,13 +1285,13 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>  		return PTR_ERR(pcie->perst_reset);
>  	}
>  
> -	ret = reset_control_deassert(pcie->rescal);
> +	ret = reset_control_reset(pcie->rescal);
>  	if (ret)
>  		dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
>  
>  	ret = brcm_phy_start(pcie);
>  	if (ret) {
> -		reset_control_assert(pcie->rescal);
> +		reset_control_rearm(pcie->rescal);
>  		clk_disable_unprepare(pcie->clk);
>  		return ret;
>  	}
> -- 
> 2.17.1
>
Florian Fainelli March 29, 2021, 4:50 p.m. UTC | #3
On 3/29/21 9:10 AM, Lorenzo Pieralisi wrote:
> On Fri, Mar 12, 2021 at 03:45:55PM -0500, Jim Quinlan wrote:
>> The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
>> The "rescal" implements a "pulse reset" so using assert/deassert is wrong
>> for this device.  Instead, we use reset/rearm.  We need to use rearm so
>> that we can reset it after a suspend/resume cycle; w/o using "rearm", the
>> "rescal" device will only ever fire once.
>>
>> Of course for suspend/resume to work we also need to put the reset/rearm
>> calls in the suspend and resume routines.
> 
> Actually - I am sorry but it looks like you will have to split the patch
> in two since this is two logical changes.

I do not believe this can be easily split, since there is currently a
misused of the reset controller API and this patch fixes all call sites
at once. It would not really make sense to fix probe/remove and then
leave suspend/resume broken in the same manner.
Lorenzo Pieralisi March 29, 2021, 4:58 p.m. UTC | #4
On Mon, Mar 29, 2021 at 09:50:13AM -0700, Florian Fainelli wrote:
> On 3/29/21 9:10 AM, Lorenzo Pieralisi wrote:
> > On Fri, Mar 12, 2021 at 03:45:55PM -0500, Jim Quinlan wrote:
> >> The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
> >> The "rescal" implements a "pulse reset" so using assert/deassert is wrong
> >> for this device.  Instead, we use reset/rearm.  We need to use rearm so
> >> that we can reset it after a suspend/resume cycle; w/o using "rearm", the
> >> "rescal" device will only ever fire once.
> >>
> >> Of course for suspend/resume to work we also need to put the reset/rearm
> >> calls in the suspend and resume routines.
> > 
> > Actually - I am sorry but it looks like you will have to split the patch
> > in two since this is two logical changes.
> 
> I do not believe this can be easily split, since there is currently a
> misused of the reset controller API and this patch fixes all call sites
> at once. It would not really make sense to fix probe/remove and then
> leave suspend/resume broken in the same manner.

Right - I was reading the previous versions of the set, it makes sense
to keep it in one logical change.

Do you want me to take it or you prefer an ACK so that it can go via
a different tree ?

Thanks,
Lorenzo
Florian Fainelli March 29, 2021, 5:01 p.m. UTC | #5
On 3/29/21 9:58 AM, Lorenzo Pieralisi wrote:
> On Mon, Mar 29, 2021 at 09:50:13AM -0700, Florian Fainelli wrote:
>> On 3/29/21 9:10 AM, Lorenzo Pieralisi wrote:
>>> On Fri, Mar 12, 2021 at 03:45:55PM -0500, Jim Quinlan wrote:
>>>> The Broadcom STB PCIe RC uses a reset control "rescal" for certain chips.
>>>> The "rescal" implements a "pulse reset" so using assert/deassert is wrong
>>>> for this device.  Instead, we use reset/rearm.  We need to use rearm so
>>>> that we can reset it after a suspend/resume cycle; w/o using "rearm", the
>>>> "rescal" device will only ever fire once.
>>>>
>>>> Of course for suspend/resume to work we also need to put the reset/rearm
>>>> calls in the suspend and resume routines.
>>>
>>> Actually - I am sorry but it looks like you will have to split the patch
>>> in two since this is two logical changes.
>>
>> I do not believe this can be easily split, since there is currently a
>> misused of the reset controller API and this patch fixes all call sites
>> at once. It would not really make sense to fix probe/remove and then
>> leave suspend/resume broken in the same manner.
> 
> Right - I was reading the previous versions of the set, it makes sense
> to keep it in one logical change.
> 
> Do you want me to take it or you prefer an ACK so that it can go via
> a different tree ?

I would be comfortable with you taking this via the PCI driver trees, we
would want an Ack from Jens that he is okay with taking the ahci_brcm.c
change as well through your tree.

Thank you!
diff mbox series

Patch

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index e330e6811f0b..3b35d629035e 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -1148,6 +1148,7 @@  static int brcm_pcie_suspend(struct device *dev)
 
 	brcm_pcie_turn_off(pcie);
 	ret = brcm_phy_stop(pcie);
+	reset_control_rearm(pcie->rescal);
 	clk_disable_unprepare(pcie->clk);
 
 	return ret;
@@ -1163,9 +1164,13 @@  static int brcm_pcie_resume(struct device *dev)
 	base = pcie->base;
 	clk_prepare_enable(pcie->clk);
 
+	ret = reset_control_reset(pcie->rescal);
+	if (ret)
+		goto err_disable_clk;
+
 	ret = brcm_phy_start(pcie);
 	if (ret)
-		goto err;
+		goto err_reset;
 
 	/* Take bridge out of reset so we can access the SERDES reg */
 	pcie->bridge_sw_init_set(pcie, 0);
@@ -1180,14 +1185,16 @@  static int brcm_pcie_resume(struct device *dev)
 
 	ret = brcm_pcie_setup(pcie);
 	if (ret)
-		goto err;
+		goto err_reset;
 
 	if (pcie->msi)
 		brcm_msi_set_regs(pcie->msi);
 
 	return 0;
 
-err:
+err_reset:
+	reset_control_rearm(pcie->rescal);
+err_disable_clk:
 	clk_disable_unprepare(pcie->clk);
 	return ret;
 }
@@ -1197,7 +1204,7 @@  static void __brcm_pcie_remove(struct brcm_pcie *pcie)
 	brcm_msi_remove(pcie);
 	brcm_pcie_turn_off(pcie);
 	brcm_phy_stop(pcie);
-	reset_control_assert(pcie->rescal);
+	reset_control_rearm(pcie->rescal);
 	clk_disable_unprepare(pcie->clk);
 }
 
@@ -1278,13 +1285,13 @@  static int brcm_pcie_probe(struct platform_device *pdev)
 		return PTR_ERR(pcie->perst_reset);
 	}
 
-	ret = reset_control_deassert(pcie->rescal);
+	ret = reset_control_reset(pcie->rescal);
 	if (ret)
 		dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
 
 	ret = brcm_phy_start(pcie);
 	if (ret) {
-		reset_control_assert(pcie->rescal);
+		reset_control_rearm(pcie->rescal);
 		clk_disable_unprepare(pcie->clk);
 		return ret;
 	}