All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6 V2] arm: omap: usb: Runtime PM support for EHCI and OHCI drivers
@ 2011-07-01 18:54 ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The Hwmod structures and Runtime PM features are implemented
For EHCI and OHCI drivers of OMAP3 and OMAP4.
The global suspend/resume of EHCI and OHCI
is validated on OMAP3430 sdp board with these patches.

Benoit Cousson (1):
  arm: omap: usb: ehci and ohci hwmod structures for omap4

Keshava Munegowda (5):
  arm: omap: usb: ehci and ohci hwmod structures for omap3
  arm: omap: usb: register hwmods of usbhs
  arm: omap: usb: device name change for the clk names of usbhs
  arm: omap: usb: Runtime PM support
  arm: omap: usb: global Suspend and resume support of ehci and ohci

 arch/arm/mach-omap2/clock3xxx_data.c       |   28 +-
 arch/arm/mach-omap2/clock44xx_data.c       |   10 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  279 +++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  235 +++++++++++
 arch/arm/mach-omap2/usb-host.c             |  113 +++---
 arch/arm/plat-omap/include/plat/usb.h      |    3 -
 drivers/mfd/omap-usb-host.c                |  620 +++++++++++++---------------
 drivers/usb/host/ehci-omap.c               |   36 ++-
 drivers/usb/host/ohci-omap3.c              |   33 ++-
 9 files changed, 914 insertions(+), 443 deletions(-)


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 0/6 V2] arm: omap: usb: Runtime PM support for EHCI and OHCI drivers
@ 2011-07-01 18:54 ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The Hwmod structures and Runtime PM features are implemented
For EHCI and OHCI drivers of OMAP3 and OMAP4.
The global suspend/resume of EHCI and OHCI
is validated on OMAP3430 sdp board with these patches.

Benoit Cousson (1):
  arm: omap: usb: ehci and ohci hwmod structures for omap4

Keshava Munegowda (5):
  arm: omap: usb: ehci and ohci hwmod structures for omap3
  arm: omap: usb: register hwmods of usbhs
  arm: omap: usb: device name change for the clk names of usbhs
  arm: omap: usb: Runtime PM support
  arm: omap: usb: global Suspend and resume support of ehci and ohci

 arch/arm/mach-omap2/clock3xxx_data.c       |   28 +-
 arch/arm/mach-omap2/clock44xx_data.c       |   10 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  279 +++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  235 +++++++++++
 arch/arm/mach-omap2/usb-host.c             |  113 +++---
 arch/arm/plat-omap/include/plat/usb.h      |    3 -
 drivers/mfd/omap-usb-host.c                |  620 +++++++++++++---------------
 drivers/usb/host/ehci-omap.c               |   36 ++-
 drivers/usb/host/ohci-omap3.c              |   33 ++-
 9 files changed, 914 insertions(+), 443 deletions(-)


^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4
  2011-07-01 18:54 ` Keshava Munegowda
@ 2011-07-01 18:54   ` Keshava Munegowda
  -1 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs

From: Benoit Cousson <b-cousson@ti.com>

Following 4 hwmod strcuture are added:
UHH hwmod of usbhs with uhh base address and functional clock,
EHCI hwmod with irq and base address,
OHCI hwmod with irq and base address,
TLL hwmod of usbhs with the TLL base address and irq.

Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  235 ++++++++++++++++++++++++++++
 1 files changed, 235 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index e1c69ff..3968b32 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -66,6 +66,10 @@ static struct omap_hwmod omap44xx_mmc2_hwmod;
 static struct omap_hwmod omap44xx_mpu_hwmod;
 static struct omap_hwmod omap44xx_mpu_private_hwmod;
 static struct omap_hwmod omap44xx_usb_otg_hs_hwmod;
