* [PATCH v4 0/4] musb/dsps: suspend related patches for 3.14 (rebased)
@ 2013-11-26 12:31 Daniel Mack
2013-11-26 12:31 ` [PATCH v4 1/4] usb: musb: unconditionally save and restore the context on suspend Daniel Mack
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Daniel Mack @ 2013-11-26 12:31 UTC (permalink / raw)
To: balbi; +Cc: bigeasy, linux-usb, linux-omap, neumann, Daniel Mack
v2 -> v3:
* removed a development left-over
v3 -> v4:
* one hunk removed that sneaked in during rebasing
Daniel Mack (4):
usb: musb: unconditionally save and restore the context on suspend
usb: musb: call musb_port_suspend from musb_bus_suspend
usb: musb: dsps: add {tx,rx}_mode to wrapper
usb: musb: dsps: add support for suspend and resume
drivers/usb/musb/musb_core.c | 14 +++++++++-
drivers/usb/musb/musb_dsps.c | 61 +++++++++++++++++++++++++++++++++++++++++
drivers/usb/musb/musb_host.c | 9 +++++-
drivers/usb/musb/musb_host.h | 4 +++
drivers/usb/musb/musb_virthub.c | 4 +--
include/linux/usb/musb.h | 3 ++
6 files changed, 91 insertions(+), 4 deletions(-)
--
1.8.4.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 1/4] usb: musb: unconditionally save and restore the context on suspend
2013-11-26 12:31 [PATCH v4 0/4] musb/dsps: suspend related patches for 3.14 (rebased) Daniel Mack
@ 2013-11-26 12:31 ` Daniel Mack
2013-11-26 12:31 ` [PATCH v4 2/4] usb: musb: call musb_port_suspend from musb_bus_suspend Daniel Mack
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2013-11-26 12:31 UTC (permalink / raw)
To: balbi; +Cc: bigeasy, linux-usb, linux-omap, neumann, Daniel Mack
It appears not all platforms featuring a musb core need to save the musb
core registers at suspend time and restore them on resume.
The dsps platform does, however, and because it should cause any trouble
on other platforms, do it unconditionally.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/usb/musb/musb_core.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0a43329..797709d 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2215,16 +2215,28 @@ static int musb_suspend(struct device *dev)
*/
}
+ musb_save_context(musb);
+
spin_unlock_irqrestore(&musb->lock, flags);
return 0;
}
static int musb_resume_noirq(struct device *dev)
{
- /* for static cmos like DaVinci, register values were preserved
+ struct musb *musb = dev_to_musb(dev);
+
+ /*
+ * For static cmos like DaVinci, register values were preserved
* unless for some reason the whole soc powered down or the USB
* module got reset through the PSC (vs just being disabled).
+ *
+ * For the DSPS glue layer though, a full register restore has to
+ * be done. As it shouldn't harm other platforms, we do it
+ * unconditionally.
*/
+
+ musb_restore_context(musb);
+
return 0;
}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 2/4] usb: musb: call musb_port_suspend from musb_bus_suspend
2013-11-26 12:31 [PATCH v4 0/4] musb/dsps: suspend related patches for 3.14 (rebased) Daniel Mack
2013-11-26 12:31 ` [PATCH v4 1/4] usb: musb: unconditionally save and restore the context on suspend Daniel Mack
@ 2013-11-26 12:31 ` Daniel Mack
2013-11-26 12:31 ` [PATCH v4 3/4] usb: musb: dsps: add {tx,rx}_mode to wrapper Daniel Mack
2013-11-26 12:31 ` [PATCH v4 4/4] usb: musb: dsps: add support for suspend and resume Daniel Mack
3 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2013-11-26 12:31 UTC (permalink / raw)
To: balbi; +Cc: bigeasy, linux-usb, linux-omap, neumann, Daniel Mack
Make musb_port_suspend() externally available, and call it when to host
goes into suspend. This allows the core to go into suspend while a
device is connected.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/usb/musb/musb_host.c | 2 ++
drivers/usb/musb/musb_host.h | 2 ++
drivers/usb/musb/musb_virthub.c | 2 +-
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 6582a20..81caf9f 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2433,6 +2433,8 @@ static int musb_bus_suspend(struct usb_hcd *hcd)
struct musb *musb = hcd_to_musb(hcd);
u8 devctl;
+ musb_port_suspend(musb, true);
+
if (!is_host_active(musb))
return 0;
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h
index 960d735..e660af9 100644
--- a/drivers/usb/musb/musb_host.h
+++ b/drivers/usb/musb/musb_host.h
@@ -92,6 +92,7 @@ extern void musb_host_rx(struct musb *, u8);
extern void musb_root_disconnect(struct musb *musb);
extern void musb_host_resume_root_hub(struct musb *musb);
extern void musb_host_poke_root_hub(struct musb *musb);
+extern void musb_port_suspend(struct musb *musb, bool do_suspend);
#else
static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
{
@@ -121,6 +122,7 @@ static inline void musb_root_disconnect(struct musb *musb) {}
static inline void musb_host_resume_root_hub(struct musb *musb) {}
static inline void musb_host_poll_rh_status(struct musb *musb) {}
static inline void musb_host_poke_root_hub(struct musb *musb) {}
+static inline void musb_port_suspend(struct musb *musb, bool do_suspend) {}
#endif
struct usb_hcd;
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index 9af6bba..e977441 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -44,7 +44,7 @@
#include "musb_core.h"
-static void musb_port_suspend(struct musb *musb, bool do_suspend)
+void musb_port_suspend(struct musb *musb, bool do_suspend)
{
struct usb_otg *otg = musb->xceiv->otg;
u8 power;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 3/4] usb: musb: dsps: add {tx,rx}_mode to wrapper
2013-11-26 12:31 [PATCH v4 0/4] musb/dsps: suspend related patches for 3.14 (rebased) Daniel Mack
2013-11-26 12:31 ` [PATCH v4 1/4] usb: musb: unconditionally save and restore the context on suspend Daniel Mack
2013-11-26 12:31 ` [PATCH v4 2/4] usb: musb: call musb_port_suspend from musb_bus_suspend Daniel Mack
@ 2013-11-26 12:31 ` Daniel Mack
2013-11-26 12:31 ` [PATCH v4 4/4] usb: musb: dsps: add support for suspend and resume Daniel Mack
3 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2013-11-26 12:31 UTC (permalink / raw)
To: balbi; +Cc: bigeasy, linux-usb, linux-omap, neumann, Daniel Mack
rx_mode and tx_mode need to be read at suspend time and restored on
resume for dsps platforms. So add it to the wrapper struct first, and
initialize the values.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/usb/musb/musb_dsps.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 1901f6f..e57d712 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -83,6 +83,8 @@ struct dsps_musb_wrapper {
u16 coreintr_status;
u16 phy_utmi;
u16 mode;
+ u16 tx_mode;
+ u16 rx_mode;
/* bit positions for control */
unsigned reset:5;
@@ -605,6 +607,8 @@ static const struct dsps_musb_wrapper am33xx_driver_data = {
.coreintr_status = 0x34,
.phy_utmi = 0xe0,
.mode = 0xe8,
+ .tx_mode = 0x70,
+ .rx_mode = 0x74,
.reset = 0,
.otg_disable = 21,
.iddig = 8,
--
1.8.4.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 4/4] usb: musb: dsps: add support for suspend and resume
2013-11-26 12:31 [PATCH v4 0/4] musb/dsps: suspend related patches for 3.14 (rebased) Daniel Mack
` (2 preceding siblings ...)
2013-11-26 12:31 ` [PATCH v4 3/4] usb: musb: dsps: add {tx,rx}_mode to wrapper Daniel Mack
@ 2013-11-26 12:31 ` Daniel Mack
3 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2013-11-26 12:31 UTC (permalink / raw)
To: balbi; +Cc: bigeasy, linux-usb, linux-omap, neumann, Daniel Mack
The dsps platform needs to save save some registers at suspend time and
restore them after resume. This patch adds a struct for these registers,
and also lets the musb core know that the core registers need to be
saved as well.
We also have to explicitly de-assert the port reset upon resume on this
platform, but musb_port_reset() should not be called from glue layers.
Hence, introduce a flag in struct musb_hdrc_config for this.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
drivers/usb/musb/musb_dsps.c | 57 +++++++++++++++++++++++++++++++++++++++++
drivers/usb/musb/musb_host.c | 7 ++++-
drivers/usb/musb/musb_host.h | 2 ++
drivers/usb/musb/musb_virthub.c | 2 +-
include/linux/usb/musb.h | 3 +++
5 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index e57d712..3600af0 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -112,6 +112,19 @@ struct dsps_musb_wrapper {
u8 poll_seconds;
};
+/*
+ * register shadow for suspend
+ */
+struct dsps_context {
+ u32 control;
+ u32 epintr;
+ u32 coreintr;
+ u32 phy_utmi;
+ u32 mode;
+ u32 tx_mode;
+ u32 rx_mode;
+};
+
/**
* DSPS glue structure.
*/
@@ -121,6 +134,8 @@ struct dsps_glue {
const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */
struct timer_list timer; /* otg_workaround timer */
unsigned long last_timer; /* last timer data for each instance */
+
+ struct dsps_context context;
};
static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
@@ -509,6 +524,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue,
config->num_eps = get_int_prop(dn, "mentor,num-eps");
config->ram_bits = get_int_prop(dn, "mentor,ram-bits");
+ config->host_port_deassert_reset_at_resume = 1;
pdata.mode = get_musb_port_mode(dev);
/* DT keeps this entry in mA, musb expects it as per USB spec */
pdata.power = get_int_prop(dn, "mentor,power") / 2;
@@ -632,11 +648,52 @@ static const struct of_device_id musb_dsps_of_match[] = {
};
MODULE_DEVICE_TABLE(of, musb_dsps_of_match);
+#ifdef CONFIG_PM
+static int dsps_suspend(struct device *dev)
+{
+ struct dsps_glue *glue = dev_get_drvdata(dev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ struct musb *musb = platform_get_drvdata(glue->musb);
+ void __iomem *mbase = musb->ctrl_base;
+
+ glue->context.control = dsps_readl(mbase, wrp->control);
+ glue->context.epintr = dsps_readl(mbase, wrp->epintr_set);
+ glue->context.coreintr = dsps_readl(mbase, wrp->coreintr_set);
+ glue->context.phy_utmi = dsps_readl(mbase, wrp->phy_utmi);
+ glue->context.mode = dsps_readl(mbase, wrp->mode);
+ glue->context.tx_mode = dsps_readl(mbase, wrp->tx_mode);
+ glue->context.rx_mode = dsps_readl(mbase, wrp->rx_mode);
+
+ return 0;
+}
+
+static int dsps_resume(struct device *dev)
+{
+ struct dsps_glue *glue = dev_get_drvdata(dev);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+ struct musb *musb = platform_get_drvdata(glue->musb);
+ void __iomem *mbase = musb->ctrl_base;
+
+ dsps_writel(mbase, wrp->control, glue->context.control);
+ dsps_writel(mbase, wrp->epintr_set, glue->context.epintr);
+ dsps_writel(mbase, wrp->coreintr_set, glue->context.coreintr);
+ dsps_writel(mbase, wrp->phy_utmi, glue->context.phy_utmi);
+ dsps_writel(mbase, wrp->mode, glue->context.mode);
+ dsps_writel(mbase, wrp->tx_mode, glue->context.tx_mode);
+ dsps_writel(mbase, wrp->rx_mode, glue->context.rx_mode);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume);
+
static struct platform_driver dsps_usbss_driver = {
.probe = dsps_probe,
.remove = dsps_remove,
.driver = {
.name = "musb-dsps",
+ .pm = &dsps_pm_ops,
.of_match_table = musb_dsps_of_match,
},
};
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 81caf9f..8224138 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2464,7 +2464,12 @@ static int musb_bus_suspend(struct usb_hcd *hcd)
static int musb_bus_resume(struct usb_hcd *hcd)
{
- /* resuming child port does the work */
+ struct musb *musb = hcd_to_musb(hcd);
+
+ if (musb->config &&
+ musb->config->host_port_deassert_reset_at_resume)
+ musb_port_reset(musb, false);
+
return 0;
}
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h
index e660af9..7436c24 100644
--- a/drivers/usb/musb/musb_host.h
+++ b/drivers/usb/musb/musb_host.h
@@ -93,6 +93,7 @@ extern void musb_root_disconnect(struct musb *musb);
extern void musb_host_resume_root_hub(struct musb *musb);
extern void musb_host_poke_root_hub(struct musb *musb);
extern void musb_port_suspend(struct musb *musb, bool do_suspend);
+extern void musb_port_reset(struct musb *musb, bool do_reset);
#else
static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
{
@@ -123,6 +124,7 @@ static inline void musb_host_resume_root_hub(struct musb *musb) {}
static inline void musb_host_poll_rh_status(struct musb *musb) {}
static inline void musb_host_poke_root_hub(struct musb *musb) {}
static inline void musb_port_suspend(struct musb *musb, bool do_suspend) {}
+static inline void musb_port_reset(struct musb *musb) {}
#endif
struct usb_hcd;
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index e977441..24e46c0 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -109,7 +109,7 @@ void musb_port_suspend(struct musb *musb, bool do_suspend)
}
}
-static void musb_port_reset(struct musb *musb, bool do_reset)
+void musb_port_reset(struct musb *musb, bool do_reset)
{
u8 power;
void __iomem *mbase = musb->mregs;
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index eb50525..a4ee1b5 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -76,6 +76,9 @@ struct musb_hdrc_config {
unsigned dma:1 __deprecated; /* supports DMA */
unsigned vendor_req:1 __deprecated; /* vendor registers required */
+ /* need to explicitly de-assert the port reset after resume? */
+ unsigned host_port_deassert_reset_at_resume:1;
+
u8 num_eps; /* number of endpoints _with_ ep0 */
u8 dma_channels __deprecated; /* number of dma channels */
u8 dyn_fifo_size; /* dynamic size in bytes */
--
1.8.4.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-11-26 12:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-26 12:31 [PATCH v4 0/4] musb/dsps: suspend related patches for 3.14 (rebased) Daniel Mack
2013-11-26 12:31 ` [PATCH v4 1/4] usb: musb: unconditionally save and restore the context on suspend Daniel Mack
2013-11-26 12:31 ` [PATCH v4 2/4] usb: musb: call musb_port_suspend from musb_bus_suspend Daniel Mack
2013-11-26 12:31 ` [PATCH v4 3/4] usb: musb: dsps: add {tx,rx}_mode to wrapper Daniel Mack
2013-11-26 12:31 ` [PATCH v4 4/4] usb: musb: dsps: add support for suspend and resume Daniel Mack
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).