summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2014-12-19 10:20:12 +0800
committerPeter Chen <peter.chen@freescale.com>2014-12-19 13:54:38 +0800
commite1959911edda217d547b2cd06bc6dcd198de36e8 (patch)
tree63dd5e6166da7a2d591dca07afca5c3d0e3dc90b
parent178bb7bed5b467463a3861aecdd5361ea9d295b7 (diff)
MLK-10039 usb: chipidea: enable usb as wakeup source if the device is connected
Enable USB as wakeup source if it is imx6sx and the usb device is connected. We do this tricky thing for disable megafix off, since megafix control code depends on wakeup source. If the usb device is connected, we want the connection is not broken, and to support HSIC device since HSIC controller does not support hot plug. It will not produce un-intended usb wakeup since the usb wakeup is controlled by WIE bit in usb ctrl register, it is only enabled through /sys entry. Acked-by: Li Jun <jun.li@freescale.com> Signed-off-by: Peter Chen <peter.chen@freescale.com>
-rw-r--r--drivers/usb/chipidea/ci.h2
-rw-r--r--drivers/usb/chipidea/ci_hdrc_imx.c1
-rw-r--r--drivers/usb/chipidea/core.c25
-rw-r--r--include/linux/usb/chipidea.h1
4 files changed, 25 insertions, 4 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index cbd9d7cfe1e7..5dbaa7afb4eb 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -149,6 +149,7 @@ struct hw_bank {
* @in_lpm: if the core in low power mode
* @wakeup_int: if wakeup interrupt occur
* @timer: timer to delay clock closing
+ * @wakeup_source: if usb as system wakeup source
*/
struct ci_hdrc {
struct device *dev;
@@ -208,6 +209,7 @@ struct ci_hdrc {
u32 pm_portsc;
u32 pm_usbmode;
struct work_struct power_lost_work;
+ bool wakeup_source;
};
static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 74a91e497318..c7fa42a7bf4b 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -76,6 +76,7 @@ static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
CI_HDRC_IMX_EHCI_QUIRK |
CI_HDRC_DISABLE_HOST_STREAMING |
CI_HDRC_OVERRIDE_AHB_BURST |
+ CI_HDRC_IS_FSL_IMX6SX |
CI_HDRC_OVERRIDE_BURST_LENGTH,
.ahbburst_config = 0,
.burst_length = 0x1010,
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 06a115a63180..3ba3fab3ef2e 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -1002,7 +1002,7 @@ static int ci_suspend(struct device *dev)
ci_role(ci)->suspend(ci);
if (device_may_wakeup(dev)) {
- enable_irq_wake(ci->irq);
+ ci->wakeup_source = true;
if (ci_otg_is_fsm_mode(ci))
ci_otg_fsm_suspend_for_srp(ci);
if (ci->transceiver)
@@ -1014,9 +1014,24 @@ static int ci_suspend(struct device *dev)
host_mode = (hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC);
connect = !!(hw_read(ci, OP_PORTSC, PORTSC_CCS));
- if (host_mode && connect)
+ if (host_mode && connect) {
/* pull down dp and dm if needed */
- usb_phy_pulldown_line(ci->transceiver, true);
+ usb_phy_pulldown_line(ci->transceiver, true);
+ /*
+ * Enable USB as wakeup source if it is imx6sx and
+ * the usb device is connected.
+ * We do this tricky thing for disable megafix off,
+ * since megafix control code depends on wakeup source.
+ *
+ * If the usb device is connected, we want the connection is
+ * not broken, and to support HSIC device since HSIC controller
+ * does not support hot plug.
+ */
+ if (ci->platdata->flags & CI_HDRC_IS_FSL_IMX6SX)
+ ci->wakeup_source = true;
+ }
+ if (ci->wakeup_source)
+ enable_irq_wake(ci->irq);
ci_controller_suspend(ci);
@@ -1038,8 +1053,10 @@ static int ci_resume(struct device *dev)
/* Restore value 0 if it was set for power lost check */
hw_write(ci, OP_ENDPTLISTADDR, ~0, 0);
- if (device_may_wakeup(dev))
+ if (ci->wakeup_source) {
disable_irq_wake(ci->irq);
+ ci->wakeup_source = false;
+ }
ret = ci_controller_resume(dev);
if (ret)
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index f3ab477871d6..d8a76e388e1a 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -34,6 +34,7 @@ struct ci_hdrc_platform_data {
CI_HDRC_DISABLE_HOST_STREAMING)
#define CI_HDRC_OVERRIDE_AHB_BURST BIT(11)
#define CI_HDRC_OVERRIDE_BURST_LENGTH BIT(12)
+#define CI_HDRC_IS_FSL_IMX6SX BIT(13)
enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1