+static struct omap_hwmod omap44xx_usb_host_hs_hwmod;
+static struct omap_hwmod omap44xx_usbhs_ohci_hwmod;
+static struct omap_hwmod omap44xx_usbhs_ehci_hwmod;
+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod;
 
 /*
  * Interconnects omap_hwmod structures
@@ -5027,6 +5031,233 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
 
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = {
+	.master		= &omap44xx_usb_host_hs_hwmod,
+	.slave		= &omap44xx_l3_main_2_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = {
+	.name = "usbhs_uhh",
+	.sysc = &omap44xx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_masters[] = {
+	&omap44xx_usb_host_hs__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x4a064000,
+		.pa_end		= 0x4a0647ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usb_host_hs_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usb_host_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_slaves[] = {
+	&omap44xx_l4_cfg__usb_host_hs,
+};
+
+static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
+	.name		= "usbhs_uhh",
+	.class		= &omap44xx_usb_host_hs_hwmod_class,
+	.main_clk	= "usb_host_hs_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_usb_host_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_slaves),
+	.masters	= omap44xx_usb_host_hs_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_masters),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* 'usbhs_ohci' class */
+static struct omap_hwmod_class omap44xx_usbhs_ohci_hwmod_class = {
+	.name = "usbhs_ohci",
+};
+
+static struct omap_hwmod_irq_info omap44xx_usbhs_ohci_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usbhs_ohci_addrs[] = {
+	{
+		.name		= "ohci",
+		.pa_start	= 0x4A064800,
+		.pa_end		= 0x4A064BFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usbhs_ohci = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usbhs_ohci_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usbhs_ohci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ohci_slaves[] = {
+	&omap44xx_l4_cfg__usbhs_ohci,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ohci_masters[] = {
+	&omap44xx_usb_host_hs__l3_main_2,
+};
+
+static struct omap_hwmod omap44xx_usbhs_ohci_hwmod = {
+	.name		= "usbhs_ohci",
+	.class		= &omap44xx_usbhs_ohci_hwmod_class,
+	.mpu_irqs	= omap44xx_usbhs_ohci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_irqs),
+	.slaves		= omap44xx_usbhs_ohci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_slaves),
+	.masters	= omap44xx_usbhs_ohci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+};
+
+/* 'usbhs_ehci' class */
+static struct omap_hwmod_class omap44xx_usbhs_ehci_hwmod_class = {
+	.name = "usbhs_ehci",
+};
+
+static struct omap_hwmod_irq_info omap44xx_usbhs_ehci_irqs[] = {
+	{ .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usbhs_ehci_addrs[] = {
+	{
+		.name		= "ehci",
+		.pa_start	= 0x4A064C00,
+		.pa_end		= 0x4A064FFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usbhs_ehci = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usbhs_ehci_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usbhs_ehci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ehci_slaves[] = {
+	&omap44xx_l4_cfg__usbhs_ehci,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ehci_masters[] = {
+	&omap44xx_usb_host_hs__l3_main_2,
+};
+
+
+static struct omap_hwmod omap44xx_usbhs_ehci_hwmod = {
+	.name		= "usbhs_ehci",
+	.class		= &omap44xx_usbhs_ehci_hwmod_class,
+	.mpu_irqs	= omap44xx_usbhs_ehci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_irqs),
+	.slaves		= omap44xx_usbhs_ehci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_slaves),
+	.masters	= omap44xx_usbhs_ehci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = {
+	.name = "usbhs_tll",
+	.sysc = &omap44xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = {
+	{ .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = {
+	{
+		.name		= "tll",
+		.pa_start	= 0x4a062000,
+		.pa_end		= 0x4a063fff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usb_tll_hs_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usb_tll_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usb_tll_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usb_tll_hs_slaves[] = {
+	&omap44xx_l4_cfg__usb_tll_hs,
+};
+
+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = {
+	.name		= "usbhs_tll",
+	.class		= &omap44xx_usb_tll_hs_hwmod_class,
+	.mpu_irqs	= omap44xx_usb_tll_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usb_tll_hs_irqs),
+	.main_clk	= "usb_tll_hs_ick",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_usb_tll_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usb_tll_hs_slaves),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
 static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 
 	/* dmm class */
@@ -5173,6 +5404,10 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	&omap44xx_wd_timer2_hwmod,
 	&omap44xx_wd_timer3_hwmod,
 
+	&omap44xx_usb_host_hs_hwmod,
+	&omap44xx_usbhs_ohci_hwmod,
+	&omap44xx_usbhs_ehci_hwmod,
+	&omap44xx_usb_tll_hs_hwmod,
 	NULL,
 };
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4
@ 2011-07-01 18:54   ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs

From: Benoit Cousson <b-cousson@ti.com>

Following 4 hwmod strcuture are added:
UHH hwmod of usbhs with uhh base address and functional clock,
EHCI hwmod with irq and base address,
OHCI hwmod with irq and base address,
TLL hwmod of usbhs with the TLL base address and irq.

Signed-off-by: Benoit Cousson <b-cousson@ti.com>
Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  235 ++++++++++++++++++++++++++++
 1 files changed, 235 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index e1c69ff..3968b32 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -66,6 +66,10 @@ static struct omap_hwmod omap44xx_mmc2_hwmod;
 static struct omap_hwmod omap44xx_mpu_hwmod;
 static struct omap_hwmod omap44xx_mpu_private_hwmod;
 static struct omap_hwmod omap44xx_usb_otg_hs_hwmod;
+static struct omap_hwmod omap44xx_usb_host_hs_hwmod;
+static struct omap_hwmod omap44xx_usbhs_ohci_hwmod;
+static struct omap_hwmod omap44xx_usbhs_ehci_hwmod;
+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod;
 
 /*
  * Interconnects omap_hwmod structures
@@ -5027,6 +5031,233 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
 };
 
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = {
+	.master		= &omap44xx_usb_host_hs_hwmod,
+	.slave		= &omap44xx_l3_main_2_hwmod,
+	.clk		= "l3_div_ck",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = {
+	.name = "usbhs_uhh",
+	.sysc = &omap44xx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_masters[] = {
+	&omap44xx_usb_host_hs__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x4a064000,
+		.pa_end		= 0x4a0647ff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usb_host_hs_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usb_host_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_slaves[] = {
+	&omap44xx_l4_cfg__usb_host_hs,
+};
+
+static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
+	.name		= "usbhs_uhh",
+	.class		= &omap44xx_usb_host_hs_hwmod_class,
+	.main_clk	= "usb_host_hs_fck",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_usb_host_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_slaves),
+	.masters	= omap44xx_usb_host_hs_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_masters),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* 'usbhs_ohci' class */
+static struct omap_hwmod_class omap44xx_usbhs_ohci_hwmod_class = {
+	.name = "usbhs_ohci",
+};
+
+static struct omap_hwmod_irq_info omap44xx_usbhs_ohci_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usbhs_ohci_addrs[] = {
+	{
+		.name		= "ohci",
+		.pa_start	= 0x4A064800,
+		.pa_end		= 0x4A064BFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usbhs_ohci = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usbhs_ohci_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usbhs_ohci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ohci_slaves[] = {
+	&omap44xx_l4_cfg__usbhs_ohci,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ohci_masters[] = {
+	&omap44xx_usb_host_hs__l3_main_2,
+};
+
+static struct omap_hwmod omap44xx_usbhs_ohci_hwmod = {
+	.name		= "usbhs_ohci",
+	.class		= &omap44xx_usbhs_ohci_hwmod_class,
+	.mpu_irqs	= omap44xx_usbhs_ohci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_irqs),
+	.slaves		= omap44xx_usbhs_ohci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_slaves),
+	.masters	= omap44xx_usbhs_ohci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_usbhs_ohci_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+};
+
+/* 'usbhs_ehci' class */
+static struct omap_hwmod_class omap44xx_usbhs_ehci_hwmod_class = {
+	.name = "usbhs_ehci",
+};
+
+static struct omap_hwmod_irq_info omap44xx_usbhs_ehci_irqs[] = {
+	{ .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usbhs_ehci_addrs[] = {
+	{
+		.name		= "ehci",
+		.pa_start	= 0x4A064C00,
+		.pa_end		= 0x4A064FFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usbhs_ehci = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usbhs_ehci_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usbhs_ehci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ehci_slaves[] = {
+	&omap44xx_l4_cfg__usbhs_ehci,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usbhs_ehci_masters[] = {
+	&omap44xx_usb_host_hs__l3_main_2,
+};
+
+
+static struct omap_hwmod omap44xx_usbhs_ehci_hwmod = {
+	.name		= "usbhs_ehci",
+	.class		= &omap44xx_usbhs_ehci_hwmod_class,
+	.mpu_irqs	= omap44xx_usbhs_ehci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_irqs),
+	.slaves		= omap44xx_usbhs_ehci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_slaves),
+	.masters	= omap44xx_usbhs_ehci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap44xx_usbhs_ehci_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = {
+	.name = "usbhs_tll",
+	.sysc = &omap44xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = {
+	{ .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = {
+	{
+		.name		= "tll",
+		.pa_start	= 0x4a062000,
+		.pa_end		= 0x4a063fff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
+	.master		= &omap44xx_l4_cfg_hwmod,
+	.slave		= &omap44xx_usb_tll_hs_hwmod,
+	.clk		= "l4_div_ck",
+	.addr		= omap44xx_usb_tll_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap44xx_usb_tll_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap44xx_usb_tll_hs_slaves[] = {
+	&omap44xx_l4_cfg__usb_tll_hs,
+};
+
+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = {
+	.name		= "usbhs_tll",
+	.class		= &omap44xx_usb_tll_hs_hwmod_class,
+	.mpu_irqs	= omap44xx_usb_tll_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usb_tll_hs_irqs),
+	.main_clk	= "usb_tll_hs_ick",
+	.prcm = {
+		.omap4 = {
+			.clkctrl_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+		},
+	},
+	.slaves		= omap44xx_usb_tll_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap44xx_usb_tll_hs_slaves),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
 static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 
 	/* dmm class */
@@ -5173,6 +5404,10 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	&omap44xx_wd_timer2_hwmod,
 	&omap44xx_wd_timer3_hwmod,
 
+	&omap44xx_usb_host_hs_hwmod,
+	&omap44xx_usbhs_ohci_hwmod,
+	&omap44xx_usbhs_ehci_hwmod,
+	&omap44xx_usb_tll_hs_hwmod,
 	NULL,
 };
 
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 2/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap3
  2011-07-01 18:54   ` Keshava Munegowda
@ 2011-07-01 18:54     ` Keshava Munegowda
  -1 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

Following 4 hwmod strcuture are added:
UHH hwmod of usbhs with uhh base address and functional clock,
EHCI hwmod with irq and base address,
OHCI hwmod with irq and base address,
TLL hwmod of usbhs with the TLL base address and irq.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  279 ++++++++++++++++++++++++++++
 1 files changed, 279 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 909a84d..8d1d4f5 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -84,6 +84,10 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod;
 static struct omap_hwmod omap3xxx_mcbsp5_hwmod;
 static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod;
 static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod;
+static struct omap_hwmod omap34xx_usb_host_hs_hwmod;
+static struct omap_hwmod omap34xx_usbhs_ohci_hwmod;
+static struct omap_hwmod omap34xx_usbhs_ehci_hwmod;
+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -3574,6 +3578,276 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+static struct omap_hwmod_ocp_if omap34xx_usb_host_hs__l3_main_2 = {
+	.master		= &omap34xx_usb_host_hs_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig omap34xx_usb_host_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_usb_host_hs_hwmod_class = {
+	.name = "usbhs_uhh",
+	.sysc = &omap34xx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_masters[] = {
+	&omap34xx_usb_host_hs__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap34xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x48064000,
+		.pa_end		= 0x480643ff,
+		.flags		= ADDR_TYPE_RT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_host_hs = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usb_host_hs_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usb_host_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap34xx_f128m_cfg__usb_host_hs = {
+	.clk		= "usbhost_120m_fck",
+	.user		= OCP_USER_MPU,
+	.flags		= OCPIF_SWSUP_IDLE,
+};
+
+static struct omap_hwmod_ocp_if omap34xx_f48m_cfg__usb_host_hs = {
+	.clk		= "usbhost_48m_fck",
+	.user		= OCP_USER_MPU,
+	.flags		= OCPIF_SWSUP_IDLE,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_slaves[] = {
+	&omap34xx_l4_cfg__usb_host_hs,
+	&omap34xx_f128m_cfg__usb_host_hs,
+	&omap34xx_f48m_cfg__usb_host_hs,
+};
+
+static struct omap_hwmod omap34xx_usb_host_hs_hwmod = {
+	.name		= "usbhs_uhh",
+	.class		= &omap34xx_usb_host_hs_hwmod_class,
+	.main_clk	= "usbhost_ick",
+	.prcm = {
+		.omap2 = {
+			.module_offs = OMAP3430ES2_USBHOST_MOD,
+			.prcm_reg_id = 1,
+			.module_bit = 0,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = 1,
+			.idlest_stdby_bit = 0,
+		},
+	},
+	.slaves		= omap34xx_usb_host_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_slaves),
+	.masters	= omap34xx_usb_host_hs_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_masters),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* 'usbhs_ohci' class  */
+static struct omap_hwmod_ocp_if omap34xx_usbhs_ohci__l3_main_2 = {
+	.master		= &omap34xx_usbhs_ohci_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class omap34xx_usbhs_ohci_hwmod_class = {
+	.name = "usbhs_ohci",
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ohci_masters[] = {
+	&omap34xx_usbhs_ohci__l3_main_2,
+};
+
+static struct omap_hwmod_irq_info omap34xx_usbhs_ohci_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usbhs_ohci_addrs[] = {
+	{
+		.name		= "ohci",
+		.pa_start	= 0x48064400,
+		.pa_end		= 0x480647FF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usbhs_ohci = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usbhs_ohci_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usbhs_ohci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ohci_slaves[] = {
+	&omap34xx_l4_cfg__usbhs_ohci,
+};
+
+static struct omap_hwmod omap34xx_usbhs_ohci_hwmod = {
+	.name		= "usbhs_ohci",
+	.class		= &omap34xx_usbhs_ohci_hwmod_class,
+	.mpu_irqs	= omap34xx_usbhs_ohci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_irqs),
+	.slaves		= omap34xx_usbhs_ohci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_slaves),
+	.masters	= omap34xx_usbhs_ohci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_masters),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* 'usbhs_ehci' class  */
+static struct omap_hwmod_ocp_if omap34xx_usbhs_ehci__l3_main_2 = {
+	.master		= &omap34xx_usbhs_ehci_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class omap34xx_usbhs_ehci_hwmod_class = {
+	.name = "usbhs_ehci",
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ehci_masters[] = {
+	&omap34xx_usbhs_ehci__l3_main_2,
+};
+
+static struct omap_hwmod_irq_info omap34xx_usbhs_ehci_irqs[] = {
+	{ .name = "ehci-irq", .irq = 77 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usbhs_ehci_addrs[] = {
+	{
+		.name		= "ehci",
+		.pa_start	= 0x48064800,
+		.pa_end		= 0x48064CFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usbhs_ehci = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usbhs_ehci_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usbhs_ehci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ehci_slaves[] = {
+	&omap34xx_l4_cfg__usbhs_ehci,
+};
+
+static struct omap_hwmod omap34xx_usbhs_ehci_hwmod = {
+	.name		= "usbhs_ehci",
+	.class		= &omap34xx_usbhs_ehci_hwmod_class,
+	.mpu_irqs	= omap34xx_usbhs_ehci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_irqs),
+	.slaves		= omap34xx_usbhs_ehci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_slaves),
+	.masters	= omap34xx_usbhs_ehci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_masters),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+static struct omap_hwmod_class_sysconfig omap34xx_usb_tll_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_usb_tll_hs_hwmod_class = {
+	.name = "usbhs_tll",
+	.sysc = &omap34xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod_irq_info omap34xx_usb_tll_hs_irqs[] = {
+	{ .name = "tll-irq", .irq = 78 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usb_tll_hs_addrs[] = {
+	{
+		.name		= "tll",
+		.pa_start	= 0x48062000,
+		.pa_end		= 0x48062fff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap34xx_f_cfg__usb_tll_hs = {
+	.clk		= "usbtll_fck",
+	.user		= OCP_USER_MPU,
+	.flags		= OCPIF_SWSUP_IDLE,
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_tll_hs = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usb_tll_hs_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usb_tll_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usb_tll_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usb_tll_hs_slaves[] = {
+	&omap34xx_l4_cfg__usb_tll_hs,
+	&omap34xx_f_cfg__usb_tll_hs,
+};
+
+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod = {
+	.name		= "usbhs_tll",
+	.class		= &omap34xx_usb_tll_hs_hwmod_class,
+	.mpu_irqs	= omap34xx_usb_tll_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usb_tll_hs_irqs),
+	.main_clk	= "usbtll_ick",
+	.prcm = {
+		.omap2 = {
+			.module_offs = CORE_MOD,
+			.prcm_reg_id = 3,
+			.module_bit = 2,
+			.idlest_reg_id = 3,
+			.idlest_idle_bit = 2,
+		},
+	},
+	.slaves		= omap34xx_usb_tll_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usb_tll_hs_slaves),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_main_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -3656,6 +3930,11 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	/* usbotg for am35x */
 	&am35xx_usbhsotg_hwmod,
 
+	&omap34xx_usb_host_hs_hwmod,
+	&omap34xx_usbhs_ohci_hwmod,
+	&omap34xx_usbhs_ehci_hwmod,
+	&omap34xx_usb_tll_hs_hwmod,
+
 	NULL,
 };
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 2/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap3
@ 2011-07-01 18:54     ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

Following 4 hwmod strcuture are added:
UHH hwmod of usbhs with uhh base address and functional clock,
EHCI hwmod with irq and base address,
OHCI hwmod with irq and base address,
TLL hwmod of usbhs with the TLL base address and irq.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  279 ++++++++++++++++++++++++++++
 1 files changed, 279 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 909a84d..8d1d4f5 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -84,6 +84,10 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod;
 static struct omap_hwmod omap3xxx_mcbsp5_hwmod;
 static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod;
 static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod;
+static struct omap_hwmod omap34xx_usb_host_hs_hwmod;
+static struct omap_hwmod omap34xx_usbhs_ohci_hwmod;
+static struct omap_hwmod omap34xx_usbhs_ehci_hwmod;
+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -3574,6 +3578,276 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = {
 	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 };
 
+/*
+ * 'usb_host_hs' class
+ * high-speed multi-port usb host controller
+ */
+static struct omap_hwmod_ocp_if omap34xx_usb_host_hs__l3_main_2 = {
+	.master		= &omap34xx_usb_host_hs_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig omap34xx_usb_host_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_usb_host_hs_hwmod_class = {
+	.name = "usbhs_uhh",
+	.sysc = &omap34xx_usb_host_hs_sysc,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_masters[] = {
+	&omap34xx_usb_host_hs__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap34xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x48064000,
+		.pa_end		= 0x480643ff,
+		.flags		= ADDR_TYPE_RT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_host_hs = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usb_host_hs_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usb_host_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap34xx_f128m_cfg__usb_host_hs = {
+	.clk		= "usbhost_120m_fck",
+	.user		= OCP_USER_MPU,
+	.flags		= OCPIF_SWSUP_IDLE,
+};
+
+static struct omap_hwmod_ocp_if omap34xx_f48m_cfg__usb_host_hs = {
+	.clk		= "usbhost_48m_fck",
+	.user		= OCP_USER_MPU,
+	.flags		= OCPIF_SWSUP_IDLE,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_slaves[] = {
+	&omap34xx_l4_cfg__usb_host_hs,
+	&omap34xx_f128m_cfg__usb_host_hs,
+	&omap34xx_f48m_cfg__usb_host_hs,
+};
+
+static struct omap_hwmod omap34xx_usb_host_hs_hwmod = {
+	.name		= "usbhs_uhh",
+	.class		= &omap34xx_usb_host_hs_hwmod_class,
+	.main_clk	= "usbhost_ick",
+	.prcm = {
+		.omap2 = {
+			.module_offs = OMAP3430ES2_USBHOST_MOD,
+			.prcm_reg_id = 1,
+			.module_bit = 0,
+			.idlest_reg_id = 1,
+			.idlest_idle_bit = 1,
+			.idlest_stdby_bit = 0,
+		},
+	},
+	.slaves		= omap34xx_usb_host_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_slaves),
+	.masters	= omap34xx_usb_host_hs_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_masters),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* 'usbhs_ohci' class  */
+static struct omap_hwmod_ocp_if omap34xx_usbhs_ohci__l3_main_2 = {
+	.master		= &omap34xx_usbhs_ohci_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class omap34xx_usbhs_ohci_hwmod_class = {
+	.name = "usbhs_ohci",
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ohci_masters[] = {
+	&omap34xx_usbhs_ohci__l3_main_2,
+};
+
+static struct omap_hwmod_irq_info omap34xx_usbhs_ohci_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usbhs_ohci_addrs[] = {
+	{
+		.name		= "ohci",
+		.pa_start	= 0x48064400,
+		.pa_end		= 0x480647FF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usbhs_ohci = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usbhs_ohci_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usbhs_ohci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ohci_slaves[] = {
+	&omap34xx_l4_cfg__usbhs_ohci,
+};
+
+static struct omap_hwmod omap34xx_usbhs_ohci_hwmod = {
+	.name		= "usbhs_ohci",
+	.class		= &omap34xx_usbhs_ohci_hwmod_class,
+	.mpu_irqs	= omap34xx_usbhs_ohci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_irqs),
+	.slaves		= omap34xx_usbhs_ohci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_slaves),
+	.masters	= omap34xx_usbhs_ohci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_usbhs_ohci_masters),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* 'usbhs_ehci' class  */
+static struct omap_hwmod_ocp_if omap34xx_usbhs_ehci__l3_main_2 = {
+	.master		= &omap34xx_usbhs_ehci_hwmod,
+	.slave		= &omap3xxx_l3_main_hwmod,
+	.clk		= "core_l3_ick",
+	.user		= OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class omap34xx_usbhs_ehci_hwmod_class = {
+	.name = "usbhs_ehci",
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ehci_masters[] = {
+	&omap34xx_usbhs_ehci__l3_main_2,
+};
+
+static struct omap_hwmod_irq_info omap34xx_usbhs_ehci_irqs[] = {
+	{ .name = "ehci-irq", .irq = 77 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usbhs_ehci_addrs[] = {
+	{
+		.name		= "ehci",
+		.pa_start	= 0x48064800,
+		.pa_end		= 0x48064CFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usbhs_ehci = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usbhs_ehci_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usbhs_ehci_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usbhs_ehci_slaves[] = {
+	&omap34xx_l4_cfg__usbhs_ehci,
+};
+
+static struct omap_hwmod omap34xx_usbhs_ehci_hwmod = {
+	.name		= "usbhs_ehci",
+	.class		= &omap34xx_usbhs_ehci_hwmod_class,
+	.mpu_irqs	= omap34xx_usbhs_ehci_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_irqs),
+	.slaves		= omap34xx_usbhs_ehci_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_slaves),
+	.masters	= omap34xx_usbhs_ehci_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_usbhs_ehci_masters),
+	.flags		= HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * 'usb_tll_hs' class
+ * usb_tll_hs module is the adapter on the usb_host_hs ports
+ */
+static struct omap_hwmod_class_sysconfig omap34xx_usb_tll_hs_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_usb_tll_hs_hwmod_class = {
+	.name = "usbhs_tll",
+	.sysc = &omap34xx_usb_tll_hs_sysc,
+};
+
+static struct omap_hwmod_irq_info omap34xx_usb_tll_hs_irqs[] = {
+	{ .name = "tll-irq", .irq = 78 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usb_tll_hs_addrs[] = {
+	{
+		.name		= "tll",
+		.pa_start	= 0x48062000,
+		.pa_end		= 0x48062fff,
+		.flags		= ADDR_TYPE_RT
+	},
+};
+
+static struct omap_hwmod_ocp_if omap34xx_f_cfg__usb_tll_hs = {
+	.clk		= "usbtll_fck",
+	.user		= OCP_USER_MPU,
+	.flags		= OCPIF_SWSUP_IDLE,
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_tll_hs = {
+	.master		= &omap3xxx_l4_core_hwmod,
+	.slave		= &omap34xx_usb_tll_hs_hwmod,
+	.clk		= "l4_ick",
+	.addr		= omap34xx_usb_tll_hs_addrs,
+	.addr_cnt	= ARRAY_SIZE(omap34xx_usb_tll_hs_addrs),
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_usb_tll_hs_slaves[] = {
+	&omap34xx_l4_cfg__usb_tll_hs,
+	&omap34xx_f_cfg__usb_tll_hs,
+};
+
+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod = {
+	.name		= "usbhs_tll",
+	.class		= &omap34xx_usb_tll_hs_hwmod_class,
+	.mpu_irqs	= omap34xx_usb_tll_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usb_tll_hs_irqs),
+	.main_clk	= "usbtll_ick",
+	.prcm = {
+		.omap2 = {
+			.module_offs = CORE_MOD,
+			.prcm_reg_id = 3,
+			.module_bit = 2,
+			.idlest_reg_id = 3,
+			.idlest_idle_bit = 2,
+		},
+	},
+	.slaves		= omap34xx_usb_tll_hs_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_usb_tll_hs_slaves),
+	.flags		= HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
 static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	&omap3xxx_l3_main_hwmod,
 	&omap3xxx_l4_core_hwmod,
@@ -3656,6 +3930,11 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	/* usbotg for am35x */
 	&am35xx_usbhsotg_hwmod,
 
+	&omap34xx_usb_host_hs_hwmod,
+	&omap34xx_usbhs_ohci_hwmod,
+	&omap34xx_usbhs_ehci_hwmod,
+	&omap34xx_usb_tll_hs_hwmod,
+
 	NULL,
 };
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 3/6 v2] arm: omap: usb: register hwmods of usbhs
  2011-07-01 18:54     ` Keshava Munegowda
@ 2011-07-01 18:54       ` Keshava Munegowda
  -1 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs

The hwmod structure of uhh, ohci, ehci and tll are
retrived and registered with omap device

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/mach-omap2/usb-host.c |  113 +++++++++++++++++----------------------
 1 files changed, 49 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 89ae298..dea0eed 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -28,51 +28,30 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <plat/usb.h>
+#include <plat/omap_device.h>
 
 #include "mux.h"
 
 #ifdef CONFIG_MFD_OMAP_USB_HOST
 
-#define OMAP_USBHS_DEVICE	"usbhs-omap"
-
-static struct resource usbhs_resources[] = {
-	{
-		.name	= "uhh",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "tll",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "ehci",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "ehci-irq",
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.name	= "ohci",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "ohci-irq",
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device usbhs_device = {
-	.name		= OMAP_USBHS_DEVICE,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(usbhs_resources),
-	.resource	= usbhs_resources,
-};
+#define OMAP_USBHS_DEVICE	"usbhs_omap"
+#define	USBHS_UHH_HWMODNAME	"usbhs_uhh"
+#define	USBHS_OHCI_HWMODNAME	"usbhs_ohci"
+#define USBHS_EHCI_HWMODNAME	"usbhs_ehci"
+#define USBHS_TLL_HWMODNAME	"usbhs_tll"
 
 static struct usbhs_omap_platform_data		usbhs_data;
 static struct ehci_hcd_omap_platform_data	ehci_data;
 static struct ohci_hcd_omap_platform_data	ohci_data;
 
+static struct omap_device_pm_latency omap_uhhtll_latency[] = {
+	  {
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func	 = omap_device_enable_hwmods,
+		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+	  },
+};
+
 /* MUX settings for EHCI pins */
 /*
  * setup_ehci_io_mux - initialize IO pad mux for USBHOST
@@ -508,7 +487,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
 
 void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
 {
-	int	i;
+	struct omap_hwmod	*oh[4];
+	struct omap_device	*od;
+	int			bus_id = -1;
+	int			i;
 
 	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
 		usbhs_data.port_mode[i] = pdata->port_mode[i];
@@ -523,44 +505,47 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
 	usbhs_data.ohci_data = &ohci_data;
 
 	if (cpu_is_omap34xx()) {
-		usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
-		usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
-		usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
-		usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
-		usbhs_resources[2].start	= OMAP34XX_EHCI_BASE;
-		usbhs_resources[2].end	= OMAP34XX_EHCI_BASE + SZ_1K - 1;
-		usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
-		usbhs_resources[4].start	= OMAP34XX_OHCI_BASE;
-		usbhs_resources[4].end	= OMAP34XX_OHCI_BASE + SZ_1K - 1;
-		usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
 		setup_ehci_io_mux(pdata->port_mode);
 		setup_ohci_io_mux(pdata->port_mode);
 	} else if (cpu_is_omap44xx()) {
-		usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
-		usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
-		usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
-		usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
-		usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
-		usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
-		usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
-		usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
-		usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
-		usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
 		setup_4430ehci_io_mux(pdata->port_mode);
 		setup_4430ohci_io_mux(pdata->port_mode);
 	}
 
-	if (platform_device_add_data(&usbhs_device,
-				&usbhs_data, sizeof(usbhs_data)) < 0) {
-		printk(KERN_ERR "USBHS platform_device_add_data failed\n");
-		goto init_end;
+	oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
+	if (!oh[0]) {
+		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
+		return;
+	}
+
+	oh[1] = omap_hwmod_lookup(USBHS_OHCI_HWMODNAME);
+	if (!oh[1]) {
+		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
+		return;
 	}
 
-	if (platform_device_register(&usbhs_device) < 0)
-		printk(KERN_ERR "USBHS platform_device_register failed\n");
+	oh[2] = omap_hwmod_lookup(USBHS_EHCI_HWMODNAME);
+	if (!oh[2]) {
+		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+		return;
+	}
 
-init_end:
-	return;
+	oh[3] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+	if (!oh[3]) {
+		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+		return;
+	}
+
+	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 4,
+				(void *)&usbhs_data, sizeof(usbhs_data),
+				omap_uhhtll_latency,
+				ARRAY_SIZE(omap_uhhtll_latency), false);
+
+	if (IS_ERR(od)) {
+		pr_err("Could not build hwmod devices %s, %s\n",
+			USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
+		return;
+	}
 }
 
 #else
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 3/6 v2] arm: omap: usb: register hwmods of usbhs
@ 2011-07-01 18:54       ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs

The hwmod structure of uhh, ohci, ehci and tll are
retrived and registered with omap device

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/mach-omap2/usb-host.c |  113 +++++++++++++++++----------------------
 1 files changed, 49 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 89ae298..dea0eed 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -28,51 +28,30 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <plat/usb.h>
+#include <plat/omap_device.h>
 
 #include "mux.h"
 
 #ifdef CONFIG_MFD_OMAP_USB_HOST
 
-#define OMAP_USBHS_DEVICE	"usbhs-omap"
-
-static struct resource usbhs_resources[] = {
-	{
-		.name	= "uhh",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "tll",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "ehci",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "ehci-irq",
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.name	= "ohci",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "ohci-irq",
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device usbhs_device = {
-	.name		= OMAP_USBHS_DEVICE,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(usbhs_resources),
-	.resource	= usbhs_resources,
-};
+#define OMAP_USBHS_DEVICE	"usbhs_omap"
+#define	USBHS_UHH_HWMODNAME	"usbhs_uhh"
+#define	USBHS_OHCI_HWMODNAME	"usbhs_ohci"
+#define USBHS_EHCI_HWMODNAME	"usbhs_ehci"
+#define USBHS_TLL_HWMODNAME	"usbhs_tll"
 
 static struct usbhs_omap_platform_data		usbhs_data;
 static struct ehci_hcd_omap_platform_data	ehci_data;
 static struct ohci_hcd_omap_platform_data	ohci_data;
 
+static struct omap_device_pm_latency omap_uhhtll_latency[] = {
+	  {
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func	 = omap_device_enable_hwmods,
+		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+	  },
+};
+
 /* MUX settings for EHCI pins */
 /*
  * setup_ehci_io_mux - initialize IO pad mux for USBHOST
@@ -508,7 +487,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
 
 void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
 {
-	int	i;
+	struct omap_hwmod	*oh[4];
+	struct omap_device	*od;
+	int			bus_id = -1;
+	int			i;
 
 	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
 		usbhs_data.port_mode[i] = pdata->port_mode[i];
@@ -523,44 +505,47 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
 	usbhs_data.ohci_data = &ohci_data;
 
 	if (cpu_is_omap34xx()) {
-		usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
-		usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
-		usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
-		usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
-		usbhs_resources[2].start	= OMAP34XX_EHCI_BASE;
-		usbhs_resources[2].end	= OMAP34XX_EHCI_BASE + SZ_1K - 1;
-		usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
-		usbhs_resources[4].start	= OMAP34XX_OHCI_BASE;
-		usbhs_resources[4].end	= OMAP34XX_OHCI_BASE + SZ_1K - 1;
-		usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
 		setup_ehci_io_mux(pdata->port_mode);
 		setup_ohci_io_mux(pdata->port_mode);
 	} else if (cpu_is_omap44xx()) {
-		usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
-		usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
-		usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
-		usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
-		usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
-		usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
-		usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
-		usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
-		usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
-		usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
 		setup_4430ehci_io_mux(pdata->port_mode);
 		setup_4430ohci_io_mux(pdata->port_mode);
 	}
 
-	if (platform_device_add_data(&usbhs_device,
-				&usbhs_data, sizeof(usbhs_data)) < 0) {
-		printk(KERN_ERR "USBHS platform_device_add_data failed\n");
-		goto init_end;
+	oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
+	if (!oh[0]) {
+		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
+		return;
+	}
+
+	oh[1] = omap_hwmod_lookup(USBHS_OHCI_HWMODNAME);
+	if (!oh[1]) {
+		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
+		return;
 	}
 
-	if (platform_device_register(&usbhs_device) < 0)
-		printk(KERN_ERR "USBHS platform_device_register failed\n");
+	oh[2] = omap_hwmod_lookup(USBHS_EHCI_HWMODNAME);
+	if (!oh[2]) {
+		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+		return;
+	}
 
-init_end:
-	return;
+	oh[3] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+	if (!oh[3]) {
+		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+		return;
+	}
+
+	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 4,
+				(void *)&usbhs_data, sizeof(usbhs_data),
+				omap_uhhtll_latency,
+				ARRAY_SIZE(omap_uhhtll_latency), false);
+
+	if (IS_ERR(od)) {
+		pr_err("Could not build hwmod devices %s, %s\n",
+			USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
+		return;
+	}
 }
 
 #else
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 4/6 v2] arm: omap: usb: device name change for the clk names of usbhs
  2011-07-01 18:54       ` Keshava Munegowda
@ 2011-07-01 18:54         ` Keshava Munegowda
  -1 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

device name usbhs clocks are changed from
usbhs-omap.0 to usbhs_omap; this is because
in the hwmod registration the device name is set
as usbhs_omap

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/mach-omap2/clock3xxx_data.c |   28 ++++++++++++++--------------
 arch/arm/mach-omap2/clock44xx_data.c |   10 +++++-----
 drivers/mfd/omap-usb-host.c          |    2 +-
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 75b119b..fabe482 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3285,7 +3285,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK("omap-mcbsp.1",	"prcm_fck",	&core_96m_fck,	CK_3XXX),
 	CLK("omap-mcbsp.5",	"prcm_fck",	&core_96m_fck,	CK_3XXX),
 	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_3XXX),
@@ -3321,7 +3321,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"pka_ick",	&pka_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_3XXX),
 	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK("omap_hsmmc.2",	"ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"icr_ick",	&icr_ick,	CK_34XX | CK_36XX),
 	CLK("omap-aes",	"ick",	&aes2_ick,	CK_34XX | CK_36XX),
@@ -3367,20 +3367,20 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"cam_ick",	&cam_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_34XX | CK_36XX),
 	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"init_60m_fclk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"init_60m_fclk",	&dummy_ck,	CK_3XXX),
 	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2PLUS | CK_36XX),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
 	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 8c96567..34e91eb 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3205,7 +3205,7 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X),
 	CLK(NULL,	"uart4_fck",			&uart4_fck,	CK_443X),
 	CLK(NULL,	"usb_host_fs_fck",		&usb_host_fs_fck,	CK_443X),
-	CLK("usbhs-omap.0",	"fs_fck",		&usb_host_fs_fck,	CK_443X),
+	CLK("usbhs_omap",	"fs_fck",		&usb_host_fs_fck,	CK_443X),
 	CLK(NULL,	"utmi_p1_gfclk",		&utmi_p1_gfclk,	CK_443X),
 	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&usb_host_hs_utmi_p1_clk,	CK_443X),
 	CLK(NULL,	"utmi_p2_gfclk",		&utmi_p2_gfclk,	CK_443X),
@@ -3217,8 +3217,8 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"usb_host_hs_hsic480m_p2_clk",	&usb_host_hs_hsic480m_p2_clk,	CK_443X),
 	CLK(NULL,	"usb_host_hs_func48mclk",	&usb_host_hs_func48mclk,	CK_443X),
 	CLK(NULL,	"usb_host_hs_fck",		&usb_host_hs_fck,	CK_443X),
-	CLK("usbhs-omap.0",	"hs_fck",		&usb_host_hs_fck,	CK_443X),
-	CLK("usbhs-omap.0",	"usbhost_ick",		&dummy_ck,		CK_443X),
+	CLK("usbhs_omap",	"hs_fck",		&usb_host_hs_fck,	CK_443X),
+	CLK("usbhs_omap",	"usbhost_ick",		&dummy_ck,		CK_443X),
 	CLK(NULL,	"otg_60m_gfclk",		&otg_60m_gfclk,	CK_443X),
 	CLK(NULL,	"usb_otg_hs_xclk",		&usb_otg_hs_xclk,	CK_443X),
 	CLK("musb-omap2430",	"ick",				&usb_otg_hs_ick,	CK_443X),
@@ -3227,8 +3227,8 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"usb_tll_hs_usb_ch0_clk",	&usb_tll_hs_usb_ch0_clk,	CK_443X),
 	CLK(NULL,	"usb_tll_hs_usb_ch1_clk",	&usb_tll_hs_usb_ch1_clk,	CK_443X),
 	CLK(NULL,	"usb_tll_hs_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK("usbhs-omap.0",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK("usbhs-omap.0",	"usbtll_fck",		&dummy_ck,	CK_443X),
+	CLK("usbhs_omap",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
+	CLK("usbhs_omap",	"usbtll_fck",		&dummy_ck,	CK_443X),
 	CLK(NULL,	"usim_ck",			&usim_ck,	CK_443X),
 	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
 	CLK(NULL,	"usim_fck",			&usim_fck,	CK_443X),
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 8552195..43de12a 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -28,7 +28,7 @@
 #include <plat/usb.h>
 #include <linux/pm_runtime.h>
 
-#define USBHS_DRIVER_NAME	"usbhs-omap"
+#define USBHS_DRIVER_NAME	"usbhs_omap"
 #define OMAP_EHCI_DEVICE	"ehci-omap"
 #define OMAP_OHCI_DEVICE	"ohci-omap3"
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 4/6 v2] arm: omap: usb: device name change for the clk names of usbhs
@ 2011-07-01 18:54         ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

device name usbhs clocks are changed from
usbhs-omap.0 to usbhs_omap; this is because
in the hwmod registration the device name is set
as usbhs_omap

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/mach-omap2/clock3xxx_data.c |   28 ++++++++++++++--------------
 arch/arm/mach-omap2/clock44xx_data.c |   10 +++++-----
 drivers/mfd/omap-usb-host.c          |    2 +-
 3 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 75b119b..fabe482 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3285,7 +3285,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK("omap-mcbsp.1",	"prcm_fck",	&core_96m_fck,	CK_3XXX),
 	CLK("omap-mcbsp.5",	"prcm_fck",	&core_96m_fck,	CK_3XXX),
 	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_3XXX),
@@ -3321,7 +3321,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"pka_ick",	&pka_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_3XXX),
 	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK("omap_hsmmc.2",	"ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"icr_ick",	&icr_ick,	CK_34XX | CK_36XX),
 	CLK("omap-aes",	"ick",	&aes2_ick,	CK_34XX | CK_36XX),
@@ -3367,20 +3367,20 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"cam_ick",	&cam_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_34XX | CK_36XX),
 	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs-omap.0",	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs-omap.0",	"init_60m_fclk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"init_60m_fclk",	&dummy_ck,	CK_3XXX),
 	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2PLUS | CK_36XX),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
 	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 8c96567..34e91eb 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3205,7 +3205,7 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X),
 	CLK(NULL,	"uart4_fck",			&uart4_fck,	CK_443X),
 	CLK(NULL,	"usb_host_fs_fck",		&usb_host_fs_fck,	CK_443X),
-	CLK("usbhs-omap.0",	"fs_fck",		&usb_host_fs_fck,	CK_443X),
+	CLK("usbhs_omap",	"fs_fck",		&usb_host_fs_fck,	CK_443X),
 	CLK(NULL,	"utmi_p1_gfclk",		&utmi_p1_gfclk,	CK_443X),
 	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&usb_host_hs_utmi_p1_clk,	CK_443X),
 	CLK(NULL,	"utmi_p2_gfclk",		&utmi_p2_gfclk,	CK_443X),
@@ -3217,8 +3217,8 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"usb_host_hs_hsic480m_p2_clk",	&usb_host_hs_hsic480m_p2_clk,	CK_443X),
 	CLK(NULL,	"usb_host_hs_func48mclk",	&usb_host_hs_func48mclk,	CK_443X),
 	CLK(NULL,	"usb_host_hs_fck",		&usb_host_hs_fck,	CK_443X),
-	CLK("usbhs-omap.0",	"hs_fck",		&usb_host_hs_fck,	CK_443X),
-	CLK("usbhs-omap.0",	"usbhost_ick",		&dummy_ck,		CK_443X),
+	CLK("usbhs_omap",	"hs_fck",		&usb_host_hs_fck,	CK_443X),
+	CLK("usbhs_omap",	"usbhost_ick",		&dummy_ck,		CK_443X),
 	CLK(NULL,	"otg_60m_gfclk",		&otg_60m_gfclk,	CK_443X),
 	CLK(NULL,	"usb_otg_hs_xclk",		&usb_otg_hs_xclk,	CK_443X),
 	CLK("musb-omap2430",	"ick",				&usb_otg_hs_ick,	CK_443X),
@@ -3227,8 +3227,8 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"usb_tll_hs_usb_ch0_clk",	&usb_tll_hs_usb_ch0_clk,	CK_443X),
 	CLK(NULL,	"usb_tll_hs_usb_ch1_clk",	&usb_tll_hs_usb_ch1_clk,	CK_443X),
 	CLK(NULL,	"usb_tll_hs_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK("usbhs-omap.0",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK("usbhs-omap.0",	"usbtll_fck",		&dummy_ck,	CK_443X),
+	CLK("usbhs_omap",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
+	CLK("usbhs_omap",	"usbtll_fck",		&dummy_ck,	CK_443X),
 	CLK(NULL,	"usim_ck",			&usim_ck,	CK_443X),
 	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
 	CLK(NULL,	"usim_fck",			&usim_fck,	CK_443X),
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 8552195..43de12a 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -28,7 +28,7 @@
 #include <plat/usb.h>
 #include <linux/pm_runtime.h>
 
-#define USBHS_DRIVER_NAME	"usbhs-omap"
+#define USBHS_DRIVER_NAME	"usbhs_omap"
 #define OMAP_EHCI_DEVICE	"ehci-omap"
 #define OMAP_OHCI_DEVICE	"ohci-omap3"
 
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 5/6 v2] arm: omap: usb: Runtime PM support
  2011-07-01 18:54         ` Keshava Munegowda
@ 2011-07-01 18:54           ` Keshava Munegowda
  -1 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The usbhs core driver does not enable/disable the intefrace and
fucntional clocks; These clocks are handled by hwmod and runtime pm,
hence insted of the clock enable/disable, the runtime pm APIS are
used. however,the port clocks and tll clocks are handled
by the usbhs core.
In this architecture, the usbhs is core driver and it is parent of
ehci and ohci drivers.The earlier APIs omap_usbhs_enable and
omap_usbhs_disable of usbhs core driver are removed;
The ehci and ohci drivers call the pm_runtime_get_sync and
pm_runtime_put_sync of parent device usbhs core.
In fact, the runtime framework takes care the get sync and
put sync of the child in turn call the get sync and put sync
of parent too; but calling get sync and put sync of parent is
by ASYNC mode; This mode queues the work item in runtime pm
work queue, which not getting scheduled in case of global suspend path.
so, here ehci and ohci runtim pm is not required, these
drivers will pass the parent usbhs dev pointer in runtime pm APIs.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/plat-omap/include/plat/usb.h |    3 -
 drivers/mfd/omap-usb-host.c           |  618 +++++++++++++++------------------
 drivers/usb/host/ehci-omap.c          |   14 +-
 drivers/usb/host/ohci-omap3.c         |   12 +-
 4 files changed, 290 insertions(+), 357 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 17d3c93..2b66dc2 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -100,9 +100,6 @@ extern void usb_musb_init(struct omap_musb_board_data *board_data);
 
 extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
 
-extern int omap_usbhs_enable(struct device *dev);
-extern void omap_usbhs_disable(struct device *dev);
-
 extern int omap4430_phy_power(struct device *dev, int ID, int on);
 extern int omap4430_phy_set_clk(struct device *dev, int on);
 extern int omap4430_phy_init(struct device *dev);
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 43de12a..521ee86 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -164,7 +164,6 @@ struct usbhs_hcd_omap {
 
 	u32				usbhs_rev;
 	spinlock_t			lock;
-	int				count;
 };
 /*-------------------------------------------------------------------------*/
 
@@ -314,218 +313,6 @@ err_end:
 	return ret;
 }
 
-/**
- * usbhs_omap_probe - initialize TI-based HCDs
- *
- * Allocates basic resources for this USB host controller.
- */
-static int __devinit usbhs_omap_probe(struct platform_device *pdev)
-{
-	struct device			*dev =  &pdev->dev;
-	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
-	struct usbhs_hcd_omap		*omap;
-	struct resource			*res;
-	int				ret = 0;
-	int				i;
-
-	if (!pdata) {
-		dev_err(dev, "Missing platform data\n");
-		ret = -ENOMEM;
-		goto end_probe;
-	}
-
-	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
-	if (!omap) {
-		dev_err(dev, "Memory allocation failed\n");
-		ret = -ENOMEM;
-		goto end_probe;
-	}
-
-	spin_lock_init(&omap->lock);
-
-	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
-		omap->platdata.port_mode[i] = pdata->port_mode[i];
-
-	omap->platdata.ehci_data = pdata->ehci_data;
-	omap->platdata.ohci_data = pdata->ohci_data;
-
-	pm_runtime_enable(&pdev->dev);
-
-	omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
-	if (IS_ERR(omap->utmi_p1_fck)) {
-		ret = PTR_ERR(omap->utmi_p1_fck);
-		dev_err(dev, "utmi_p1_gfclk failed error:%d\n",	ret);
-		goto err_end;
-	}
-
-	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
-	if (IS_ERR(omap->xclk60mhsp1_ck)) {
-		ret = PTR_ERR(omap->xclk60mhsp1_ck);
-		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-		goto err_utmi_p1_fck;
-	}
-
-	omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
-	if (IS_ERR(omap->utmi_p2_fck)) {
-		ret = PTR_ERR(omap->utmi_p2_fck);
-		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-		goto err_xclk60mhsp1_ck;
-	}
-
-	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
-	if (IS_ERR(omap->xclk60mhsp2_ck)) {
-		ret = PTR_ERR(omap->xclk60mhsp2_ck);
-		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-		goto err_utmi_p2_fck;
-	}
-
-	omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
-	if (IS_ERR(omap->usbhost_p1_fck)) {
-		ret = PTR_ERR(omap->usbhost_p1_fck);
-		dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
-		goto err_xclk60mhsp2_ck;
-	}
-
-	omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
-	if (IS_ERR(omap->usbtll_p1_fck)) {
-		ret = PTR_ERR(omap->usbtll_p1_fck);
-		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
-		goto err_usbhost_p1_fck;
-	}
-
-	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
-	if (IS_ERR(omap->usbhost_p2_fck)) {
-		ret = PTR_ERR(omap->usbhost_p2_fck);
-		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
-		goto err_usbtll_p1_fck;
-	}
-
-	omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
-	if (IS_ERR(omap->usbtll_p2_fck)) {
-		ret = PTR_ERR(omap->usbtll_p2_fck);
-		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
-		goto err_usbhost_p2_fck;
-	}
-
-	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
-	if (IS_ERR(omap->init_60m_fclk)) {
-		ret = PTR_ERR(omap->init_60m_fclk);
-		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-		goto err_usbtll_p2_fck;
-	}
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
-	if (!res) {
-		dev_err(dev, "UHH EHCI get resource failed\n");
-		ret = -ENODEV;
-		goto err_init_60m_fclk;
-	}
-
-	omap->uhh_base = ioremap(res->start, resource_size(res));
-	if (!omap->uhh_base) {
-		dev_err(dev, "UHH ioremap failed\n");
-		ret = -ENOMEM;
-		goto err_init_60m_fclk;
-	}
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
-	if (!res) {
-		dev_err(dev, "UHH EHCI get resource failed\n");
-		ret = -ENODEV;
-		goto err_tll;
-	}
-
-	omap->tll_base = ioremap(res->start, resource_size(res));
-	if (!omap->tll_base) {
-		dev_err(dev, "TLL ioremap failed\n");
-		ret = -ENOMEM;
-		goto err_tll;
-	}
-
-	platform_set_drvdata(pdev, omap);
-
-	ret = omap_usbhs_alloc_children(pdev);
-	if (ret) {
-		dev_err(dev, "omap_usbhs_alloc_children failed\n");
-		goto err_alloc;
-	}
-
-	goto end_probe;
-
-err_alloc:
-	iounmap(omap->tll_base);
-
-err_tll:
-	iounmap(omap->uhh_base);
-
-err_init_60m_fclk:
-	clk_put(omap->init_60m_fclk);
-
-err_usbtll_p2_fck:
-	clk_put(omap->usbtll_p2_fck);
-
-err_usbhost_p2_fck:
-	clk_put(omap->usbhost_p2_fck);
-
-err_usbtll_p1_fck:
-	clk_put(omap->usbtll_p1_fck);
-
-err_usbhost_p1_fck:
-	clk_put(omap->usbhost_p1_fck);
-
-err_xclk60mhsp2_ck:
-	clk_put(omap->xclk60mhsp2_ck);
-
-err_utmi_p2_fck:
-	clk_put(omap->utmi_p2_fck);
-
-err_xclk60mhsp1_ck:
-	clk_put(omap->xclk60mhsp1_ck);
-
-err_utmi_p1_fck:
-	clk_put(omap->utmi_p1_fck);
-
-err_end:
-	pm_runtime_disable(&pdev->dev);
-	kfree(omap);
-
-end_probe:
-	return ret;
-}
-
-/**
- * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
- * @pdev: USB Host Controller being removed
- *
- * Reverses the effect of usbhs_omap_probe().
- */
-static int __devexit usbhs_omap_remove(struct platform_device *pdev)
-{
-	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
-
-	if (omap->count != 0) {
-		dev_err(&pdev->dev,
-			"Either EHCI or OHCI is still using usbhs core\n");
-		return -EBUSY;
-	}
-
-	iounmap(omap->tll_base);
-	iounmap(omap->uhh_base);
-	clk_put(omap->init_60m_fclk);
-	clk_put(omap->usbtll_p2_fck);
-	clk_put(omap->usbhost_p2_fck);
-	clk_put(omap->usbtll_p1_fck);
-	clk_put(omap->usbhost_p1_fck);
-	clk_put(omap->xclk60mhsp2_ck);
-	clk_put(omap->utmi_p2_fck);
-	clk_put(omap->xclk60mhsp1_ck);
-	clk_put(omap->utmi_p1_fck);
-	pm_runtime_disable(&pdev->dev);
-	kfree(omap);
-
-	return 0;
-}
-
 static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
 {
 	switch (pmode) {
@@ -634,26 +421,73 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
 	}
 }
 
-static int usbhs_enable(struct device *dev)
+static int usbhs_runtime_resume(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
-	unsigned long			flags = 0;
-	int				ret = 0;
-	unsigned			reg;
 
-	dev_dbg(dev, "starting TI HSUSB Controller\n");
+	dev_dbg(dev, "usbhs_runtime_resume\n");
+
 	if (!pdata) {
 		dev_dbg(dev, "missing platform_data\n");
 		return  -ENODEV;
 	}
 
-	spin_lock_irqsave(&omap->lock, flags);
-	if (omap->count > 0)
-		goto end_count;
+	if (is_omap_usbhs_rev2(omap)) {
+		if (is_ehci_tll_mode(pdata->port_mode[0])) {
+			clk_enable(omap->usbhost_p1_fck);
+			clk_enable(omap->usbtll_p1_fck);
+		}
+		if (is_ehci_tll_mode(pdata->port_mode[1])) {
+			clk_enable(omap->usbhost_p2_fck);
+			clk_enable(omap->usbtll_p2_fck);
+		}
+		clk_enable(omap->utmi_p1_fck);
+		clk_enable(omap->utmi_p2_fck);
+	}
+	return 0;
+}
+
+static int usbhs_runtime_suspend(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+
+	dev_dbg(dev, "usbhs_runtime_suspend\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	if (is_omap_usbhs_rev2(omap)) {
+		if (is_ehci_tll_mode(pdata->port_mode[0])) {
+			clk_disable(omap->usbhost_p1_fck);
+			clk_disable(omap->usbtll_p1_fck);
+		}
+		if (is_ehci_tll_mode(pdata->port_mode[1])) {
+			clk_disable(omap->usbhost_p2_fck);
+			clk_disable(omap->usbtll_p2_fck);
+		}
+		clk_disable(omap->utmi_p2_fck);
+		clk_disable(omap->utmi_p1_fck);
+	}
+	return 0;
+}
+
+static void omap_usbhs_init(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+	unsigned long			flags = 0;
+	unsigned			reg;
+
+	dev_dbg(dev, "starting TI HSUSB Controller\n");
 
 	pm_runtime_get_sync(dev);
 
+	spin_lock_irqsave(&omap->lock, flags);
+
 	if (pdata->ehci_data->phy_reset) {
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
 			gpio_request(pdata->ehci_data->reset_gpio_port[0],
@@ -676,6 +510,14 @@ static int usbhs_enable(struct device *dev)
 	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
 	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 
+	/*
+	 * Really enable the port clocks
+	 * first call of pm_runtime_get_sync does not enable these
+	 * port clocks; because omap->usbhs_rev was aviable
+	 * This omap->usbhs_rev is aviable now!
+	 */
+	usbhs_runtime_resume(dev);
+
 	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
 	/* setup ULPI bypass and burst configurations */
 	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
@@ -721,49 +563,6 @@ static int usbhs_enable(struct device *dev)
 		reg &= ~OMAP4_P1_MODE_CLEAR;
 		reg &= ~OMAP4_P2_MODE_CLEAR;
 
-		if (is_ehci_phy_mode(pdata->port_mode[0])) {
-			ret = clk_set_parent(omap->utmi_p1_fck,
-						omap->xclk60mhsp1_ck);
-			if (ret != 0) {
-				dev_err(dev, "xclk60mhsp1_ck set parent"
-				"failed error:%d\n", ret);
-				goto err_tll;
-			}
-		} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
-			ret = clk_set_parent(omap->utmi_p1_fck,
-						omap->init_60m_fclk);
-			if (ret != 0) {
-				dev_err(dev, "init_60m_fclk set parent"
-				"failed error:%d\n", ret);
-				goto err_tll;
-			}
-			clk_enable(omap->usbhost_p1_fck);
-			clk_enable(omap->usbtll_p1_fck);
-		}
-
-		if (is_ehci_phy_mode(pdata->port_mode[1])) {
-			ret = clk_set_parent(omap->utmi_p2_fck,
-						omap->xclk60mhsp2_ck);
-			if (ret != 0) {
-				dev_err(dev, "xclk60mhsp1_ck set parent"
-					"failed error:%d\n", ret);
-				goto err_tll;
-			}
-		} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
-			ret = clk_set_parent(omap->utmi_p2_fck,
-						omap->init_60m_fclk);
-			if (ret != 0) {
-				dev_err(dev, "init_60m_fclk set parent"
-				"failed error:%d\n", ret);
-				goto err_tll;
-			}
-			clk_enable(omap->usbhost_p2_fck);
-			clk_enable(omap->usbtll_p2_fck);
-		}
-
-		clk_enable(omap->utmi_p1_fck);
-		clk_enable(omap->utmi_p2_fck);
-
 		if (is_ehci_tll_mode(pdata->port_mode[0]) ||
 			(is_ohci_port(pdata->port_mode[0])))
 			reg |= OMAP4_P1_MODE_TLL;
@@ -809,14 +608,17 @@ static int usbhs_enable(struct device *dev)
 				(pdata->ehci_data->reset_gpio_port[1], 1);
 	}
 
-end_count:
-	omap->count++;
 	spin_unlock_irqrestore(&omap->lock, flags);
-	return 0;
-
-err_tll:
 	pm_runtime_put_sync(dev);
-	spin_unlock_irqrestore(&omap->lock, flags);
+}
+
+static void omap_usbhs_deinit(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+
+	dev_dbg(dev, "stopping TI HSUSB Controller\n");
+
 	if (pdata->ehci_data->phy_reset) {
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
 			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
@@ -824,112 +626,256 @@ err_tll:
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
 			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
 	}
-	return ret;
 }
 
-static void usbhs_disable(struct device *dev)
+/**
+ * usbhs_omap_probe - initialize TI-based HCDs
+ *
+ * Allocates basic resources for this USB host controller.
+ */
+static int __devinit usbhs_omap_probe(struct platform_device *pdev)
 {
-	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
-	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
-	unsigned long			flags = 0;
-	unsigned long			timeout;
+	struct device			*dev =  &pdev->dev;
+	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
+	struct usbhs_hcd_omap		*omap;
+	struct resource			*res;
+	int				ret = 0;
+	int				i;
 
-	dev_dbg(dev, "stopping TI HSUSB Controller\n");
+	if (!pdata) {
+		dev_err(dev, "Missing platform data\n");
+		ret = -ENOMEM;
+		goto end_probe;
+	}
 
-	spin_lock_irqsave(&omap->lock, flags);
+	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		dev_err(dev, "Memory allocation failed\n");
+		ret = -ENOMEM;
+		goto end_probe;
+	}
 
-	if (omap->count == 0)
-		goto end_disble;
+	spin_lock_init(&omap->lock);
 
-	omap->count--;
+	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
+		omap->platdata.port_mode[i] = pdata->port_mode[i];
 
-	if (omap->count != 0)
-		goto end_disble;
+	omap->platdata.ehci_data = pdata->ehci_data;
+	omap->platdata.ohci_data = pdata->ohci_data;
 
-	/* Reset OMAP modules for insmod/rmmod to work */
-	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
-			is_omap_usbhs_rev2(omap) ?
-			OMAP4_UHH_SYSCONFIG_SOFTRESET :
-			OMAP_UHH_SYSCONFIG_SOFTRESET);
+	pm_runtime_enable(dev);
 
-	timeout = jiffies + msecs_to_jiffies(100);
-	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
-				& (1 << 0))) {
-		cpu_relax();
+	omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
+	if (IS_ERR(omap->utmi_p1_fck)) {
+		ret = PTR_ERR(omap->utmi_p1_fck);
+		dev_err(dev, "utmi_p1_gfclk failed error:%d\n",	ret);
+		goto err_end;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
+	if (IS_ERR(omap->xclk60mhsp1_ck)) {
+		ret = PTR_ERR(omap->xclk60mhsp1_ck);
+		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
+		goto err_utmi_p1_fck;
 	}
 
-	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
-				& (1 << 1))) {
-		cpu_relax();
+	omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
+	if (IS_ERR(omap->utmi_p2_fck)) {
+		ret = PTR_ERR(omap->utmi_p2_fck);
+		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
+		goto err_xclk60mhsp1_ck;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
+	if (IS_ERR(omap->xclk60mhsp2_ck)) {
+		ret = PTR_ERR(omap->xclk60mhsp2_ck);
+		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
+		goto err_utmi_p2_fck;
 	}
 
-	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
-				& (1 << 2))) {
-		cpu_relax();
+	omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
+	if (IS_ERR(omap->usbhost_p1_fck)) {
+		ret = PTR_ERR(omap->usbhost_p1_fck);
+		dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
+		goto err_xclk60mhsp2_ck;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
+	if (IS_ERR(omap->usbtll_p1_fck)) {
+		ret = PTR_ERR(omap->usbtll_p1_fck);
+		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
+		goto err_usbhost_p1_fck;
 	}
 
-	usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
+	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
+	if (IS_ERR(omap->usbhost_p2_fck)) {
+		ret = PTR_ERR(omap->usbhost_p2_fck);
+		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
+		goto err_usbtll_p1_fck;
+	}
 
-	while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
-				& (1 << 0))) {
-		cpu_relax();
+	omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
+	if (IS_ERR(omap->usbtll_p2_fck)) {
+		ret = PTR_ERR(omap->usbtll_p2_fck);
+		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
+		goto err_usbhost_p2_fck;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
+	if (IS_ERR(omap->init_60m_fclk)) {
+		ret = PTR_ERR(omap->init_60m_fclk);
+		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
+		goto err_usbtll_p2_fck;
 	}
 
-	if (is_omap_usbhs_rev2(omap)) {
-		if (is_ehci_tll_mode(pdata->port_mode[0]))
-			clk_enable(omap->usbtll_p1_fck);
-		if (is_ehci_tll_mode(pdata->port_mode[1]))
-			clk_enable(omap->usbtll_p2_fck);
-		clk_disable(omap->utmi_p2_fck);
-		clk_disable(omap->utmi_p1_fck);
+	if (is_ehci_phy_mode(pdata->port_mode[0])) {
+		/* for OMAP3 , the clk set paretn fails */
+		ret = clk_set_parent(omap->utmi_p1_fck,
+					omap->xclk60mhsp1_ck);
+		if (ret != 0)
+			dev_err(dev, "xclk60mhsp1_ck set parent"
+				"failed error:%d\n", ret);
+	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
+		ret = clk_set_parent(omap->utmi_p1_fck,
+					omap->init_60m_fclk);
+		if (ret != 0)
+			dev_err(dev, "init_60m_fclk set parent"
+				"failed error:%d\n", ret);
 	}
 
-	pm_runtime_put_sync(dev);
+	if (is_ehci_phy_mode(pdata->port_mode[1])) {
+		ret = clk_set_parent(omap->utmi_p2_fck,
+					omap->xclk60mhsp2_ck);
+		if (ret != 0)
+			dev_err(dev, "xclk60mhsp2_ck set parent"
+					"failed error:%d\n", ret);
+	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
+		ret = clk_set_parent(omap->utmi_p2_fck,
+						omap->init_60m_fclk);
+		if (ret != 0)
+			dev_err(dev, "init_60m_fclk set parent"
+				"failed error:%d\n", ret);
+	}
 
-	/* The gpio_free migh sleep; so unlock the spinlock */
-	spin_unlock_irqrestore(&omap->lock, flags);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
+	if (!res) {
+		dev_err(dev, "UHH EHCI get resource failed\n");
+		ret = -ENODEV;
+		goto err_init_60m_fclk;
+	}
 
-	if (pdata->ehci_data->phy_reset) {
-		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
+	omap->uhh_base = ioremap(res->start, resource_size(res));
+	if (!omap->uhh_base) {
+		dev_err(dev, "UHH ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_init_60m_fclk;
+	}
 
-		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
+	if (!res) {
+		dev_err(dev, "UHH EHCI get resource failed\n");
+		ret = -ENODEV;
+		goto err_tll;
 	}
-	return;
 
-end_disble:
-	spin_unlock_irqrestore(&omap->lock, flags);
-}
+	omap->tll_base = ioremap(res->start, resource_size(res));
+	if (!omap->tll_base) {
+		dev_err(dev, "TLL ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_tll;
+	}
 
-int omap_usbhs_enable(struct device *dev)
-{
-	return  usbhs_enable(dev->parent);
+	platform_set_drvdata(pdev, omap);
+
+	ret = omap_usbhs_alloc_children(pdev);
+	if (ret) {
+		dev_err(dev, "omap_usbhs_alloc_children failed\n");
+		goto err_alloc;
+	}
+
+	omap_usbhs_init(dev);
+
+	goto end_probe;
+
+err_alloc:
+	iounmap(omap->tll_base);
+
+err_tll:
+	iounmap(omap->uhh_base);
+
+err_init_60m_fclk:
+	clk_put(omap->init_60m_fclk);
+
+err_usbtll_p2_fck:
+	clk_put(omap->usbtll_p2_fck);
+
+err_usbhost_p2_fck:
+	clk_put(omap->usbhost_p2_fck);
+
+err_usbtll_p1_fck:
+	clk_put(omap->usbtll_p1_fck);
+
+err_usbhost_p1_fck:
+	clk_put(omap->usbhost_p1_fck);
+
+err_xclk60mhsp2_ck:
+	clk_put(omap->xclk60mhsp2_ck);
+
+err_utmi_p2_fck:
+	clk_put(omap->utmi_p2_fck);
+
+err_xclk60mhsp1_ck:
+	clk_put(omap->xclk60mhsp1_ck);
+
+err_utmi_p1_fck:
+	clk_put(omap->utmi_p1_fck);
+
+err_end:
+	pm_runtime_disable(dev);
+	kfree(omap);
+
+end_probe:
+	return ret;
 }
-EXPORT_SYMBOL_GPL(omap_usbhs_enable);
 
-void omap_usbhs_disable(struct device *dev)
+/**
+ * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
+ * @pdev: USB Host Controller being removed
+ *
+ * Reverses the effect of usbhs_omap_probe().
+ */
+static int __devexit usbhs_omap_remove(struct platform_device *pdev)
 {
-	usbhs_disable(dev->parent);
+	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
+
+	omap_usbhs_deinit(&pdev->dev);
+	iounmap(omap->tll_base);
+	iounmap(omap->uhh_base);
+	clk_put(omap->init_60m_fclk);
+	clk_put(omap->usbtll_p2_fck);
+	clk_put(omap->usbhost_p2_fck);
+	clk_put(omap->usbtll_p1_fck);
+	clk_put(omap->usbhost_p1_fck);
+	clk_put(omap->xclk60mhsp2_ck);
+	clk_put(omap->utmi_p2_fck);
+	clk_put(omap->xclk60mhsp1_ck);
+	clk_put(omap->utmi_p1_fck);
+	pm_runtime_disable(&pdev->dev);
+	kfree(omap);
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_usbhs_disable);
+
+static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
+	.runtime_suspend	= usbhs_runtime_suspend,
+	.runtime_resume		= usbhs_runtime_resume,
+};
 
 static struct platform_driver usbhs_omap_driver = {
 	.driver = {
 		.name		= (char *)usbhs_driver_name,
 		.owner		= THIS_MODULE,
+		.pm		= &usbhsomap_dev_pm_ops,
 	},
 	.remove		= __exit_p(usbhs_omap_remove),
 };
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 55a57c2..178f63e 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -41,6 +41,7 @@
 #include <linux/usb/ulpi.h>
 #include <plat/usb.h>
 #include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
 
 /* EHCI Register Set */
 #define EHCI_INSNREG04					(0xA0)
@@ -178,11 +179,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 		}
 	}
 
-	ret = omap_usbhs_enable(dev);
-	if (ret) {
-		dev_err(dev, "failed to start usbhs with err %d\n", ret);
-		goto err_enable;
-	}
+	pm_runtime_get_sync(dev->parent);
 
 	/*
 	 * An undocumented "feature" in the OMAP3 EHCI controller,
@@ -228,10 +225,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 	return 0;
 
 err_add_hcd:
-	omap_usbhs_disable(dev);
-
-err_enable:
-	usb_put_hcd(hcd);
+	pm_runtime_put_sync(dev->parent);
 
 err_io:
 	return ret;
@@ -252,7 +246,7 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
 	struct usb_hcd *hcd	= dev_get_drvdata(dev);
 
 	usb_remove_hcd(hcd);
-	omap_usbhs_disable(dev);
+	pm_runtime_put_sync(dev->parent);
 	usb_put_hcd(hcd);
 	return 0;
 }
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 6048f2f..6ce50de 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -31,6 +31,7 @@
 
 #include <linux/platform_device.h>
 #include <plat/usb.h>
+#include <linux/pm_runtime.h>
 
 /*-------------------------------------------------------------------------*/
 
@@ -172,11 +173,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
 	hcd->rsrc_len = resource_size(res);
 	hcd->regs =  regs;
 
-	ret = omap_usbhs_enable(dev);
-	if (ret) {
-		dev_dbg(dev, "failed to start ohci\n");
-		goto err_end;
-	}
+	pm_runtime_get_sync(dev->parent);
 
 	ohci_hcd_init(hcd_to_ohci(hcd));
 
@@ -189,7 +186,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
 	return 0;
 
 err_add_hcd:
-	omap_usbhs_disable(dev);
+	pm_runtime_get_sync(dev->parent);
 
 err_end:
 	usb_put_hcd(hcd);
@@ -220,9 +217,8 @@ static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev)
 
 	iounmap(hcd->regs);
 	usb_remove_hcd(hcd);
-	omap_usbhs_disable(dev);
+	pm_runtime_put_sync(dev->parent);
 	usb_put_hcd(hcd);
-
 	return 0;
 }
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 5/6 v2] arm: omap: usb: Runtime PM support
@ 2011-07-01 18:54           ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The usbhs core driver does not enable/disable the intefrace and
fucntional clocks; These clocks are handled by hwmod and runtime pm,
hence insted of the clock enable/disable, the runtime pm APIS are
used. however,the port clocks and tll clocks are handled
by the usbhs core.
In this architecture, the usbhs is core driver and it is parent of
ehci and ohci drivers.The earlier APIs omap_usbhs_enable and
omap_usbhs_disable of usbhs core driver are removed;
The ehci and ohci drivers call the pm_runtime_get_sync and
pm_runtime_put_sync of parent device usbhs core.
In fact, the runtime framework takes care the get sync and
put sync of the child in turn call the get sync and put sync
of parent too; but calling get sync and put sync of parent is
by ASYNC mode; This mode queues the work item in runtime pm
work queue, which not getting scheduled in case of global suspend path.
so, here ehci and ohci runtim pm is not required, these
drivers will pass the parent usbhs dev pointer in runtime pm APIs.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 arch/arm/plat-omap/include/plat/usb.h |    3 -
 drivers/mfd/omap-usb-host.c           |  618 +++++++++++++++------------------
 drivers/usb/host/ehci-omap.c          |   14 +-
 drivers/usb/host/ohci-omap3.c         |   12 +-
 4 files changed, 290 insertions(+), 357 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 17d3c93..2b66dc2 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -100,9 +100,6 @@ extern void usb_musb_init(struct omap_musb_board_data *board_data);
 
 extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
 
-extern int omap_usbhs_enable(struct device *dev);
-extern void omap_usbhs_disable(struct device *dev);
-
 extern int omap4430_phy_power(struct device *dev, int ID, int on);
 extern int omap4430_phy_set_clk(struct device *dev, int on);
 extern int omap4430_phy_init(struct device *dev);
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 43de12a..521ee86 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -164,7 +164,6 @@ struct usbhs_hcd_omap {
 
 	u32				usbhs_rev;
 	spinlock_t			lock;
-	int				count;
 };
 /*-------------------------------------------------------------------------*/
 
@@ -314,218 +313,6 @@ err_end:
 	return ret;
 }
 
-/**
- * usbhs_omap_probe - initialize TI-based HCDs
- *
- * Allocates basic resources for this USB host controller.
- */
-static int __devinit usbhs_omap_probe(struct platform_device *pdev)
-{
-	struct device			*dev =  &pdev->dev;
-	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
-	struct usbhs_hcd_omap		*omap;
-	struct resource			*res;
-	int				ret = 0;
-	int				i;
-
-	if (!pdata) {
-		dev_err(dev, "Missing platform data\n");
-		ret = -ENOMEM;
-		goto end_probe;
-	}
-
-	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
-	if (!omap) {
-		dev_err(dev, "Memory allocation failed\n");
-		ret = -ENOMEM;
-		goto end_probe;
-	}
-
-	spin_lock_init(&omap->lock);
-
-	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
-		omap->platdata.port_mode[i] = pdata->port_mode[i];
-
-	omap->platdata.ehci_data = pdata->ehci_data;
-	omap->platdata.ohci_data = pdata->ohci_data;
-
-	pm_runtime_enable(&pdev->dev);
-
-	omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
-	if (IS_ERR(omap->utmi_p1_fck)) {
-		ret = PTR_ERR(omap->utmi_p1_fck);
-		dev_err(dev, "utmi_p1_gfclk failed error:%d\n",	ret);
-		goto err_end;
-	}
-
-	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
-	if (IS_ERR(omap->xclk60mhsp1_ck)) {
-		ret = PTR_ERR(omap->xclk60mhsp1_ck);
-		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
-		goto err_utmi_p1_fck;
-	}
-
-	omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
-	if (IS_ERR(omap->utmi_p2_fck)) {
-		ret = PTR_ERR(omap->utmi_p2_fck);
-		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
-		goto err_xclk60mhsp1_ck;
-	}
-
-	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
-	if (IS_ERR(omap->xclk60mhsp2_ck)) {
-		ret = PTR_ERR(omap->xclk60mhsp2_ck);
-		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
-		goto err_utmi_p2_fck;
-	}
-
-	omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
-	if (IS_ERR(omap->usbhost_p1_fck)) {
-		ret = PTR_ERR(omap->usbhost_p1_fck);
-		dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
-		goto err_xclk60mhsp2_ck;
-	}
-
-	omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
-	if (IS_ERR(omap->usbtll_p1_fck)) {
-		ret = PTR_ERR(omap->usbtll_p1_fck);
-		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
-		goto err_usbhost_p1_fck;
-	}
-
-	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
-	if (IS_ERR(omap->usbhost_p2_fck)) {
-		ret = PTR_ERR(omap->usbhost_p2_fck);
-		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
-		goto err_usbtll_p1_fck;
-	}
-
-	omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
-	if (IS_ERR(omap->usbtll_p2_fck)) {
-		ret = PTR_ERR(omap->usbtll_p2_fck);
-		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
-		goto err_usbhost_p2_fck;
-	}
-
-	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
-	if (IS_ERR(omap->init_60m_fclk)) {
-		ret = PTR_ERR(omap->init_60m_fclk);
-		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-		goto err_usbtll_p2_fck;
-	}
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
-	if (!res) {
-		dev_err(dev, "UHH EHCI get resource failed\n");
-		ret = -ENODEV;
-		goto err_init_60m_fclk;
-	}
-
-	omap->uhh_base = ioremap(res->start, resource_size(res));
-	if (!omap->uhh_base) {
-		dev_err(dev, "UHH ioremap failed\n");
-		ret = -ENOMEM;
-		goto err_init_60m_fclk;
-	}
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
-	if (!res) {
-		dev_err(dev, "UHH EHCI get resource failed\n");
-		ret = -ENODEV;
-		goto err_tll;
-	}
-
-	omap->tll_base = ioremap(res->start, resource_size(res));
-	if (!omap->tll_base) {
-		dev_err(dev, "TLL ioremap failed\n");
-		ret = -ENOMEM;
-		goto err_tll;
-	}
-
-	platform_set_drvdata(pdev, omap);
-
-	ret = omap_usbhs_alloc_children(pdev);
-	if (ret) {
-		dev_err(dev, "omap_usbhs_alloc_children failed\n");
-		goto err_alloc;
-	}
-
-	goto end_probe;
-
-err_alloc:
-	iounmap(omap->tll_base);
-
-err_tll:
-	iounmap(omap->uhh_base);
-
-err_init_60m_fclk:
-	clk_put(omap->init_60m_fclk);
-
-err_usbtll_p2_fck:
-	clk_put(omap->usbtll_p2_fck);
-
-err_usbhost_p2_fck:
-	clk_put(omap->usbhost_p2_fck);
-
-err_usbtll_p1_fck:
-	clk_put(omap->usbtll_p1_fck);
-
-err_usbhost_p1_fck:
-	clk_put(omap->usbhost_p1_fck);
-
-err_xclk60mhsp2_ck:
-	clk_put(omap->xclk60mhsp2_ck);
-
-err_utmi_p2_fck:
-	clk_put(omap->utmi_p2_fck);
-
-err_xclk60mhsp1_ck:
-	clk_put(omap->xclk60mhsp1_ck);
-
-err_utmi_p1_fck:
-	clk_put(omap->utmi_p1_fck);
-
-err_end:
-	pm_runtime_disable(&pdev->dev);
-	kfree(omap);
-
-end_probe:
-	return ret;
-}
-
-/**
- * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
- * @pdev: USB Host Controller being removed
- *
- * Reverses the effect of usbhs_omap_probe().
- */
-static int __devexit usbhs_omap_remove(struct platform_device *pdev)
-{
-	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
-
-	if (omap->count != 0) {
-		dev_err(&pdev->dev,
-			"Either EHCI or OHCI is still using usbhs core\n");
-		return -EBUSY;
-	}
-
-	iounmap(omap->tll_base);
-	iounmap(omap->uhh_base);
-	clk_put(omap->init_60m_fclk);
-	clk_put(omap->usbtll_p2_fck);
-	clk_put(omap->usbhost_p2_fck);
-	clk_put(omap->usbtll_p1_fck);
-	clk_put(omap->usbhost_p1_fck);
-	clk_put(omap->xclk60mhsp2_ck);
-	clk_put(omap->utmi_p2_fck);
-	clk_put(omap->xclk60mhsp1_ck);
-	clk_put(omap->utmi_p1_fck);
-	pm_runtime_disable(&pdev->dev);
-	kfree(omap);
-
-	return 0;
-}
-
 static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
 {
 	switch (pmode) {
@@ -634,26 +421,73 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
 	}
 }
 
-static int usbhs_enable(struct device *dev)
+static int usbhs_runtime_resume(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
 	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
-	unsigned long			flags = 0;
-	int				ret = 0;
-	unsigned			reg;
 
-	dev_dbg(dev, "starting TI HSUSB Controller\n");
+	dev_dbg(dev, "usbhs_runtime_resume\n");
+
 	if (!pdata) {
 		dev_dbg(dev, "missing platform_data\n");
 		return  -ENODEV;
 	}
 
-	spin_lock_irqsave(&omap->lock, flags);
-	if (omap->count > 0)
-		goto end_count;
+	if (is_omap_usbhs_rev2(omap)) {
+		if (is_ehci_tll_mode(pdata->port_mode[0])) {
+			clk_enable(omap->usbhost_p1_fck);
+			clk_enable(omap->usbtll_p1_fck);
+		}
+		if (is_ehci_tll_mode(pdata->port_mode[1])) {
+			clk_enable(omap->usbhost_p2_fck);
+			clk_enable(omap->usbtll_p2_fck);
+		}
+		clk_enable(omap->utmi_p1_fck);
+		clk_enable(omap->utmi_p2_fck);
+	}
+	return 0;
+}
+
+static int usbhs_runtime_suspend(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+
+	dev_dbg(dev, "usbhs_runtime_suspend\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	if (is_omap_usbhs_rev2(omap)) {
+		if (is_ehci_tll_mode(pdata->port_mode[0])) {
+			clk_disable(omap->usbhost_p1_fck);
+			clk_disable(omap->usbtll_p1_fck);
+		}
+		if (is_ehci_tll_mode(pdata->port_mode[1])) {
+			clk_disable(omap->usbhost_p2_fck);
+			clk_disable(omap->usbtll_p2_fck);
+		}
+		clk_disable(omap->utmi_p2_fck);
+		clk_disable(omap->utmi_p1_fck);
+	}
+	return 0;
+}
+
+static void omap_usbhs_init(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+	unsigned long			flags = 0;
+	unsigned			reg;
+
+	dev_dbg(dev, "starting TI HSUSB Controller\n");
 
 	pm_runtime_get_sync(dev);
 
+	spin_lock_irqsave(&omap->lock, flags);
+
 	if (pdata->ehci_data->phy_reset) {
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
 			gpio_request(pdata->ehci_data->reset_gpio_port[0],
@@ -676,6 +510,14 @@ static int usbhs_enable(struct device *dev)
 	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
 	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 
+	/*
+	 * Really enable the port clocks
+	 * first call of pm_runtime_get_sync does not enable these
+	 * port clocks; because omap->usbhs_rev was aviable
+	 * This omap->usbhs_rev is aviable now!
+	 */
+	usbhs_runtime_resume(dev);
+
 	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
 	/* setup ULPI bypass and burst configurations */
 	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
@@ -721,49 +563,6 @@ static int usbhs_enable(struct device *dev)
 		reg &= ~OMAP4_P1_MODE_CLEAR;
 		reg &= ~OMAP4_P2_MODE_CLEAR;
 
-		if (is_ehci_phy_mode(pdata->port_mode[0])) {
-			ret = clk_set_parent(omap->utmi_p1_fck,
-						omap->xclk60mhsp1_ck);
-			if (ret != 0) {
-				dev_err(dev, "xclk60mhsp1_ck set parent"
-				"failed error:%d\n", ret);
-				goto err_tll;
-			}
-		} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
-			ret = clk_set_parent(omap->utmi_p1_fck,
-						omap->init_60m_fclk);
-			if (ret != 0) {
-				dev_err(dev, "init_60m_fclk set parent"
-				"failed error:%d\n", ret);
-				goto err_tll;
-			}
-			clk_enable(omap->usbhost_p1_fck);
-			clk_enable(omap->usbtll_p1_fck);
-		}
-
-		if (is_ehci_phy_mode(pdata->port_mode[1])) {
-			ret = clk_set_parent(omap->utmi_p2_fck,
-						omap->xclk60mhsp2_ck);
-			if (ret != 0) {
-				dev_err(dev, "xclk60mhsp1_ck set parent"
-					"failed error:%d\n", ret);
-				goto err_tll;
-			}
-		} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
-			ret = clk_set_parent(omap->utmi_p2_fck,
-						omap->init_60m_fclk);
-			if (ret != 0) {
-				dev_err(dev, "init_60m_fclk set parent"
-				"failed error:%d\n", ret);
-				goto err_tll;
-			}
-			clk_enable(omap->usbhost_p2_fck);
-			clk_enable(omap->usbtll_p2_fck);
-		}
-
-		clk_enable(omap->utmi_p1_fck);
-		clk_enable(omap->utmi_p2_fck);
-
 		if (is_ehci_tll_mode(pdata->port_mode[0]) ||
 			(is_ohci_port(pdata->port_mode[0])))
 			reg |= OMAP4_P1_MODE_TLL;
@@ -809,14 +608,17 @@ static int usbhs_enable(struct device *dev)
 				(pdata->ehci_data->reset_gpio_port[1], 1);
 	}
 
-end_count:
-	omap->count++;
 	spin_unlock_irqrestore(&omap->lock, flags);
-	return 0;
-
-err_tll:
 	pm_runtime_put_sync(dev);
-	spin_unlock_irqrestore(&omap->lock, flags);
+}
+
+static void omap_usbhs_deinit(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+
+	dev_dbg(dev, "stopping TI HSUSB Controller\n");
+
 	if (pdata->ehci_data->phy_reset) {
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
 			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
@@ -824,112 +626,256 @@ err_tll:
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
 			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
 	}
-	return ret;
 }
 
-static void usbhs_disable(struct device *dev)
+/**
+ * usbhs_omap_probe - initialize TI-based HCDs
+ *
+ * Allocates basic resources for this USB host controller.
+ */
+static int __devinit usbhs_omap_probe(struct platform_device *pdev)
 {
-	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
-	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
-	unsigned long			flags = 0;
-	unsigned long			timeout;
+	struct device			*dev =  &pdev->dev;
+	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
+	struct usbhs_hcd_omap		*omap;
+	struct resource			*res;
+	int				ret = 0;
+	int				i;
 
-	dev_dbg(dev, "stopping TI HSUSB Controller\n");
+	if (!pdata) {
+		dev_err(dev, "Missing platform data\n");
+		ret = -ENOMEM;
+		goto end_probe;
+	}
 
-	spin_lock_irqsave(&omap->lock, flags);
+	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		dev_err(dev, "Memory allocation failed\n");
+		ret = -ENOMEM;
+		goto end_probe;
+	}
 
-	if (omap->count == 0)
-		goto end_disble;
+	spin_lock_init(&omap->lock);
 
-	omap->count--;
+	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
+		omap->platdata.port_mode[i] = pdata->port_mode[i];
 
-	if (omap->count != 0)
-		goto end_disble;
+	omap->platdata.ehci_data = pdata->ehci_data;
+	omap->platdata.ohci_data = pdata->ohci_data;
 
-	/* Reset OMAP modules for insmod/rmmod to work */
-	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
-			is_omap_usbhs_rev2(omap) ?
-			OMAP4_UHH_SYSCONFIG_SOFTRESET :
-			OMAP_UHH_SYSCONFIG_SOFTRESET);
+	pm_runtime_enable(dev);
 
-	timeout = jiffies + msecs_to_jiffies(100);
-	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
-				& (1 << 0))) {
-		cpu_relax();
+	omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
+	if (IS_ERR(omap->utmi_p1_fck)) {
+		ret = PTR_ERR(omap->utmi_p1_fck);
+		dev_err(dev, "utmi_p1_gfclk failed error:%d\n",	ret);
+		goto err_end;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
+	if (IS_ERR(omap->xclk60mhsp1_ck)) {
+		ret = PTR_ERR(omap->xclk60mhsp1_ck);
+		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
+		goto err_utmi_p1_fck;
 	}
 
-	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
-				& (1 << 1))) {
-		cpu_relax();
+	omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
+	if (IS_ERR(omap->utmi_p2_fck)) {
+		ret = PTR_ERR(omap->utmi_p2_fck);
+		dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
+		goto err_xclk60mhsp1_ck;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
+	if (IS_ERR(omap->xclk60mhsp2_ck)) {
+		ret = PTR_ERR(omap->xclk60mhsp2_ck);
+		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
+		goto err_utmi_p2_fck;
 	}
 
-	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
-				& (1 << 2))) {
-		cpu_relax();
+	omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
+	if (IS_ERR(omap->usbhost_p1_fck)) {
+		ret = PTR_ERR(omap->usbhost_p1_fck);
+		dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
+		goto err_xclk60mhsp2_ck;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
+	if (IS_ERR(omap->usbtll_p1_fck)) {
+		ret = PTR_ERR(omap->usbtll_p1_fck);
+		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
+		goto err_usbhost_p1_fck;
 	}
 
-	usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
+	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
+	if (IS_ERR(omap->usbhost_p2_fck)) {
+		ret = PTR_ERR(omap->usbhost_p2_fck);
+		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
+		goto err_usbtll_p1_fck;
+	}
 
-	while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
-				& (1 << 0))) {
-		cpu_relax();
+	omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
+	if (IS_ERR(omap->usbtll_p2_fck)) {
+		ret = PTR_ERR(omap->usbtll_p2_fck);
+		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
+		goto err_usbhost_p2_fck;
+	}
 
-		if (time_after(jiffies, timeout))
-			dev_dbg(dev, "operation timed out\n");
+	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
+	if (IS_ERR(omap->init_60m_fclk)) {
+		ret = PTR_ERR(omap->init_60m_fclk);
+		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
+		goto err_usbtll_p2_fck;
 	}
 
-	if (is_omap_usbhs_rev2(omap)) {
-		if (is_ehci_tll_mode(pdata->port_mode[0]))
-			clk_enable(omap->usbtll_p1_fck);
-		if (is_ehci_tll_mode(pdata->port_mode[1]))
-			clk_enable(omap->usbtll_p2_fck);
-		clk_disable(omap->utmi_p2_fck);
-		clk_disable(omap->utmi_p1_fck);
+	if (is_ehci_phy_mode(pdata->port_mode[0])) {
+		/* for OMAP3 , the clk set paretn fails */
+		ret = clk_set_parent(omap->utmi_p1_fck,
+					omap->xclk60mhsp1_ck);
+		if (ret != 0)
+			dev_err(dev, "xclk60mhsp1_ck set parent"
+				"failed error:%d\n", ret);
+	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
+		ret = clk_set_parent(omap->utmi_p1_fck,
+					omap->init_60m_fclk);
+		if (ret != 0)
+			dev_err(dev, "init_60m_fclk set parent"
+				"failed error:%d\n", ret);
 	}
 
-	pm_runtime_put_sync(dev);
+	if (is_ehci_phy_mode(pdata->port_mode[1])) {
+		ret = clk_set_parent(omap->utmi_p2_fck,
+					omap->xclk60mhsp2_ck);
+		if (ret != 0)
+			dev_err(dev, "xclk60mhsp2_ck set parent"
+					"failed error:%d\n", ret);
+	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
+		ret = clk_set_parent(omap->utmi_p2_fck,
+						omap->init_60m_fclk);
+		if (ret != 0)
+			dev_err(dev, "init_60m_fclk set parent"
+				"failed error:%d\n", ret);
+	}
 
-	/* The gpio_free migh sleep; so unlock the spinlock */
-	spin_unlock_irqrestore(&omap->lock, flags);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
+	if (!res) {
+		dev_err(dev, "UHH EHCI get resource failed\n");
+		ret = -ENODEV;
+		goto err_init_60m_fclk;
+	}
 
-	if (pdata->ehci_data->phy_reset) {
-		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
+	omap->uhh_base = ioremap(res->start, resource_size(res));
+	if (!omap->uhh_base) {
+		dev_err(dev, "UHH ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_init_60m_fclk;
+	}
 
-		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
+	if (!res) {
+		dev_err(dev, "UHH EHCI get resource failed\n");
+		ret = -ENODEV;
+		goto err_tll;
 	}
-	return;
 
-end_disble:
-	spin_unlock_irqrestore(&omap->lock, flags);
-}
+	omap->tll_base = ioremap(res->start, resource_size(res));
+	if (!omap->tll_base) {
+		dev_err(dev, "TLL ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_tll;
+	}
 
-int omap_usbhs_enable(struct device *dev)
-{
-	return  usbhs_enable(dev->parent);
+	platform_set_drvdata(pdev, omap);
+
+	ret = omap_usbhs_alloc_children(pdev);
+	if (ret) {
+		dev_err(dev, "omap_usbhs_alloc_children failed\n");
+		goto err_alloc;
+	}
+
+	omap_usbhs_init(dev);
+
+	goto end_probe;
+
+err_alloc:
+	iounmap(omap->tll_base);
+
+err_tll:
+	iounmap(omap->uhh_base);
+
+err_init_60m_fclk:
+	clk_put(omap->init_60m_fclk);
+
+err_usbtll_p2_fck:
+	clk_put(omap->usbtll_p2_fck);
+
+err_usbhost_p2_fck:
+	clk_put(omap->usbhost_p2_fck);
+
+err_usbtll_p1_fck:
+	clk_put(omap->usbtll_p1_fck);
+
+err_usbhost_p1_fck:
+	clk_put(omap->usbhost_p1_fck);
+
+err_xclk60mhsp2_ck:
+	clk_put(omap->xclk60mhsp2_ck);
+
+err_utmi_p2_fck:
+	clk_put(omap->utmi_p2_fck);
+
+err_xclk60mhsp1_ck:
+	clk_put(omap->xclk60mhsp1_ck);
+
+err_utmi_p1_fck:
+	clk_put(omap->utmi_p1_fck);
+
+err_end:
+	pm_runtime_disable(dev);
+	kfree(omap);
+
+end_probe:
+	return ret;
 }
-EXPORT_SYMBOL_GPL(omap_usbhs_enable);
 
-void omap_usbhs_disable(struct device *dev)
+/**
+ * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
+ * @pdev: USB Host Controller being removed
+ *
+ * Reverses the effect of usbhs_omap_probe().
+ */
+static int __devexit usbhs_omap_remove(struct platform_device *pdev)
 {
-	usbhs_disable(dev->parent);
+	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
+
+	omap_usbhs_deinit(&pdev->dev);
+	iounmap(omap->tll_base);
+	iounmap(omap->uhh_base);
+	clk_put(omap->init_60m_fclk);
+	clk_put(omap->usbtll_p2_fck);
+	clk_put(omap->usbhost_p2_fck);
+	clk_put(omap->usbtll_p1_fck);
+	clk_put(omap->usbhost_p1_fck);
+	clk_put(omap->xclk60mhsp2_ck);
+	clk_put(omap->utmi_p2_fck);
+	clk_put(omap->xclk60mhsp1_ck);
+	clk_put(omap->utmi_p1_fck);
+	pm_runtime_disable(&pdev->dev);
+	kfree(omap);
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_usbhs_disable);
+
+static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
+	.runtime_suspend	= usbhs_runtime_suspend,
+	.runtime_resume		= usbhs_runtime_resume,
+};
 
 static struct platform_driver usbhs_omap_driver = {
 	.driver = {
 		.name		= (char *)usbhs_driver_name,
 		.owner		= THIS_MODULE,
+		.pm		= &usbhsomap_dev_pm_ops,
 	},
 	.remove		= __exit_p(usbhs_omap_remove),
 };
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 55a57c2..178f63e 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -41,6 +41,7 @@
 #include <linux/usb/ulpi.h>
 #include <plat/usb.h>
 #include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
 
 /* EHCI Register Set */
 #define EHCI_INSNREG04					(0xA0)
@@ -178,11 +179,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 		}
 	}
 
-	ret = omap_usbhs_enable(dev);
-	if (ret) {
-		dev_err(dev, "failed to start usbhs with err %d\n", ret);
-		goto err_enable;
-	}
+	pm_runtime_get_sync(dev->parent);
 
 	/*
 	 * An undocumented "feature" in the OMAP3 EHCI controller,
@@ -228,10 +225,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 	return 0;
 
 err_add_hcd:
-	omap_usbhs_disable(dev);
-
-err_enable:
-	usb_put_hcd(hcd);
+	pm_runtime_put_sync(dev->parent);
 
 err_io:
 	return ret;
@@ -252,7 +246,7 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
 	struct usb_hcd *hcd	= dev_get_drvdata(dev);
 
 	usb_remove_hcd(hcd);
-	omap_usbhs_disable(dev);
+	pm_runtime_put_sync(dev->parent);
 	usb_put_hcd(hcd);
 	return 0;
 }
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 6048f2f..6ce50de 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -31,6 +31,7 @@
 
 #include <linux/platform_device.h>
 #include <plat/usb.h>
+#include <linux/pm_runtime.h>
 
 /*-------------------------------------------------------------------------*/
 
@@ -172,11 +173,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
 	hcd->rsrc_len = resource_size(res);
 	hcd->regs =  regs;
 
-	ret = omap_usbhs_enable(dev);
-	if (ret) {
-		dev_dbg(dev, "failed to start ohci\n");
-		goto err_end;
-	}
+	pm_runtime_get_sync(dev->parent);
 
 	ohci_hcd_init(hcd_to_ohci(hcd));
 
@@ -189,7 +186,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
 	return 0;
 
 err_add_hcd:
-	omap_usbhs_disable(dev);
+	pm_runtime_get_sync(dev->parent);
 
 err_end:
 	usb_put_hcd(hcd);
@@ -220,9 +217,8 @@ static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev)
 
 	iounmap(hcd->regs);
 	usb_remove_hcd(hcd);
-	omap_usbhs_disable(dev);
+	pm_runtime_put_sync(dev->parent);
 	usb_put_hcd(hcd);
-
 	return 0;
 }
 
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-01 18:54             ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, johnstul, vishwanath.bs, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The global suspend and resume functions for ehci and ohci
drivers are implemented; these functions does the
pm_runtime_get_sync and pm_runtime_put_sync of the
parent device usbhs core driver respectively.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
 drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 178f63e..a02a684 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct platform_device *pdev)
 		hcd->driver->shutdown(hcd);
 }
 
+static int omap_ehci_resume(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_get_sync(dev->parent);
+	return 0;
+}
+
+static int omap_ehci_suspend(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_put_sync(dev->parent);
+	return 0;
+}
+
+static const struct dev_pm_ops omap_ehci_dev_pm_ops = {
+	.suspend	= omap_ehci_suspend,
+	.resume		= omap_ehci_resume,
+};
+
 static struct platform_driver ehci_hcd_omap_driver = {
 	.probe			= ehci_hcd_omap_probe,
 	.remove			= ehci_hcd_omap_remove,
 	.shutdown		= ehci_hcd_omap_shutdown,
-	/*.suspend		= ehci_hcd_omap_suspend, */
-	/*.resume		= ehci_hcd_omap_resume, */
 	.driver = {
 		.name		= "ehci-omap",
+		.pm		= &omap_ehci_dev_pm_ops,
 	}
 };
 
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 6ce50de..a1a7981 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -230,12 +230,33 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev)
 		hcd->driver->shutdown(hcd);
 }
 
+
+static int omap_ohci_resume(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_get_sync(dev->parent);
+	return 0;
+}
+
+static int omap_ohci_suspend(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_put_sync(dev->parent);
+	return 0;
+}
+
+static const struct dev_pm_ops omap_ohci_dev_pm_ops = {
+	.suspend	= omap_ohci_suspend,
+	.resume		= omap_ohci_resume,
+};
+
 static struct platform_driver ohci_hcd_omap3_driver = {
 	.probe		= ohci_hcd_omap3_probe,
 	.remove		= __devexit_p(ohci_hcd_omap3_remove),
 	.shutdown	= ohci_hcd_omap3_shutdown,
 	.driver		= {
 		.name	= "ohci-omap3",
+		.pm		= &omap_ohci_dev_pm_ops,
 	},
 };
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-01 18:54             ` Keshava Munegowda
  0 siblings, 0 replies; 49+ messages in thread
From: Keshava Munegowda @ 2011-07-01 18:54 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Keshava Munegowda, balbi-l0cyMroinI0, gadiyar-l0cyMroinI0,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, khilman-l0cyMroinI0,
	b-cousson-l0cyMroinI0, paul-DWxLp4Yu+b8AvxtiuMwx3w,
	johnstul-r/Jw6+rmf7HQT0dZR+AlfA, vishwanath.bs-l0cyMroinI0,
	Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>

The global suspend and resume functions for ehci and ohci
drivers are implemented; these functions does the
pm_runtime_get_sync and pm_runtime_put_sync of the
parent device usbhs core driver respectively.

Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
---
 drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
 drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 178f63e..a02a684 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct platform_device *pdev)
 		hcd->driver->shutdown(hcd);
 }
 
+static int omap_ehci_resume(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_get_sync(dev->parent);
+	return 0;
+}
+
+static int omap_ehci_suspend(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_put_sync(dev->parent);
+	return 0;
+}
+
+static const struct dev_pm_ops omap_ehci_dev_pm_ops = {
+	.suspend	= omap_ehci_suspend,
+	.resume		= omap_ehci_resume,
+};
+
 static struct platform_driver ehci_hcd_omap_driver = {
 	.probe			= ehci_hcd_omap_probe,
 	.remove			= ehci_hcd_omap_remove,
 	.shutdown		= ehci_hcd_omap_shutdown,
-	/*.suspend		= ehci_hcd_omap_suspend, */
-	/*.resume		= ehci_hcd_omap_resume, */
 	.driver = {
 		.name		= "ehci-omap",
+		.pm		= &omap_ehci_dev_pm_ops,
 	}
 };
 
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 6ce50de..a1a7981 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -230,12 +230,33 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev)
 		hcd->driver->shutdown(hcd);
 }
 
+
+static int omap_ohci_resume(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_get_sync(dev->parent);
+	return 0;
+}
+
+static int omap_ohci_suspend(struct device *dev)
+{
+	if (dev->parent)
+		pm_runtime_put_sync(dev->parent);
+	return 0;
+}
+
+static const struct dev_pm_ops omap_ohci_dev_pm_ops = {
+	.suspend	= omap_ohci_suspend,
+	.resume		= omap_ohci_resume,
+};
+
 static struct platform_driver ohci_hcd_omap3_driver = {
 	.probe		= ohci_hcd_omap3_probe,
 	.remove		= __devexit_p(ohci_hcd_omap3_remove),
 	.shutdown	= ohci_hcd_omap3_shutdown,
 	.driver		= {
 		.name	= "ohci-omap3",
+		.pm		= &omap_ohci_dev_pm_ops,
 	},
 };
 
-- 
1.6.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-01 18:54             ` Keshava Munegowda
@ 2011-07-01 19:06               ` Alan Stern
  -1 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-01 19:06 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, khilman, b-cousson, paul, johnstul, vishwanath.bs

On Sat, 2 Jul 2011, Keshava Munegowda wrote:

> From: Keshava Munegowda <Keshava_mgowda@ti.com>
> 
> The global suspend and resume functions for ehci and ohci
> drivers are implemented; these functions does the
> pm_runtime_get_sync and pm_runtime_put_sync of the
> parent device usbhs core driver respectively.
> 
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
> ---
>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
>  2 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
> index 178f63e..a02a684 100644
> --- a/drivers/usb/host/ehci-omap.c
> +++ b/drivers/usb/host/ehci-omap.c
> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct platform_device *pdev)
>  		hcd->driver->shutdown(hcd);
>  }
>  
> +static int omap_ehci_resume(struct device *dev)
> +{
> +	if (dev->parent)
> +		pm_runtime_get_sync(dev->parent);
> +	return 0;
> +}
> +
> +static int omap_ehci_suspend(struct device *dev)
> +{
> +	if (dev->parent)
> +		pm_runtime_put_sync(dev->parent);
> +	return 0;
> +}

I don't see any point in these routines (and likewise for
omap_ohci_suspend/resume).  When the whole system is going to sleep
anyway, what reason is there for enabling runtime PM on the parent
device?

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-01 19:06               ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-01 19:06 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, khilman, b-cousson, paul, johnstul, vishwanath.bs

On Sat, 2 Jul 2011, Keshava Munegowda wrote:

> From: Keshava Munegowda <Keshava_mgowda@ti.com>
> 
> The global suspend and resume functions for ehci and ohci
> drivers are implemented; these functions does the
> pm_runtime_get_sync and pm_runtime_put_sync of the
> parent device usbhs core driver respectively.
> 
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
> ---
>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
>  2 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
> index 178f63e..a02a684 100644
> --- a/drivers/usb/host/ehci-omap.c
> +++ b/drivers/usb/host/ehci-omap.c
> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct platform_device *pdev)
>  		hcd->driver->shutdown(hcd);
>  }
>  
> +static int omap_ehci_resume(struct device *dev)
> +{
> +	if (dev->parent)
> +		pm_runtime_get_sync(dev->parent);
> +	return 0;
> +}
> +
> +static int omap_ehci_suspend(struct device *dev)
> +{
> +	if (dev->parent)
> +		pm_runtime_put_sync(dev->parent);
> +	return 0;
> +}

I don't see any point in these routines (and likewise for
omap_ohci_suspend/resume).  When the whole system is going to sleep
anyway, what reason is there for enabling runtime PM on the parent
device?

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04  5:06                 ` Partha Basak
  0 siblings, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-04  5:06 UTC (permalink / raw)
  To: Alan Stern, Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, Felipe Balbi, Anand Gadiyar,
	sameo, parthab, tony, Kevin Hilman, Benoit Cousson, paul,
	johnstul, Vishwanath Sripathy

>-----Original Message-----
>From: Alan Stern [mailto:stern@rowland.harvard.edu]
>Sent: Saturday, July 02, 2011 12:37 AM
>To: Keshava Munegowda
>Cc: linux-usb@vger.kernel.org; linux-omap@vger.kernel.org; linux-
>kernel@vger.kernel.org; balbi@ti.com; gadiyar@ti.com;
>sameo@linux.intel.com; parthab@india.ti.com; tony@atomide.com;
>khilman@ti.com; b-cousson@ti.com; paul@pwsan.com; johnstul@us.ibm.com;
>vishwanath.bs@ti.com
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>On Sat, 2 Jul 2011, Keshava Munegowda wrote:
>
>> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>>
>> The global suspend and resume functions for ehci and ohci
>> drivers are implemented; these functions does the
>> pm_runtime_get_sync and pm_runtime_put_sync of the
>> parent device usbhs core driver respectively.
>>
>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>> ---
>>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
>>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
>>  2 files changed, 41 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-
>omap.c
>> index 178f63e..a02a684 100644
>> --- a/drivers/usb/host/ehci-omap.c
>> +++ b/drivers/usb/host/ehci-omap.c
>> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct
>platform_device *pdev)
>>  		hcd->driver->shutdown(hcd);
>>  }
>>
>> +static int omap_ehci_resume(struct device *dev)
>> +{
>> +	if (dev->parent)
>> +		pm_runtime_get_sync(dev->parent);
>> +	return 0;
>> +}
>> +
>> +static int omap_ehci_suspend(struct device *dev)
>> +{
>> +	if (dev->parent)
>> +		pm_runtime_put_sync(dev->parent);
>> +	return 0;
>> +}
>
>I don't see any point in these routines (and likewise for
>omap_ohci_suspend/resume).  When the whole system is going to sleep
>anyway, what reason is there for enabling runtime PM on the parent
>device?

Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).

Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
will turn-off the parent clocks in the Suspend path.

Similarly, calling pm_runtime_get_sync(dev->parent) within
omap_ehci_resume
will turn-on the parent clocks in the resume path.

This way, all reference counting are implicit within the Runtime PM layer
and takes care of all combinations of only EHCI insmoded, OHCI insmoded,
both insmoded etc.

When both EHCI & OHCI are suspended, parent clocks will actually be
turned OFF and vice-versa.

Note that the parent per-se does not have any .suspend & .resume hooked
up.
At the end of the _probe of parent, the clocks are turned OFF.
Subsequently, enabling
the parent clocks are entirely done implicitly by the children get_sync()
in their _probe.

Therefore while .suspend/.resume of children are called they call back
into the parent to turn-off the clocks.

FYI, Keshava is out of office due to some emergency this week,
there will be some delays in replying from his side.

>
>Alan Stern

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04  5:06                 ` Partha Basak
  0 siblings, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-04  5:06 UTC (permalink / raw)
  To: Alan Stern, Keshava Munegowda
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Felipe Balbi, Anand Gadiyar,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, Kevin Hilman, Benoit Cousson,
	paul-DWxLp4Yu+b8AvxtiuMwx3w, johnstul-r/Jw6+rmf7HQT0dZR+AlfA,
	Vishwanath Sripathy

>-----Original Message-----
>From: Alan Stern [mailto:stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org]
>Sent: Saturday, July 02, 2011 12:37 AM
>To: Keshava Munegowda
>Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-
>kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; balbi-l0cyMroinI0@public.gmane.org; gadiyar-l0cyMroinI0@public.gmane.org;
>sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org; parthab-PpE0FKYn9XJWk0Htik3J/w@public.gmane.org; tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org;
>khilman-l0cyMroinI0@public.gmane.org; b-cousson-l0cyMroinI0@public.gmane.org; paul-DWxLp4Yu+b8AvxtiuMwx3w@public.gmane.org; johnstul-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org;
>vishwanath.bs-l0cyMroinI0@public.gmane.org
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>On Sat, 2 Jul 2011, Keshava Munegowda wrote:
>
>> From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>
>> The global suspend and resume functions for ehci and ohci
>> drivers are implemented; these functions does the
>> pm_runtime_get_sync and pm_runtime_put_sync of the
>> parent device usbhs core driver respectively.
>>
>> Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
>> ---
>>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
>>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
>>  2 files changed, 41 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-
>omap.c
>> index 178f63e..a02a684 100644
>> --- a/drivers/usb/host/ehci-omap.c
>> +++ b/drivers/usb/host/ehci-omap.c
>> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct
>platform_device *pdev)
>>  		hcd->driver->shutdown(hcd);
>>  }
>>
>> +static int omap_ehci_resume(struct device *dev)
>> +{
>> +	if (dev->parent)
>> +		pm_runtime_get_sync(dev->parent);
>> +	return 0;
>> +}
>> +
>> +static int omap_ehci_suspend(struct device *dev)
>> +{
>> +	if (dev->parent)
>> +		pm_runtime_put_sync(dev->parent);
>> +	return 0;
>> +}
>
>I don't see any point in these routines (and likewise for
>omap_ohci_suspend/resume).  When the whole system is going to sleep
>anyway, what reason is there for enabling runtime PM on the parent
>device?

Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).

Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
will turn-off the parent clocks in the Suspend path.

Similarly, calling pm_runtime_get_sync(dev->parent) within
omap_ehci_resume
will turn-on the parent clocks in the resume path.

This way, all reference counting are implicit within the Runtime PM layer
and takes care of all combinations of only EHCI insmoded, OHCI insmoded,
both insmoded etc.

When both EHCI & OHCI are suspended, parent clocks will actually be
turned OFF and vice-versa.

Note that the parent per-se does not have any .suspend & .resume hooked
up.
At the end of the _probe of parent, the clocks are turned OFF.
Subsequently, enabling
the parent clocks are entirely done implicitly by the children get_sync()
in their _probe.

Therefore while .suspend/.resume of children are called they call back
into the parent to turn-off the clocks.

FYI, Keshava is out of office due to some emergency this week,
there will be some delays in replying from his side.

>
>Alan Stern
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04  8:25                   ` Felipe Balbi
  0 siblings, 0 replies; 49+ messages in thread
From: Felipe Balbi @ 2011-07-04  8:25 UTC (permalink / raw)
  To: Partha Basak
  Cc: Alan Stern, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Felipe Balbi, Anand Gadiyar, sameo, parthab, tony,
	Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 3049 bytes --]

Hi,

On Mon, Jul 04, 2011 at 10:36:54AM +0530, Partha Basak wrote:
> >-----Original Message-----
> >From: Alan Stern [mailto:stern@rowland.harvard.edu]
> >Sent: Saturday, July 02, 2011 12:37 AM
> >To: Keshava Munegowda
> >Cc: linux-usb@vger.kernel.org; linux-omap@vger.kernel.org; linux-
> >kernel@vger.kernel.org; balbi@ti.com; gadiyar@ti.com;
> >sameo@linux.intel.com; parthab@india.ti.com; tony@atomide.com;
> >khilman@ti.com; b-cousson@ti.com; paul@pwsan.com; johnstul@us.ibm.com;
> >vishwanath.bs@ti.com
> >Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
> >support of ehci and ohci
> >
> >On Sat, 2 Jul 2011, Keshava Munegowda wrote:
> >
> >> From: Keshava Munegowda <Keshava_mgowda@ti.com>
> >>
> >> The global suspend and resume functions for ehci and ohci
> >> drivers are implemented; these functions does the
> >> pm_runtime_get_sync and pm_runtime_put_sync of the
> >> parent device usbhs core driver respectively.
> >>
> >> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
> >> ---
> >>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
> >>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
> >>  2 files changed, 41 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-
> >omap.c
> >> index 178f63e..a02a684 100644
> >> --- a/drivers/usb/host/ehci-omap.c
> >> +++ b/drivers/usb/host/ehci-omap.c
> >> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct
> >platform_device *pdev)
> >>  		hcd->driver->shutdown(hcd);
> >>  }
> >>
> >> +static int omap_ehci_resume(struct device *dev)
> >> +{
> >> +	if (dev->parent)
> >> +		pm_runtime_get_sync(dev->parent);
> >> +	return 0;
> >> +}
> >> +
> >> +static int omap_ehci_suspend(struct device *dev)
> >> +{
> >> +	if (dev->parent)
> >> +		pm_runtime_put_sync(dev->parent);
> >> +	return 0;
> >> +}
> >
> >I don't see any point in these routines (and likewise for
> >omap_ohci_suspend/resume).  When the whole system is going to sleep
> >anyway, what reason is there for enabling runtime PM on the parent
> >device?
> 
> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
> 
> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
> will turn-off the parent clocks in the Suspend path.
> 
> Similarly, calling pm_runtime_get_sync(dev->parent) within
> omap_ehci_resume
> will turn-on the parent clocks in the resume path.
> 
> This way, all reference counting are implicit within the Runtime PM layer
> and takes care of all combinations of only EHCI insmoded, OHCI insmoded,
> both insmoded etc.
> 
> When both EHCI & OHCI are suspended, parent clocks will actually be
> turned OFF and vice-versa.

not sure this is necessary. I would expect:

pm_runtime_get_sync(dev) to propagate up the parent tree and enable all
necessary resources to get the child in a working state. IOW, you
shouldn't need to manuall access the parent device.

Kevin ? Paul ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04  8:25                   ` Felipe Balbi
  0 siblings, 0 replies; 49+ messages in thread
From: Felipe Balbi @ 2011-07-04  8:25 UTC (permalink / raw)
  To: Partha Basak
  Cc: Alan Stern, Keshava Munegowda, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Felipe Balbi, Anand Gadiyar,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, Kevin Hilman, Benoit Cousson,
	paul-DWxLp4Yu+b8AvxtiuMwx3w, johnstul-r/Jw6+rmf7HQT0dZR+AlfA,
	Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 3443 bytes --]

Hi,

On Mon, Jul 04, 2011 at 10:36:54AM +0530, Partha Basak wrote:
> >-----Original Message-----
> >From: Alan Stern [mailto:stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org]
> >Sent: Saturday, July 02, 2011 12:37 AM
> >To: Keshava Munegowda
> >Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-
> >kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; balbi-l0cyMroinI0@public.gmane.org; gadiyar-l0cyMroinI0@public.gmane.org;
> >sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org; parthab-PpE0FKYn9XJWk0Htik3J/w@public.gmane.org; tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org;
> >khilman-l0cyMroinI0@public.gmane.org; b-cousson-l0cyMroinI0@public.gmane.org; paul-DWxLp4Yu+b8AvxtiuMwx3w@public.gmane.org; johnstul-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org;
> >vishwanath.bs-l0cyMroinI0@public.gmane.org
> >Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
> >support of ehci and ohci
> >
> >On Sat, 2 Jul 2011, Keshava Munegowda wrote:
> >
> >> From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>
> >>
> >> The global suspend and resume functions for ehci and ohci
> >> drivers are implemented; these functions does the
> >> pm_runtime_get_sync and pm_runtime_put_sync of the
> >> parent device usbhs core driver respectively.
> >>
> >> Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
> >> ---
> >>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
> >>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
> >>  2 files changed, 41 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-
> >omap.c
> >> index 178f63e..a02a684 100644
> >> --- a/drivers/usb/host/ehci-omap.c
> >> +++ b/drivers/usb/host/ehci-omap.c
> >> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct
> >platform_device *pdev)
> >>  		hcd->driver->shutdown(hcd);
> >>  }
> >>
> >> +static int omap_ehci_resume(struct device *dev)
> >> +{
> >> +	if (dev->parent)
> >> +		pm_runtime_get_sync(dev->parent);
> >> +	return 0;
> >> +}
> >> +
> >> +static int omap_ehci_suspend(struct device *dev)
> >> +{
> >> +	if (dev->parent)
> >> +		pm_runtime_put_sync(dev->parent);
> >> +	return 0;
> >> +}
> >
> >I don't see any point in these routines (and likewise for
> >omap_ohci_suspend/resume).  When the whole system is going to sleep
> >anyway, what reason is there for enabling runtime PM on the parent
> >device?
> 
> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
> 
> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
> will turn-off the parent clocks in the Suspend path.
> 
> Similarly, calling pm_runtime_get_sync(dev->parent) within
> omap_ehci_resume
> will turn-on the parent clocks in the resume path.
> 
> This way, all reference counting are implicit within the Runtime PM layer
> and takes care of all combinations of only EHCI insmoded, OHCI insmoded,
> both insmoded etc.
> 
> When both EHCI & OHCI are suspended, parent clocks will actually be
> turned OFF and vice-versa.

not sure this is necessary. I would expect:

pm_runtime_get_sync(dev) to propagate up the parent tree and enable all
necessary resources to get the child in a working state. IOW, you
shouldn't need to manuall access the parent device.

Kevin ? Paul ?

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04  9:26                     ` Partha Basak
  0 siblings, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-04  9:26 UTC (permalink / raw)
  To: balbi
  Cc: Alan Stern, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

>-----Original Message-----
>From: Felipe Balbi [mailto:balbi@ti.com]
>Sent: Monday, July 04, 2011 1:56 PM
>To: Partha Basak
>Cc: Alan Stern; Keshava Munegowda; linux-usb@vger.kernel.org; linux-
>omap@vger.kernel.org; linux-kernel@vger.kernel.org; Felipe Balbi; Anand
>Gadiyar; sameo@linux.intel.com; parthab@india.ti.com; tony@atomide.com;
>Kevin Hilman; Benoit Cousson; paul@pwsan.com; johnstul@us.ibm.com;
>Vishwanath Sripathy
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>Hi,
>
>On Mon, Jul 04, 2011 at 10:36:54AM +0530, Partha Basak wrote:
>> >-----Original Message-----
>> >From: Alan Stern [mailto:stern@rowland.harvard.edu]
>> >Sent: Saturday, July 02, 2011 12:37 AM
>> >To: Keshava Munegowda
>> >Cc: linux-usb@vger.kernel.org; linux-omap@vger.kernel.org; linux-
>> >kernel@vger.kernel.org; balbi@ti.com; gadiyar@ti.com;
>> >sameo@linux.intel.com; parthab@india.ti.com; tony@atomide.com;
>> >khilman@ti.com; b-cousson@ti.com; paul@pwsan.com;
>> >johnstul@us.ibm.com; vishwanath.bs@ti.com
>> >Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>> >support of ehci and ohci
>> >
>> >On Sat, 2 Jul 2011, Keshava Munegowda wrote:
>> >
>> >> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>> >>
>> >> The global suspend and resume functions for ehci and ohci drivers
>> >> are implemented; these functions does the pm_runtime_get_sync and
>> >> pm_runtime_put_sync of the parent device usbhs core driver
>> >> respectively.
>> >>
>> >> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>> >> ---
>> >>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
>> >>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
>> >>  2 files changed, 41 insertions(+), 2 deletions(-)
>> >>
>> >> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-
>> >omap.c
>> >> index 178f63e..a02a684 100644
>> >> --- a/drivers/usb/host/ehci-omap.c
>> >> +++ b/drivers/usb/host/ehci-omap.c
>> >> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct
>> >platform_device *pdev)
>> >>  		hcd->driver->shutdown(hcd);
>> >>  }
>> >>
>> >> +static int omap_ehci_resume(struct device *dev) {
>> >> +	if (dev->parent)
>> >> +		pm_runtime_get_sync(dev->parent);
>> >> +	return 0;
>> >> +}
>> >> +
>> >> +static int omap_ehci_suspend(struct device *dev) {
>> >> +	if (dev->parent)
>> >> +		pm_runtime_put_sync(dev->parent);
>> >> +	return 0;
>> >> +}
>> >
>> >I don't see any point in these routines (and likewise for
>> >omap_ohci_suspend/resume).  When the whole system is going to sleep
>> >anyway, what reason is there for enabling runtime PM on the parent
>> >device?
>>
>> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
>>
>> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend will
>> turn-off the parent clocks in the Suspend path.
>>
>> Similarly, calling pm_runtime_get_sync(dev->parent) within
>> omap_ehci_resume will turn-on the parent clocks in the resume path.
>>
>> This way, all reference counting are implicit within the Runtime PM
>> layer and takes care of all combinations of only EHCI insmoded, OHCI
>> insmoded, both insmoded etc.
>>
>> When both EHCI & OHCI are suspended, parent clocks will actually be
>> turned OFF and vice-versa.
>
>not sure this is necessary. I would expect:
>
>pm_runtime_get_sync(dev) to propagate up the parent tree and enable all
>necessary resources to get the child in a working state. IOW, you
>shouldn't need to manuall access the parent device.
>
Refer to the description in Patch(5/6)
<snip>
In fact, the runtime framework takes care the get sync and put sync of the
child
in turn call the get sync and put sync of parent too; but calling get sync
and
put sync of parent is by ASYNC mode;
This mode queues the work item in runtime pm work queue,
which not getting scheduled in case of global suspend path.
<snip>
This approach was tried, but did not work in the Suspend path
static int rpm_suspend(struct device *dev, int rpmflags)
	__releases(&dev->power.lock) __acquires(&dev->power.lock)
{
.
.
.
no_callback:
.
.
.
	/* Maybe the parent is now able to suspend. */
	if (parent && !parent->power.ignore_children &&
!dev->power.irq_safe) {
		spin_unlock(&dev->power.lock);

		spin_lock(&parent->power.lock);
		rpm_idle(parent, RPM_ASYNC);
		spin_unlock(&parent->power.lock);

		spin_lock(&dev->power.lock);
	}
This is the reason of directly calling the parent Runtime PM calls from
the children.
If directly calling Runtime PM APIs with parent dev-pointer isn't
acceptable,
this can be achieved by exporting wrapper APIs from the
parent and calling them from the chidren .suspend/.resume routines.

>Kevin ? Paul ?
>
>--
>balbi

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04  9:26                     ` Partha Basak
  0 siblings, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-04  9:26 UTC (permalink / raw)
  To: balbi-l0cyMroinI0
  Cc: Alan Stern, Keshava Munegowda, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Anand Gadiyar,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, Kevin Hilman, Benoit Cousson,
	paul-DWxLp4Yu+b8AvxtiuMwx3w, johnstul-r/Jw6+rmf7HQT0dZR+AlfA,
	Vishwanath Sripathy

>-----Original Message-----
>From: Felipe Balbi [mailto:balbi-l0cyMroinI0@public.gmane.org]
>Sent: Monday, July 04, 2011 1:56 PM
>To: Partha Basak
>Cc: Alan Stern; Keshava Munegowda; linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-
>omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Felipe Balbi; Anand
>Gadiyar; sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org; parthab-PpE0FKYn9XJWk0Htik3J/w@public.gmane.org; tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org;
>Kevin Hilman; Benoit Cousson; paul-DWxLp4Yu+b8AvxtiuMwx3w@public.gmane.org; johnstul-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org;
>Vishwanath Sripathy
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>Hi,
>
>On Mon, Jul 04, 2011 at 10:36:54AM +0530, Partha Basak wrote:
>> >-----Original Message-----
>> >From: Alan Stern [mailto:stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz@public.gmane.org]
>> >Sent: Saturday, July 02, 2011 12:37 AM
>> >To: Keshava Munegowda
>> >Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-
>> >kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; balbi-l0cyMroinI0@public.gmane.org; gadiyar-l0cyMroinI0@public.gmane.org;
>> >sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org; parthab-PpE0FKYn9XJWk0Htik3J/w@public.gmane.org; tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org;
>> >khilman-l0cyMroinI0@public.gmane.org; b-cousson-l0cyMroinI0@public.gmane.org; paul-DWxLp4Yu+b8AvxtiuMwx3w@public.gmane.org;
>> >johnstul-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org; vishwanath.bs-l0cyMroinI0@public.gmane.org
>> >Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>> >support of ehci and ohci
>> >
>> >On Sat, 2 Jul 2011, Keshava Munegowda wrote:
>> >
>> >> From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>
>> >>
>> >> The global suspend and resume functions for ehci and ohci drivers
>> >> are implemented; these functions does the pm_runtime_get_sync and
>> >> pm_runtime_put_sync of the parent device usbhs core driver
>> >> respectively.
>> >>
>> >> Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
>> >> ---
>> >>  drivers/usb/host/ehci-omap.c  |   22 ++++++++++++++++++++--
>> >>  drivers/usb/host/ohci-omap3.c |   21 +++++++++++++++++++++
>> >>  2 files changed, 41 insertions(+), 2 deletions(-)
>> >>
>> >> diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-
>> >omap.c
>> >> index 178f63e..a02a684 100644
>> >> --- a/drivers/usb/host/ehci-omap.c
>> >> +++ b/drivers/usb/host/ehci-omap.c
>> >> @@ -259,14 +259,32 @@ static void ehci_hcd_omap_shutdown(struct
>> >platform_device *pdev)
>> >>  		hcd->driver->shutdown(hcd);
>> >>  }
>> >>
>> >> +static int omap_ehci_resume(struct device *dev) {
>> >> +	if (dev->parent)
>> >> +		pm_runtime_get_sync(dev->parent);
>> >> +	return 0;
>> >> +}
>> >> +
>> >> +static int omap_ehci_suspend(struct device *dev) {
>> >> +	if (dev->parent)
>> >> +		pm_runtime_put_sync(dev->parent);
>> >> +	return 0;
>> >> +}
>> >
>> >I don't see any point in these routines (and likewise for
>> >omap_ohci_suspend/resume).  When the whole system is going to sleep
>> >anyway, what reason is there for enabling runtime PM on the parent
>> >device?
>>
>> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
>>
>> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend will
>> turn-off the parent clocks in the Suspend path.
>>
>> Similarly, calling pm_runtime_get_sync(dev->parent) within
>> omap_ehci_resume will turn-on the parent clocks in the resume path.
>>
>> This way, all reference counting are implicit within the Runtime PM
>> layer and takes care of all combinations of only EHCI insmoded, OHCI
>> insmoded, both insmoded etc.
>>
>> When both EHCI & OHCI are suspended, parent clocks will actually be
>> turned OFF and vice-versa.
>
>not sure this is necessary. I would expect:
>
>pm_runtime_get_sync(dev) to propagate up the parent tree and enable all
>necessary resources to get the child in a working state. IOW, you
>shouldn't need to manuall access the parent device.
>
Refer to the description in Patch(5/6)
<snip>
In fact, the runtime framework takes care the get sync and put sync of the
child
in turn call the get sync and put sync of parent too; but calling get sync
and
put sync of parent is by ASYNC mode;
This mode queues the work item in runtime pm work queue,
which not getting scheduled in case of global suspend path.
<snip>
This approach was tried, but did not work in the Suspend path
static int rpm_suspend(struct device *dev, int rpmflags)
	__releases(&dev->power.lock) __acquires(&dev->power.lock)
{
.
.
.
no_callback:
.
.
.
	/* Maybe the parent is now able to suspend. */
	if (parent && !parent->power.ignore_children &&
!dev->power.irq_safe) {
		spin_unlock(&dev->power.lock);

		spin_lock(&parent->power.lock);
		rpm_idle(parent, RPM_ASYNC);
		spin_unlock(&parent->power.lock);

		spin_lock(&dev->power.lock);
	}
This is the reason of directly calling the parent Runtime PM calls from
the children.
If directly calling Runtime PM APIs with parent dev-pointer isn't
acceptable,
this can be achieved by exporting wrapper APIs from the
parent and calling them from the chidren .suspend/.resume routines.

>Kevin ? Paul ?
>
>--
>balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-04  9:26                     ` Partha Basak
  (?)
@ 2011-07-04  9:30                     ` Felipe Balbi
  2011-07-04 11:01                       ` Partha Basak
  2011-07-04 16:01                         ` Alan Stern
  -1 siblings, 2 replies; 49+ messages in thread
From: Felipe Balbi @ 2011-07-04  9:30 UTC (permalink / raw)
  To: Partha Basak
  Cc: balbi, Alan Stern, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 2531 bytes --]

Hi,

On Mon, Jul 04, 2011 at 02:56:30PM +0530, Partha Basak wrote:
> >> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
> >>
> >> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend will
> >> turn-off the parent clocks in the Suspend path.
> >>
> >> Similarly, calling pm_runtime_get_sync(dev->parent) within
> >> omap_ehci_resume will turn-on the parent clocks in the resume path.
> >>
> >> This way, all reference counting are implicit within the Runtime PM
> >> layer and takes care of all combinations of only EHCI insmoded, OHCI
> >> insmoded, both insmoded etc.
> >>
> >> When both EHCI & OHCI are suspended, parent clocks will actually be
> >> turned OFF and vice-versa.
> >
> >not sure this is necessary. I would expect:
> >
> >pm_runtime_get_sync(dev) to propagate up the parent tree and enable all
> >necessary resources to get the child in a working state. IOW, you
> >shouldn't need to manuall access the parent device.
> >
> Refer to the description in Patch(5/6)
> <snip>
> In fact, the runtime framework takes care the get sync and put sync of the
> child
> in turn call the get sync and put sync of parent too; but calling get sync
> and
> put sync of parent is by ASYNC mode;
> This mode queues the work item in runtime pm work queue,
> which not getting scheduled in case of global suspend path.
> <snip>
> This approach was tried, but did not work in the Suspend path

sounds to me like a bug on pm runtime ? If you're calling
pm_runtime_*_sync() family, shouldn't all calls be _sync() too ?

> static int rpm_suspend(struct device *dev, int rpmflags)
> 	__releases(&dev->power.lock) __acquires(&dev->power.lock)
> {
> .
> .
> .
> no_callback:
> .
> .
> .
> 	/* Maybe the parent is now able to suspend. */
> 	if (parent && !parent->power.ignore_children &&
> !dev->power.irq_safe) {
> 		spin_unlock(&dev->power.lock);
> 
> 		spin_lock(&parent->power.lock);
> 		rpm_idle(parent, RPM_ASYNC);

to me this is bogus, if you called pm_runtime_put_sync() should should
be sync too. Shouldn't it ?

> 		spin_unlock(&parent->power.lock);
> 
> 		spin_lock(&dev->power.lock);
> 	}
> This is the reason of directly calling the parent Runtime PM calls from
> the children.
> If directly calling Runtime PM APIs with parent dev-pointer isn't
> acceptable,
> this can be achieved by exporting wrapper APIs from the
> parent and calling them from the chidren .suspend/.resume routines.

Still no good, IMHO.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-04  9:30                     ` Felipe Balbi
@ 2011-07-04 11:01                       ` Partha Basak
  2011-07-04 16:01                         ` Alan Stern
  1 sibling, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-04 11:01 UTC (permalink / raw)
  To: balbi
  Cc: Alan Stern, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

>-----Original Message-----
>From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
>owner@vger.kernel.org] On Behalf Of Felipe Balbi
>Sent: Monday, July 04, 2011 3:01 PM
>To: Partha Basak
>Cc: balbi@ti.com; Alan Stern; Keshava Munegowda; linux-
>usb@vger.kernel.org; linux-omap@vger.kernel.org; linux-
>kernel@vger.kernel.org; Anand Gadiyar; sameo@linux.intel.com;
>parthab@india.ti.com; tony@atomide.com; Kevin Hilman; Benoit Cousson;
>paul@pwsan.com; johnstul@us.ibm.com; Vishwanath Sripathy
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>Hi,
>
>On Mon, Jul 04, 2011 at 02:56:30PM +0530, Partha Basak wrote:
>> >> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
>> >>
>> >> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
>> >> will turn-off the parent clocks in the Suspend path.
>> >>
>> >> Similarly, calling pm_runtime_get_sync(dev->parent) within
>> >> omap_ehci_resume will turn-on the parent clocks in the resume path.
>> >>
>> >> This way, all reference counting are implicit within the Runtime PM
>> >> layer and takes care of all combinations of only EHCI insmoded,
>> >> OHCI insmoded, both insmoded etc.
>> >>
>> >> When both EHCI & OHCI are suspended, parent clocks will actually be
>> >> turned OFF and vice-versa.
>> >
>> >not sure this is necessary. I would expect:
>> >
>> >pm_runtime_get_sync(dev) to propagate up the parent tree and enable
>> >all necessary resources to get the child in a working state. IOW, you
>> >shouldn't need to manuall access the parent device.
>> >
>> Refer to the description in Patch(5/6) <snip> In fact, the runtime
>> framework takes care the get sync and put sync of the child in turn
>> call the get sync and put sync of parent too; but calling get sync and
>> put sync of parent is by ASYNC mode; This mode queues the work item in
>> runtime pm work queue, which not getting scheduled in case of global
>> suspend path.
>> <snip>
>> This approach was tried, but did not work in the Suspend path
>
>sounds to me like a bug on pm runtime ? If you're calling
>pm_runtime_*_sync() family, shouldn't all calls be _sync() too ?
>
>> static int rpm_suspend(struct device *dev, int rpmflags)
>> 	__releases(&dev->power.lock) __acquires(&dev->power.lock) { .
>> .
>> .
>> no_callback:
>> .
>> .
>> .
>> 	/* Maybe the parent is now able to suspend. */
>> 	if (parent && !parent->power.ignore_children &&
>> !dev->power.irq_safe) {
>> 		spin_unlock(&dev->power.lock);
>>
>> 		spin_lock(&parent->power.lock);
>> 		rpm_idle(parent, RPM_ASYNC);
>
>to me this is bogus, if you called pm_runtime_put_sync() should should
>be sync too. Shouldn't it ?
>
>> 		spin_unlock(&parent->power.lock);
>>
>> 		spin_lock(&dev->power.lock);
>> 	}
>> This is the reason of directly calling the parent Runtime PM calls
>> from the children.
>> If directly calling Runtime PM APIs with parent dev-pointer isn't
>> acceptable, this can be achieved by exporting wrapper APIs from the
>> parent and calling them from the chidren .suspend/.resume routines.
>
>Still no good, IMHO.

Kevin, any comments?

Shouldn't the framework ensure that if put_sync(dev) is called
it should ensure that the parent is rmp_idled synchronously?
>
>--
>balbi

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-04  5:06                 ` Partha Basak
@ 2011-07-04 15:50                   ` Alan Stern
  -1 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-04 15:50 UTC (permalink / raw)
  To: Partha Basak
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel,
	Felipe Balbi, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

On Mon, 4 Jul 2011, Partha Basak wrote:

> >I don't see any point in these routines (and likewise for
> >omap_ohci_suspend/resume).  When the whole system is going to sleep
> >anyway, what reason is there for enabling runtime PM on the parent
> >device?
> 
> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
> 
> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
> will turn-off the parent clocks in the Suspend path.
> 
> Similarly, calling pm_runtime_get_sync(dev->parent) within
> omap_ehci_resume
> will turn-on the parent clocks in the resume path.
> 
> This way, all reference counting are implicit within the Runtime PM layer
> and takes care of all combinations of only EHCI insmoded, OHCI insmoded,
> both insmoded etc.
> 
> When both EHCI & OHCI are suspended, parent clocks will actually be
> turned OFF and vice-versa.
> 
> Note that the parent per-se does not have any .suspend & .resume hooked
> up.

Why not?  That sounds like a big bug.

> At the end of the _probe of parent, the clocks are turned OFF.
> Subsequently, enabling
> the parent clocks are entirely done implicitly by the children get_sync()
> in their _probe.
> 
> Therefore while .suspend/.resume of children are called they call back
> into the parent to turn-off the clocks.

You have ignored a few very important points:

Firstly, system suspend is supposed to work even when runtime PM is not 
configured.

Secondly, the user can disable runtime PM via sysfs at any time.  This 
shouldn't mess up system suspend.

Basically, it's a bad idea to mix up system suspend with runtime PM.

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04 15:50                   ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-04 15:50 UTC (permalink / raw)
  To: Partha Basak
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel,
	Felipe Balbi, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

On Mon, 4 Jul 2011, Partha Basak wrote:

> >I don't see any point in these routines (and likewise for
> >omap_ohci_suspend/resume).  When the whole system is going to sleep
> >anyway, what reason is there for enabling runtime PM on the parent
> >device?
> 
> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
> 
> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
> will turn-off the parent clocks in the Suspend path.
> 
> Similarly, calling pm_runtime_get_sync(dev->parent) within
> omap_ehci_resume
> will turn-on the parent clocks in the resume path.
> 
> This way, all reference counting are implicit within the Runtime PM layer
> and takes care of all combinations of only EHCI insmoded, OHCI insmoded,
> both insmoded etc.
> 
> When both EHCI & OHCI are suspended, parent clocks will actually be
> turned OFF and vice-versa.
> 
> Note that the parent per-se does not have any .suspend & .resume hooked
> up.

Why not?  That sounds like a big bug.

> At the end of the _probe of parent, the clocks are turned OFF.
> Subsequently, enabling
> the parent clocks are entirely done implicitly by the children get_sync()
> in their _probe.
> 
> Therefore while .suspend/.resume of children are called they call back
> into the parent to turn-off the clocks.

You have ignored a few very important points:

Firstly, system suspend is supposed to work even when runtime PM is not 
configured.

Secondly, the user can disable runtime PM via sysfs at any time.  This 
shouldn't mess up system suspend.

Basically, it's a bad idea to mix up system suspend with runtime PM.

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-04  9:30                     ` Felipe Balbi
@ 2011-07-04 16:01                         ` Alan Stern
  2011-07-04 16:01                         ` Alan Stern
  1 sibling, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-04 16:01 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Partha Basak, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

On Mon, 4 Jul 2011, Felipe Balbi wrote:

> sounds to me like a bug on pm runtime ? If you're calling
> pm_runtime_*_sync() family, shouldn't all calls be _sync() too ?

No.  This was a deliberate design decision.  It minimizes stack usage 
and it gives a chance for some other child to resume before the parent 
is powered down.

> > static int rpm_suspend(struct device *dev, int rpmflags)
> > 	__releases(&dev->power.lock) __acquires(&dev->power.lock)
> > {
> > .
> > .
> > .
> > no_callback:
> > .
> > .
> > .
> > 	/* Maybe the parent is now able to suspend. */
> > 	if (parent && !parent->power.ignore_children &&
> > !dev->power.irq_safe) {
> > 		spin_unlock(&dev->power.lock);
> > 
> > 		spin_lock(&parent->power.lock);
> > 		rpm_idle(parent, RPM_ASYNC);
> 
> to me this is bogus, if you called pm_runtime_put_sync() should should
> be sync too. Shouldn't it ?

No, it shouldn't.

> > 		spin_unlock(&parent->power.lock);
> > 
> > 		spin_lock(&dev->power.lock);
> > 	}
> > This is the reason of directly calling the parent Runtime PM calls from
> > the children.
> > If directly calling Runtime PM APIs with parent dev-pointer isn't
> > acceptable,
> > this can be achieved by exporting wrapper APIs from the
> > parent and calling them from the chidren .suspend/.resume routines.
> 
> Still no good, IMHO.

The real problem here is that you guys are trying to use the runtime PM
framework to carry out activities during system suspend.  That won't
work; it's just a bad idea all round.  Use the proper callbacks to do
what you want.

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-04 16:01                         ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-04 16:01 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Partha Basak, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

On Mon, 4 Jul 2011, Felipe Balbi wrote:

> sounds to me like a bug on pm runtime ? If you're calling
> pm_runtime_*_sync() family, shouldn't all calls be _sync() too ?

No.  This was a deliberate design decision.  It minimizes stack usage 
and it gives a chance for some other child to resume before the parent 
is powered down.

> > static int rpm_suspend(struct device *dev, int rpmflags)
> > 	__releases(&dev->power.lock) __acquires(&dev->power.lock)
> > {
> > .
> > .
> > .
> > no_callback:
> > .
> > .
> > .
> > 	/* Maybe the parent is now able to suspend. */
> > 	if (parent && !parent->power.ignore_children &&
> > !dev->power.irq_safe) {
> > 		spin_unlock(&dev->power.lock);
> > 
> > 		spin_lock(&parent->power.lock);
> > 		rpm_idle(parent, RPM_ASYNC);
> 
> to me this is bogus, if you called pm_runtime_put_sync() should should
> be sync too. Shouldn't it ?

No, it shouldn't.

> > 		spin_unlock(&parent->power.lock);
> > 
> > 		spin_lock(&dev->power.lock);
> > 	}
> > This is the reason of directly calling the parent Runtime PM calls from
> > the children.
> > If directly calling Runtime PM APIs with parent dev-pointer isn't
> > acceptable,
> > this can be achieved by exporting wrapper APIs from the
> > parent and calling them from the chidren .suspend/.resume routines.
> 
> Still no good, IMHO.

The real problem here is that you guys are trying to use the runtime PM
framework to carry out activities during system suspend.  That won't
work; it's just a bad idea all round.  Use the proper callbacks to do
what you want.

Alan Stern

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/6 V2] arm: omap: usb: Runtime PM support for EHCI and OHCI drivers
  2011-07-01 18:54 ` Keshava Munegowda
  (?)
  (?)
@ 2011-07-04 17:25 ` Samuel Ortiz
  -1 siblings, 0 replies; 49+ messages in thread
From: Samuel Ortiz @ 2011-07-04 17:25 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, parthab,
	tony, khilman, b-cousson, paul, johnstul, vishwanath.bs

Hi Keshava,

On Sat, Jul 02, 2011 at 12:24:28AM +0530, Keshava Munegowda wrote:
> From: Keshava Munegowda <Keshava_mgowda@ti.com>
> 
> The Hwmod structures and Runtime PM features are implemented
> For EHCI and OHCI drivers of OMAP3 and OMAP4.
> The global suspend/resume of EHCI and OHCI
> is validated on OMAP3430 sdp board with these patches.
Hust fr your information, this will not make it to 3.0. I have a revert of
your patch queued for the 3.0 MFC update pull request that I'm going to send
soon.
So this is 3.1 merge window material.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-04 16:01                         ` Alan Stern
  (?)
@ 2011-07-05 12:52                         ` Felipe Balbi
  2011-07-05 14:17                             ` Alan Stern
  -1 siblings, 1 reply; 49+ messages in thread
From: Felipe Balbi @ 2011-07-05 12:52 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Partha Basak, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, Anand Gadiyar, sameo, parthab, tony,
	Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 2484 bytes --]

Hi,

On Mon, Jul 04, 2011 at 12:01:24PM -0400, Alan Stern wrote:
> On Mon, 4 Jul 2011, Felipe Balbi wrote:
> 
> > sounds to me like a bug on pm runtime ? If you're calling
> > pm_runtime_*_sync() family, shouldn't all calls be _sync() too ?
> 
> No.  This was a deliberate design decision.  It minimizes stack usage 
> and it gives a chance for some other child to resume before the parent 
> is powered down.

fair enough.

> > > 		spin_unlock(&parent->power.lock);
> > > 
> > > 		spin_lock(&dev->power.lock);
> > > 	}
> > > This is the reason of directly calling the parent Runtime PM calls from
> > > the children.
> > > If directly calling Runtime PM APIs with parent dev-pointer isn't
> > > acceptable,
> > > this can be achieved by exporting wrapper APIs from the
> > > parent and calling them from the chidren .suspend/.resume routines.
> > 
> > Still no good, IMHO.
> 
> The real problem here is that you guys are trying to use the runtime PM
> framework to carry out activities during system suspend.  That won't
> work; it's just a bad idea all round.  Use the proper callbacks to do
> what you want.

then what's the point in even having runtime PM if we will still have to
implement the same functionality on the other callbacks ? Well, of
course runtime PM will conserve power on runtime, but system suspend
should be no different other than an "always deepest sleep state"
decision.

The thing now is that pm_runtime was done so that drivers would stop
caring about clocks, which is a big plus, but if we still have to handle
->suspend()/->resume() differently, we will still need to clk_get();
clk_enable(); clk_disable(); Then what was the big deal with runtime PM?

IMHO, we should have only one PM layer. System suspend/resume should be
implemented so that core PM "forcefully" calls
->runtime_suspend()/->runtime_resume() of call drivers, all
synchronously. Maybe we need an extra
RPM_STATIC_SUSPEND_PLEASE_HANDLE_IT_ALL_SYNCHRONOUSLY flag, but that's
another detail.

If drivers are really supposed to stop handling clocks directly, then
runtime PM is THE framework to do that, but if we still have system
suspend/resume the old way, I don't see the benefit for the driver
(other than the uAmps saved during runtime, which is great, don't get me
wrong ;-) that this will bring. Having two PM layers which, in fact, are
doing the same thing - reducing power consumption - is just too much
IMO.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-04 15:50                   ` Alan Stern
  (?)
@ 2011-07-05 14:00                   ` Partha Basak
  2011-07-05 14:22                       ` Alan Stern
  -1 siblings, 1 reply; 49+ messages in thread
From: Partha Basak @ 2011-07-05 14:00 UTC (permalink / raw)
  To: Alan Stern
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel,
	Felipe Balbi, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

>-----Original Message-----
>From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
>owner@vger.kernel.org] On Behalf Of Alan Stern
>Sent: Monday, July 04, 2011 9:21 PM
>To: Partha Basak
>Cc: Keshava Munegowda; linux-usb@vger.kernel.org; linux-
>omap@vger.kernel.org; linux-kernel@vger.kernel.org; Felipe Balbi; Anand
>Gadiyar; sameo@linux.intel.com; parthab@india.ti.com; tony@atomide.com;
>Kevin Hilman; Benoit Cousson; paul@pwsan.com; johnstul@us.ibm.com;
>Vishwanath Sripathy
>Subject: RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>On Mon, 4 Jul 2011, Partha Basak wrote:
>
>> >I don't see any point in these routines (and likewise for
>> >omap_ohci_suspend/resume).  When the whole system is going to sleep
>> >anyway, what reason is there for enabling runtime PM on the parent
>> >device?
>>
>> Both for EHCI & OHCI, the clocks are owned by the parent (uhh-tll).
>>
>> Calling pm_runtime_put_sync(dev->parent) within omap_ehci_suspend
>> will turn-off the parent clocks in the Suspend path.
>>
>> Similarly, calling pm_runtime_get_sync(dev->parent) within
>> omap_ehci_resume
>> will turn-on the parent clocks in the resume path.
>>
>> This way, all reference counting are implicit within the Runtime PM
>layer
>> and takes care of all combinations of only EHCI insmoded, OHCI
>insmoded,
>> both insmoded etc.
>>
>> When both EHCI & OHCI are suspended, parent clocks will actually be
>> turned OFF and vice-versa.
>>
>> Note that the parent per-se does not have any .suspend & .resume
>hooked
>> up.
>
>Why not?  That sounds like a big bug.

This was a design decision since the parent needs to be activated only
when at-least one child is insmoded.

If the chidren are suspended, automatically the parent is suspended
via the pm_runtime_putsync calls to the parent.

So, effectively, we do not need an explicit suspend for the parent.
>
>> At the end of the _probe of parent, the clocks are turned OFF.
>> Subsequently, enabling
>> the parent clocks are entirely done implicitly by the children
>get_sync()
>> in their _probe.
>>
>> Therefore while .suspend/.resume of children are called they call back
>> into the parent to turn-off the clocks.
>
>You have ignored a few very important points:
>
>Firstly, system suspend is supposed to work even when runtime PM is not
>configured.
>
>Secondly, the user can disable runtime PM via sysfs at any time.  This
>shouldn't mess up system suspend.
>
>Basically, it's a bad idea to mix up system suspend with runtime PM.

Your observations are correct but this is a generic limitation and Kevin
is working
on this problem in parallel.

As of now, all OMAP drivers are mandated to use ONLY runtime pm framework
for enabling/disabling clocks. I will let Kevin comment further.

>
>Alan Stern
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-05 12:52                         ` Felipe Balbi
@ 2011-07-05 14:17                             ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-05 14:17 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Partha Basak, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, Anand Gadiyar, sameo, parthab, tony,
	Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

On Tue, 5 Jul 2011, Felipe Balbi wrote:

> > The real problem here is that you guys are trying to use the runtime PM
> > framework to carry out activities during system suspend.  That won't
> > work; it's just a bad idea all round.  Use the proper callbacks to do
> > what you want.
> 
> then what's the point in even having runtime PM if we will still have to
> implement the same functionality on the other callbacks ?

You don't have to duplicate the functionality.  You can use exactly the
same functions for both sets of callbacks if you want; just make sure
the callbacks point to them.

>  Well, of
> course runtime PM will conserve power on runtime, but system suspend
> should be no different other than an "always deepest sleep state"
> decision.

No, it is significantly different for several reasons.  Some of the
most important differences are concerned with freezing userspace and
deciding what events should be allowed to wake up the system.  Also, 
there are systems which can achieve greater power savings by system 
sleep than they can by runtime PM + cpuidle.

> The thing now is that pm_runtime was done so that drivers would stop
> caring about clocks, which is a big plus, but if we still have to handle
> ->suspend()/->resume() differently, we will still need to clk_get();
> clk_enable(); clk_disable(); Then what was the big deal with runtime PM?

I don't know about that.  Clock usage has always been internal to the
implementation you guys have been working on, and I haven't followed
it.  If your implementation was designed incorrectly, well, that's a
shame but it's understandable.  Things like that happen.  It shouldn't
be too hard to fix.

But first you do need to understand that system suspend really _is_ 
different from runtime suspend.  Sure, you may be able to share some 
code between them, but you should not expect to be able to use one in 
place of the other.

> IMHO, we should have only one PM layer. System suspend/resume should be
> implemented so that core PM "forcefully" calls
> ->runtime_suspend()/->runtime_resume() of call drivers, all
> synchronously. Maybe we need an extra
> RPM_STATIC_SUSPEND_PLEASE_HANDLE_IT_ALL_SYNCHRONOUSLY flag, but that's
> another detail.

Statements like this should be posted to linux-pm where they can be 
discussed properly.  It certainly isn't fair to make such claims 
without even CC-ing the PM maintainer.

Besides, handling runtime PM synchronously won't do you any good if the 
user has disabled runtime PM via sysfs or not enabled 
CONFIG_PM_RUNTIME in the first place.  Have you forgotten about those 
possibilities?

Furthermore, from what I've gathered so far from this thread, the
_real_ problem is that nobody has written suspend and resume callbacks
for the parent device.  You're relying on runtime PM to do things with
the parent, but instead you should make use of the usual system sleep
mechanism: Parents are always suspended after their children and
awakened before.  Have the parent's suspend routine disable the clocks 
and have the resume routine enable them.  Problem solved, no changes 
needed in the child's driver code.

> If drivers are really supposed to stop handling clocks directly, then
> runtime PM is THE framework to do that, but if we still have system
> suspend/resume the old way, I don't see the benefit for the driver
> (other than the uAmps saved during runtime, which is great, don't get me
> wrong ;-) that this will bring. Having two PM layers which, in fact, are
> doing the same thing - reducing power consumption - is just too much
> IMO.

They aren't doing the same thing.  If you don't believe me, ask the PM 
maintainer.

And if you actually do need your callbacks to do the same thing, simply
use shared subroutines.

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-05 14:17                             ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-05 14:17 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Partha Basak, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, Anand Gadiyar, sameo, parthab, tony,
	Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

On Tue, 5 Jul 2011, Felipe Balbi wrote:

> > The real problem here is that you guys are trying to use the runtime PM
> > framework to carry out activities during system suspend.  That won't
> > work; it's just a bad idea all round.  Use the proper callbacks to do
> > what you want.
> 
> then what's the point in even having runtime PM if we will still have to
> implement the same functionality on the other callbacks ?

You don't have to duplicate the functionality.  You can use exactly the
same functions for both sets of callbacks if you want; just make sure
the callbacks point to them.

>  Well, of
> course runtime PM will conserve power on runtime, but system suspend
> should be no different other than an "always deepest sleep state"
> decision.

No, it is significantly different for several reasons.  Some of the
most important differences are concerned with freezing userspace and
deciding what events should be allowed to wake up the system.  Also, 
there are systems which can achieve greater power savings by system 
sleep than they can by runtime PM + cpuidle.

> The thing now is that pm_runtime was done so that drivers would stop
> caring about clocks, which is a big plus, but if we still have to handle
> ->suspend()/->resume() differently, we will still need to clk_get();
> clk_enable(); clk_disable(); Then what was the big deal with runtime PM?

I don't know about that.  Clock usage has always been internal to the
implementation you guys have been working on, and I haven't followed
it.  If your implementation was designed incorrectly, well, that's a
shame but it's understandable.  Things like that happen.  It shouldn't
be too hard to fix.

But first you do need to understand that system suspend really _is_ 
different from runtime suspend.  Sure, you may be able to share some 
code between them, but you should not expect to be able to use one in 
place of the other.

> IMHO, we should have only one PM layer. System suspend/resume should be
> implemented so that core PM "forcefully" calls
> ->runtime_suspend()/->runtime_resume() of call drivers, all
> synchronously. Maybe we need an extra
> RPM_STATIC_SUSPEND_PLEASE_HANDLE_IT_ALL_SYNCHRONOUSLY flag, but that's
> another detail.

Statements like this should be posted to linux-pm where they can be 
discussed properly.  It certainly isn't fair to make such claims 
without even CC-ing the PM maintainer.

Besides, handling runtime PM synchronously won't do you any good if the 
user has disabled runtime PM via sysfs or not enabled 
CONFIG_PM_RUNTIME in the first place.  Have you forgotten about those 
possibilities?

Furthermore, from what I've gathered so far from this thread, the
_real_ problem is that nobody has written suspend and resume callbacks
for the parent device.  You're relying on runtime PM to do things with
the parent, but instead you should make use of the usual system sleep
mechanism: Parents are always suspended after their children and
awakened before.  Have the parent's suspend routine disable the clocks 
and have the resume routine enable them.  Problem solved, no changes 
needed in the child's driver code.

> If drivers are really supposed to stop handling clocks directly, then
> runtime PM is THE framework to do that, but if we still have system
> suspend/resume the old way, I don't see the benefit for the driver
> (other than the uAmps saved during runtime, which is great, don't get me
> wrong ;-) that this will bring. Having two PM layers which, in fact, are
> doing the same thing - reducing power consumption - is just too much
> IMO.

They aren't doing the same thing.  If you don't believe me, ask the PM 
maintainer.

And if you actually do need your callbacks to do the same thing, simply
use shared subroutines.

Alan Stern

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-05 14:00                   ` Partha Basak
@ 2011-07-05 14:22                       ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-05 14:22 UTC (permalink / raw)
  To: Partha Basak
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel,
	Felipe Balbi, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

On Tue, 5 Jul 2011, Partha Basak wrote:

> >> Note that the parent per-se does not have any .suspend & .resume
> >hooked
> >> up.
> >
> >Why not?  That sounds like a big bug.
> 
> This was a design decision since the parent needs to be activated only
> when at-least one child is insmoded.
> 
> If the chidren are suspended, automatically the parent is suspended
> via the pm_runtime_putsync calls to the parent.

Now you know that this isn't true, because those calls don't get made 
while a system sleep transition is in progress.

> So, effectively, we do not need an explicit suspend for the parent.

Now you know that effectively you _do_ need an explicit suspend for the 
parent.

> >You have ignored a few very important points:
> >
> >Firstly, system suspend is supposed to work even when runtime PM is not
> >configured.
> >
> >Secondly, the user can disable runtime PM via sysfs at any time.  This
> >shouldn't mess up system suspend.
> >
> >Basically, it's a bad idea to mix up system suspend with runtime PM.
> 
> Your observations are correct but this is a generic limitation and Kevin
> is working
> on this problem in parallel.
> 
> As of now, all OMAP drivers are mandated to use ONLY runtime pm framework
> for enabling/disabling clocks. I will let Kevin comment further.

Okay, let's see what Kevin says.

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-05 14:22                       ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-05 14:22 UTC (permalink / raw)
  To: Partha Basak
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel,
	Felipe Balbi, Anand Gadiyar, sameo, parthab, tony, Kevin Hilman,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

On Tue, 5 Jul 2011, Partha Basak wrote:

> >> Note that the parent per-se does not have any .suspend & .resume
> >hooked
> >> up.
> >
> >Why not?  That sounds like a big bug.
> 
> This was a design decision since the parent needs to be activated only
> when at-least one child is insmoded.
> 
> If the chidren are suspended, automatically the parent is suspended
> via the pm_runtime_putsync calls to the parent.

Now you know that this isn't true, because those calls don't get made 
while a system sleep transition is in progress.

> So, effectively, we do not need an explicit suspend for the parent.

Now you know that effectively you _do_ need an explicit suspend for the 
parent.

> >You have ignored a few very important points:
> >
> >Firstly, system suspend is supposed to work even when runtime PM is not
> >configured.
> >
> >Secondly, the user can disable runtime PM via sysfs at any time.  This
> >shouldn't mess up system suspend.
> >
> >Basically, it's a bad idea to mix up system suspend with runtime PM.
> 
> Your observations are correct but this is a generic limitation and Kevin
> is working
> on this problem in parallel.
> 
> As of now, all OMAP drivers are mandated to use ONLY runtime pm framework
> for enabling/disabling clocks. I will let Kevin comment further.

Okay, let's see what Kevin says.

Alan Stern

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-05 14:17                             ` Alan Stern
  (?)
@ 2011-07-05 15:53                             ` Felipe Balbi
  2011-07-05 16:28                                 ` Alan Stern
  -1 siblings, 1 reply; 49+ messages in thread
From: Felipe Balbi @ 2011-07-05 15:53 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Partha Basak, Keshava Munegowda, USB list,
	linux-omap, Kernel development list, Anand Gadiyar, sameo,
	parthab, tony, Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 4642 bytes --]

Hi,

On Tue, Jul 05, 2011 at 10:17:14AM -0400, Alan Stern wrote:
> On Tue, 5 Jul 2011, Felipe Balbi wrote:
> 
> > > The real problem here is that you guys are trying to use the runtime PM
> > > framework to carry out activities during system suspend.  That won't
> > > work; it's just a bad idea all round.  Use the proper callbacks to do
> > > what you want.
> > 
> > then what's the point in even having runtime PM if we will still have to
> > implement the same functionality on the other callbacks ?
> 
> You don't have to duplicate the functionality.  You can use exactly the
> same functions for both sets of callbacks if you want; just make sure
> the callbacks point to them.

true, good point.

> >  Well, of
> > course runtime PM will conserve power on runtime, but system suspend
> > should be no different other than an "always deepest sleep state"
> > decision.
> 
> No, it is significantly different for several reasons.  Some of the
> most important differences are concerned with freezing userspace and
> deciding what events should be allowed to wake up the system.  Also, 
> there are systems which can achieve greater power savings by system 
> sleep than they can by runtime PM + cpuidle.

I remember we've been through this discussion before and it's just
nonsensical to make such statement. What does freezing userspace have to
do with power consumption ? If you can't reach lower power consumption
with runtime PM it only means userspace is waking the system too much.

> > The thing now is that pm_runtime was done so that drivers would stop
> > caring about clocks, which is a big plus, but if we still have to handle
> > ->suspend()/->resume() differently, we will still need to clk_get();
> > clk_enable(); clk_disable(); Then what was the big deal with runtime PM?
> 
> I don't know about that.  Clock usage has always been internal to the
> implementation you guys have been working on, and I haven't followed
> it.  If your implementation was designed incorrectly, well, that's a
> shame but it's understandable.  Things like that happen.  It shouldn't
> be too hard to fix.
> 
> But first you do need to understand that system suspend really _is_ 
> different from runtime suspend.  Sure, you may be able to share some 
> code between them, but you should not expect to be able to use one in 
> place of the other.

I really fail to see why not, and maybe it's only my fault and I need to
read the Documentation/ more carefully :-s

> > IMHO, we should have only one PM layer. System suspend/resume should be
> > implemented so that core PM "forcefully" calls
> > ->runtime_suspend()/->runtime_resume() of call drivers, all
> > synchronously. Maybe we need an extra
> > RPM_STATIC_SUSPEND_PLEASE_HANDLE_IT_ALL_SYNCHRONOUSLY flag, but that's
> > another detail.
> 
> Statements like this should be posted to linux-pm where they can be 
> discussed properly.  It certainly isn't fair to make such claims 
> without even CC-ing the PM maintainer.
> 
> Besides, handling runtime PM synchronously won't do you any good if the 
> user has disabled runtime PM via sysfs or not enabled 
> CONFIG_PM_RUNTIME in the first place.  Have you forgotten about those 
> possibilities?

I thought that the "we should have only one PM layer" already carried
the idea that CONFIG_PM and CONFIG_PM_RUNTIME would be combined into
one, and sysfs would need a little re-factoring...

> Furthermore, from what I've gathered so far from this thread, the
> _real_ problem is that nobody has written suspend and resume callbacks
> for the parent device.  You're relying on runtime PM to do things with
> the parent, but instead you should make use of the usual system sleep
> mechanism: Parents are always suspended after their children and
> awakened before.  Have the parent's suspend routine disable the clocks 
> and have the resume routine enable them.  Problem solved, no changes 
> needed in the child's driver code.

that's currently hidden on the omap rutime pm support. No driver is to
talk to clk API directly anymore. Granted, now that I read what I just
wrote it does sound like it's a limitation, although it's really nice
not to have to remember all the numerous clocks needed for a particular
device to work properly. So, if there would be a way, other than
pm_runtime_resume(), to enable all clocks a particular device has
without really having to clk_get(); clk_enable() each one of them, fine,
this would be solved. But as of today, we only have pm_runtime_resume()
to achieve that, unless I'm missing something.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-05 15:53                             ` Felipe Balbi
@ 2011-07-05 16:28                                 ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-05 16:28 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Partha Basak, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, Anand Gadiyar, sameo, parthab, tony,
	Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

On Tue, 5 Jul 2011, Felipe Balbi wrote:

> > >  Well, of
> > > course runtime PM will conserve power on runtime, but system suspend
> > > should be no different other than an "always deepest sleep state"
> > > decision.
> > 
> > No, it is significantly different for several reasons.  Some of the
> > most important differences are concerned with freezing userspace and
> > deciding what events should be allowed to wake up the system.  Also, 
> > there are systems which can achieve greater power savings by system 
> > sleep than they can by runtime PM + cpuidle.
> 
> I remember we've been through this discussion before and it's just
> nonsensical to make such statement. What does freezing userspace have to
> do with power consumption ? If you can't reach lower power consumption
> with runtime PM it only means userspace is waking the system too much.

_That's_ what freezing userspace has to do with power consumption.  You 
have answered your own question.

And don't forget the other points about wakeup events and greater power
savings.  If you want to discuss this further, you should start a new
thread on linux-pm.


> > Furthermore, from what I've gathered so far from this thread, the
> > _real_ problem is that nobody has written suspend and resume callbacks
> > for the parent device.  You're relying on runtime PM to do things with
> > the parent, but instead you should make use of the usual system sleep
> > mechanism: Parents are always suspended after their children and
> > awakened before.  Have the parent's suspend routine disable the clocks 
> > and have the resume routine enable them.  Problem solved, no changes 
> > needed in the child's driver code.
> 
> that's currently hidden on the omap rutime pm support. No driver is to
> talk to clk API directly anymore. Granted, now that I read what I just
> wrote it does sound like it's a limitation, although it's really nice
> not to have to remember all the numerous clocks needed for a particular
> device to work properly. So, if there would be a way, other than
> pm_runtime_resume(), to enable all clocks a particular device has
> without really having to clk_get(); clk_enable() each one of them, fine,
> this would be solved. But as of today, we only have pm_runtime_resume()
> to achieve that, unless I'm missing something.

(Actually, your problem isn't enabling clocks during resume; it is 
disabling them during suspend.)

The OMAP maintainer should be involved in this discussion.  Basically,
the new PM domain framework is now supposed to handle these issues.

Alan Stern


^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-05 16:28                                 ` Alan Stern
  0 siblings, 0 replies; 49+ messages in thread
From: Alan Stern @ 2011-07-05 16:28 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Partha Basak, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, Anand Gadiyar, sameo, parthab, tony,
	Kevin Hilman, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

On Tue, 5 Jul 2011, Felipe Balbi wrote:

> > >  Well, of
> > > course runtime PM will conserve power on runtime, but system suspend
> > > should be no different other than an "always deepest sleep state"
> > > decision.
> > 
> > No, it is significantly different for several reasons.  Some of the
> > most important differences are concerned with freezing userspace and
> > deciding what events should be allowed to wake up the system.  Also, 
> > there are systems which can achieve greater power savings by system 
> > sleep than they can by runtime PM + cpuidle.
> 
> I remember we've been through this discussion before and it's just
> nonsensical to make such statement. What does freezing userspace have to
> do with power consumption ? If you can't reach lower power consumption
> with runtime PM it only means userspace is waking the system too much.

_That's_ what freezing userspace has to do with power consumption.  You 
have answered your own question.

And don't forget the other points about wakeup events and greater power
savings.  If you want to discuss this further, you should start a new
thread on linux-pm.


> > Furthermore, from what I've gathered so far from this thread, the
> > _real_ problem is that nobody has written suspend and resume callbacks
> > for the parent device.  You're relying on runtime PM to do things with
> > the parent, but instead you should make use of the usual system sleep
> > mechanism: Parents are always suspended after their children and
> > awakened before.  Have the parent's suspend routine disable the clocks 
> > and have the resume routine enable them.  Problem solved, no changes 
> > needed in the child's driver code.
> 
> that's currently hidden on the omap rutime pm support. No driver is to
> talk to clk API directly anymore. Granted, now that I read what I just
> wrote it does sound like it's a limitation, although it's really nice
> not to have to remember all the numerous clocks needed for a particular
> device to work properly. So, if there would be a way, other than
> pm_runtime_resume(), to enable all clocks a particular device has
> without really having to clk_get(); clk_enable() each one of them, fine,
> this would be solved. But as of today, we only have pm_runtime_resume()
> to achieve that, unless I'm missing something.

(Actually, your problem isn't enabling clocks during resume; it is 
disabling them during suspend.)

The OMAP maintainer should be involved in this discussion.  Basically,
the new PM domain framework is now supposed to handle these issues.

Alan Stern

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-05 14:22                       ` Alan Stern
@ 2011-07-05 17:37                         ` Kevin Hilman
  -1 siblings, 0 replies; 49+ messages in thread
From: Kevin Hilman @ 2011-07-05 17:37 UTC (permalink / raw)
  To: Alan Stern
  Cc: Partha Basak, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Felipe Balbi, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

Alan Stern <stern@rowland.harvard.edu> writes:

[...]

>>>You have ignored a few very important points:
>>>
>>>Firstly, system suspend is supposed to work even when runtime PM is
>>>not configured.
>>>
>>>Secondly, the user can disable runtime PM via sysfs at any time.
>>>This shouldn't mess up system suspend.
>>>
>>>Basically, it's a bad idea to mix up system suspend with runtime PM.
>> 
>> Your observations are correct but this is a generic limitation and
>> Kevin is working on this problem in parallel.
>> 
>> As of now, all OMAP drivers are mandated to use ONLY runtime pm framework
>> for enabling/disabling clocks. I will let Kevin comment further.
>
> Okay, let's see what Kevin says.

While I did design the OMAP PM core to be runtime PM centric, and we
implemented several drivers based on runtime PM alone, after some long
discussions on linux-pm[1] with Alan and Rafael (PM maintainer) over the
last couple weeks, I'm now convinced I had the wrong design/approach.

Rafael and Alan have been patient with my stubborness, but now I've been
pursuaded.  Rafael has detailed on linux-pm the various
problems/limitations/races between runtime PM and system PM[2], so I
don't plan debating them again here.

That being said, today we have several drivers that use runtime PM calls
in their suspend/resume path and our PM domain implementation (inside
omap_device) deals with most of the limitations fine.  However, there
are 2 main problems/limitation with this that we've chosen to live with
(for now):
        
1) synchronous calls must be used in the suspend/resume path (because
   PM workqueue is frozen during suspend/resumea)
2) disabling runtime PM from userspace will prevent that device
   from hitting its low-power state during suspend.

For v3.1 (and before), we've lived with these limitations, and I'm OK
with merging other drivers for v3.1 with these limitations.  After 3.1,
this will be changing (more on this below.)  

So, while I've been OK with merging drivers with the above limitations
for one more merge window, $SUBJECT patch adds a new twist by forcibly
managing the parent device from the child device.  Personally, I really
don't like that approach and it serves as a good illustration of yet
another reason why system PM and runtime PM need understood as
conceptually very different.

For v3.2, the PM core will change[2] to futher limit/protect
interactions between runtime PM and system PM, and I will be reworking
our PM domain (omap_device) implementation accordingly.  

Basically, what that will mean is that our PM domain layer (omap_device)
will also call omap_device_idle() in the suspend path, but only if the
device is *not* already idle (from previous runtime suspend.)  The PM
domain layer will then omap_device_enable() the device in the system
resume path if it was suspended in the system suspend path.  A minimally
tested patch to do this is below.

So, the driver still does not have to care about it's specific clocks
etc. (which should address Felipe's concern), clocks and other
IP-specific PM details will all continue to be handled by omap_device,
just like it is with runtime PM.

The primary change to the driver, is that whatever needs to be done to
prepare for both runtime PM and system PM (including context
save/restore etc.) will have to be done in a common function(s) that
will be called by *both* of its ->runtime_suspend() and ->suspend()
callbacks, and similar for ->runtime_resume() and ->resume().  

Some drivers will have additional work to do for system PM though.  This
is mainly because system PM can happen at *any* time, including in the
middle of ongoing activity, whereas runtime PM transitions happen when
the device is known to be idle.  What that means is that for example, a
drivers ->suspend() method might need to wait for (or forcibly stop) any
ongoing activity in order to be sure the device is ready to be suspended.

Frankly, this is not a very big change for the drivers, as the
device-specific idle work will still be handled by the PM domain layer.

Hope that helps clarify the background.

As for this particular patch, since it is rather late in the development
cycle for v3.1, I would recommend that it wait until the omap_device
changes, and then let the PM core (for system PM and runtime PM) handle
the parent/child relationships as they are designed to.   But that is up
to Felipe and USB maintainers to decide.

Kevin

[1] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031559.html
[2] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031977.html


>From 6696e9a2b106ca9c9936e5c2ad89650010120e10 Mon Sep 17 00:00:00 2001
From: Kevin Hilman <khilman@ti.com>
Date: Tue, 7 Jun 2011 16:07:28 -0700
Subject: [PATCH] OMAP: PM: omap_device: add system PM methods for PM domain handling

Using PM domain callbacks, use omap_device idle/enable to
automatically suspend/resume devices.  Also use pm_generic_* routines
to ensure driver's callbacks are correctly called.

Driver ->suspend callback is needed to ensure the driver is in a state
that it can be suspended.

If device is already idle (typically because of previous runtime PM
activity), there's nothing extra to do.

KJH: The omap_device_* calls should probably actually be done in the
     _noirq() methods.

Not-yet-Signed-off-by: Kevin Hilman <khilman@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    4 +++
 arch/arm/plat-omap/omap_device.c              |   32 +++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349f..bc36d05 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -44,6 +44,9 @@ extern struct device omap_device_parent;
 #define OMAP_DEVICE_STATE_IDLE		2
 #define OMAP_DEVICE_STATE_SHUTDOWN	3
 
+/* omap_device.flags values */
+#define OMAP_DEVICE_SUSPENDED BIT(0)
+
 /**
  * struct omap_device - omap_device wrapper for platform_devices
  * @pdev: platform_device
@@ -73,6 +76,7 @@ struct omap_device {
 	s8				pm_lat_level;
 	u8				hwmods_cnt;
 	u8				_state;
+	u8                              flags;
 };
 
 /* Device driver interface (call via platform_data fn ptrs) */
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 49fc0df..f2711c3 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -564,12 +564,44 @@ static int _od_runtime_resume(struct device *dev)
 	return pm_generic_runtime_resume(dev);
 }
 
+static int _od_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *od = to_omap_device(pdev);
+	int ret;
+
+	ret = pm_generic_suspend(dev);
+
+	od->flags &= ~OMAP_DEVICE_SUSPENDED;
+
+	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+		omap_device_idle(pdev);
+		od->flags |= OMAP_DEVICE_SUSPENDED;
+	}
+
+	return ret;
+}
+
+static int _od_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *od = to_omap_device(pdev);
+
+	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
+	    (od->_state == OMAP_DEVICE_STATE_IDLE))
+		omap_device_enable(pdev);
+	
+	return pm_generic_resume(dev);
+}
+
 static struct dev_power_domain omap_device_power_domain = {
 	.ops = {
 		.runtime_suspend = _od_runtime_suspend,
 		.runtime_idle = _od_runtime_idle,
 		.runtime_resume = _od_runtime_resume,
 		USE_PLATFORM_PM_SLEEP_OPS
+		.suspend = _od_suspend,
+		.resume = _od_resume,
 	}
 };
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-05 17:37                         ` Kevin Hilman
  0 siblings, 0 replies; 49+ messages in thread
From: Kevin Hilman @ 2011-07-05 17:37 UTC (permalink / raw)
  To: Alan Stern
  Cc: Partha Basak, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Felipe Balbi, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

Alan Stern <stern@rowland.harvard.edu> writes:

[...]

>>>You have ignored a few very important points:
>>>
>>>Firstly, system suspend is supposed to work even when runtime PM is
>>>not configured.
>>>
>>>Secondly, the user can disable runtime PM via sysfs at any time.
>>>This shouldn't mess up system suspend.
>>>
>>>Basically, it's a bad idea to mix up system suspend with runtime PM.
>> 
>> Your observations are correct but this is a generic limitation and
>> Kevin is working on this problem in parallel.
>> 
>> As of now, all OMAP drivers are mandated to use ONLY runtime pm framework
>> for enabling/disabling clocks. I will let Kevin comment further.
>
> Okay, let's see what Kevin says.

While I did design the OMAP PM core to be runtime PM centric, and we
implemented several drivers based on runtime PM alone, after some long
discussions on linux-pm[1] with Alan and Rafael (PM maintainer) over the
last couple weeks, I'm now convinced I had the wrong design/approach.

Rafael and Alan have been patient with my stubborness, but now I've been
pursuaded.  Rafael has detailed on linux-pm the various
problems/limitations/races between runtime PM and system PM[2], so I
don't plan debating them again here.

That being said, today we have several drivers that use runtime PM calls
in their suspend/resume path and our PM domain implementation (inside
omap_device) deals with most of the limitations fine.  However, there
are 2 main problems/limitation with this that we've chosen to live with
(for now):
        
1) synchronous calls must be used in the suspend/resume path (because
   PM workqueue is frozen during suspend/resumea)
2) disabling runtime PM from userspace will prevent that device
   from hitting its low-power state during suspend.

For v3.1 (and before), we've lived with these limitations, and I'm OK
with merging other drivers for v3.1 with these limitations.  After 3.1,
this will be changing (more on this below.)  

So, while I've been OK with merging drivers with the above limitations
for one more merge window, $SUBJECT patch adds a new twist by forcibly
managing the parent device from the child device.  Personally, I really
don't like that approach and it serves as a good illustration of yet
another reason why system PM and runtime PM need understood as
conceptually very different.

For v3.2, the PM core will change[2] to futher limit/protect
interactions between runtime PM and system PM, and I will be reworking
our PM domain (omap_device) implementation accordingly.  

Basically, what that will mean is that our PM domain layer (omap_device)
will also call omap_device_idle() in the suspend path, but only if the
device is *not* already idle (from previous runtime suspend.)  The PM
domain layer will then omap_device_enable() the device in the system
resume path if it was suspended in the system suspend path.  A minimally
tested patch to do this is below.

So, the driver still does not have to care about it's specific clocks
etc. (which should address Felipe's concern), clocks and other
IP-specific PM details will all continue to be handled by omap_device,
just like it is with runtime PM.

The primary change to the driver, is that whatever needs to be done to
prepare for both runtime PM and system PM (including context
save/restore etc.) will have to be done in a common function(s) that
will be called by *both* of its ->runtime_suspend() and ->suspend()
callbacks, and similar for ->runtime_resume() and ->resume().  

Some drivers will have additional work to do for system PM though.  This
is mainly because system PM can happen at *any* time, including in the
middle of ongoing activity, whereas runtime PM transitions happen when
the device is known to be idle.  What that means is that for example, a
drivers ->suspend() method might need to wait for (or forcibly stop) any
ongoing activity in order to be sure the device is ready to be suspended.

Frankly, this is not a very big change for the drivers, as the
device-specific idle work will still be handled by the PM domain layer.

Hope that helps clarify the background.

As for this particular patch, since it is rather late in the development
cycle for v3.1, I would recommend that it wait until the omap_device
changes, and then let the PM core (for system PM and runtime PM) handle
the parent/child relationships as they are designed to.   But that is up
to Felipe and USB maintainers to decide.

Kevin

[1] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031559.html
[2] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031977.html


>From 6696e9a2b106ca9c9936e5c2ad89650010120e10 Mon Sep 17 00:00:00 2001
From: Kevin Hilman <khilman@ti.com>
Date: Tue, 7 Jun 2011 16:07:28 -0700
Subject: [PATCH] OMAP: PM: omap_device: add system PM methods for PM domain handling

Using PM domain callbacks, use omap_device idle/enable to
automatically suspend/resume devices.  Also use pm_generic_* routines
to ensure driver's callbacks are correctly called.

Driver ->suspend callback is needed to ensure the driver is in a state
that it can be suspended.

If device is already idle (typically because of previous runtime PM
activity), there's nothing extra to do.

KJH: The omap_device_* calls should probably actually be done in the
     _noirq() methods.

Not-yet-Signed-off-by: Kevin Hilman <khilman@ti.com>
---
 arch/arm/plat-omap/include/plat/omap_device.h |    4 +++
 arch/arm/plat-omap/omap_device.c              |   32 +++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349f..bc36d05 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -44,6 +44,9 @@ extern struct device omap_device_parent;
 #define OMAP_DEVICE_STATE_IDLE		2
 #define OMAP_DEVICE_STATE_SHUTDOWN	3
 
+/* omap_device.flags values */
+#define OMAP_DEVICE_SUSPENDED BIT(0)
+
 /**
  * struct omap_device - omap_device wrapper for platform_devices
  * @pdev: platform_device
@@ -73,6 +76,7 @@ struct omap_device {
 	s8				pm_lat_level;
 	u8				hwmods_cnt;
 	u8				_state;
+	u8                              flags;
 };
 
 /* Device driver interface (call via platform_data fn ptrs) */
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 49fc0df..f2711c3 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -564,12 +564,44 @@ static int _od_runtime_resume(struct device *dev)
 	return pm_generic_runtime_resume(dev);
 }
 
+static int _od_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *od = to_omap_device(pdev);
+	int ret;
+
+	ret = pm_generic_suspend(dev);
+
+	od->flags &= ~OMAP_DEVICE_SUSPENDED;
+
+	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+		omap_device_idle(pdev);
+		od->flags |= OMAP_DEVICE_SUSPENDED;
+	}
+
+	return ret;
+}
+
+static int _od_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *od = to_omap_device(pdev);
+
+	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
+	    (od->_state == OMAP_DEVICE_STATE_IDLE))
+		omap_device_enable(pdev);
+	
+	return pm_generic_resume(dev);
+}
+
 static struct dev_power_domain omap_device_power_domain = {
 	.ops = {
 		.runtime_suspend = _od_runtime_suspend,
 		.runtime_idle = _od_runtime_idle,
 		.runtime_resume = _od_runtime_resume,
 		USE_PLATFORM_PM_SLEEP_OPS
+		.suspend = _od_suspend,
+		.resume = _od_resume,
 	}
 };
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-05 17:37                         ` Kevin Hilman
  (?)
@ 2011-07-06 17:54                         ` Felipe Balbi
  2011-07-06 19:20                             ` Kevin Hilman
  -1 siblings, 1 reply; 49+ messages in thread
From: Felipe Balbi @ 2011-07-06 17:54 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Alan Stern, Partha Basak, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, Felipe Balbi, Anand Gadiyar, sameo,
	parthab, tony, Benoit Cousson, paul, johnstul,
	Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 8066 bytes --]

Hi,

On Tue, Jul 05, 2011 at 10:37:40AM -0700, Kevin Hilman wrote:
> While I did design the OMAP PM core to be runtime PM centric, and we
> implemented several drivers based on runtime PM alone, after some long
> discussions on linux-pm[1] with Alan and Rafael (PM maintainer) over the
> last couple weeks, I'm now convinced I had the wrong design/approach.
> 
> Rafael and Alan have been patient with my stubborness, but now I've been
> pursuaded.  Rafael has detailed on linux-pm the various
> problems/limitations/races between runtime PM and system PM[2], so I
> don't plan debating them again here.
> 
> That being said, today we have several drivers that use runtime PM calls
> in their suspend/resume path and our PM domain implementation (inside
> omap_device) deals with most of the limitations fine.  However, there
> are 2 main problems/limitation with this that we've chosen to live with
> (for now):
>         
> 1) synchronous calls must be used in the suspend/resume path (because
>    PM workqueue is frozen during suspend/resumea)
> 2) disabling runtime PM from userspace will prevent that device
>    from hitting its low-power state during suspend.
> 
> For v3.1 (and before), we've lived with these limitations, and I'm OK
> with merging other drivers for v3.1 with these limitations.  After 3.1,
> this will be changing (more on this below.)  
> 
> So, while I've been OK with merging drivers with the above limitations
> for one more merge window, $SUBJECT patch adds a new twist by forcibly
> managing the parent device from the child device.  Personally, I really
> don't like that approach and it serves as a good illustration of yet
> another reason why system PM and runtime PM need understood as
> conceptually very different.
> 
> For v3.2, the PM core will change[2] to futher limit/protect
> interactions between runtime PM and system PM, and I will be reworking
> our PM domain (omap_device) implementation accordingly.  
> 
> Basically, what that will mean is that our PM domain layer (omap_device)
> will also call omap_device_idle() in the suspend path, but only if the
> device is *not* already idle (from previous runtime suspend.)  The PM
> domain layer will then omap_device_enable() the device in the system
> resume path if it was suspended in the system suspend path.  A minimally
> tested patch to do this is below.
> 
> So, the driver still does not have to care about it's specific clocks
> etc. (which should address Felipe's concern), clocks and other
> IP-specific PM details will all continue to be handled by omap_device,
> just like it is with runtime PM.
> 
> The primary change to the driver, is that whatever needs to be done to
> prepare for both runtime PM and system PM (including context
> save/restore etc.) will have to be done in a common function(s) that
> will be called by *both* of its ->runtime_suspend() and ->suspend()
> callbacks, and similar for ->runtime_resume() and ->resume().  
> 
> Some drivers will have additional work to do for system PM though.  This
> is mainly because system PM can happen at *any* time, including in the
> middle of ongoing activity, whereas runtime PM transitions happen when
> the device is known to be idle.  What that means is that for example, a
> drivers ->suspend() method might need to wait for (or forcibly stop) any
> ongoing activity in order to be sure the device is ready to be suspended.
> 
> Frankly, this is not a very big change for the drivers, as the
> device-specific idle work will still be handled by the PM domain layer.
> 
> Hope that helps clarify the background.
> 
> As for this particular patch, since it is rather late in the development
> cycle for v3.1, I would recommend that it wait until the omap_device
> changes, and then let the PM core (for system PM and runtime PM) handle
> the parent/child relationships as they are designed to.   But that is up
> to Felipe and USB maintainers to decide.
> 
> Kevin
> 
> [1] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031559.html
> [2] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031977.html
> 
> 
> From 6696e9a2b106ca9c9936e5c2ad89650010120e10 Mon Sep 17 00:00:00 2001
> From: Kevin Hilman <khilman@ti.com>
> Date: Tue, 7 Jun 2011 16:07:28 -0700
> Subject: [PATCH] OMAP: PM: omap_device: add system PM methods for PM domain handling
> 
> Using PM domain callbacks, use omap_device idle/enable to
> automatically suspend/resume devices.  Also use pm_generic_* routines
> to ensure driver's callbacks are correctly called.
> 
> Driver ->suspend callback is needed to ensure the driver is in a state
> that it can be suspended.
> 
> If device is already idle (typically because of previous runtime PM
> activity), there's nothing extra to do.
> 
> KJH: The omap_device_* calls should probably actually be done in the
>      _noirq() methods.
> 
> Not-yet-Signed-off-by: Kevin Hilman <khilman@ti.com>
> ---
>  arch/arm/plat-omap/include/plat/omap_device.h |    4 +++
>  arch/arm/plat-omap/omap_device.c              |   32 +++++++++++++++++++++++++
>  2 files changed, 36 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
> index e4c349f..bc36d05 100644
> --- a/arch/arm/plat-omap/include/plat/omap_device.h
> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
> @@ -44,6 +44,9 @@ extern struct device omap_device_parent;
>  #define OMAP_DEVICE_STATE_IDLE		2
>  #define OMAP_DEVICE_STATE_SHUTDOWN	3
>  
> +/* omap_device.flags values */
> +#define OMAP_DEVICE_SUSPENDED BIT(0)
> +
>  /**
>   * struct omap_device - omap_device wrapper for platform_devices
>   * @pdev: platform_device
> @@ -73,6 +76,7 @@ struct omap_device {
>  	s8				pm_lat_level;
>  	u8				hwmods_cnt;
>  	u8				_state;
> +	u8                              flags;
>  };
>  
>  /* Device driver interface (call via platform_data fn ptrs) */
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 49fc0df..f2711c3 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -564,12 +564,44 @@ static int _od_runtime_resume(struct device *dev)
>  	return pm_generic_runtime_resume(dev);
>  }
>  
> +static int _od_suspend(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct omap_device *od = to_omap_device(pdev);
> +	int ret;
> +
> +	ret = pm_generic_suspend(dev);
> +
> +	od->flags &= ~OMAP_DEVICE_SUSPENDED;
> +
> +	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
> +		omap_device_idle(pdev);
> +		od->flags |= OMAP_DEVICE_SUSPENDED;
> +	}
> +
> +	return ret;
> +}
> +
> +static int _od_resume(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct omap_device *od = to_omap_device(pdev);

seems like you guys have duplicated helpers for this. There's
_find_by_pdev() and to_omap_device and both do the exact same thing:

static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
{
	return container_of(pdev, struct omap_device, pdev);
}

#define to_omap_device(x) container_of((x), struct omap_device, pdev)

> +
> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
> +		omap_device_enable(pdev);
> +	
> +	return pm_generic_resume(dev);
> +}
> +
>  static struct dev_power_domain omap_device_power_domain = {
>  	.ops = {
>  		.runtime_suspend = _od_runtime_suspend,
>  		.runtime_idle = _od_runtime_idle,
>  		.runtime_resume = _od_runtime_resume,
>  		USE_PLATFORM_PM_SLEEP_OPS
> +		.suspend = _od_suspend,
> +		.resume = _od_resume,
>  	}
>  };

it all depends on when are you planning to get this patch upstream. I'm
considering getting some PM working on USB host and remove the
pm_runtime calls from system suspend/resume either during -rc or next
merge window.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-06 19:20                             ` Kevin Hilman
  0 siblings, 0 replies; 49+ messages in thread
From: Kevin Hilman @ 2011-07-06 19:20 UTC (permalink / raw)
  To: balbi
  Cc: Alan Stern, Partha Basak, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

Felipe Balbi <balbi@ti.com> writes:

> Hi,
>
> On Tue, Jul 05, 2011 at 10:37:40AM -0700, Kevin Hilman wrote:
>> While I did design the OMAP PM core to be runtime PM centric, and we
>> implemented several drivers based on runtime PM alone, after some long
>> discussions on linux-pm[1] with Alan and Rafael (PM maintainer) over the
>> last couple weeks, I'm now convinced I had the wrong design/approach.
>> 
>> Rafael and Alan have been patient with my stubborness, but now I've been
>> pursuaded.  Rafael has detailed on linux-pm the various
>> problems/limitations/races between runtime PM and system PM[2], so I
>> don't plan debating them again here.
>> 
>> That being said, today we have several drivers that use runtime PM calls
>> in their suspend/resume path and our PM domain implementation (inside
>> omap_device) deals with most of the limitations fine.  However, there
>> are 2 main problems/limitation with this that we've chosen to live with
>> (for now):
>>         
>> 1) synchronous calls must be used in the suspend/resume path (because
>>    PM workqueue is frozen during suspend/resumea)
>> 2) disabling runtime PM from userspace will prevent that device
>>    from hitting its low-power state during suspend.
>> 
>> For v3.1 (and before), we've lived with these limitations, and I'm OK
>> with merging other drivers for v3.1 with these limitations.  After 3.1,
>> this will be changing (more on this below.)  
>> 
>> So, while I've been OK with merging drivers with the above limitations
>> for one more merge window, $SUBJECT patch adds a new twist by forcibly
>> managing the parent device from the child device.  Personally, I really
>> don't like that approach and it serves as a good illustration of yet
>> another reason why system PM and runtime PM need understood as
>> conceptually very different.
>> 
>> For v3.2, the PM core will change[2] to futher limit/protect
>> interactions between runtime PM and system PM, and I will be reworking
>> our PM domain (omap_device) implementation accordingly.  
>> 
>> Basically, what that will mean is that our PM domain layer (omap_device)
>> will also call omap_device_idle() in the suspend path, but only if the
>> device is *not* already idle (from previous runtime suspend.)  The PM
>> domain layer will then omap_device_enable() the device in the system
>> resume path if it was suspended in the system suspend path.  A minimally
>> tested patch to do this is below.
>> 
>> So, the driver still does not have to care about it's specific clocks
>> etc. (which should address Felipe's concern), clocks and other
>> IP-specific PM details will all continue to be handled by omap_device,
>> just like it is with runtime PM.
>> 
>> The primary change to the driver, is that whatever needs to be done to
>> prepare for both runtime PM and system PM (including context
>> save/restore etc.) will have to be done in a common function(s) that
>> will be called by *both* of its ->runtime_suspend() and ->suspend()
>> callbacks, and similar for ->runtime_resume() and ->resume().  
>> 
>> Some drivers will have additional work to do for system PM though.  This
>> is mainly because system PM can happen at *any* time, including in the
>> middle of ongoing activity, whereas runtime PM transitions happen when
>> the device is known to be idle.  What that means is that for example, a
>> drivers ->suspend() method might need to wait for (or forcibly stop) any
>> ongoing activity in order to be sure the device is ready to be suspended.
>> 
>> Frankly, this is not a very big change for the drivers, as the
>> device-specific idle work will still be handled by the PM domain layer.
>> 
>> Hope that helps clarify the background.
>> 
>> As for this particular patch, since it is rather late in the development
>> cycle for v3.1, I would recommend that it wait until the omap_device
>> changes, and then let the PM core (for system PM and runtime PM) handle
>> the parent/child relationships as they are designed to.   But that is up
>> to Felipe and USB maintainers to decide.
>> 
>> Kevin
>> 
>> [1] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031559.html
>> [2] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031977.html
>> 
>> 
>> From 6696e9a2b106ca9c9936e5c2ad89650010120e10 Mon Sep 17 00:00:00 2001
>> From: Kevin Hilman <khilman@ti.com>
>> Date: Tue, 7 Jun 2011 16:07:28 -0700
>> Subject: [PATCH] OMAP: PM: omap_device: add system PM methods for PM domain handling
>> 
>> Using PM domain callbacks, use omap_device idle/enable to
>> automatically suspend/resume devices.  Also use pm_generic_* routines
>> to ensure driver's callbacks are correctly called.
>> 
>> Driver ->suspend callback is needed to ensure the driver is in a state
>> that it can be suspended.
>> 
>> If device is already idle (typically because of previous runtime PM
>> activity), there's nothing extra to do.
>> 
>> KJH: The omap_device_* calls should probably actually be done in the
>>      _noirq() methods.
>> 
>> Not-yet-Signed-off-by: Kevin Hilman <khilman@ti.com>
>> ---
>>  arch/arm/plat-omap/include/plat/omap_device.h |    4 +++
>>  arch/arm/plat-omap/omap_device.c              |   32 +++++++++++++++++++++++++
>>  2 files changed, 36 insertions(+), 0 deletions(-)
>> 
>> diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
>> index e4c349f..bc36d05 100644
>> --- a/arch/arm/plat-omap/include/plat/omap_device.h
>> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
>> @@ -44,6 +44,9 @@ extern struct device omap_device_parent;
>>  #define OMAP_DEVICE_STATE_IDLE		2
>>  #define OMAP_DEVICE_STATE_SHUTDOWN	3
>>  
>> +/* omap_device.flags values */
>> +#define OMAP_DEVICE_SUSPENDED BIT(0)
>> +
>>  /**
>>   * struct omap_device - omap_device wrapper for platform_devices
>>   * @pdev: platform_device
>> @@ -73,6 +76,7 @@ struct omap_device {
>>  	s8				pm_lat_level;
>>  	u8				hwmods_cnt;
>>  	u8				_state;
>> +	u8                              flags;
>>  };
>>  
>>  /* Device driver interface (call via platform_data fn ptrs) */
>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
>> index 49fc0df..f2711c3 100644
>> --- a/arch/arm/plat-omap/omap_device.c
>> +++ b/arch/arm/plat-omap/omap_device.c
>> @@ -564,12 +564,44 @@ static int _od_runtime_resume(struct device *dev)
>>  	return pm_generic_runtime_resume(dev);
>>  }
>>  
>> +static int _od_suspend(struct device *dev)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct omap_device *od = to_omap_device(pdev);
>> +	int ret;
>> +
>> +	ret = pm_generic_suspend(dev);
>> +
>> +	od->flags &= ~OMAP_DEVICE_SUSPENDED;
>> +
>> +	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>> +		omap_device_idle(pdev);
>> +		od->flags |= OMAP_DEVICE_SUSPENDED;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int _od_resume(struct device *dev)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct omap_device *od = to_omap_device(pdev);
>
> seems like you guys have duplicated helpers for this. There's
> _find_by_pdev() and to_omap_device and both do the exact same thing:
>
> static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
> {
> 	return container_of(pdev, struct omap_device, pdev);
> }
>
> #define to_omap_device(x) container_of((x), struct omap_device, pdev)

Yeah, I know.

>> +
>> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
>> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
>> +		omap_device_enable(pdev);
>> +	
>> +	return pm_generic_resume(dev);
>> +}
>> +
>>  static struct dev_power_domain omap_device_power_domain = {
>>  	.ops = {
>>  		.runtime_suspend = _od_runtime_suspend,
>>  		.runtime_idle = _od_runtime_idle,
>>  		.runtime_resume = _od_runtime_resume,
>>  		USE_PLATFORM_PM_SLEEP_OPS
>> +		.suspend = _od_suspend,
>> +		.resume = _od_resume,
>>  	}
>>  };
>
> it all depends on when are you planning to get this patch upstream. I'm
> considering getting some PM working on USB host and remove the
> pm_runtime calls from system suspend/resume either during -rc or next
> merge window.

Well, IMO it's way too late for this kind of change for -rc, so I'm
considering it for the upcoming merge window.

Kevin

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-06 19:20                             ` Kevin Hilman
  0 siblings, 0 replies; 49+ messages in thread
From: Kevin Hilman @ 2011-07-06 19:20 UTC (permalink / raw)
  To: balbi-l0cyMroinI0
  Cc: Alan Stern, Partha Basak, Keshava Munegowda,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Anand Gadiyar,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, Benoit Cousson,
	paul-DWxLp4Yu+b8AvxtiuMwx3w, johnstul-r/Jw6+rmf7HQT0dZR+AlfA,
	Vishwanath Sripathy

Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org> writes:

> Hi,
>
> On Tue, Jul 05, 2011 at 10:37:40AM -0700, Kevin Hilman wrote:
>> While I did design the OMAP PM core to be runtime PM centric, and we
>> implemented several drivers based on runtime PM alone, after some long
>> discussions on linux-pm[1] with Alan and Rafael (PM maintainer) over the
>> last couple weeks, I'm now convinced I had the wrong design/approach.
>> 
>> Rafael and Alan have been patient with my stubborness, but now I've been
>> pursuaded.  Rafael has detailed on linux-pm the various
>> problems/limitations/races between runtime PM and system PM[2], so I
>> don't plan debating them again here.
>> 
>> That being said, today we have several drivers that use runtime PM calls
>> in their suspend/resume path and our PM domain implementation (inside
>> omap_device) deals with most of the limitations fine.  However, there
>> are 2 main problems/limitation with this that we've chosen to live with
>> (for now):
>>         
>> 1) synchronous calls must be used in the suspend/resume path (because
>>    PM workqueue is frozen during suspend/resumea)
>> 2) disabling runtime PM from userspace will prevent that device
>>    from hitting its low-power state during suspend.
>> 
>> For v3.1 (and before), we've lived with these limitations, and I'm OK
>> with merging other drivers for v3.1 with these limitations.  After 3.1,
>> this will be changing (more on this below.)  
>> 
>> So, while I've been OK with merging drivers with the above limitations
>> for one more merge window, $SUBJECT patch adds a new twist by forcibly
>> managing the parent device from the child device.  Personally, I really
>> don't like that approach and it serves as a good illustration of yet
>> another reason why system PM and runtime PM need understood as
>> conceptually very different.
>> 
>> For v3.2, the PM core will change[2] to futher limit/protect
>> interactions between runtime PM and system PM, and I will be reworking
>> our PM domain (omap_device) implementation accordingly.  
>> 
>> Basically, what that will mean is that our PM domain layer (omap_device)
>> will also call omap_device_idle() in the suspend path, but only if the
>> device is *not* already idle (from previous runtime suspend.)  The PM
>> domain layer will then omap_device_enable() the device in the system
>> resume path if it was suspended in the system suspend path.  A minimally
>> tested patch to do this is below.
>> 
>> So, the driver still does not have to care about it's specific clocks
>> etc. (which should address Felipe's concern), clocks and other
>> IP-specific PM details will all continue to be handled by omap_device,
>> just like it is with runtime PM.
>> 
>> The primary change to the driver, is that whatever needs to be done to
>> prepare for both runtime PM and system PM (including context
>> save/restore etc.) will have to be done in a common function(s) that
>> will be called by *both* of its ->runtime_suspend() and ->suspend()
>> callbacks, and similar for ->runtime_resume() and ->resume().  
>> 
>> Some drivers will have additional work to do for system PM though.  This
>> is mainly because system PM can happen at *any* time, including in the
>> middle of ongoing activity, whereas runtime PM transitions happen when
>> the device is known to be idle.  What that means is that for example, a
>> drivers ->suspend() method might need to wait for (or forcibly stop) any
>> ongoing activity in order to be sure the device is ready to be suspended.
>> 
>> Frankly, this is not a very big change for the drivers, as the
>> device-specific idle work will still be handled by the PM domain layer.
>> 
>> Hope that helps clarify the background.
>> 
>> As for this particular patch, since it is rather late in the development
>> cycle for v3.1, I would recommend that it wait until the omap_device
>> changes, and then let the PM core (for system PM and runtime PM) handle
>> the parent/child relationships as they are designed to.   But that is up
>> to Felipe and USB maintainers to decide.
>> 
>> Kevin
>> 
>> [1] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031559.html
>> [2] https://lists.linux-foundation.org/pipermail/linux-pm/2011-June/031977.html
>> 
>> 
>> From 6696e9a2b106ca9c9936e5c2ad89650010120e10 Mon Sep 17 00:00:00 2001
>> From: Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org>
>> Date: Tue, 7 Jun 2011 16:07:28 -0700
>> Subject: [PATCH] OMAP: PM: omap_device: add system PM methods for PM domain handling
>> 
>> Using PM domain callbacks, use omap_device idle/enable to
>> automatically suspend/resume devices.  Also use pm_generic_* routines
>> to ensure driver's callbacks are correctly called.
>> 
>> Driver ->suspend callback is needed to ensure the driver is in a state
>> that it can be suspended.
>> 
>> If device is already idle (typically because of previous runtime PM
>> activity), there's nothing extra to do.
>> 
>> KJH: The omap_device_* calls should probably actually be done in the
>>      _noirq() methods.
>> 
>> Not-yet-Signed-off-by: Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org>
>> ---
>>  arch/arm/plat-omap/include/plat/omap_device.h |    4 +++
>>  arch/arm/plat-omap/omap_device.c              |   32 +++++++++++++++++++++++++
>>  2 files changed, 36 insertions(+), 0 deletions(-)
>> 
>> diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
>> index e4c349f..bc36d05 100644
>> --- a/arch/arm/plat-omap/include/plat/omap_device.h
>> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
>> @@ -44,6 +44,9 @@ extern struct device omap_device_parent;
>>  #define OMAP_DEVICE_STATE_IDLE		2
>>  #define OMAP_DEVICE_STATE_SHUTDOWN	3
>>  
>> +/* omap_device.flags values */
>> +#define OMAP_DEVICE_SUSPENDED BIT(0)
>> +
>>  /**
>>   * struct omap_device - omap_device wrapper for platform_devices
>>   * @pdev: platform_device
>> @@ -73,6 +76,7 @@ struct omap_device {
>>  	s8				pm_lat_level;
>>  	u8				hwmods_cnt;
>>  	u8				_state;
>> +	u8                              flags;
>>  };
>>  
>>  /* Device driver interface (call via platform_data fn ptrs) */
>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
>> index 49fc0df..f2711c3 100644
>> --- a/arch/arm/plat-omap/omap_device.c
>> +++ b/arch/arm/plat-omap/omap_device.c
>> @@ -564,12 +564,44 @@ static int _od_runtime_resume(struct device *dev)
>>  	return pm_generic_runtime_resume(dev);
>>  }
>>  
>> +static int _od_suspend(struct device *dev)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct omap_device *od = to_omap_device(pdev);
>> +	int ret;
>> +
>> +	ret = pm_generic_suspend(dev);
>> +
>> +	od->flags &= ~OMAP_DEVICE_SUSPENDED;
>> +
>> +	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>> +		omap_device_idle(pdev);
>> +		od->flags |= OMAP_DEVICE_SUSPENDED;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int _od_resume(struct device *dev)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct omap_device *od = to_omap_device(pdev);
>
> seems like you guys have duplicated helpers for this. There's
> _find_by_pdev() and to_omap_device and both do the exact same thing:
>
> static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
> {
> 	return container_of(pdev, struct omap_device, pdev);
> }
>
> #define to_omap_device(x) container_of((x), struct omap_device, pdev)

Yeah, I know.

>> +
>> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
>> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
>> +		omap_device_enable(pdev);
>> +	
>> +	return pm_generic_resume(dev);
>> +}
>> +
>>  static struct dev_power_domain omap_device_power_domain = {
>>  	.ops = {
>>  		.runtime_suspend = _od_runtime_suspend,
>>  		.runtime_idle = _od_runtime_idle,
>>  		.runtime_resume = _od_runtime_resume,
>>  		USE_PLATFORM_PM_SLEEP_OPS
>> +		.suspend = _od_suspend,
>> +		.resume = _od_resume,
>>  	}
>>  };
>
> it all depends on when are you planning to get this patch upstream. I'm
> considering getting some PM working on USB host and remove the
> pm_runtime calls from system suspend/resume either during -rc or next
> merge window.

Well, IMO it's way too late for this kind of change for -rc, so I'm
considering it for the upcoming merge window.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-06 19:20                             ` Kevin Hilman
  (?)
@ 2011-07-06 22:17                             ` Felipe Balbi
  2011-07-07  4:53                                 ` Partha Basak
  -1 siblings, 1 reply; 49+ messages in thread
From: Felipe Balbi @ 2011-07-06 22:17 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: balbi, Alan Stern, Partha Basak, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 1155 bytes --]

