From: Li Jun Date: Thu, 15 Jan 2015 11:13:13 +0000 (+0800) Subject: MLK-10102-1 usb: chipidea: imx: usb resume from power lost during system sleep X-Git-Tag: C0P2-H0.0--20200415~4724 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=b2d407d2397a7c1dff4c11dbfc79db99344310c4;p=linux.git MLK-10102-1 usb: chipidea: imx: usb resume from power lost during system sleep i.MX6SX mega off can shutdown domain power supply if none of peripheral in this domain is registered as wakeup source, this patch adds usb controller imx specific re-init after resume from such power lost during system sleep. Signed-off-by: Li Jun (cherry picked from commit cd37f9b7157322e28c1d336e42813d441eb1f778) --- diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index e15e0933a40b..1e77fba754cc 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -528,6 +528,16 @@ static int imx_controller_resume(struct device *dev) data->in_lpm = false; + ret = imx_usbmisc_power_lost_check(data->usbmisc_data); + /* re-init if resume from power lost */ + if (ret > 0) { + ret = imx_usbmisc_init(data->usbmisc_data); + if (ret) { + dev_err(dev, "usbmisc init failed, ret=%d\n", ret); + goto clk_disable; + } + } + ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false); if (ret) { dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret); diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h index 1447d2c8839d..d0d18cf07703 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.h +++ b/drivers/usb/chipidea/ci_hdrc_imx.h @@ -54,5 +54,6 @@ int imx_usbmisc_init_post(struct imx_usbmisc_data *); int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool); int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect); int imx_usbmisc_charger_secondary_detection(struct imx_usbmisc_data *data); +int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *); #endif /* __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H */ diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 5e7d241973b7..c2c3d088e96d 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -111,6 +111,8 @@ struct usbmisc_ops { int (*charger_primary_detection)(struct imx_usbmisc_data *data); /* usb charger secondary detection */ int (*charger_secondary_detection)(struct imx_usbmisc_data *data); + /* It's called when system resume from usb power lost */ + int (*power_lost_check)(struct imx_usbmisc_data *data); }; struct imx_usbmisc { @@ -550,6 +552,25 @@ int imx6_charger_secondary_detection(struct imx_usbmisc_data *data) return 0; } +static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data) +{ + struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); + unsigned long flags; + u32 val; + + spin_lock_irqsave(&usbmisc->lock, flags); + val = readl(usbmisc->base + data->index * 4); + spin_unlock_irqrestore(&usbmisc->lock, flags); + /* + * Here use a power on reset value to judge + * if the controller experienced a power lost + */ + if (val == 0x30001000) + return 1; + else + return 0; +} + static const struct usbmisc_ops imx25_usbmisc_ops = { .init = usbmisc_imx25_init, .post = usbmisc_imx25_post, @@ -579,6 +600,7 @@ static const struct usbmisc_ops imx6sx_usbmisc_ops = { .init = usbmisc_imx6sx_init, .charger_primary_detection = imx6_charger_primary_detection, .charger_secondary_detection = imx6_charger_secondary_detection, + .power_lost_check = usbmisc_imx6sx_power_lost_check, }; static const struct usbmisc_ops imx7d_usbmisc_ops = { @@ -679,6 +701,20 @@ int imx_usbmisc_charger_secondary_detection(struct imx_usbmisc_data *data) } EXPORT_SYMBOL_GPL(imx_usbmisc_charger_secondary_detection); +int imx_usbmisc_power_lost_check(struct imx_usbmisc_data *data) +{ + struct imx_usbmisc *usbmisc; + + if (!data) + return 0; + + usbmisc = dev_get_drvdata(data->dev); + if (!usbmisc->ops->power_lost_check) + return 0; + return usbmisc->ops->power_lost_check(data); +} +EXPORT_SYMBOL_GPL(imx_usbmisc_power_lost_check); + static const struct of_device_id usbmisc_imx_dt_ids[] = { { .compatible = "fsl,imx25-usbmisc",