On Tue, Nov 05, 2013 at 11:05:15AM +0800, Shawn Guo wrote: > On Tue, Nov 05, 2013 at 09:49:43AM +0800, Peter Chen wrote: > > We need this to keep PHY's power on or off during the system > > suspend mode. If we need to enable USB wakeup, then we > > must keep PHY's power being on during the system suspend mode. > > Otherwise, we need to keep PHY's power being off to save power. > > > > Signed-off-by: Peter Chen <peter.chen@xxxxxxxxxxxxx> > > --- > > drivers/usb/phy/phy-mxs-usb.c | 66 +++++++++++++++++++++++++++++++++++++++-- > > 1 files changed, 63 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c > > index ff8b98c..4588c72 100644 > > --- a/drivers/usb/phy/phy-mxs-usb.c > > +++ b/drivers/usb/phy/phy-mxs-usb.c > > @@ -55,11 +55,18 @@ > > #define BM_USBPHY_DEBUG_CLKGATE BIT(30) > > > > /* Anatop Registers */ > > +#define ANADIG_ANA_MISC0 0x150 > > +#define ANADIG_ANA_MISC0_SET 0x154 > > +#define ANADIG_ANA_MISC0_CLR 0x158 > > + > > #define ANADIG_USB1_VBUS_DET_STAT 0x1c0 > > > > #define ANADIG_USB1_LOOPBACK_SET 0x1e4 > > #define ANADIG_USB1_LOOPBACK_CLR 0x1e8 > > > > +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12) > > +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11) > > + > > #define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3) > > > > #define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2) > > @@ -83,6 +90,15 @@ > > */ > > #define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2) > > > > +/* imx23 style PHY */ > > +#define MXS_PHY_IMX23 BIT(3) > > + > > +/* imx6q style PHY */ > > +#define MXS_PHY_IMX6Q BIT(4) > > + > > +/* imx6sl style PHY */ > > +#define MXS_PHY_IMX6SL BIT(5) > > + > > We will not need these, if we do what I suggested to carry a pointer > to mxs_phy_data in mxs_phy. > > struct mxs_phy { > ... > struct mxs_phy_data *data; > }; > > The check then can be done like below. > > static inline int is_imx6q_phy(struct mxs_phy *mxs_phy) > { > return mxs_phy->data == &imx6q_phy_data; > } > What's the benefit compared to current one? Peter > Shawn > > > /* > > * IC fix for MXS_PHY_ABNORAML_IN_SUSPEND, bit 17 is the effective bit > > * in HW_USBPHY_IP. > > @@ -100,19 +116,23 @@ struct mxs_phy_platform_flag { > > }; > > > > static const struct mxs_phy_platform_flag imx23_phy_data = { > > - .flags = MXS_PHY_ABNORAML_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST, > > + .flags = MXS_PHY_ABNORAML_IN_SUSPEND | > > + MXS_PHY_SENDING_SOF_TOO_FAST | > > + MXS_PHY_IMX23, > > }; > > > > static const struct mxs_phy_platform_flag imx6q_phy_data = { > > .flags = MXS_PHY_SENDING_SOF_TOO_FAST | > > MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | > > - MXS_PHY_FIX_ABNORAML_IN_SUSPEND, > > + MXS_PHY_FIX_ABNORAML_IN_SUSPEND | > > + MXS_PHY_IMX6Q, > > }; > > > > static const struct mxs_phy_platform_flag imx6sl_phy_data = { > > .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS | > > MXS_PHY_FIX_ABNORAML_IN_SUSPEND | > > - MXS_PHY_FIX_SENDING_SOF_TOO_FAST, > > + MXS_PHY_FIX_SENDING_SOF_TOO_FAST | > > + MXS_PHY_IMX6SL, > > }; > > > > static const struct of_device_id mxs_phy_dt_ids[] = { > > @@ -210,6 +230,22 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) > > ? "disconnected" : "connected"); > > } > > > > +static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on) > > +{ > > + unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR; > > + > > + /* If the SoCs don't have anatop, quit */ > > + if (!mxs_phy->regmap_anatop) > > + return; > > + > > + if (mxs_phy->flags & MXS_PHY_IMX6Q) > > + regmap_write(mxs_phy->regmap_anatop, reg, > > + BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG); > > + else if (mxs_phy->flags & MXS_PHY_IMX6SL) > > + regmap_write(mxs_phy->regmap_anatop, > > + reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL); > > +} > > + > > static int mxs_phy_init(struct usb_phy *phy) > > { > > struct mxs_phy *mxs_phy = to_mxs_phy(phy); > > @@ -395,6 +431,7 @@ static int mxs_phy_probe(struct platform_device *pdev) > > > > platform_set_drvdata(pdev, &mxs_phy->phy); > > > > + device_set_wakeup_capable(&pdev->dev, true); > > ret = usb_add_phy_dev(&mxs_phy->phy); > > if (ret) > > return ret; > > @@ -411,6 +448,28 @@ static int mxs_phy_remove(struct platform_device *pdev) > > return 0; > > } > > > > +static int mxs_phy_system_suspend(struct device *dev) > > +{ > > + struct mxs_phy *mxs_phy = dev_get_drvdata(dev); > > + > > + if (device_may_wakeup(dev)) > > + mxs_phy_enable_ldo_in_suspend(mxs_phy, true); > > + > > + return 0; > > +} > > + > > +static int mxs_phy_system_resume(struct device *dev) > > +{ > > + struct mxs_phy *mxs_phy = dev_get_drvdata(dev); > > + > > + if (device_may_wakeup(dev)) > > + mxs_phy_enable_ldo_in_suspend(mxs_phy, false); > > + > > + return 0; > > +} > > + > > +SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend, mxs_phy_system_resume); > > + > > static struct platform_driver mxs_phy_driver = { > > .probe = mxs_phy_probe, > > .remove = mxs_phy_remove, > > @@ -418,6 +477,7 @@ static struct platform_driver mxs_phy_driver = { > > .name = DRIVER_NAME, > > .owner = THIS_MODULE, > > .of_match_table = mxs_phy_dt_ids, > > + .pm = &mxs_phy_pm, > > }, > > }; > > > > -- > > 1.7.1 > > > > -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html