Hi,

On Wed, Jul 06, 2011 at 12:20:40PM -0700, Kevin Hilman wrote:
> >> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
> >> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
> >> +		omap_device_enable(pdev);
> >> +	
> >> +	return pm_generic_resume(dev);
> >> +}
> >> +
> >>  static struct dev_power_domain omap_device_power_domain = {
> >>  	.ops = {
> >>  		.runtime_suspend = _od_runtime_suspend,
> >>  		.runtime_idle = _od_runtime_idle,
> >>  		.runtime_resume = _od_runtime_resume,
> >>  		USE_PLATFORM_PM_SLEEP_OPS
> >> +		.suspend = _od_suspend,
> >> +		.resume = _od_resume,
> >>  	}
> >>  };
> >
> > it all depends on when are you planning to get this patch upstream. I'm
> > considering getting some PM working on USB host and remove the
> > pm_runtime calls from system suspend/resume either during -rc or next
> > merge window.
> 
> Well, IMO it's way too late for this kind of change for -rc, so I'm
> considering it for the upcoming merge window.

yes, that's true. Who should take the hwmod patches btw ? I'm still
wondering if we should patch hwmod data first and push the _correct_ PM
part on 3.2.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-07  4:53                                 ` Partha Basak
  0 siblings, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-07  4:53 UTC (permalink / raw)
  To: balbi, Kevin Hilman
  Cc: Alan Stern, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

>-----Original Message-----
>From: Felipe Balbi [mailto:balbi@ti.com]
>Sent: Thursday, July 07, 2011 3:48 AM
>To: Kevin Hilman
>Cc: balbi@ti.com; Alan Stern; Partha Basak; Keshava Munegowda; linux-
>usb@vger.kernel.org; linux-omap@vger.kernel.org; linux-
>kernel@vger.kernel.org; Anand Gadiyar; sameo@linux.intel.com;
>parthab@india.ti.com; tony@atomide.com; Benoit Cousson; paul@pwsan.com;
>johnstul@us.ibm.com; Vishwanath Sripathy
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>Hi,
>
>On Wed, Jul 06, 2011 at 12:20:40PM -0700, Kevin Hilman wrote:
>> >> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
>> >> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
>> >> +		omap_device_enable(pdev);
>> >> +
>> >> +	return pm_generic_resume(dev);
>> >> +}
>> >> +
>> >>  static struct dev_power_domain omap_device_power_domain = {
>> >>  	.ops = {
>> >>  		.runtime_suspend = _od_runtime_suspend,
>> >>  		.runtime_idle = _od_runtime_idle,
>> >>  		.runtime_resume = _od_runtime_resume,
>> >>  		USE_PLATFORM_PM_SLEEP_OPS
>> >> +		.suspend = _od_suspend,
>> >> +		.resume = _od_resume,
>> >>  	}
>> >>  };
>> >
>> > it all depends on when are you planning to get this patch upstream.
>> > I'm considering getting some PM working on USB host and remove the
>> > pm_runtime calls from system suspend/resume either during -rc or
>> > next merge window.
>>
>> Well, IMO it's way too late for this kind of change for -rc, so I'm
>> considering it for the upcoming merge window.
>
>yes, that's true. Who should take the hwmod patches btw ? I'm still
>wondering if we should patch hwmod data first and push the _correct_ PM
>part on 3.2.

Once Kevin pushes this infrastructure enhancement, all drivers have to
rework
the Suspend/Resume anyways. Another way would be to go by the current
approach
now and then do the rework in 3.2 along with other drivers.

In this way, we can soak the Runtime support of EHCI/OHCI for one merge
window.
>
>--
>balbi

^ permalink raw reply	[flat|nested] 49+ messages in thread

* RE: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
@ 2011-07-07  4:53                                 ` Partha Basak
  0 siblings, 0 replies; 49+ messages in thread
