* [PATCH v3 00/10] Add power management support for chipidea
@ 2013-11-05 1:55 Peter Chen
2013-11-05 1:55 ` [PATCH v3 01/10] usb: chipidea: Add power management support Peter Chen
` (10 more replies)
0 siblings, 11 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
Hi Greg,
This serial adds power management (system & runtime) for chipidea core.
With this, the chipidea controller can be at low power mode when it is not in
use, and the chipidea controller can be the system wakeup source.
It needs to depend on my patch[1], since [1]-"Add power management support for MXS PHY"
adds some common PHY APIs, and this serial uses it.
It has been verified at Freescale i.mx6Q/DL SabreSD, i.mx28 evk platform
(no runtime pm support), I will verify it at other FSL platforms during
the patch review.
Hi Alan,
Due to chipidea core and imx concontroller needs some special operations
during the standard ehci routine, I override .hub_control, .bus_suspend,
and .bus_resume.
There is one special thing is I use flag ehci->bus_suspended to know it
was a global suspend before due to I need to notify PHY when the suspend
has finished (portsc.suspendM is set) and the resume signal has finished
(portsc.fpr is cleared) for high speed device, but there are two places
will send suspend/resume, and I don't want to patch ehci-hub.c (if you think
patch ehci-hub.c is a good way, I can do it).
The related host patches:
usb: chipidea: host: add quirk for ehci operation
usb: chipidea: host: add ehci quirk for imx controller
My github tree: https://github.com/hzpeterchen/linux-usb
branch: master
It is based on linux-next-1029.
Changes for v3:
- Using flag bit to indicate SoC features/bugs [7/10][10/10]
Changes for v2:
- Do not use atomic_read and atomic_set for ci->in_lpm
- Do not use "supports_runtime_pm" as DT property due to it is
not a hardware feature, instead of it, we use compatible string
to enable it.
Peter Chen (10):
usb: chipidea: Add power management support
usb: chipidea: imx: add power management support
usb: chipidea: add wakeup interrupt handler
usb: chipidea: usbmisc_imx: remove the controller's clock information
usb: chipidea: usbmisc_imx: add set_wakup API
usb: chipidea: imx: call set_wakeup when necessary
usb: chipidea: imx: Enable runtime pm support for imx6q
usb: chipidea: host: add quirk for ehci operation
usb: chipidea: host: add ehci quirk for imx controller
usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK
drivers/usb/chipidea/ci.h | 3 +
drivers/usb/chipidea/ci_hdrc_imx.c | 156 ++++++++++++++++++++++++++++++-
drivers/usb/chipidea/ci_hdrc_imx.h | 1 +
drivers/usb/chipidea/core.c | 139 +++++++++++++++++++++++++++
drivers/usb/chipidea/host.c | 180 ++++++++++++++++++++++++++++++++++++
drivers/usb/chipidea/otg.c | 5 +
drivers/usb/chipidea/usbmisc_imx.c | 59 ++++++++----
include/linux/usb/chipidea.h | 2 +
8 files changed, 522 insertions(+), 23 deletions(-)
[1] http://marc.info/?l=linux-usb&m=138361739523355&w=2
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 01/10] usb: chipidea: Add power management support
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 02/10] usb: chipidea: imx: add " Peter Chen
` (9 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
This commit adds runtime and system power management support for
chipidea core. The runtime pm support is controlled by glue
layer, it can be enabled by flag CI_HDRC_SUPPORTS_RUNTIME_PM.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci.h | 2 +
drivers/usb/chipidea/core.c | 119 ++++++++++++++++++++++++++++++++++++++++++
include/linux/usb/chipidea.h | 1 +
3 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f9b1914..f296d66 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -175,6 +175,8 @@ struct ci_hdrc {
bool b_sess_valid_event;
/* imx28 needs swp instruction for writing */
bool imx28_write_fix;
+ bool supports_runtime_pm;
+ bool in_lpm;
};
static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index e26e616..b05470f 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -583,6 +583,10 @@ static int ci_hdrc_probe(struct platform_device *pdev)
hw_phymode_configure(ci);
dr_mode = ci->platdata->dr_mode;
+
+ ci->supports_runtime_pm = !!(ci->platdata->flags &
+ CI_HDRC_SUPPORTS_RUNTIME_PM);
+
/* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
ret = ci_hdrc_host_init(ci);
@@ -656,6 +660,13 @@ static int ci_hdrc_probe(struct platform_device *pdev)
if (ret)
goto stop;
+ device_set_wakeup_capable(&pdev->dev, true);
+
+ if (ci->supports_runtime_pm) {
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
+
ret = dbg_create_files(ci);
if (!ret)
return 0;
@@ -673,6 +684,11 @@ static int ci_hdrc_remove(struct platform_device *pdev)
{
struct ci_hdrc *ci = platform_get_drvdata(pdev);
+ if (ci->supports_runtime_pm) {
+ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ }
dbg_remove_files(ci);
free_irq(ci->irq, ci);
ci_role_destroy(ci);
@@ -683,11 +699,114 @@ static int ci_hdrc_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int ci_controller_suspend(struct device *dev)
+{
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "at %s\n", __func__);
+
+ if (ci->in_lpm)
+ return 0;
+
+ disable_irq(ci->irq);
+
+ if (ci->transceiver)
+ usb_phy_set_wakeup(ci->transceiver, true);
+
+ ci_hdrc_enter_lpm(ci, true);
+
+ if (ci->transceiver)
+ usb_phy_set_suspend(ci->transceiver, 1);
+
+ ci->in_lpm = true;
+
+ enable_irq(ci->irq);
+
+ return 0;
+}
+
+static int ci_controller_resume(struct device *dev)
+{
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "at %s\n", __func__);
+
+ if (!ci->in_lpm)
+ return 0;
+
+ ci_hdrc_enter_lpm(ci, false);
+
+ if (ci->transceiver) {
+ usb_phy_set_suspend(ci->transceiver, 0);
+ usb_phy_set_wakeup(ci->transceiver, false);
+ }
+
+ ci->in_lpm = false;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ci_suspend(struct device *dev)
+{
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
+ int ret;
+
+ ret = ci_controller_suspend(dev);
+ if (ret)
+ return ret;
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(ci->irq);
+
+ return ret;
+}
+
+static int ci_resume(struct device *dev)
+{
+ struct ci_hdrc *ci = dev_get_drvdata(dev);
+ int ret;
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(ci->irq);
+
+ ret = ci_controller_resume(dev);
+ if (!ret && ci->supports_runtime_pm) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM_RUNTIME
+static int ci_runtime_suspend(struct device *dev)
+{
+ return ci_controller_suspend(dev);
+}
+
+static int ci_runtime_resume(struct device *dev)
+{
+ return ci_controller_resume(dev);
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+#endif /* CONFIG_PM */
+static const struct dev_pm_ops ci_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ci_suspend, ci_resume)
+ SET_RUNTIME_PM_OPS(ci_runtime_suspend,
+ ci_runtime_resume, NULL)
+};
+
static struct platform_driver ci_hdrc_driver = {
.probe = ci_hdrc_probe,
.remove = ci_hdrc_remove,
.driver = {
.name = "ci_hdrc",
+ .pm = &ci_pm_ops,
},
};
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 708bd11..3842431 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -18,6 +18,7 @@ struct ci_hdrc_platform_data {
unsigned long flags;
#define CI_HDRC_REGS_SHARED BIT(0)
#define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1)
+#define CI_HDRC_SUPPORTS_RUNTIME_PM BIT(2)
#define CI_HDRC_DISABLE_STREAMING BIT(3)
/*
* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 02/10] usb: chipidea: imx: add power management support
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
2013-11-05 1:55 ` [PATCH v3 01/10] usb: chipidea: Add power management support Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 03/10] usb: chipidea: add wakeup interrupt handler Peter Chen
` (8 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
Add system and runtime power management support for imx gluy layer.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci_hdrc_imx.c | 94 ++++++++++++++++++++++++++++++++++-
1 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 0bd7ce1..803630e 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -48,6 +48,8 @@ struct ci_hdrc_imx_data {
struct platform_device *ci_pdev;
struct clk *clk;
struct imx_usbmisc_data *usbmisc_data;
+ bool supports_runtime_pm;
+ bool in_lpm;
};
/* Common functions shared by usbmisc drivers */
@@ -176,8 +178,12 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
- pm_runtime_no_callbacks(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
+ device_set_wakeup_capable(&pdev->dev, true);
+
+ if (data->supports_runtime_pm) {
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
return 0;
@@ -192,13 +198,94 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
{
struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev);
- pm_runtime_disable(&pdev->dev);
ci_hdrc_remove_device(data->ci_pdev);
+ if (data->supports_runtime_pm) {
+ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+ }
+ clk_disable_unprepare(data->clk);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int imx_controller_suspend(struct device *dev)
+{
+ struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "at %s\n", __func__);
+
+ if (data->in_lpm)
+ return 0;
+
clk_disable_unprepare(data->clk);
+ data->in_lpm = true;
+
return 0;
}
+static int imx_controller_resume(struct device *dev)
+{
+ struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+ int ret = 0;
+
+ dev_dbg(dev, "at %s\n", __func__);
+
+ if (!data->in_lpm)
+ return 0;
+
+ ret = clk_prepare_enable(data->clk);
+ if (ret)
+ return ret;
+
+ data->in_lpm = false;
+
+ return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ci_hdrc_imx_suspend(struct device *dev)
+{
+ return imx_controller_suspend(dev);
+}
+
+static int ci_hdrc_imx_resume(struct device *dev)
+{
+ struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ ret = imx_controller_resume(dev);
+ if (!ret && data->supports_runtime_pm) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM_RUNTIME
+static int ci_hdrc_imx_runtime_suspend(struct device *dev)
+{
+ return imx_controller_suspend(dev);
+}
+
+static int ci_hdrc_imx_runtime_resume(struct device *dev)
+{
+ return imx_controller_resume(dev);
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+#endif /* CONFIG_PM */
+static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
+ SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
+ ci_hdrc_imx_runtime_resume, NULL)
+};
+
static struct platform_driver ci_hdrc_imx_driver = {
.probe = ci_hdrc_imx_probe,
.remove = ci_hdrc_imx_remove,
@@ -206,6 +293,7 @@ static struct platform_driver ci_hdrc_imx_driver = {
.name = "imx_usb",
.owner = THIS_MODULE,
.of_match_table = ci_hdrc_imx_dt_ids,
+ .pm = &ci_hdrc_imx_pm_ops,
},
};
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 03/10] usb: chipidea: add wakeup interrupt handler
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
2013-11-05 1:55 ` [PATCH v3 01/10] usb: chipidea: Add power management support Peter Chen
2013-11-05 1:55 ` [PATCH v3 02/10] usb: chipidea: imx: add " Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 04/10] usb: chipidea: usbmisc_imx: remove the controller's clock information Peter Chen
` (7 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
When the controller is at suspend mode, it can be waken up by
external events (like vbus, dp/dm or id change). Once we receive
the wakeup interrupt, we need to resume the controller first, eg
open clocks, disable some wakeup settings, etc. After that, the
controller can receive the normal USB interrupts.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci.h | 1 +
drivers/usb/chipidea/core.c | 20 ++++++++++++++++++++
drivers/usb/chipidea/otg.c | 5 +++++
3 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index f296d66..3e848b1 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -177,6 +177,7 @@ struct ci_hdrc {
bool imx28_write_fix;
bool supports_runtime_pm;
bool in_lpm;
+ bool wakeup_int;
};
static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index b05470f..4ba9e68 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -190,6 +190,13 @@ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
* than 1ms) to leave low power mode.
*/
usleep_range(1500, 2000);
+ } else if (!enable) {
+ /*
+ * At wakeup interrupt, the phcd will be cleared by hardware
+ * automatically, but the controller needs at least 1ms
+ * to reflect PHY's status.
+ */
+ usleep_range(1200, 1800);
}
}
@@ -355,6 +362,13 @@ static irqreturn_t ci_irq(int irq, void *data)
irqreturn_t ret = IRQ_NONE;
u32 otgsc = 0;
+ if (ci->in_lpm) {
+ disable_irq_nosync(irq);
+ ci->wakeup_int = true;
+ pm_runtime_get(ci->dev);
+ return IRQ_HANDLED;
+ }
+
if (ci->is_otg)
otgsc = hw_read(ci, OP_OTGSC, ~0);
@@ -744,6 +758,12 @@ static int ci_controller_resume(struct device *dev)
ci->in_lpm = false;
+ if (ci->wakeup_int) {
+ ci->wakeup_int = false;
+ enable_irq(ci->irq);
+ pm_runtime_put(ci->dev);
+ }
+
return 0;
}
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 39bd7ec..54bc7c0 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -78,10 +78,15 @@ static void ci_otg_work(struct work_struct *work)
if (ci->id_event) {
ci->id_event = false;
+ /* Keep controller active during id switch */
+ pm_runtime_get_sync(ci->dev);
ci_handle_id_switch(ci);
+ pm_runtime_put_sync(ci->dev);
} else if (ci->b_sess_valid_event) {
ci->b_sess_valid_event = false;
+ pm_runtime_get_sync(ci->dev);
ci_handle_vbus_change(ci);
+ pm_runtime_put_sync(ci->dev);
} else
dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 04/10] usb: chipidea: usbmisc_imx: remove the controller's clock information
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (2 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 03/10] usb: chipidea: add wakeup interrupt handler Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 05/10] usb: chipidea: usbmisc_imx: add set_wakup API Peter Chen
` (6 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
Currently, the usbmisc is just an API supplier for controller
driver, the controller calls related APIs to handle different
things among the SoCs, before calling it, the clock must
be on. So the clock operation is useless for usbmisc, it also
increases the difficulties to manage the clock, especially at
runtime power management situation.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/usbmisc_imx.c | 18 ------------------
1 files changed, 0 insertions(+), 18 deletions(-)
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 8a1094b..1fd9a12 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/of_platform.h>
-#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/delay.h>
@@ -40,7 +39,6 @@ struct usbmisc_ops {
struct imx_usbmisc {
void __iomem *base;
spinlock_t lock;
- struct clk *clk;
const struct usbmisc_ops *ops;
};
@@ -177,7 +175,6 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
{
struct resource *res;
struct imx_usbmisc *data;
- int ret;
struct of_device_id *tmp_dev;
if (usbmisc)
@@ -194,20 +191,6 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
if (IS_ERR(data->base))
return PTR_ERR(data->base);
- data->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(data->clk)) {
- dev_err(&pdev->dev,
- "failed to get clock, err=%ld\n", PTR_ERR(data->clk));
- return PTR_ERR(data->clk);
- }
-
- ret = clk_prepare_enable(data->clk);
- if (ret) {
- dev_err(&pdev->dev,
- "clk_prepare_enable failed, err=%d\n", ret);
- return ret;
- }
-
tmp_dev = (struct of_device_id *)
of_match_device(usbmisc_imx_dt_ids, &pdev->dev);
data->ops = (const struct usbmisc_ops *)tmp_dev->data;
@@ -218,7 +201,6 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
static int usbmisc_imx_remove(struct platform_device *pdev)
{
- clk_disable_unprepare(usbmisc->clk);
usbmisc = NULL;
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 05/10] usb: chipidea: usbmisc_imx: add set_wakup API
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (3 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 04/10] usb: chipidea: usbmisc_imx: remove the controller's clock information Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 06/10] usb: chipidea: imx: call set_wakeup when necessary Peter Chen
` (5 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
It is used to enable USB wakeup, currently only imx6 SoC serial
usb's wakeup is enabled.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci_hdrc_imx.h | 1 +
drivers/usb/chipidea/usbmisc_imx.c | 41 ++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.h b/drivers/usb/chipidea/ci_hdrc_imx.h
index c727159..92f4c30 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.h
+++ b/drivers/usb/chipidea/ci_hdrc_imx.h
@@ -18,3 +18,4 @@ struct imx_usbmisc_data {
int imx_usbmisc_init(struct imx_usbmisc_data *);
int imx_usbmisc_init_post(struct imx_usbmisc_data *);
+int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *, bool);
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 1fd9a12..55b59e0 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -28,12 +28,18 @@
#define MX53_BM_OVER_CUR_DIS_UHx BIT(30)
#define MX6_BM_OVER_CUR_DIS BIT(7)
+#define MX6_BM_WAKEUP_ENABLE BIT(10)
+#define MX6_BM_ID_WAKEUP BIT(16)
+#define MX6_BM_VBUS_WAKEUP BIT(17)
+#define MX6_BM_WAKEUP_INTR BIT(31)
struct usbmisc_ops {
/* It's called once when probe a usb device */
int (*init)(struct imx_usbmisc_data *data);
/* It's called once after adding a usb device */
int (*post)(struct imx_usbmisc_data *data);
+ /* It's called when we need to enable usb wakeup */
+ int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled);
};
struct imx_usbmisc {
@@ -122,6 +128,30 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
return 0;
}
+static int usbmisc_imx6q_set_wakeup
+ (struct imx_usbmisc_data *data, bool enabled)
+{
+ unsigned long flags;
+ u32 reg, val = (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP
+ | MX6_BM_ID_WAKEUP);
+
+ if (data->index > 3)
+ return -EINVAL;
+
+ spin_lock_irqsave(&usbmisc->lock, flags);
+ reg = readl(usbmisc->base + data->index * 4);
+ if (enabled) {
+ writel(reg | val, usbmisc->base + data->index * 4);
+ } else {
+ if (reg & MX6_BM_WAKEUP_INTR)
+ pr_debug("wakeup int at ci_hdrc.%d\n", data->index);
+ writel(reg & ~val, usbmisc->base + data->index * 4);
+ }
+ spin_unlock_irqrestore(&usbmisc->lock, flags);
+
+ return 0;
+}
+
static const struct usbmisc_ops imx25_usbmisc_ops = {
.post = usbmisc_imx25_post,
};
@@ -132,6 +162,7 @@ static const struct usbmisc_ops imx53_usbmisc_ops = {
static const struct usbmisc_ops imx6q_usbmisc_ops = {
.init = usbmisc_imx6q_init,
+ .set_wakeup = usbmisc_imx6q_set_wakeup,
};
int imx_usbmisc_init(struct imx_usbmisc_data *data)
@@ -154,6 +185,16 @@ int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
}
EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
+int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled)
+{
+ if (!usbmisc)
+ return -ENODEV;
+ if (!usbmisc->ops->set_wakeup)
+ return 0;
+ return usbmisc->ops->set_wakeup(data, enabled);
+}
+EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup);
+
static const struct of_device_id usbmisc_imx_dt_ids[] = {
{
.compatible = "fsl,imx25-usbmisc",
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 06/10] usb: chipidea: imx: call set_wakeup when necessary
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (4 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 05/10] usb: chipidea: usbmisc_imx: add set_wakup API Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 07/10] usb: chipidea: imx: Enable runtime pm support for imx6q Peter Chen
` (4 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
- Disable wakeup after probe
- Enable wakeup during the suspend
- Disable wakeup after controller is active
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci_hdrc_imx.c | 36 ++++++++++++++++++++++++++++++++++++
1 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 803630e..5fbaa73 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -176,6 +176,15 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
}
}
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
+ if (ret) {
+ dev_err(&pdev->dev, "usbmisc set_wakeup failed, ret=%d\n",
+ ret);
+ goto disable_device;
+ }
+ }
+
platform_set_drvdata(pdev, data);
device_set_wakeup_capable(&pdev->dev, true);
@@ -213,12 +222,23 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)
static int imx_controller_suspend(struct device *dev)
{
struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
+ int ret;
dev_dbg(dev, "at %s\n", __func__);
if (data->in_lpm)
return 0;
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
+ if (ret) {
+ dev_err(dev,
+ "usbmisc set_wakeup failed, ret=%d\n",
+ ret);
+ return ret;
+ }
+ }
+
clk_disable_unprepare(data->clk);
data->in_lpm = true;
@@ -242,6 +262,22 @@ static int imx_controller_resume(struct device *dev)
data->in_lpm = false;
+ if (data->usbmisc_data) {
+ ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
+ if (ret) {
+ dev_err(dev,
+ "usbmisc set_wakeup failed, ret=%d\n",
+ ret);
+ ret = -EINVAL;
+ goto clk_disable;
+ }
+ }
+
+ return 0;
+
+clk_disable:
+ clk_disable_unprepare(data->clk);
+
return ret;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 07/10] usb: chipidea: imx: Enable runtime pm support for imx6q
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (5 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 06/10] usb: chipidea: imx: call set_wakeup when necessary Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 08/10] usb: chipidea: host: add quirk for ehci operation Peter Chen
` (3 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
Currently, only imx6q adds wakeup logic, so only enable
runtime pm for imx6q.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci_hdrc_imx.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 5fbaa73..fd26c38 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -23,7 +23,8 @@
#include "ci.h"
#include "ci_hdrc_imx.h"
-#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
+#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
+#define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
struct ci_hdrc_imx_platform_flag {
unsigned int flags;
@@ -36,7 +37,12 @@ static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
.flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
};
+static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
+ .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM,
+};
+
static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
+ { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
{ /* sentinel */ }
@@ -147,6 +153,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
+ if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM)
+ pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
+ data->supports_runtime_pm = true;
+ }
+
if (data->usbmisc_data) {
ret = imx_usbmisc_init(data->usbmisc_data);
if (ret) {
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 08/10] usb: chipidea: host: add quirk for ehci operation
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (6 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 07/10] usb: chipidea: imx: Enable runtime pm support for imx6q Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 09/10] usb: chipidea: host: add ehci quirk for imx controller Peter Chen
` (2 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
For chipidea controller, it does not follow ehci spec strictly.
Taking resume signal as an example, it will stop resume signal about
20-21ms later automatically, but standard ehci spec says, the resume
signal is controlled by software (clear portsc.PORT_RESUME).
This operation causes some remote wakeup problems for high speed
devices due to host controller does not send SOF in time since
software can't guarantee set run/stop bit in time (run/stop bit
was cleared at the ehci suspend routine).
When software sets run/stop bit, it needs 1 SoF time to make it effect.
If we close the PHY clock just after setting run/stop bit, it does
not be set in practice, so a software delay is needed.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/host.c | 51 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 06fd042..de0c2de 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -33,6 +33,53 @@
#include "host.h"
static struct hc_driver __read_mostly ci_ehci_hc_driver;
+static int (*orig_bus_suspend)(struct usb_hcd *hcd);
+
+static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int port;
+ u32 tmp;
+
+ int ret = orig_bus_suspend(hcd);
+
+ if (ret)
+ return ret;
+
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ u32 __iomem *reg = &ehci->regs->port_status[port];
+ u32 portsc = ehci_readl(ehci, reg);
+
+ if (portsc & PORT_CONNECT) {
+ /*
+ * For chipidea, the resume signal will be ended
+ * automatically, so for remote wakeup case, the
+ * usbcmd.rs may not be set before the resume has
+ * ended if other resume path consumes too much
+ * time (~23ms-24ms), in that case, the SOF will not
+ * send out within 3ms after resume ends, then the
+ * device will enter suspend again.
+ */
+ if (hcd->self.root_hub->do_remote_wakeup) {
+ ehci_dbg(ehci,
+ "Remote wakeup is enabled, "
+ "and device is on the port\n");
+
+ tmp = ehci_readl(ehci, &ehci->regs->command);
+ tmp |= CMD_RUN;
+ ehci_writel(ehci, tmp, &ehci->regs->command);
+ /*
+ * It needs a short delay between set RUNSTOP
+ * and set PHCD.
+ */
+ udelay(125);
+ }
+ }
+ }
+
+ return 0;
+}
static irqreturn_t host_irq(struct ci_hdrc *ci)
{
@@ -135,5 +182,9 @@ int ci_hdrc_host_init(struct ci_hdrc *ci)
ehci_init_driver(&ci_ehci_hc_driver, NULL);
+ orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
+
+ ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
+
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 09/10] usb: chipidea: host: add ehci quirk for imx controller
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (7 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 08/10] usb: chipidea: host: add quirk for ehci operation Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-11-05 1:55 ` [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK Peter Chen
2013-12-03 18:15 ` [PATCH v3 00/10] Add power management support for chipidea Greg KH
10 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
When the port goes to suspend or finishes resme, it needs to
notify PHY, it is not a standard EHCI operation, so we add a
quirk for it.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/host.c | 129 ++++++++++++++++++++++++++++++++++++++++++
include/linux/usb/chipidea.h | 1 +
2 files changed, 130 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index de0c2de..66866cd 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -34,6 +34,10 @@
static struct hc_driver __read_mostly ci_ehci_hc_driver;
static int (*orig_bus_suspend)(struct usb_hcd *hcd);
+static int (*orig_bus_resume)(struct usb_hcd *hcd);
+static int (*orig_hub_control)(struct usb_hcd *hcd,
+ u16 typeReq, u16 wValue, u16 wIndex,
+ char *buf, u16 wLength);
static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
{
@@ -75,12 +79,131 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
*/
udelay(125);
}
+ if (hcd->phy && test_bit(port, &ehci->bus_suspended)
+ && (ehci_port_speed(ehci, portsc) ==
+ USB_PORT_STAT_HIGH_SPEED))
+ /*
+ * notify the USB PHY, it is for global
+ * suspend case.
+ */
+ usb_phy_notify_suspend(hcd->phy,
+ USB_SPEED_HIGH);
}
}
return 0;
}
+static int ci_imx_ehci_bus_resume(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int port;
+
+ int ret = orig_bus_resume(hcd);
+
+ if (ret)
+ return ret;
+
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ u32 __iomem *reg = &ehci->regs->port_status[port];
+ u32 portsc = ehci_readl(ehci, reg);
+ /*
+ * Notify PHY after resume signal has finished, it is
+ * for global suspend case.
+ */
+ if (hcd->phy
+ && test_bit(port, &ehci->bus_suspended)
+ && (portsc & PORT_CONNECT)
+ && (ehci_port_speed(ehci, portsc) ==
+ USB_PORT_STAT_HIGH_SPEED))
+ /* notify the USB PHY */
+ usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
+ }
+
+ return 0;
+}
+
+/* The below code is based on tegra ehci driver */
+static int ci_imx_ehci_hub_control(
+ struct usb_hcd *hcd,
+ u16 typeReq,
+ u16 wValue,
+ u16 wIndex,
+ char *buf,
+ u16 wLength
+)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ u32 __iomem *status_reg;
+ u32 temp;
+ unsigned long flags;
+ int retval = 0;
+
+ status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+
+ spin_lock_irqsave(&ehci->lock, flags);
+
+ if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
+ temp = ehci_readl(ehci, status_reg);
+ if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
+ retval = -EPIPE;
+ goto done;
+ }
+
+ temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
+ temp |= PORT_WKDISC_E | PORT_WKOC_E;
+ ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+
+ /*
+ * If a transaction is in progress, there may be a delay in
+ * suspending the port. Poll until the port is suspended.
+ */
+ if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
+ PORT_SUSPEND, 5000))
+ ehci_err(ehci, "timeout waiting for SUSPEND\n");
+
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ if (ehci_port_speed(ehci, temp) ==
+ USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
+ /* notify the USB PHY */
+ usb_phy_notify_suspend(hcd->phy, USB_SPEED_HIGH);
+ }
+ spin_lock_irqsave(&ehci->lock, flags);
+
+ set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
+ goto done;
+ }
+
+ /*
+ * After resume has finished, it needs do some post resume
+ * operation for some SoCs.
+ */
+ else if (typeReq == ClearPortFeature &&
+ wValue == USB_PORT_FEAT_C_SUSPEND) {
+
+ /* Make sure the resume has finished, it should be finished */
+ if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
+ ehci_err(ehci, "timeout waiting for resume\n");
+
+ temp = ehci_readl(ehci, status_reg);
+
+ if (ehci_port_speed(ehci, temp) ==
+ USB_PORT_STAT_HIGH_SPEED && hcd->phy) {
+ /* notify the USB PHY */
+ usb_phy_notify_resume(hcd->phy, USB_SPEED_HIGH);
+ }
+ }
+
+ spin_unlock_irqrestore(&ehci->lock, flags);
+
+ /* Handle the hub control events here */
+ return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+done:
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ return retval;
+}
+
static irqreturn_t host_irq(struct ci_hdrc *ci)
{
return usb_hcd_irq(ci->irq, ci->hcd);
@@ -183,8 +306,14 @@ int ci_hdrc_host_init(struct ci_hdrc *ci)
ehci_init_driver(&ci_ehci_hc_driver, NULL);
orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
+ orig_bus_resume = ci_ehci_hc_driver.bus_resume;
+ orig_hub_control = ci_ehci_hc_driver.hub_control;
ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
+ if (ci->platdata->flags & CI_HDRC_IMX_EHCI_QUIRK) {
+ ci_ehci_hc_driver.bus_resume = ci_imx_ehci_bus_resume;
+ ci_ehci_hc_driver.hub_control = ci_imx_ehci_hub_control;
+ }
return 0;
}
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 3842431..8c3b7e2 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -26,6 +26,7 @@ struct ci_hdrc_platform_data {
*/
#define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4)
#define CI_HDRC_IMX28_WRITE_FIX BIT(5)
+#define CI_HDRC_IMX_EHCI_QUIRK BIT(6)
enum usb_dr_mode dr_mode;
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (8 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 09/10] usb: chipidea: host: add ehci quirk for imx controller Peter Chen
@ 2013-11-05 1:55 ` Peter Chen
2013-12-03 21:50 ` Marc Kleine-Budde
2013-12-03 18:15 ` [PATCH v3 00/10] Add power management support for chipidea Greg KH
10 siblings, 1 reply; 17+ messages in thread
From: Peter Chen @ 2013-11-05 1:55 UTC (permalink / raw)
To: linux-arm-kernel
Enable CI_HDRC_IMX_EHCI_QUIRK for controllers who use mxs-phy.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
drivers/usb/chipidea/ci_hdrc_imx.c | 17 ++++++++++++++---
1 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index fd26c38..78ccde1 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -25,6 +25,7 @@
#define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
#define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
+#define CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK BIT(2)
struct ci_hdrc_imx_platform_flag {
unsigned int flags;
@@ -33,17 +34,24 @@ struct ci_hdrc_imx_platform_flag {
static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
};
+static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
+ .flags = CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
+};
+
static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
- .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
+ .flags = CI_HDRC_IMX_IMX28_WRITE_FIX |
+ CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
};
static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
- .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM,
+ .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
+ CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
};
static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
+ { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
{ /* sentinel */ }
};
@@ -153,11 +161,14 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
- if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM)
+ if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
data->supports_runtime_pm = true;
}
+ if (imx_platform_flag->flags & CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK)
+ pdata.flags |= CI_HDRC_IMX_EHCI_QUIRK;
+
if (data->usbmisc_data) {
ret = imx_usbmisc_init(data->usbmisc_data);
if (ret) {
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 00/10] Add power management support for chipidea
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
` (9 preceding siblings ...)
2013-11-05 1:55 ` [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK Peter Chen
@ 2013-12-03 18:15 ` Greg KH
2013-12-04 1:35 ` Peter Chen
10 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2013-12-03 18:15 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 05, 2013 at 09:55:15AM +0800, Peter Chen wrote:
> Hi Greg,
>
> This serial adds power management (system & runtime) for chipidea core.
> With this, the chipidea controller can be at low power mode when it is not in
> use, and the chipidea controller can be the system wakeup source.
> It needs to depend on my patch[1], since [1]-"Add power management support for MXS PHY"
> adds some common PHY APIs, and this serial uses it.
>
> It has been verified at Freescale i.mx6Q/DL SabreSD, i.mx28 evk platform
> (no runtime pm support), I will verify it at other FSL platforms during
> the patch review.
This series doesn't apply to my tree anymore.
And there have been a ton of chipidea patches floating around, I've now
dropped them all from my "todo" queue and will wait for you to collect
them and forward them on as I'm totally lost with all of the different
versions and objections and the like.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK
2013-11-05 1:55 ` [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK Peter Chen
@ 2013-12-03 21:50 ` Marc Kleine-Budde
2013-12-04 1:40 ` Peter Chen
0 siblings, 1 reply; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-12-03 21:50 UTC (permalink / raw)
To: linux-arm-kernel
On 11/05/2013 02:55 AM, Peter Chen wrote:
> Enable CI_HDRC_IMX_EHCI_QUIRK for controllers who use mxs-phy.
>
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
> ---
> drivers/usb/chipidea/ci_hdrc_imx.c | 17 ++++++++++++++---
> 1 files changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
> index fd26c38..78ccde1 100644
> --- a/drivers/usb/chipidea/ci_hdrc_imx.c
> +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
> @@ -25,6 +25,7 @@
>
> #define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
> #define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
> +#define CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK BIT(2)
>
> struct ci_hdrc_imx_platform_flag {
> unsigned int flags;
> @@ -33,17 +34,24 @@ struct ci_hdrc_imx_platform_flag {
> static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
> };
>
> +static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
> + .flags = CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
> +};
> +
> static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
> - .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
> + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX |
> + CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
> };
>
> static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
> - .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM,
> + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
> + CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
> };
>
> static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
> { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
> { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
> + { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
> { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
> { /* sentinel */ }
> };
> @@ -153,11 +161,14 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
> if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
> pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
>
> - if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM)
> + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
^^^^
Please squash into the correct patch.
> pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
> data->supports_runtime_pm = true;
> }
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 259 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131203/bbeaee29/attachment.sig>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 00/10] Add power management support for chipidea
2013-12-03 18:15 ` [PATCH v3 00/10] Add power management support for chipidea Greg KH
@ 2013-12-04 1:35 ` Peter Chen
0 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-12-04 1:35 UTC (permalink / raw)
To: linux-arm-kernel
> > Hi Greg,
> >
> > This serial adds power management (system & runtime) for chipidea core.
> > With this, the chipidea controller can be at low power mode when it is
> not in
> > use, and the chipidea controller can be the system wakeup source.
> > It needs to depend on my patch[1], since [1]-"Add power management
> support for MXS PHY"
> > adds some common PHY APIs, and this serial uses it.
> >
> > It has been verified at Freescale i.mx6Q/DL SabreSD, i.mx28 evk
> platform
> > (no runtime pm support), I will verify it at other FSL platforms during
> > the patch review.
>
> This series doesn't apply to my tree anymore.
>
> And there have been a ton of chipidea patches floating around, I've now
> dropped them all from my "todo" queue and will wait for you to collect
> them and forward them on as I'm totally lost with all of the different
> versions and objections and the like.
>
Greg, I will do that.
Peter
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK
2013-12-03 21:50 ` Marc Kleine-Budde
@ 2013-12-04 1:40 ` Peter Chen
2013-12-04 8:33 ` Marc Kleine-Budde
0 siblings, 1 reply; 17+ messages in thread
From: Peter Chen @ 2013-12-04 1:40 UTC (permalink / raw)
To: linux-arm-kernel
>
> On 11/05/2013 02:55 AM, Peter Chen wrote:
> > Enable CI_HDRC_IMX_EHCI_QUIRK for controllers who use mxs-phy.
> >
> > Signed-off-by: Peter Chen <peter.chen@freescale.com>
> > ---
> > drivers/usb/chipidea/ci_hdrc_imx.c | 17 ++++++++++++++---
> > 1 files changed, 14 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c
> b/drivers/usb/chipidea/ci_hdrc_imx.c
> > index fd26c38..78ccde1 100644
> > --- a/drivers/usb/chipidea/ci_hdrc_imx.c
> > +++ b/drivers/usb/chipidea/ci_hdrc_imx.c
> > @@ -25,6 +25,7 @@
> >
> > #define CI_HDRC_IMX_IMX28_WRITE_FIX BIT(0)
> > #define CI_HDRC_IMX_SUPPORT_RUNTIME_PM BIT(1)
> > +#define CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK BIT(2)
> >
> > struct ci_hdrc_imx_platform_flag {
> > unsigned int flags;
> > @@ -33,17 +34,24 @@ struct ci_hdrc_imx_platform_flag {
> > static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
> > };
> >
> > +static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
> > + .flags = CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
> > +};
> > +
> > static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
> > - .flags = CI_HDRC_IMX_IMX28_WRITE_FIX,
> > + .flags = CI_HDRC_IMX_IMX28_WRITE_FIX |
> > + CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
> > };
> >
> > static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
> > - .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM,
> > + .flags = CI_HDRC_IMX_SUPPORT_RUNTIME_PM |
> > + CI_HDRC_IMX_MXS_PHY_EHCI_QUIRK,
> > };
> >
> > static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
> > { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
> > { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
> > + { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
> > { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
> > { /* sentinel */ }
> > };
> > @@ -153,11 +161,14 @@ static int ci_hdrc_imx_probe(struct
> platform_device *pdev)
> > if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
> > pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
> >
> > - if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM)
> > + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
> ^^^^
>
> Please squash into the correct patch.
>
There are some re-work for this serial, I will do it.
But I don't get your mean why it needs to squash into another patch?
Peter
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK
2013-12-04 1:40 ` Peter Chen
@ 2013-12-04 8:33 ` Marc Kleine-Budde
2013-12-04 13:05 ` Peter Chen
0 siblings, 1 reply; 17+ messages in thread
From: Marc Kleine-Budde @ 2013-12-04 8:33 UTC (permalink / raw)
To: linux-arm-kernel
On 12/04/2013 02:40 AM, Peter Chen wrote:
> There are some re-work for this serial, I will do it.
> But I don't get your mean why it needs to squash into another patch?
Let's look at the code again:
> - if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM)
> + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
> pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
> data->supports_runtime_pm = true;
> }
Without that patch, the driver will not compile.
before:
if ()
/* code */
}
after:
if () {
/* code */
}
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 259 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131204/38456ffe/attachment.sig>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK
2013-12-04 8:33 ` Marc Kleine-Budde
@ 2013-12-04 13:05 ` Peter Chen
0 siblings, 0 replies; 17+ messages in thread
From: Peter Chen @ 2013-12-04 13:05 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 04, 2013 at 09:33:26AM +0100, Marc Kleine-Budde wrote:
> On 12/04/2013 02:40 AM, Peter Chen wrote:
> > There are some re-work for this serial, I will do it.
> > But I don't get your mean why it needs to squash into another patch?
>
> Let's look at the code again:
>
> > - if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM)
> > + if (imx_platform_flag->flags & CI_HDRC_IMX_SUPPORT_RUNTIME_PM) {
> > pdata.flags |= CI_HDRC_SUPPORTS_RUNTIME_PM;
> > data->supports_runtime_pm = true;
> > }
>
> Without that patch, the driver will not compile.
>
> before:
>
> if ()
> /* code */
> }
>
> after:
>
> if () {
> /* code */
> }
>
> Marc
>
> --
Oh, thanks. I need to sqhash [7/10] and [10/10]
--
Best Regards,
Peter Chen
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2013-12-04 13:05 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-05 1:55 [PATCH v3 00/10] Add power management support for chipidea Peter Chen
2013-11-05 1:55 ` [PATCH v3 01/10] usb: chipidea: Add power management support Peter Chen
2013-11-05 1:55 ` [PATCH v3 02/10] usb: chipidea: imx: add " Peter Chen
2013-11-05 1:55 ` [PATCH v3 03/10] usb: chipidea: add wakeup interrupt handler Peter Chen
2013-11-05 1:55 ` [PATCH v3 04/10] usb: chipidea: usbmisc_imx: remove the controller's clock information Peter Chen
2013-11-05 1:55 ` [PATCH v3 05/10] usb: chipidea: usbmisc_imx: add set_wakup API Peter Chen
2013-11-05 1:55 ` [PATCH v3 06/10] usb: chipidea: imx: call set_wakeup when necessary Peter Chen
2013-11-05 1:55 ` [PATCH v3 07/10] usb: chipidea: imx: Enable runtime pm support for imx6q Peter Chen
2013-11-05 1:55 ` [PATCH v3 08/10] usb: chipidea: host: add quirk for ehci operation Peter Chen
2013-11-05 1:55 ` [PATCH v3 09/10] usb: chipidea: host: add ehci quirk for imx controller Peter Chen
2013-11-05 1:55 ` [PATCH v3 10/10] usb: chipidea: imx: Enable CI_HDRC_IMX_EHCI_QUIRK Peter Chen
2013-12-03 21:50 ` Marc Kleine-Budde
2013-12-04 1:40 ` Peter Chen
2013-12-04 8:33 ` Marc Kleine-Budde
2013-12-04 13:05 ` Peter Chen
2013-12-03 18:15 ` [PATCH v3 00/10] Add power management support for chipidea Greg KH
2013-12-04 1:35 ` Peter Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).