diff mbox series

[v9,7/8] PCI: imx6: Move the phy driver callbacks to the proper places

Message ID 1651801629-30223-8-git-send-email-hongxing.zhu@nxp.com (mailing list archive)
State New, archived
Delegated to: Lorenzo Pieralisi
Headers show
Series PCI: imx6: refine codes and add compliance tests mode support | expand

Commit Message

Hongxing Zhu May 6, 2022, 1:47 a.m. UTC
To make it more reasonable, move the phy_power_on/phy_init callbacks to
the proper places.
- move the phy_power_on() out of imx6_pcie_clk_enable().
- move the phy_init() out of imx6_pcie_deassert_core_reset().

In order to save power consumption, turn off the clocks and regulators when
the imx6_pcie_host_init() return error.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 77 +++++++++++++++++++++------
 1 file changed, 61 insertions(+), 16 deletions(-)

Comments

Lucas Stach June 8, 2022, 7:44 a.m. UTC | #1
Am Freitag, dem 06.05.2022 um 09:47 +0800 schrieb Richard Zhu:
> To make it more reasonable, move the phy_power_on/phy_init callbacks to
> the proper places.
> - move the phy_power_on() out of imx6_pcie_clk_enable().
> - move the phy_init() out of imx6_pcie_deassert_core_reset().
> 
> In order to save power consumption, turn off the clocks and regulators when
> the imx6_pcie_host_init() return error.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 77 +++++++++++++++++++++------
>  1 file changed, 61 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index d122c12193a6..f0ffd9011975 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -497,14 +497,6 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
>  		goto err_ref_clk;
>  	}
>  
> -	switch (imx6_pcie->drvdata->variant) {
> -	case IMX8MM:
> -		if (phy_power_on(imx6_pcie->phy))
> -			dev_err(dev, "unable to power on PHY\n");
> -		break;
> -	default:
> -		break;
> -	}
>  	/* allow the clocks to stabilize */
>  	usleep_range(200, 500);
>  	return 0;
> @@ -597,10 +589,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
>  	switch (imx6_pcie->drvdata->variant) {
>  	case IMX8MQ:
>  		reset_control_deassert(imx6_pcie->pciephy_reset);
> -		break;
>  	case IMX8MM:
> -		if (phy_init(imx6_pcie->phy))
> -			dev_err(dev, "waiting for phy ready timeout!\n");

This looks fishy. You now fall-through from the 8MQ case to the 8MM
case, just to break there. Please move the 8MM case down to the 6QP
case that also doesn't need to do anything here.

>  		break;
>  	case IMX7D:
>  		reset_control_deassert(imx6_pcie->pciephy_reset);
> @@ -918,15 +907,38 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
>  
>  	imx6_pcie_assert_core_reset(imx6_pcie);
>  	imx6_pcie_init_phy(imx6_pcie);
> +	if (imx6_pcie->phy != NULL) {

Same comment as on the last patch: drop the "!= NULL".

> +		ret = phy_power_on(imx6_pcie->phy);
> +		if (ret) {
> +			dev_err(dev, "pcie phy power up failed.\n");
> +			return ret;
> +		}
> +	}
> +
>  	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
>  	if (ret < 0) {
>  		dev_err(dev, "pcie host init failed: %d.\n", ret);
> -		return ret;
> +		goto err_exit0;

This label is not very descriptive. Please rename to something like
err_phy_off or something like that.

> +	} else if (imx6_pcie->phy != NULL) {

The else path isn't needed here. If there was an error you already
moved the contol flow to the error label. So drop the else and again
have this block under a simple "if (imx6_pcie->phy)" statement.

> +		ret = phy_init(imx6_pcie->phy);
> +		if (ret) {
> +			dev_err(dev, "waiting for phy ready timeout!\n");
> +			goto err_exit1;

Again, please give those labels a more descriptive name.

All of the above comments also apply to the changes in
imx6_pcie_resume_noirq.

Regards,
Lucas

> +		}
>  	}
>  
>  	imx6_setup_phy_mpll(imx6_pcie);
>  
>  	return 0;
> +
> +err_exit1:
> +	imx6_pcie_clk_disable(imx6_pcie);
> +	if (imx6_pcie->vpcie)
> +		regulator_disable(imx6_pcie->vpcie);
> +err_exit0:
> +	if (imx6_pcie->phy != NULL)
> +		phy_power_off(imx6_pcie->phy);
> +	return ret;
>  }
>  
>  static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
> @@ -1031,14 +1043,47 @@ static int imx6_pcie_resume_noirq(struct device *dev)
>  		regulator_disable(imx6_pcie->vpcie);
>  
>  	imx6_pcie_init_phy(imx6_pcie);
> -	imx6_pcie_deassert_core_reset(imx6_pcie);
> -	dw_pcie_setup_rc(pp);
> +	if (imx6_pcie->phy != NULL) {
> +		ret = phy_power_on(imx6_pcie->phy);
> +		if (ret) {
> +			dev_err(dev, "pcie phy power up failed.\n");
> +			return ret;
> +		}
> +	}
> +
> +	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
> +	if (ret < 0) {
> +		dev_err(dev, "pcie deassert core reset failed: %d.\n", ret);
> +		goto err_exit0;
> +	} else if (imx6_pcie->phy != NULL) {
> +		ret = phy_init(imx6_pcie->phy);
> +		if (ret) {
> +			dev_err(dev, "pcie phy init failed.\n");
> +			goto err_exit1;
> +		}
> +	}
>  
> +	dw_pcie_setup_rc(pp);
>  	ret = imx6_pcie_start_link(imx6_pcie->pci);
> -	if (ret < 0)
> -		dev_info(dev, "pcie link is down after resume.\n");
> +	if (ret < 0) {
> +		/*
> +		 * Return ret directly, since there are error exit
> +		 * handle in imx6_pcie_start_link()
> +		 */
> +		dev_err(dev, "pcie link is down after resume.\n");
> +		return ret;
> +	}
>  
>  	return 0;
> +
> +err_exit1:
> +	imx6_pcie_clk_disable(imx6_pcie);
> +	if (imx6_pcie->vpcie)
> +		regulator_disable(imx6_pcie->vpcie);
> +err_exit0:
> +	if (imx6_pcie->phy != NULL)
> +		phy_power_off(imx6_pcie->phy);
> +	return ret;
>  }
>  #endif
>
Bjorn Helgaas June 8, 2022, 6:57 p.m. UTC | #2
On Fri, May 06, 2022 at 09:47:08AM +0800, Richard Zhu wrote:
> To make it more reasonable, move the phy_power_on/phy_init callbacks to
> the proper places.
> - move the phy_power_on() out of imx6_pcie_clk_enable().
> - move the phy_init() out of imx6_pcie_deassert_core_reset().