From: Partha Basak @ 2011-07-07  4:53 UTC (permalink / raw)
  To: balbi-l0cyMroinI0, Kevin Hilman
  Cc: Alan Stern, Keshava Munegowda, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Anand Gadiyar,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, Benoit Cousson,
	paul-DWxLp4Yu+b8AvxtiuMwx3w, johnstul-r/Jw6+rmf7HQT0dZR+AlfA,
	Vishwanath Sripathy

>-----Original Message-----
>From: Felipe Balbi [mailto:balbi-l0cyMroinI0@public.gmane.org]
>Sent: Thursday, July 07, 2011 3:48 AM
>To: Kevin Hilman
>Cc: balbi-l0cyMroinI0@public.gmane.org; Alan Stern; Partha Basak; Keshava Munegowda; linux-
>usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-
>kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Anand Gadiyar; sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org;
>parthab-PpE0FKYn9XJWk0Htik3J/w@public.gmane.org; tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org; Benoit Cousson; paul-DWxLp4Yu+b8AvxtiuMwx3w@public.gmane.org;
>johnstul-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org; Vishwanath Sripathy
>Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
>support of ehci and ohci
>
>Hi,
>
>On Wed, Jul 06, 2011 at 12:20:40PM -0700, Kevin Hilman wrote:
>> >> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
>> >> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
>> >> +		omap_device_enable(pdev);
>> >> +
>> >> +	return pm_generic_resume(dev);
>> >> +}
>> >> +
>> >>  static struct dev_power_domain omap_device_power_domain = {
>> >>  	.ops = {
>> >>  		.runtime_suspend = _od_runtime_suspend,
>> >>  		.runtime_idle = _od_runtime_idle,
>> >>  		.runtime_resume = _od_runtime_resume,
>> >>  		USE_PLATFORM_PM_SLEEP_OPS
>> >> +		.suspend = _od_suspend,
>> >> +		.resume = _od_resume,
>> >>  	}
>> >>  };
>> >
>> > it all depends on when are you planning to get this patch upstream.
>> > I'm considering getting some PM working on USB host and remove the
>> > pm_runtime calls from system suspend/resume either during -rc or
>> > next merge window.
>>
>> Well, IMO it's way too late for this kind of change for -rc, so I'm
>> considering it for the upcoming merge window.
>
>yes, that's true. Who should take the hwmod patches btw ? I'm still
>wondering if we should patch hwmod data first and push the _correct_ PM
>part on 3.2.