I'm not sure what "make it more reasonable" is telling me.  In subject
line and commit log, please say something more specific than "the
proper places."  

It's probably more important to say where they are moving *to* than
where they're moving *out of*.

> In order to save power consumption, turn off the clocks and regulators when
> the imx6_pcie_host_init() return error.

Is the power savings the *reason* for this change?  I can't tell from
the commit log.
Hongxing Zhu June 9, 2022, 6:18 a.m. UTC | #3
> -----Original Message-----
> From: Lucas Stach <l.stach@pengutronix.de>
> Sent: 2022年6月8日 15:45
> To: Hongxing Zhu <hongxing.zhu@nxp.com>; bhelgaas@google.com;
> robh+dt@kernel.org; broonie@kernel.org; lorenzo.pieralisi@arm.com;
> jingoohan1@gmail.com; festevam@gmail.com;
> francesco.dolcini@toradex.com
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org; kernel@pengutronix.de; dl-linux-imx
> <linux-imx@nxp.com>
> Subject: Re: [PATCH v9 7/8] PCI: imx6: Move the phy driver callbacks to the
> proper places
> 
> Am Freitag, dem 06.05.2022 um 09:47 +0800 schrieb Richard Zhu:
> > To make it more reasonable, move the phy_power_on/phy_init callbacks
> > to the proper places.
> > - move the phy_power_on() out of imx6_pcie_clk_enable().
> > - move the phy_init() out of imx6_pcie_deassert_core_reset().
> >
> > In order to save power consumption, turn off the clocks and regulators
> > when the imx6_pcie_host_init() return error.
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 77
> > +++++++++++++++++++++------
> >  1 file changed, 61 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index d122c12193a6..f0ffd9011975 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -497,14 +497,6 @@ static int imx6_pcie_clk_enable(struct imx6_pcie
> *imx6_pcie)
> >  		goto err_ref_clk;
> >  	}
> >
> > -	switch (imx6_pcie->drvdata->variant) {
> > -	case IMX8MM:
> > -		if (phy_power_on(imx6_pcie->phy))
> > -			dev_err(dev, "unable to power on PHY\n");
> > -		break;
> > -	default:
> > -		break;
> > -	}
> >  	/* allow the clocks to stabilize */
> >  	usleep_range(200, 500);
> >  	return 0;
> > @@ -597,10 +589,7 @@ static int imx6_pcie_deassert_core_reset(struct
> imx6_pcie *imx6_pcie)
> >  	switch (imx6_pcie->drvdata->variant) {
> >  	case IMX8MQ:
> >  		reset_control_deassert(imx6_pcie->pciephy_reset);
> > -		break;
> >  	case IMX8MM:
> > -		if (phy_init(imx6_pcie->phy))
> > -			dev_err(dev, "waiting for phy ready timeout!\n");
> 
> This looks fishy. You now fall-through from the 8MQ case to the 8MM case,
> just to break there. Please move the 8MM case down to the 6QP case that also
> doesn't need to do anything here.
> 
Thanks for your comments.
Would be changed.

> >  		break;
> >  	case IMX7D:
> >  		reset_control_deassert(imx6_pcie->pciephy_reset);
> > @@ -918,15 +907,38 @@ static int imx6_pcie_host_init(struct pcie_port
> > *pp)
> >
> >  	imx6_pcie_assert_core_reset(imx6_pcie);
> >  	imx6_pcie_init_phy(imx6_pcie);
> > +	if (imx6_pcie->phy != NULL) {
> 
> Same comment as on the last patch: drop the "!= NULL".
Okay, got that, all of them would be changed.
Thanks.

> 
> > +		ret = phy_power_on(imx6_pcie->phy);
> > +		if (ret) {
> > +			dev_err(dev, "pcie phy power up failed.\n");
> > +			return ret;
> > +		}
> > +	}
> > +
> >  	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
> >  	if (ret < 0) {
> >  		dev_err(dev, "pcie host init failed: %d.\n", ret);
> > -		return ret;
> > +		goto err_exit0;
> 
> This label is not very descriptive. Please rename to something like err_phy_off
> or something like that.
Okay. Thanks.

> 
> > +	} else if (imx6_pcie->phy != NULL) {
> 
> The else path isn't needed here. If there was an error you already moved the
> contol flow to the error label. So drop the else and again have this block under
> a simple "if (imx6_pcie->phy)" statement.
Okay. Thanks.

> 
> > +		ret = phy_init(imx6_pcie->phy);
> > +		if (ret) {
> > +			dev_err(dev, "waiting for phy ready timeout!\n");
> > +			goto err_exit1;
> 
> Again, please give those labels a more descriptive name.
> 
> All of the above comments also apply to the changes in
> imx6_pcie_resume_noirq.
Okay, thanks. Would be changed later.

Best Regards
Richard Zhu

> 
> Regards,
> Lucas
> 
> > +		}
> >  	}
> >
> >  	imx6_setup_phy_mpll(imx6_pcie);
> >
> >  	return 0;
> > +
> > +err_exit1:
> > +	imx6_pcie_clk_disable(imx6_pcie);
> > +	if (imx6_pcie->vpcie)
> > +		regulator_disable(imx6_pcie->vpcie);
> > +err_exit0:
> > +	if (imx6_pcie->phy != NULL)
> > +		phy_power_off(imx6_pcie->phy);
> > +	return ret;
> >  }
> >
> >  static const struct dw_pcie_host_ops imx6_pcie_host_ops = { @@
> > -1031,14 +1043,47 @@ static int imx6_pcie_resume_noirq(struct device
> *dev)
> >  		regulator_disable(imx6_pcie->vpcie);
> >
> >  	imx6_pcie_init_phy(imx6_pcie);
> > -	imx6_pcie_deassert_core_reset(imx6_pcie);
> > -	dw_pcie_setup_rc(pp);
> > +	if (imx6_pcie->phy != NULL) {
> > +		ret = phy_power_on(imx6_pcie->phy);
> > +		if (ret) {
> > +			dev_err(dev, "pcie phy power up failed.\n");
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
> > +	if (ret < 0) {
> > +		dev_err(dev, "pcie deassert core reset failed: %d.\n", ret);
> > +		goto err_exit0;
> > +	} else if (imx6_pcie->phy != NULL) {
> > +		ret = phy_init(imx6_pcie->phy);
> > +		if (ret) {
> > +			dev_err(dev, "pcie phy init failed.\n");
> > +			goto err_exit1;
> > +		}
> > +	}
> >
> > +	dw_pcie_setup_rc(pp);
> >  	ret = imx6_pcie_start_link(imx6_pcie->pci);
> > -	if (ret < 0)
> > -		dev_info(dev, "pcie link is down after resume.\n");
> > +	if (ret < 0) {
> > +		/*
> > +		 * Return ret directly, since there are error exit
> > +		 * handle in imx6_pcie_start_link()
> > +		 */
> > +		dev_err(dev, "pcie link is down after resume.\n");
> > +		return ret;
> > +	}
> >
> >  	return 0;
> > +
> > +err_exit1:
> > +	imx6_pcie_clk_disable(imx6_pcie);
> > +	if (imx6_pcie->vpcie)
> > +		regulator_disable(imx6_pcie->vpcie);
> > +err_exit0:
> > +	if (imx6_pcie->phy != NULL)
> > +		phy_power_off(imx6_pcie->phy);
> > +	return ret;
> >  }
> >  #endif
> >
>
Hongxing Zhu June 9, 2022, 6:20 a.m. UTC | #4
> -----Original Message-----
> From: Bjorn Helgaas <helgaas@kernel.org>
> Sent: 2022年6月9日 2:58
> To: Hongxing Zhu <hongxing.zhu@nxp.com>
> Cc: l.stach@pengutronix.de; bhelgaas@google.com; robh+dt@kernel.org;
> broonie@kernel.org; lorenzo.pieralisi@arm.com; jingoohan1@gmail.com;
> festevam@gmail.com; francesco.dolcini@toradex.com;
> linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org; kernel@pengutronix.de; dl-linux-imx
> <linux-imx@nxp.com>
> Subject: Re: [PATCH v9 7/8] PCI: imx6: Move the phy driver callbacks to the
> proper places
> 
> On Fri, May 06, 2022 at 09:47:08AM +0800, Richard Zhu wrote:
> > To make it more reasonable, move the phy_power_on/phy_init callbacks
> > to the proper places.
> > - move the phy_power_on() out of imx6_pcie_clk_enable().
> > - move the phy_init() out of imx6_pcie_deassert_core_reset().
> 
> I'm not sure what "make it more reasonable" is telling me.  In subject line and
> commit log, please say something more specific than "the proper places."
> 
> It's probably more important to say where they are moving *to* than where
> they're moving *out of*.
Thanks for your comments.
In another review loop listed below, Lucas used said that it's not good to hide
 PHY init in imx6_pcie_assert_core_reset()
So, I make a try to move the phy_init() out of imx6_pcie_assert_core_reset().
And move phy_power_on() out of imx6_pcie_clk_enable() accordingly.
https://patchwork.kernel.org/project/linux-pci/patch/1646289275-17813-1-git-send-email-hongxing.zhu@nxp.com/
Okay, I would specific that they are moving *to* later.

> 
> > In order to save power consumption, turn off the clocks and regulators
> > when the imx6_pcie_host_init() return error.
> 
> Is the power savings the *reason* for this change?  I can't tell from the
> commit log.
The error handling of the imx6_pcie_host_init() is not mentioned in the subject.
Should I split these changes into two patches?

Best Regards
Richard Zhu
Bjorn Helgaas June 9, 2022, 4:25 p.m. UTC | #5
On Thu, Jun 09, 2022 at 06:20:16AM +0000, Hongxing Zhu wrote:
> > -----Original Message-----
> > From: Bjorn Helgaas <helgaas@kernel.org>
> > Sent: 2022年6月9日 2:58
> > To: Hongxing Zhu <hongxing.zhu@nxp.com>
> > Cc: l.stach@pengutronix.de; bhelgaas@google.com; robh+dt@kernel.org;
> > broonie@kernel.org; lorenzo.pieralisi@arm.com; jingoohan1@gmail.com;
> > festevam@gmail.com; francesco.dolcini@toradex.com;
> > linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > linux-kernel@vger.kernel.org; kernel@pengutronix.de; dl-linux-imx
> > <linux-imx@nxp.com>
> > Subject: Re: [PATCH v9 7/8] PCI: imx6: Move the phy driver callbacks to the
> > proper places
> > 
> > On Fri, May 06, 2022 at 09:47:08AM +0800, Richard Zhu wrote:
> > > To make it more reasonable, move the phy_power_on/phy_init callbacks
> > > to the proper places.
> > > - move the phy_power_on() out of imx6_pcie_clk_enable().
> > > - move the phy_init() out of imx6_pcie_deassert_core_reset().
> > 
> > I'm not sure what "make it more reasonable" is telling me.  In
> > subject line and commit log, please say something more specific
> > than "the proper places."
> > 
> > It's probably more important to say where they are moving *to*
> > than where they're moving *out of*.

> Thanks for your comments.
> In another review loop listed below, Lucas used said that it's not
> good to hide PHY init in imx6_pcie_assert_core_reset() So, I make a
> try to move the phy_init() out of imx6_pcie_assert_core_reset().
> And move phy_power_on() out of imx6_pcie_clk_enable() accordingly.
> https://patchwork.kernel.org/project/linux-pci/patch/1646289275-17813-1-git-send-email-hongxing.zhu@nxp.com/
> Okay, I would specific that they are moving *to* later.
> 
> > > In order to save power consumption, turn off the clocks and
> > > regulators when the imx6_pcie_host_init() return error.
> > 
> > Is the power savings the *reason* for this change?  I can't tell
> > from the commit log.
>
> The error handling of the imx6_pcie_host_init() is not mentioned in
> the subject.  Should I split these changes into two patches?

If they can be split, they probably should be split.
Hongxing Zhu June 10, 2022, 6:51 a.m. UTC | #6
> -----Original Message-----
> From: Bjorn Helgaas <helgaas@kernel.org>
> Sent: 2022年6月10日 0:26
> To: Hongxing Zhu <hongxing.zhu@nxp.com>
> Cc: l.stach@pengutronix.de; bhelgaas@google.com; robh+dt@kernel.org;
> broonie@kernel.org; lorenzo.pieralisi@arm.com; jingoohan1@gmail.com;
> festevam@gmail.com; francesco.dolcini@toradex.com;
> linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org; kernel@pengutronix.de; dl-linux-imx
> <linux-imx@nxp.com>
> Subject: Re: [PATCH v9 7/8] PCI: imx6: Move the phy driver callbacks to the
> proper places
> 
> On Thu, Jun 09, 2022 at 06:20:16AM +0000, Hongxing Zhu wrote:
> > > -----Original Message-----
> > > From: Bjorn Helgaas <helgaas@kernel.org>
> > > Sent: 2022年6月9日 2:58
> > > To: Hongxing Zhu <hongxing.zhu@nxp.com>
> > > Cc: l.stach@pengutronix.de; bhelgaas@google.com; robh+dt@kernel.org;
> > > broonie@kernel.org; lorenzo.pieralisi@arm.com; jingoohan1@gmail.com;
> > > festevam@gmail.com; francesco.dolcini@toradex.com;
> > > linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > > linux-kernel@vger.kernel.org; kernel@pengutronix.de; dl-linux-imx
> > > <linux-imx@nxp.com>
> > > Subject: Re: [PATCH v9 7/8] PCI: imx6: Move the phy driver callbacks
> > > to the proper places
> > >
> > > On Fri, May 06, 2022 at 09:47:08AM +0800, Richard Zhu wrote:
> > > > To make it more reasonable, move the phy_power_on/phy_init
> > > > callbacks to the proper places.
> > > > - move the phy_power_on() out of imx6_pcie_clk_enable().
> > > > - move the phy_init() out of imx6_pcie_deassert_core_reset().
> > >
> > > I'm not sure what "make it more reasonable" is telling me.  In
> > > subject line and commit log, please say something more specific than
> > > "the proper places."
> > >
> > > It's probably more important to say where they are moving *to* than
> > > where they're moving *out of*.
> 
> > Thanks for your comments.
> > In another review loop listed below, Lucas used said that it's not
> > good to hide PHY init in imx6_pcie_assert_core_reset() So, I make a
> > try to move the phy_init() out of imx6_pcie_assert_core_reset().
> > And move phy_power_on() out of imx6_pcie_clk_enable() accordingly.
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatc
> >
> hwork.kernel.org%2Fproject%2Flinux-pci%2Fpatch%2F1646289275-17813-1-g
> i
> >
> t-send-email-hongxing.zhu%40nxp.com%2F&amp;data=05%7C01%7Chongxing
> .zhu
> > %40nxp.com%7C0094cb503bd64d9d8c0008da4a34bbc8%7C686ea1d3bc2b
> 4c6fa92cd9
> >
> 9c5c301635%7C0%7C0%7C637903887598125451%7CUnknown%7CTWFpbG
> Zsb3d8eyJWIj
> >
> oiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C30
> 00%7C
> > %7C%7C&amp;sdata=ntbjAv6s3M0mUI8uCAUX23HiPNBlgvWKlAaw7lAh%2F
> pE%3D&amp;
> > reserved=0 Okay, I would specific that they are moving *to* later.
> >
> > > > In order to save power consumption, turn off the clocks and
> > > > regulators when the imx6_pcie_host_init() return error.
> > >
> > > Is the power savings the *reason* for this change?  I can't tell
> > > from the commit log.
> >
> > The error handling of the imx6_pcie_host_init() is not mentioned in
> > the subject.  Should I split these changes into two patches?
> 
> If they can be split, they probably should be split.
Got that, thanks a lot.

Best Regards
Richard Zhu
diff mbox series

Patch

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index d122c12193a6..f0ffd9011975 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -497,14 +497,6 @@  static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 		goto err_ref_clk;
 	}
 
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MM:
-		if (phy_power_on(imx6_pcie->phy))
-			dev_err(dev, "unable to power on PHY\n");
-		break;
-	default:
-		break;
-	}
 	/* allow the clocks to stabilize */
 	usleep_range(200, 500);
 	return 0;
@@ -597,10 +589,7 @@  static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX8MQ:
 		reset_control_deassert(imx6_pcie->pciephy_reset);
-		break;
 	case IMX8MM:
-		if (phy_init(imx6_pcie->phy))
-			dev_err(dev, "waiting for phy ready timeout!\n");
 		break;
 	case IMX7D:
 		reset_control_deassert(imx6_pcie->pciephy_reset);
@@ -918,15 +907,38 @@  static int imx6_pcie_host_init(struct pcie_port *pp)
 
 	imx6_pcie_assert_core_reset(imx6_pcie);
 	imx6_pcie_init_phy(imx6_pcie);
+	if (imx6_pcie->phy != NULL) {
+		ret = phy_power_on(imx6_pcie->phy);
+		if (ret) {
+			dev_err(dev, "pcie phy power up failed.\n");
+			return ret;
+		}
+	}
+
 	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
 	if (ret < 0) {
 		dev_err(dev, "pcie host init failed: %d.\n", ret);
-		return ret;
+		goto err_exit0;
+	} else if (imx6_pcie->phy != NULL) {
+		ret = phy_init(imx6_pcie->phy);
+		if (ret) {
+			dev_err(dev, "waiting for phy ready timeout!\n");
+			goto err_exit1;
+		}
 	}
 
 	imx6_setup_phy_mpll(imx6_pcie);
 
 	return 0;