Once Kevin pushes this infrastructure enhancement, all drivers have to
rework
the Suspend/Resume anyways. Another way would be to go by the current
approach
now and then do the rework in 3.2 along with other drivers.

In this way, we can soak the Runtime support of EHCI/OHCI for one merge
window.
>
>--
>balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci
  2011-07-07  4:53                                 ` Partha Basak
  (?)
@ 2011-07-07  7:28                                 ` Felipe Balbi
  -1 siblings, 0 replies; 49+ messages in thread
From: Felipe Balbi @ 2011-07-07  7:28 UTC (permalink / raw)
  To: Partha Basak
  Cc: balbi, Kevin Hilman, Alan Stern, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul, johnstul, Vishwanath Sripathy

[-- Attachment #1: Type: text/plain, Size: 2444 bytes --]

Hi,

On Thu, Jul 07, 2011 at 10:23:59AM +0530, Partha Basak wrote:
> >-----Original Message-----
> >From: Felipe Balbi [mailto:balbi@ti.com]
> >Sent: Thursday, July 07, 2011 3:48 AM
> >To: Kevin Hilman
> >Cc: balbi@ti.com; Alan Stern; Partha Basak; Keshava Munegowda; linux-
> >usb@vger.kernel.org; linux-omap@vger.kernel.org; linux-
> >kernel@vger.kernel.org; Anand Gadiyar; sameo@linux.intel.com;
> >parthab@india.ti.com; tony@atomide.com; Benoit Cousson; paul@pwsan.com;
> >johnstul@us.ibm.com; Vishwanath Sripathy
> >Subject: Re: [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume
> >support of ehci and ohci
> >
> >Hi,
> >
> >On Wed, Jul 06, 2011 at 12:20:40PM -0700, Kevin Hilman wrote:
> >> >> +	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
> >> >> +	    (od->_state == OMAP_DEVICE_STATE_IDLE))
> >> >> +		omap_device_enable(pdev);
> >> >> +
> >> >> +	return pm_generic_resume(dev);
> >> >> +}
> >> >> +
> >> >>  static struct dev_power_domain omap_device_power_domain = {
> >> >>  	.ops = {
> >> >>  		.runtime_suspend = _od_runtime_suspend,
> >> >>  		.runtime_idle = _od_runtime_idle,
> >> >>  		.runtime_resume = _od_runtime_resume,
> >> >>  		USE_PLATFORM_PM_SLEEP_OPS
> >> >> +		.suspend = _od_suspend,
> >> >> +		.resume = _od_resume,
> >> >>  	}
> >> >>  };
> >> >
> >> > it all depends on when are you planning to get this patch upstream.
> >> > I'm considering getting some PM working on USB host and remove the
> >> > pm_runtime calls from system suspend/resume either during -rc or
> >> > next merge window.
> >>
> >> Well, IMO it's way too late for this kind of change for -rc, so I'm
> >> considering it for the upcoming merge window.
> >
> >yes, that's true. Who should take the hwmod patches btw ? I'm still
> >wondering if we should patch hwmod data first and push the _correct_ PM
> >part on 3.2.
> 
> Once Kevin pushes this infrastructure enhancement, all drivers have to
> rework
> the Suspend/Resume anyways. Another way would be to go by the current
> approach
> now and then do the rework in 3.2 along with other drivers.
> 
> In this way, we can soak the Runtime support of EHCI/OHCI for one merge
> window.