+
+err_exit1:
+	imx6_pcie_clk_disable(imx6_pcie);
+	if (imx6_pcie->vpcie)
+		regulator_disable(imx6_pcie->vpcie);
+err_exit0:
+	if (imx6_pcie->phy != NULL)
+		phy_power_off(imx6_pcie->phy);
+	return ret;
 }
 
 static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
@@ -1031,14 +1043,47 @@  static int imx6_pcie_resume_noirq(struct device *dev)
 		regulator_disable(imx6_pcie->vpcie);
 
 	imx6_pcie_init_phy(imx6_pcie);
-	imx6_pcie_deassert_core_reset(imx6_pcie);
-	dw_pcie_setup_rc(pp);
+	if (imx6_pcie->phy != NULL) {
+		ret = phy_power_on(imx6_pcie->phy);
+		if (ret) {
+			dev_err(dev, "pcie phy power up failed.\n");
+			return ret;
+		}
+	}
+
+	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
+	if (ret < 0) {
+		dev_err(dev, "pcie deassert core reset failed: %d.\n", ret);
+		goto err_exit0;
+	} else if (imx6_pcie->phy != NULL) {
+		ret = phy_init(imx6_pcie->phy);
+		if (ret) {
+			dev_err(dev, "pcie phy init failed.\n");
+			goto err_exit1;
+		}
+	}
 
+	dw_pcie_setup_rc(pp);
 	ret = imx6_pcie_start_link(imx6_pcie->pci);
-	if (ret < 0)
-		dev_info(dev, "pcie link is down after resume.\n");
+	if (ret < 0) {
+		/*
+		 * Return ret directly, since there are error exit
+		 * handle in imx6_pcie_start_link()
+		 */
+		dev_err(dev, "pcie link is down after resume.\n");
+		return ret;
+	}
 
 	return 0;
+
+err_exit1:
+	imx6_pcie_clk_disable(imx6_pcie);
+	if (imx6_pcie->vpcie)
+		regulator_disable(imx6_pcie->vpcie);
+err_exit0:
+	if (imx6_pcie->phy != NULL)
+		phy_power_off(imx6_pcie->phy);
+	return ret;
 }
 #endif