but if it's known to be broken, why add something which is broken
anyway ?

Tony, can you queue the arch/arm/*omap*/ patches ? I'll take care of
the EHCI stuff for the next merge window, will keep them pending in my
queue.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4
  2011-07-01 18:54   ` Keshava Munegowda
  (?)
  (?)
@ 2011-07-07 10:29   ` Felipe Balbi
  2011-07-07 15:57     ` Kevin Hilman
  -1 siblings, 1 reply; 49+ messages in thread
From: Felipe Balbi @ 2011-07-07 10:29 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, khilman, b-cousson, paul, johnstul, vishwanath.bs

[-- Attachment #1: Type: text/plain, Size: 647 bytes --]

Hi Tony, Benoit, Kevin, Paul,

On Sat, Jul 02, 2011 at 12:24:29AM +0530, Keshava Munegowda wrote:
> From: Benoit Cousson <b-cousson@ti.com>
> 
> Following 4 hwmod strcuture are added:
> UHH hwmod of usbhs with uhh base address and functional clock,
> EHCI hwmod with irq and base address,
> OHCI hwmod with irq and base address,
> TLL hwmod of usbhs with the TLL base address and irq.
> 
> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

Can the hwmod part go into this merge window ? I can fix the PM part
later on but without hwmod, I can't do anything.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4
  2011-07-07 10:29   ` [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4 Felipe Balbi
@ 2011-07-07 15:57     ` Kevin Hilman
  0 siblings, 0 replies; 49+ messages in thread
From: Kevin Hilman @ 2011-07-07 15:57 UTC (permalink / raw)
  To: balbi
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel, gadiyar,
	sameo, parthab, tony, b-cousson, paul, johnstul, vishwanath.bs

Felipe Balbi <balbi@ti.com> writes:

> Hi Tony, Benoit, Kevin, Paul,
>
> On Sat, Jul 02, 2011 at 12:24:29AM +0530, Keshava Munegowda wrote:
>> From: Benoit Cousson <b-cousson@ti.com>
>> 
>> Following 4 hwmod strcuture are added:
>> UHH hwmod of usbhs with uhh base address and functional clock,
>> EHCI hwmod with irq and base address,
>> OHCI hwmod with irq and base address,
>> TLL hwmod of usbhs with the TLL base address and irq.
>> 
>> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>
> Can the hwmod part go into this merge window ? I can fix the PM part
> later on but without hwmod, I can't do anything.

The hwmod data parts of this series need to be udpated on top of
Benoit's changes since some new fields have been added for proper
clockdomain and modulemode support.

Benoit has updated the autogen tools so any hwmod data submitted for new
IP blocks needs to use the new autogenerated data.

Kevin

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2011-07-07 15:57 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-01 18:54 [PATCH 0/6 V2] arm: omap: usb: Runtime PM support for EHCI and OHCI drivers Keshava Munegowda
2011-07-01 18:54 ` Keshava Munegowda
2011-07-01 18:54 ` [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4 Keshava Munegowda
2011-07-01 18:54   ` Keshava Munegowda
2011-07-01 18:54   ` [PATCH 2/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap3 Keshava Munegowda
2011-07-01 18:54     ` Keshava Munegowda
2011-07-01 18:54     ` [PATCH 3/6 v2] arm: omap: usb: register hwmods of usbhs Keshava Munegowda
2011-07-01 18:54       ` Keshava Munegowda
2011-07-01 18:54       ` [PATCH 4/6 v2] arm: omap: usb: device name change for the clk names " Keshava Munegowda
2011-07-01 18:54         ` Keshava Munegowda
2011-07-01 18:54         ` [PATCH 5/6 v2] arm: omap: usb: Runtime PM support Keshava Munegowda
2011-07-01 18:54           ` Keshava Munegowda
2011-07-01 18:54           ` [PATCH 6/6 v2] arm: omap: usb: global Suspend and resume support of ehci and ohci Keshava Munegowda
2011-07-01 18:54             ` Keshava Munegowda
2011-07-01 19:06             ` Alan Stern
2011-07-01 19:06               ` Alan Stern
2011-07-04  5:06               ` Partha Basak
2011-07-04  5:06                 ` Partha Basak
2011-07-04  8:25                 ` Felipe Balbi
2011-07-04  8:25                   ` Felipe Balbi
2011-07-04  9:26                   ` Partha Basak
2011-07-04  9:26                     ` Partha Basak
2011-07-04  9:30                     ` Felipe Balbi
2011-07-04 11:01                       ` Partha Basak
2011-07-04 16:01                       ` Alan Stern
2011-07-04 16:01                         ` Alan Stern
2011-07-05 12:52                         ` Felipe Balbi
2011-07-05 14:17                           ` Alan Stern
2011-07-05 14:17                             ` Alan Stern
2011-07-05 15:53                             ` Felipe Balbi
2011-07-05 16:28                               ` Alan Stern
2011-07-05 16:28                                 ` Alan Stern
2011-07-04 15:50                 ` Alan Stern
2011-07-04 15:50                   ` Alan Stern
2011-07-05 14:00                   ` Partha Basak
2011-07-05 14:22                     ` Alan Stern
2011-07-05 14:22                       ` Alan Stern
2011-07-05 17:37                       ` Kevin Hilman
2011-07-05 17:37                         ` Kevin Hilman
2011-07-06 17:54                         ` Felipe Balbi
2011-07-06 19:20                           ` Kevin Hilman
2011-07-06 19:20                             ` Kevin Hilman
2011-07-06 22:17                             ` Felipe Balbi
2011-07-07  4:53                               ` Partha Basak
2011-07-07  4:53                                 ` Partha Basak
2011-07-07  7:28                                 ` Felipe Balbi
2011-07-07 10:29   ` [PATCH 1/6 v2] arm: omap: usb: ehci and ohci hwmod structures for omap4 Felipe Balbi
2011-07-07 15:57     ` Kevin Hilman
2011-07-04 17:25 ` [PATCH 0/6 V2] arm: omap: usb: Runtime PM support for EHCI and OHCI drivers Samuel Ortiz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.