All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] arm: omap: usb: Hwmod and Runtime PM support for EHCI & OHCI
@ 2011-06-01 13:27 ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

These set of patches 
- defines the hwmod structures of ehci and ohci of omap3 and omap4 socs.
- Implements the Run time pm 
- global suspend/resume of EHCI and OHCI

Since, existing omap usbhs core driver of v3.0-rc1 release uses
the run time PM APIs, these patches enables the ehci and ohci
functionalaties.

Keshava Munegowda (4):
  arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
  arm: omap: usb: register hwmods of usbhs
  arm: omap: usb: device name change for the clk names of usbhs
  mfd: 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 |  184 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  153 +++++++++++++++++++++++
 arch/arm/mach-omap2/usb-host.c             |   99 ++++++----------
 drivers/mfd/omap-usb-host.c                |  105 ++++++++++++++++-
 6 files changed, 495 insertions(+), 84 deletions(-)


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

* [PATCH 0/4] arm: omap: usb: Hwmod and Runtime PM support for EHCI & OHCI
@ 2011-06-01 13:27 ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

These set of patches 
- defines the hwmod structures of ehci and ohci of omap3 and omap4 socs.
- Implements the Run time pm 
- global suspend/resume of EHCI and OHCI

Since, existing omap usbhs core driver of v3.0-rc1 release uses
the run time PM APIs, these patches enables the ehci and ohci
functionalaties.

Keshava Munegowda (4):
  arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
  arm: omap: usb: register hwmods of usbhs
  arm: omap: usb: device name change for the clk names of usbhs
  mfd: 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 |  184 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  153 +++++++++++++++++++++++
 arch/arm/mach-omap2/usb-host.c             |   99 ++++++----------
 drivers/mfd/omap-usb-host.c                |  105 ++++++++++++++++-
 6 files changed, 495 insertions(+), 84 deletions(-)

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

* [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
@ 2011-06-01 13:27   ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

Following 2 hwmod strcuture are added:
UHH hwmod of usbhs with uhh base address and
EHCI , OHCI irq and base addresses.
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 |  184 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  153 +++++++++++++++++++++++
 2 files changed, 337 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..fe9a176 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -84,6 +84,8 @@ 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_usb_tll_hs_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -3574,6 +3576,185 @@ 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_irq_info omap34xx_usb_host_hs_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 },
+	{ .name = "ehci-irq", .irq = 77 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x48064000,
+		.pa_end		= 0x480643ff,
+		.flags		= ADDR_TYPE_RT
+	},
+	{
+		.name		= "ohci",
+		.pa_start	= 0x48064400,
+		.pa_end		= 0x480647FF,
+		.flags		= ADDR_MAP_ON_INIT
+	},
+	{
+		.name		= "ehci",
+		.pa_start	= 0x48064800,
+		.pa_end		= 0x48064CFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+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,
+	.mpu_irqs	= omap34xx_usb_host_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_irqs),
+	.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),
+};
+
+/*
+ * '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 +3837,9 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	/* usbotg for am35x */
 	&am35xx_usbhsotg_hwmod,
 
+	&omap34xx_usb_host_hs_hwmod,
+	&omap34xx_usb_tll_hs_hwmod,
+
 	NULL,
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index abc548a..d7112b0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -66,6 +66,8 @@ 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_usb_tll_hs_hwmod;
 
 /*
  * Interconnects omap_hwmod structures
@@ -5027,6 +5029,155 @@ 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_irq_info omap44xx_usb_host_hs_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x4a064000,
+		.pa_end		= 0x4a0647ff,
+		.flags		= ADDR_TYPE_RT
+	},
+	{
+		.name		= "ohci",
+		.pa_start	= 0x4A064800,
+		.pa_end		= 0x4A064BFF,
+		.flags		= ADDR_MAP_ON_INIT
+	},
+	{
+		.name		= "ehci",
+		.pa_start	= 0x4A064C00,
+		.pa_end		= 0x4A064FFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+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,
+	.mpu_irqs	= omap44xx_usb_host_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_irqs),
+	.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),
+};
+
+/*
+ * '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 +5324,8 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	&omap44xx_wd_timer2_hwmod,
 	&omap44xx_wd_timer3_hwmod,
 
+	&omap44xx_usb_host_hs_hwmod,
+	&omap44xx_usb_tll_hs_hwmod,
 	NULL,
 };
 
-- 
1.6.0.4


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

* [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
@ 2011-06-01 13:27   ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 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

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

Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  184 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  153 +++++++++++++++++++++++
 2 files changed, 337 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..fe9a176 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -84,6 +84,8 @@ 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_usb_tll_hs_hwmod;
 
 /* L3 -> L4_CORE interface */
 static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -3574,6 +3576,185 @@ 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_irq_info omap34xx_usb_host_hs_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 },
+	{ .name = "ehci-irq", .irq = 77 },
+};
+
+static struct omap_hwmod_addr_space omap34xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x48064000,
+		.pa_end		= 0x480643ff,
+		.flags		= ADDR_TYPE_RT
+	},
+	{
+		.name		= "ohci",
+		.pa_start	= 0x48064400,
+		.pa_end		= 0x480647FF,
+		.flags		= ADDR_MAP_ON_INIT
+	},
+	{
+		.name		= "ehci",
+		.pa_start	= 0x48064800,
+		.pa_end		= 0x48064CFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+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,
+	.mpu_irqs	= omap34xx_usb_host_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap34xx_usb_host_hs_irqs),
+	.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),
+};
+
+/*
+ * '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 +3837,9 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
 	/* usbotg for am35x */
 	&am35xx_usbhsotg_hwmod,
 
+	&omap34xx_usb_host_hs_hwmod,
+	&omap34xx_usb_tll_hs_hwmod,
+
 	NULL,
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index abc548a..d7112b0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -66,6 +66,8 @@ 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_usb_tll_hs_hwmod;
 
 /*
  * Interconnects omap_hwmod structures
@@ -5027,6 +5029,155 @@ 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_irq_info omap44xx_usb_host_hs_irqs[] = {
+	{ .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
+	{ .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
+	{
+		.name		= "uhh",
+		.pa_start	= 0x4a064000,
+		.pa_end		= 0x4a0647ff,
+		.flags		= ADDR_TYPE_RT
+	},
+	{
+		.name		= "ohci",
+		.pa_start	= 0x4A064800,
+		.pa_end		= 0x4A064BFF,
+		.flags		= ADDR_MAP_ON_INIT
+	},
+	{
+		.name		= "ehci",
+		.pa_start	= 0x4A064C00,
+		.pa_end		= 0x4A064FFF,
+		.flags		= ADDR_MAP_ON_INIT
+	}
+};
+
+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,
+	.mpu_irqs	= omap44xx_usb_host_hs_irqs,
+	.mpu_irqs_cnt	= ARRAY_SIZE(omap44xx_usb_host_hs_irqs),
+	.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),
+};
+
+/*
+ * '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 +5324,8 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
 	&omap44xx_wd_timer2_hwmod,
 	&omap44xx_wd_timer3_hwmod,
 
+	&omap44xx_usb_host_hs_hwmod,
+	&omap44xx_usb_tll_hs_hwmod,
 	NULL,
 };
 
-- 
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] 50+ messages in thread

* [PATCH 2/4] arm: omap: usb: register hwmods of usbhs
@ 2011-06-01 13:27     ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

The hwmod structure of uhh 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 |   99 ++++++++++++++--------------------------
 1 files changed, 35 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 89ae298..9d762c4 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -28,51 +28,28 @@
 #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_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 +485,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[2];
+	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 +503,35 @@ 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;
 	}
 
-	if (platform_device_register(&usbhs_device) < 0)
-		printk(KERN_ERR "USBHS platform_device_register failed\n");
+	oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+	if (!oh[1]) {
+		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+		return;
+	}
 
-init_end:
-	return;
+	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
+				(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] 50+ messages in thread

* [PATCH 2/4] arm: omap: usb: register hwmods of usbhs
@ 2011-06-01 13:27     ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 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

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

Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
---
 arch/arm/mach-omap2/usb-host.c |   99 ++++++++++++++--------------------------
 1 files changed, 35 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 89ae298..9d762c4 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -28,51 +28,28 @@
 #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_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 +485,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[2];
+	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 +503,35 @@ 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;
 	}
 
-	if (platform_device_register(&usbhs_device) < 0)
-		printk(KERN_ERR "USBHS platform_device_register failed\n");
+	oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+	if (!oh[1]) {
+		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
+		return;
+	}
 
-init_end:
-	return;
+	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
+				(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

--
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] 50+ messages in thread

* [PATCH 3/4] arm: omap: usb: device name change for the clk names of usbhs
@ 2011-06-01 13:27       ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, 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] 50+ messages in thread

* [PATCH 3/4] arm: omap: usb: device name change for the clk names of usbhs
@ 2011-06-01 13:27       ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 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,
	Keshava Munegowda

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

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-l0cyMroinI0@public.gmane.org>
---
 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

--
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] 50+ messages in thread

* [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 13:27       ` Keshava Munegowda
@ 2011-06-01 13:27         ` Keshava Munegowda
  -1 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The global suspend and resume functions for usbhs core driver
are implemented.These routine are called when the global suspend
and resume occurs. Before calling these functions, the
bus suspend and resume of ehci and ohci drivers are called
from runtime pm.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 43de12a..32d19e2 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -146,6 +146,10 @@
 #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
 
 
+/* USBHS state bits */
+#define OMAP_USBHS_INIT		0
+#define OMAP_USBHS_SUSPEND	4
+
 struct usbhs_hcd_omap {
 	struct clk			*xclk60mhsp1_ck;
 	struct clk			*xclk60mhsp2_ck;
@@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
 	u32				usbhs_rev;
 	spinlock_t			lock;
 	int				count;
+	unsigned long			state;
 };
 /*-------------------------------------------------------------------------*/
 
@@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
 				(pdata->ehci_data->reset_gpio_port[1], 1);
 	}
 
+	set_bit(OMAP_USBHS_INIT, &omap->state);
+
 end_count:
 	omap->count++;
 	spin_unlock_irqrestore(&omap->lock, flags);
@@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
 	}
 
 	pm_runtime_put_sync(dev);
+	clear_bit(OMAP_USBHS_INIT, &omap->state);
 
 	/* The gpio_free migh sleep; so unlock the spinlock */
 	spin_unlock_irqrestore(&omap->lock, flags);
@@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(omap_usbhs_disable);
 
+#ifdef	CONFIG_PM
+
+static int usbhs_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;
+
+	dev_dbg(dev, "Resuming TI HSUSB Controller\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	spin_lock_irqsave(&omap->lock, flags);
+
+	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
+		!test_bit(OMAP_USBHS_SUSPEND, &omap->state))
+			goto end_resume;
+
+	pm_runtime_get_sync(dev);
+
+	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);
+	}
+	clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
+
+end_resume:
+	spin_unlock_irqrestore(&omap->lock, flags);
+	return 0;
+}
+
+
+static int usbhs_suspend(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+	unsigned long			flags = 0;
+
+	dev_dbg(dev, "Suspending TI HSUSB Controller\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	spin_lock_irqsave(&omap->lock, flags);
+
+	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
+		test_bit(OMAP_USBHS_SUSPEND, &omap->state))
+			goto end_suspend;
+
+	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);
+	}
+
+	set_bit(OMAP_USBHS_SUSPEND, &omap->state);
+	pm_runtime_put_sync(dev);
+
+end_suspend:
+	spin_unlock_irqrestore(&omap->lock, flags);
+	return 0;
+}
+
+
+static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
+	.suspend	= usbhs_suspend,
+	.resume		= usbhs_resume,
+};
+
+#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
+#else
+#define	USBHS_OMAP_DEV_PM_OPS	NULL
+#endif
+
 static struct platform_driver usbhs_omap_driver = {
 	.driver = {
 		.name		= (char *)usbhs_driver_name,
 		.owner		= THIS_MODULE,
+		.pm		= USBHS_OMAP_DEV_PM_OPS,
 	},
 	.remove		= __exit_p(usbhs_omap_remove),
 };
-- 
1.6.0.4


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

* [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-01 13:27         ` Keshava Munegowda
  0 siblings, 0 replies; 50+ messages in thread
From: Keshava Munegowda @ 2011-06-01 13:27 UTC (permalink / raw)
  To: linux-usb, linux-omap, linux-kernel
  Cc: Keshava Munegowda, balbi, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul, Keshava Munegowda

From: Keshava Munegowda <Keshava_mgowda@ti.com>

The global suspend and resume functions for usbhs core driver
are implemented.These routine are called when the global suspend
and resume occurs. Before calling these functions, the
bus suspend and resume of ehci and ohci drivers are called
from runtime pm.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
---
 drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 43de12a..32d19e2 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -146,6 +146,10 @@
 #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
 
 
+/* USBHS state bits */
+#define OMAP_USBHS_INIT		0
+#define OMAP_USBHS_SUSPEND	4
+
 struct usbhs_hcd_omap {
 	struct clk			*xclk60mhsp1_ck;
 	struct clk			*xclk60mhsp2_ck;
@@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
 	u32				usbhs_rev;
 	spinlock_t			lock;
 	int				count;
+	unsigned long			state;
 };
 /*-------------------------------------------------------------------------*/
 
@@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
 				(pdata->ehci_data->reset_gpio_port[1], 1);
 	}
 
+	set_bit(OMAP_USBHS_INIT, &omap->state);
+
 end_count:
 	omap->count++;
 	spin_unlock_irqrestore(&omap->lock, flags);
@@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
 	}
 
 	pm_runtime_put_sync(dev);
+	clear_bit(OMAP_USBHS_INIT, &omap->state);
 
 	/* The gpio_free migh sleep; so unlock the spinlock */
 	spin_unlock_irqrestore(&omap->lock, flags);
@@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(omap_usbhs_disable);
 
+#ifdef	CONFIG_PM
+
+static int usbhs_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;
+
+	dev_dbg(dev, "Resuming TI HSUSB Controller\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	spin_lock_irqsave(&omap->lock, flags);
+
+	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
+		!test_bit(OMAP_USBHS_SUSPEND, &omap->state))
+			goto end_resume;
+
+	pm_runtime_get_sync(dev);
+
+	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);
+	}
+	clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
+
+end_resume:
+	spin_unlock_irqrestore(&omap->lock, flags);
+	return 0;
+}
+
+
+static int usbhs_suspend(struct device *dev)
+{
+	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
+	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
+	unsigned long			flags = 0;
+
+	dev_dbg(dev, "Suspending TI HSUSB Controller\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	spin_lock_irqsave(&omap->lock, flags);
+
+	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
+		test_bit(OMAP_USBHS_SUSPEND, &omap->state))
+			goto end_suspend;
+
+	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);
+	}
+
+	set_bit(OMAP_USBHS_SUSPEND, &omap->state);
+	pm_runtime_put_sync(dev);
+
+end_suspend:
+	spin_unlock_irqrestore(&omap->lock, flags);
+	return 0;
+}
+
+
+static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
+	.suspend	= usbhs_suspend,
+	.resume		= usbhs_resume,
+};
+
+#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
+#else
+#define	USBHS_OMAP_DEV_PM_OPS	NULL
+#endif
+
 static struct platform_driver usbhs_omap_driver = {
 	.driver = {
 		.name		= (char *)usbhs_driver_name,
 		.owner		= THIS_MODULE,
+		.pm		= USBHS_OMAP_DEV_PM_OPS,
 	},
 	.remove		= __exit_p(usbhs_omap_remove),
 };
-- 
1.6.0.4

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 13:27         ` Keshava Munegowda
  (?)
@ 2011-06-01 13:31         ` Felipe Balbi
  2011-06-01 13:38           ` Munegowda, Keshava
  -1 siblings, 1 reply; 50+ messages in thread
From: Felipe Balbi @ 2011-06-01 13:31 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, khilman, b-cousson, paul

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

Hi,

On Wed, Jun 01, 2011 at 06:57:27PM +0530, Keshava Munegowda wrote:
> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> index 43de12a..32d19e2 100644
> --- a/drivers/mfd/omap-usb-host.c
> +++ b/drivers/mfd/omap-usb-host.c
> @@ -146,6 +146,10 @@
>  #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
>  
>  
> +/* USBHS state bits */
> +#define OMAP_USBHS_INIT		0
> +#define OMAP_USBHS_SUSPEND	4

#define OMAP_USBHS_INIT		BIT(0)
#define OMAP_USBHS_SUSPEND	BIT(1)

???

-- 
balbi

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

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 13:31         ` Felipe Balbi
@ 2011-06-01 13:38           ` Munegowda, Keshava
  0 siblings, 0 replies; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-01 13:38 UTC (permalink / raw)
  To: balbi
  Cc: linux-usb, linux-omap, linux-kernel, gadiyar, sameo, parthab,
	tony, khilman, b-cousson, paul

On Wed, Jun 1, 2011 at 7:01 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Wed, Jun 01, 2011 at 06:57:27PM +0530, Keshava Munegowda wrote:
>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>> index 43de12a..32d19e2 100644
>> --- a/drivers/mfd/omap-usb-host.c
>> +++ b/drivers/mfd/omap-usb-host.c
>> @@ -146,6 +146,10 @@
>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>
>>
>> +/* USBHS state bits */
>> +#define OMAP_USBHS_INIT              0
>> +#define OMAP_USBHS_SUSPEND   4
>
> #define OMAP_USBHS_INIT         BIT(0)
> #define OMAP_USBHS_SUSPEND      BIT(1)
>
> ???

yes, I will do.. please comment on other patches too

keshava

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 13:27         ` Keshava Munegowda
  (?)
  (?)
@ 2011-06-01 13:54         ` Rafael J. Wysocki
  2011-06-01 14:32           ` Felipe Balbi
  -1 siblings, 1 reply; 50+ messages in thread
From: Rafael J. Wysocki @ 2011-06-01 13:54 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, khilman, b-cousson, paul

On Wednesday, June 01, 2011, Keshava Munegowda wrote:
> From: Keshava Munegowda <Keshava_mgowda@ti.com>
> 
> The global suspend and resume functions for usbhs core driver
> are implemented.These routine are called when the global suspend
> and resume occurs. Before calling these functions, the
> bus suspend and resume of ehci and ohci drivers are called
> from runtime pm.
> 
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
> ---
>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 103 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> index 43de12a..32d19e2 100644
> --- a/drivers/mfd/omap-usb-host.c
> +++ b/drivers/mfd/omap-usb-host.c
> @@ -146,6 +146,10 @@
>  #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
>  
>  
> +/* USBHS state bits */
> +#define OMAP_USBHS_INIT		0
> +#define OMAP_USBHS_SUSPEND	4
> +
>  struct usbhs_hcd_omap {
>  	struct clk			*xclk60mhsp1_ck;
>  	struct clk			*xclk60mhsp2_ck;
> @@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
>  	u32				usbhs_rev;
>  	spinlock_t			lock;
>  	int				count;
> +	unsigned long			state;
>  };
>  /*-------------------------------------------------------------------------*/
>  
> @@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
>  				(pdata->ehci_data->reset_gpio_port[1], 1);
>  	}
>  
> +	set_bit(OMAP_USBHS_INIT, &omap->state);
> +
>  end_count:
>  	omap->count++;
>  	spin_unlock_irqrestore(&omap->lock, flags);
> @@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
>  	}
>  
>  	pm_runtime_put_sync(dev);
> +	clear_bit(OMAP_USBHS_INIT, &omap->state);
>  
>  	/* The gpio_free migh sleep; so unlock the spinlock */
>  	spin_unlock_irqrestore(&omap->lock, flags);
> @@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(omap_usbhs_disable);
>  
> +#ifdef	CONFIG_PM
> +
> +static int usbhs_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;
> +
> +	dev_dbg(dev, "Resuming TI HSUSB Controller\n");
> +
> +	if (!pdata) {
> +		dev_dbg(dev, "missing platform_data\n");
> +		return  -ENODEV;
> +	}
> +
> +	spin_lock_irqsave(&omap->lock, flags);
> +
> +	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
> +		!test_bit(OMAP_USBHS_SUSPEND, &omap->state))
> +			goto end_resume;
> +
> +	pm_runtime_get_sync(dev);
> +
> +	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);
> +	}
> +	clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
> +
> +end_resume:
> +	spin_unlock_irqrestore(&omap->lock, flags);
> +	return 0;
> +}
> +
> +
> +static int usbhs_suspend(struct device *dev)
> +{
> +	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
> +	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
> +	unsigned long			flags = 0;
> +
> +	dev_dbg(dev, "Suspending TI HSUSB Controller\n");
> +
> +	if (!pdata) {
> +		dev_dbg(dev, "missing platform_data\n");
> +		return  -ENODEV;
> +	}
> +
> +	spin_lock_irqsave(&omap->lock, flags);
> +
> +	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
> +		test_bit(OMAP_USBHS_SUSPEND, &omap->state))
> +			goto end_suspend;
> +
> +	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);
> +	}
> +
> +	set_bit(OMAP_USBHS_SUSPEND, &omap->state);
> +	pm_runtime_put_sync(dev);
> +
> +end_suspend:
> +	spin_unlock_irqrestore(&omap->lock, flags);
> +	return 0;
> +}
> +
> +
> +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
> +	.suspend	= usbhs_suspend,
> +	.resume		= usbhs_resume,
> +};

Please add .freeze()/.thaw() and .poweroff()/.restore() callbacks too.
They may point to the same routines, but must be present.

You can actually use the SIMPLE_DEV_PM_OPS() convenience macro for this
purpose.

> +
> +#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
> +#else
> +#define	USBHS_OMAP_DEV_PM_OPS	NULL
> +#endif
> +
>  static struct platform_driver usbhs_omap_driver = {
>  	.driver = {
>  		.name		= (char *)usbhs_driver_name,
>  		.owner		= THIS_MODULE,
> +		.pm		= USBHS_OMAP_DEV_PM_OPS,
>  	},
>  	.remove		= __exit_p(usbhs_omap_remove),
>  };
> 

Thanks,
Rafael

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 13:54         ` Rafael J. Wysocki
@ 2011-06-01 14:32           ` Felipe Balbi
  2011-06-05 17:19             ` Rafael J. Wysocki
  0 siblings, 1 reply; 50+ messages in thread
From: Felipe Balbi @ 2011-06-01 14:32 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel, balbi,
	gadiyar, sameo, parthab, tony, khilman, b-cousson, paul

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

Hi,

On Wed, Jun 01, 2011 at 03:54:38PM +0200, Rafael J. Wysocki wrote:
> > +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
> > +	.suspend	= usbhs_suspend,
> > +	.resume		= usbhs_resume,
> > +};
> 
> Please add .freeze()/.thaw() and .poweroff()/.restore() callbacks too.
> They may point to the same routines, but must be present.
> 
> You can actually use the SIMPLE_DEV_PM_OPS() convenience macro for this
> purpose.

good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
popping on most drivers recently ? To me it looks like driver.pm field
is always available even if PM is disabled, so what's the point ? Saving
a few bytes ?

-- 
balbi

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

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

* Re: [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
  2011-06-01 13:27   ` Keshava Munegowda
@ 2011-06-01 19:56     ` Kevin Hilman
  -1 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 19:56 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> Following 2 hwmod strcuture are added:
> UHH hwmod of usbhs with uhh base address and
> EHCI , OHCI irq and base addresses.
> TLL hwmod of usbhs with the TLL base address and irq.
>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

I believe the OMAP4 data came from Benoit, so should be in a patch with
his authorship and signoff.  OMAP3 can be a separate patch with your
authorship.

Kevin

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

* Re: [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
@ 2011-06-01 19:56     ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 19:56 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> Following 2 hwmod strcuture are added:
> UHH hwmod of usbhs with uhh base address and
> EHCI , OHCI irq and base addresses.
> TLL hwmod of usbhs with the TLL base address and irq.
>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

I believe the OMAP4 data came from Benoit, so should be in a patch with
his authorship and signoff.  OMAP3 can be a separate patch with your
authorship.

Kevin

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

* Re: [PATCH 2/4] arm: omap: usb: register hwmods of usbhs
  2011-06-01 13:27     ` Keshava Munegowda
@ 2011-06-01 20:01       ` Kevin Hilman
  -1 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 20:01 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

Hi Kesheva,

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> The hwmod structure of uhh and tll are retrived
> and registered with omap device
>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

Minor comment below...

> ---
>  arch/arm/mach-omap2/usb-host.c |   99 ++++++++++++++--------------------------
>  1 files changed, 35 insertions(+), 64 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
> index 89ae298..9d762c4 100644
> --- a/arch/arm/mach-omap2/usb-host.c
> +++ b/arch/arm/mach-omap2/usb-host.c
> @@ -28,51 +28,28 @@
>  #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_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;

While changing the platform_data registration, these platform_data
structs should be alloc'd and then free'd after omap_device_build, since
a copy of them is made during device registration.

Kevin

> +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 +485,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[2];
> +	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 +503,35 @@ 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;
>  	}
>  
> -	if (platform_device_register(&usbhs_device) < 0)
> -		printk(KERN_ERR "USBHS platform_device_register failed\n");
> +	oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
> +	if (!oh[1]) {
> +		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
> +		return;
> +	}
>  
> -init_end:
> -	return;
> +	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
> +				(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

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

* Re: [PATCH 2/4] arm: omap: usb: register hwmods of usbhs
@ 2011-06-01 20:01       ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 20:01 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

Hi Kesheva,

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> The hwmod structure of uhh and tll are retrived
> and registered with omap device
>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

Minor comment below...

> ---
>  arch/arm/mach-omap2/usb-host.c |   99 ++++++++++++++--------------------------
>  1 files changed, 35 insertions(+), 64 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
> index 89ae298..9d762c4 100644
> --- a/arch/arm/mach-omap2/usb-host.c
> +++ b/arch/arm/mach-omap2/usb-host.c
> @@ -28,51 +28,28 @@
>  #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_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;

While changing the platform_data registration, these platform_data
structs should be alloc'd and then free'd after omap_device_build, since
a copy of them is made during device registration.

Kevin

> +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 +485,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[2];
> +	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 +503,35 @@ 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;
>  	}
>  
> -	if (platform_device_register(&usbhs_device) < 0)
> -		printk(KERN_ERR "USBHS platform_device_register failed\n");
> +	oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
> +	if (!oh[1]) {
> +		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
> +		return;
> +	}
>  
> -init_end:
> -	return;
> +	od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
> +				(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

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

* Re: [PATCH 2/4] arm: omap: usb: register hwmods of usbhs
  2011-06-01 13:27     ` Keshava Munegowda
@ 2011-06-01 20:04       ` Kevin Hilman
  -1 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 20:04 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> The hwmod structure of uhh and tll are retrived
> and registered with omap device

And the name strings are changed as well as the device identifier
changed from zero to -1.  Please comment and justify.

Kevin

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

* Re: [PATCH 2/4] arm: omap: usb: register hwmods of usbhs
@ 2011-06-01 20:04       ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 20:04 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> The hwmod structure of uhh and tll are retrived
> and registered with omap device

And the name strings are changed as well as the device identifier
changed from zero to -1.  Please comment and justify.

Kevin

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

* Re: [PATCH 3/4] arm: omap: usb: device name change for the clk names of usbhs
  2011-06-01 13:27       ` Keshava Munegowda
@ 2011-06-01 20:05         ` Kevin Hilman
  -1 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 20:05 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul, Keshava Munegowda

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> 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

..and because the identifier is changed to -1 in the previous patch
without being documented.

Kevin

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

* Re: [PATCH 3/4] arm: omap: usb: device name change for the clk names of usbhs
@ 2011-06-01 20:05         ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-01 20:05 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul, Keshava Munegowda

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> 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

..and because the identifier is changed to -1 in the previous patch
without being documented.

Kevin

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 13:27         ` Keshava Munegowda
@ 2011-06-02  0:06           ` Kevin Hilman
  -1 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-02  0:06 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul, Keshava Munegowda

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>
> The global suspend and resume functions for usbhs core driver
> are implemented.These routine are called when the global suspend
> and resume occurs. Before calling these functions, the
> bus suspend and resume of ehci and ohci drivers are called
> from runtime pm.
>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

First, from what I can see, this is only a partial implementation of
runtime PM.  What I mean is that the runtime PM methods are used only
during the suspend path.  The rest of the time the USB host IP block is
left enabled, even when nothing is connected.

I tested this on my 3530/Overo board, and verified that indeed the
usbhost powerdomain hits retention on suspend, but while idle, when
nothing is connected, I would expect the driver could be clever enough
to use runtime PM (probably using autosuspend timeouts) to disable the
hardware as well.

> ---
>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 103 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> index 43de12a..32d19e2 100644
> --- a/drivers/mfd/omap-usb-host.c
> +++ b/drivers/mfd/omap-usb-host.c
> @@ -146,6 +146,10 @@
>  #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
>  
>  
> +/* USBHS state bits */
> +#define OMAP_USBHS_INIT		0
> +#define OMAP_USBHS_SUSPEND	4

These additional state bits don't seem to be necessary.

For suspend, just check 'pm_runtime_is_suspended()'

The init flag is only used in the suspend/resume hooks, but the need for
it is a side effect of not correctly using the runtime PM callbacks.

Remember that the runtime PM get/put hooks have usage counting.  Only
when the usage count transitions to/from zero is the actual
hardware-level enable/disable (via omap_hwmod) being done.   

The current code is making the assumption that every call to get/put is
going to result in an enable/disable of the hardware.

Instead, all of the code that needs to be run only upon actual
enable/disable of the hardware should be done in the driver's
runtime_suspend/runtime_resume callbacks.  These are only called when
the hardware actually changes state.   

Not knowing that much about the EHCI block, upon first glance, it looks
like mmuch of what is done in usbhs_enable() should actually be done in
the ->runtime_resume() callback, and similarily, much of what is done in
usbhs_disable() should be done in the ->runtime_suspend() callback.

Another thing to be aware of is that runtime PM can be disabled from
userspace.  For example, try this:

   echo on > /sys/devices/platform/omap/usbhs_omap/power/control

This disables runtime PM for the device.  After doing this and
suspending, you'll notice that usbhost powerdomain no longer hits
retention on suspend.  Setting it back to 'auto' allows it to work
again.

Because of this, you can not simply call pm_runtime_put() from the
static suspend callback.  You should check pm_runtime_is_suspended().
If it is, there's nothing to do.  If not, the runtime PM callbacks for
the subsystem need to manually be called.  See drivers/i2c/i2c-omap.c
for an example (and check the version in my PM branch, which has a fix
required starting with kernel v3.0.)

While I'm preaching on runtime PM here, some other things that should be
cleaned up because they duplicate what other frameworks are doing:

- drivers should not be touching their SYSCONFIG register.  This
  is managed by omap_hwmod
- current driver is doing usage counting, but runtime PM core is
  already handling usage counting.

My apologies for not reviewing the runtime PM work in this driver
earlier.  Some of the problems above come from code that's already in
mainline (which I should've reviewed earlier), and some are added with
this series.  All of them should be cleaned up before merging this.

Kevin

>  struct usbhs_hcd_omap {
>  	struct clk			*xclk60mhsp1_ck;
>  	struct clk			*xclk60mhsp2_ck;
> @@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
>  	u32				usbhs_rev;
>  	spinlock_t			lock;
>  	int				count;
> +	unsigned long			state;
>  };
>  /*-------------------------------------------------------------------------*/
>  
> @@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
>  				(pdata->ehci_data->reset_gpio_port[1], 1);
>  	}
>  
> +	set_bit(OMAP_USBHS_INIT, &omap->state);
> +
>  end_count:
>  	omap->count++;
>  	spin_unlock_irqrestore(&omap->lock, flags);
> @@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
>  	}
>  
>  	pm_runtime_put_sync(dev);
> +	clear_bit(OMAP_USBHS_INIT, &omap->state);
>  
>  	/* The gpio_free migh sleep; so unlock the spinlock */
>  	spin_unlock_irqrestore(&omap->lock, flags);
> @@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(omap_usbhs_disable);
>  
> +#ifdef	CONFIG_PM
> +
> +static int usbhs_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;
> +
> +	dev_dbg(dev, "Resuming TI HSUSB Controller\n");
> +
> +	if (!pdata) {
> +		dev_dbg(dev, "missing platform_data\n");
> +		return  -ENODEV;
> +	}
> +
> +	spin_lock_irqsave(&omap->lock, flags);
> +
> +	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
> +		!test_bit(OMAP_USBHS_SUSPEND, &omap->state))
> +			goto end_resume;
> +
> +	pm_runtime_get_sync(dev);
> +
> +	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);
> +	}
> +	clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
> +
> +end_resume:
> +	spin_unlock_irqrestore(&omap->lock, flags);
> +	return 0;
> +}
> +
> +
> +static int usbhs_suspend(struct device *dev)
> +{
> +	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
> +	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
> +	unsigned long			flags = 0;
> +
> +	dev_dbg(dev, "Suspending TI HSUSB Controller\n");
> +
> +	if (!pdata) {
> +		dev_dbg(dev, "missing platform_data\n");
> +		return  -ENODEV;
> +	}
> +
> +	spin_lock_irqsave(&omap->lock, flags);
> +
> +	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
> +		test_bit(OMAP_USBHS_SUSPEND, &omap->state))
> +			goto end_suspend;
> +
> +	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);
> +	}
> +
> +	set_bit(OMAP_USBHS_SUSPEND, &omap->state);
> +	pm_runtime_put_sync(dev);
> +
> +end_suspend:
> +	spin_unlock_irqrestore(&omap->lock, flags);
> +	return 0;
> +}
> +
> +
> +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
> +	.suspend	= usbhs_suspend,
> +	.resume		= usbhs_resume,
> +};
> +
> +#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
> +#else
> +#define	USBHS_OMAP_DEV_PM_OPS	NULL
> +#endif
> +
>  static struct platform_driver usbhs_omap_driver = {
>  	.driver = {
>  		.name		= (char *)usbhs_driver_name,
>  		.owner		= THIS_MODULE,
> +		.pm		= USBHS_OMAP_DEV_PM_OPS,
>  	},
>  	.remove		= __exit_p(usbhs_omap_remove),
>  };

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-02  0:06           ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-02  0:06 UTC (permalink / raw)
  To: Keshava Munegowda
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul, Keshava Munegowda

Keshava Munegowda <keshava_mgowda@ti.com> writes:

> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>
> The global suspend and resume functions for usbhs core driver
> are implemented.These routine are called when the global suspend
> and resume occurs. Before calling these functions, the
> bus suspend and resume of ehci and ohci drivers are called
> from runtime pm.
>
> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>

First, from what I can see, this is only a partial implementation of
runtime PM.  What I mean is that the runtime PM methods are used only
during the suspend path.  The rest of the time the USB host IP block is
left enabled, even when nothing is connected.

I tested this on my 3530/Overo board, and verified that indeed the
usbhost powerdomain hits retention on suspend, but while idle, when
nothing is connected, I would expect the driver could be clever enough
to use runtime PM (probably using autosuspend timeouts) to disable the
hardware as well.

> ---
>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 103 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> index 43de12a..32d19e2 100644
> --- a/drivers/mfd/omap-usb-host.c
> +++ b/drivers/mfd/omap-usb-host.c
> @@ -146,6 +146,10 @@
>  #define is_ehci_hsic_mode(x)	(x == OMAP_EHCI_PORT_MODE_HSIC)
>  
>  
> +/* USBHS state bits */
> +#define OMAP_USBHS_INIT		0
> +#define OMAP_USBHS_SUSPEND	4

These additional state bits don't seem to be necessary.

For suspend, just check 'pm_runtime_is_suspended()'

The init flag is only used in the suspend/resume hooks, but the need for
it is a side effect of not correctly using the runtime PM callbacks.

Remember that the runtime PM get/put hooks have usage counting.  Only
when the usage count transitions to/from zero is the actual
hardware-level enable/disable (via omap_hwmod) being done.   

The current code is making the assumption that every call to get/put is
going to result in an enable/disable of the hardware.

Instead, all of the code that needs to be run only upon actual
enable/disable of the hardware should be done in the driver's
runtime_suspend/runtime_resume callbacks.  These are only called when
the hardware actually changes state.   

Not knowing that much about the EHCI block, upon first glance, it looks
like mmuch of what is done in usbhs_enable() should actually be done in
the ->runtime_resume() callback, and similarily, much of what is done in
usbhs_disable() should be done in the ->runtime_suspend() callback.

Another thing to be aware of is that runtime PM can be disabled from
userspace.  For example, try this:

   echo on > /sys/devices/platform/omap/usbhs_omap/power/control

This disables runtime PM for the device.  After doing this and
suspending, you'll notice that usbhost powerdomain no longer hits
retention on suspend.  Setting it back to 'auto' allows it to work
again.

Because of this, you can not simply call pm_runtime_put() from the
static suspend callback.  You should check pm_runtime_is_suspended().
If it is, there's nothing to do.  If not, the runtime PM callbacks for
the subsystem need to manually be called.  See drivers/i2c/i2c-omap.c
for an example (and check the version in my PM branch, which has a fix
required starting with kernel v3.0.)

While I'm preaching on runtime PM here, some other things that should be
cleaned up because they duplicate what other frameworks are doing:

- drivers should not be touching their SYSCONFIG register.  This
  is managed by omap_hwmod
- current driver is doing usage counting, but runtime PM core is
  already handling usage counting.

My apologies for not reviewing the runtime PM work in this driver
earlier.  Some of the problems above come from code that's already in
mainline (which I should've reviewed earlier), and some are added with
this series.  All of them should be cleaned up before merging this.

Kevin

>  struct usbhs_hcd_omap {
>  	struct clk			*xclk60mhsp1_ck;
>  	struct clk			*xclk60mhsp2_ck;
> @@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
>  	u32				usbhs_rev;
>  	spinlock_t			lock;
>  	int				count;
> +	unsigned long			state;
>  };
>  /*-------------------------------------------------------------------------*/
>  
> @@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
>  				(pdata->ehci_data->reset_gpio_port[1], 1);
>  	}
>  
> +	set_bit(OMAP_USBHS_INIT, &omap->state);
> +
>  end_count:
>  	omap->count++;
>  	spin_unlock_irqrestore(&omap->lock, flags);
> @@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
>  	}
>  
>  	pm_runtime_put_sync(dev);
> +	clear_bit(OMAP_USBHS_INIT, &omap->state);
>  
>  	/* The gpio_free migh sleep; so unlock the spinlock */
>  	spin_unlock_irqrestore(&omap->lock, flags);
> @@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(omap_usbhs_disable);
>  
> +#ifdef	CONFIG_PM
> +
> +static int usbhs_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;
> +
> +	dev_dbg(dev, "Resuming TI HSUSB Controller\n");
> +
> +	if (!pdata) {
> +		dev_dbg(dev, "missing platform_data\n");
> +		return  -ENODEV;
> +	}
> +
> +	spin_lock_irqsave(&omap->lock, flags);
> +
> +	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
> +		!test_bit(OMAP_USBHS_SUSPEND, &omap->state))
> +			goto end_resume;
> +
> +	pm_runtime_get_sync(dev);
> +
> +	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);
> +	}
> +	clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
> +
> +end_resume:
> +	spin_unlock_irqrestore(&omap->lock, flags);
> +	return 0;
> +}
> +
> +
> +static int usbhs_suspend(struct device *dev)
> +{
> +	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
> +	struct usbhs_omap_platform_data	*pdata = &omap->platdata;
> +	unsigned long			flags = 0;
> +
> +	dev_dbg(dev, "Suspending TI HSUSB Controller\n");
> +
> +	if (!pdata) {
> +		dev_dbg(dev, "missing platform_data\n");
> +		return  -ENODEV;
> +	}
> +
> +	spin_lock_irqsave(&omap->lock, flags);
> +
> +	if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
> +		test_bit(OMAP_USBHS_SUSPEND, &omap->state))
> +			goto end_suspend;
> +
> +	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);
> +	}
> +
> +	set_bit(OMAP_USBHS_SUSPEND, &omap->state);
> +	pm_runtime_put_sync(dev);
> +
> +end_suspend:
> +	spin_unlock_irqrestore(&omap->lock, flags);
> +	return 0;
> +}
> +
> +
> +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
> +	.suspend	= usbhs_suspend,
> +	.resume		= usbhs_resume,
> +};
> +
> +#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
> +#else
> +#define	USBHS_OMAP_DEV_PM_OPS	NULL
> +#endif
> +
>  static struct platform_driver usbhs_omap_driver = {
>  	.driver = {
>  		.name		= (char *)usbhs_driver_name,
>  		.owner		= THIS_MODULE,
> +		.pm		= USBHS_OMAP_DEV_PM_OPS,
>  	},
>  	.remove		= __exit_p(usbhs_omap_remove),
>  };

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

* Re: [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4
  2011-06-01 19:56     ` Kevin Hilman
  (?)
@ 2011-06-02  6:55     ` Munegowda, Keshava
  -1 siblings, 0 replies; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-02  6:55 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

On Thu, Jun 2, 2011 at 1:26 AM, Kevin Hilman <khilman@ti.com> wrote:
> Keshava Munegowda <keshava_mgowda@ti.com> writes:
>
>> Following 2 hwmod strcuture are added:
>> UHH hwmod of usbhs with uhh base address and
>> EHCI , OHCI irq and base addresses.
>> TLL hwmod of usbhs with the TLL base address and irq.
>>
>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>
> I believe the OMAP4 data came from Benoit, so should be in a patch with
> his authorship and signoff.  OMAP3 can be a separate patch with your
> authorship.

yes , you are right.
I apologizes for this. Benoit should be author.

>
> Kevin
>

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-01 14:32           ` Felipe Balbi
@ 2011-06-05 17:19             ` Rafael J. Wysocki
  2011-06-05 18:50               ` Felipe Balbi
  0 siblings, 1 reply; 50+ messages in thread
From: Rafael J. Wysocki @ 2011-06-05 17:19 UTC (permalink / raw)
  To: balbi
  Cc: Keshava Munegowda, linux-usb, linux-omap, linux-kernel, gadiyar,
	sameo, parthab, tony, khilman, b-cousson, paul

On Wednesday, June 01, 2011, Felipe Balbi wrote:
> Hi,
> 
> On Wed, Jun 01, 2011 at 03:54:38PM +0200, Rafael J. Wysocki wrote:
> > > +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
> > > +	.suspend	= usbhs_suspend,
> > > +	.resume		= usbhs_resume,
> > > +};
> > 
> > Please add .freeze()/.thaw() and .poweroff()/.restore() callbacks too.
> > They may point to the same routines, but must be present.
> > 
> > You can actually use the SIMPLE_DEV_PM_OPS() convenience macro for this
> > purpose.
> 
> good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> popping on most drivers recently ? To me it looks like driver.pm field
> is always available even if PM is disabled, so what's the point ? Saving
> a few bytes ?

Basically, yes (you may want to avoid defining the object this points to if
CONFIG_PM is unset).

Thanks,
Rafael

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-05 17:19             ` Rafael J. Wysocki
@ 2011-06-05 18:50               ` Felipe Balbi
  2011-06-05 19:30                   ` Alan Stern
  0 siblings, 1 reply; 50+ messages in thread
From: Felipe Balbi @ 2011-06-05 18:50 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: balbi, Keshava Munegowda, linux-usb, linux-omap, linux-kernel,
	gadiyar, sameo, parthab, tony, khilman, b-cousson, paul

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

Hi,

On Sun, Jun 05, 2011 at 07:19:38PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Jun 01, 2011 at 03:54:38PM +0200, Rafael J. Wysocki wrote:
> > > > +static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
> > > > +	.suspend	= usbhs_suspend,
> > > > +	.resume		= usbhs_resume,
> > > > +};
> > > 
> > > Please add .freeze()/.thaw() and .poweroff()/.restore() callbacks too.
> > > They may point to the same routines, but must be present.
> > > 
> > > You can actually use the SIMPLE_DEV_PM_OPS() convenience macro for this
> > > purpose.
> > 
> > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > popping on most drivers recently ? To me it looks like driver.pm field
> > is always available even if PM is disabled, so what's the point ? Saving
> > a few bytes ?
> 
> Basically, yes (you may want to avoid defining the object this points to if
> CONFIG_PM is unset).

wouldn't it look nicer to have a specific section for dev_pm_ops which
gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
few drivers which don't have the ifdeferry around dev_pm_ops anyway.

So, something like:

#define __pm_ops	__section(.pm.ops)

static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
	.suspend	= my_driver_suspend,
	.resume		= my_driver_resume,
	[ blablabla ]
};

to simplify things, you could:

#define DEFINE_DEV_PM_OPS(_ops)		\
	const struct dev_pm_ops _ops __pm_ops

that would mean changes to all linker scripts, though and a utility call
that only does anything ifndef CONFIG_PM to free the .pm.ops section.

-- 
balbi

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

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-05 18:50               ` Felipe Balbi
@ 2011-06-05 19:30                   ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-05 19:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Rafael J. Wysocki, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, gadiyar, sameo, parthab, tony, khilman, b-cousson,
	paul

On Sun, 5 Jun 2011, Felipe Balbi wrote:

> > > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > > popping on most drivers recently ? To me it looks like driver.pm field
> > > is always available even if PM is disabled, so what's the point ? Saving
> > > a few bytes ?
> > 
> > Basically, yes (you may want to avoid defining the object this points to if
> > CONFIG_PM is unset).
> 
> wouldn't it look nicer to have a specific section for dev_pm_ops which
> gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
> few drivers which don't have the ifdeferry around dev_pm_ops anyway.
> 
> So, something like:
> 
> #define __pm_ops	__section(.pm.ops)
> 
> static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> 	.suspend	= my_driver_suspend,
> 	.resume		= my_driver_resume,
> 	[ blablabla ]
> };
> 
> to simplify things, you could:
> 
> #define DEFINE_DEV_PM_OPS(_ops)		\
> 	const struct dev_pm_ops _ops __pm_ops
> 
> that would mean changes to all linker scripts, though and a utility call
> that only does anything ifndef CONFIG_PM to free the .pm.ops section.

In my opinion this would make programming harder, not easier.  It's
very easy to understand "#ifdef" followed by "#endif"; people see them
all the time.  The new tags you propose would force people to go
searching through tons of source files to see what they mean, and then
readers would still have to figure out when these tags should be used
or what advantage they might bring.

It's a little like "typedef struct foo foo_t;" -- doing this forces
people to remember one extra piece of information that serves no real
purpose except perhaps a minimal reduction in the amount of typing.  
Since the limiting factor in kernel programming is human brainpower,
not source file length, this is a bad tradeoff.  (Not to mention that
it also obscures an important fact: A foo_t is an extended structure
rather than a single value.)

Alan Stern


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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-05 19:30                   ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-05 19:30 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Rafael J. Wysocki, Keshava Munegowda, linux-usb, linux-omap,
	linux-kernel, gadiyar, sameo, parthab, tony, khilman, b-cousson,
	paul

On Sun, 5 Jun 2011, Felipe Balbi wrote:

> > > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > > popping on most drivers recently ? To me it looks like driver.pm field
> > > is always available even if PM is disabled, so what's the point ? Saving
> > > a few bytes ?
> > 
> > Basically, yes (you may want to avoid defining the object this points to if
> > CONFIG_PM is unset).
> 
> wouldn't it look nicer to have a specific section for dev_pm_ops which
> gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
> few drivers which don't have the ifdeferry around dev_pm_ops anyway.
> 
> So, something like:
> 
> #define __pm_ops	__section(.pm.ops)
> 
> static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> 	.suspend	= my_driver_suspend,
> 	.resume		= my_driver_resume,
> 	[ blablabla ]
> };
> 
> to simplify things, you could:
> 
> #define DEFINE_DEV_PM_OPS(_ops)		\
> 	const struct dev_pm_ops _ops __pm_ops
> 
> that would mean changes to all linker scripts, though and a utility call
> that only does anything ifndef CONFIG_PM to free the .pm.ops section.

In my opinion this would make programming harder, not easier.  It's
very easy to understand "#ifdef" followed by "#endif"; people see them
all the time.  The new tags you propose would force people to go
searching through tons of source files to see what they mean, and then
readers would still have to figure out when these tags should be used
or what advantage they might bring.

It's a little like "typedef struct foo foo_t;" -- doing this forces
people to remember one extra piece of information that serves no real
purpose except perhaps a minimal reduction in the amount of typing.  
Since the limiting factor in kernel programming is human brainpower,
not source file length, this is a bad tradeoff.  (Not to mention that
it also obscures an important fact: A foo_t is an extended structure
rather than a single value.)

Alan Stern

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-05 19:54                     ` Felipe Balbi
  0 siblings, 0 replies; 50+ messages in thread
From: Felipe Balbi @ 2011-06-05 19:54 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Rafael J. Wysocki, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

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

Hi,

On Sun, Jun 05, 2011 at 03:30:55PM -0400, Alan Stern wrote:
> > > > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > > > popping on most drivers recently ? To me it looks like driver.pm field
> > > > is always available even if PM is disabled, so what's the point ? Saving
> > > > a few bytes ?
> > > 
> > > Basically, yes (you may want to avoid defining the object this points to if
> > > CONFIG_PM is unset).
> > 
> > wouldn't it look nicer to have a specific section for dev_pm_ops which
> > gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
> > few drivers which don't have the ifdeferry around dev_pm_ops anyway.
> > 
> > So, something like:
> > 
> > #define __pm_ops	__section(.pm.ops)
> > 
> > static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> > 	.suspend	= my_driver_suspend,
> > 	.resume		= my_driver_resume,
> > 	[ blablabla ]
> > };
> > 
> > to simplify things, you could:
> > 
> > #define DEFINE_DEV_PM_OPS(_ops)		\
> > 	const struct dev_pm_ops _ops __pm_ops
> > 
> > that would mean changes to all linker scripts, though and a utility call
> > that only does anything ifndef CONFIG_PM to free the .pm.ops section.
> 
> In my opinion this would make programming harder, not easier.  It's

I tend to disagree with this statement, see below.

> very easy to understand "#ifdef" followed by "#endif"; people see them

very true... Still everybody has to put them in place.

> all the time.  The new tags you propose would force people to go
> searching through tons of source files to see what they mean, and then

only those who want to see "how things work" would be forced to do that,
other people would be allowed to "assume it's doing the right thing".

> readers would still have to figure out when these tags should be used
> or what advantage they might bring.

not really, if you add a macro which adds that correctly and during
review we only accept drivers using that particular macro, things
wouldn't go bad at all.

> It's a little like "typedef struct foo foo_t;" -- doing this forces

hey c'mon. Then you're saying that all __initdata, __devinitdata,
__initconst and all of those are "typedef struct foo foo_t" ;-)

> people to remember one extra piece of information that serves no real
> purpose except perhaps a minimal reduction in the amount of typing.  

and a guarantee that the unused data will be freed when it's really not
needed ;-)

> Since the limiting factor in kernel programming is human brainpower,
> not source file length, this is a bad tradeoff.  (Not to mention that

OTOH we are going through a big re-factor of the ARM port to reduce the
amount of code. Not that these few characters would change much but my
point is that amount of code also matters. So does uniformity, coding
style, etc...

> it also obscures an important fact: A foo_t is an extended structure
> rather than a single value.)

then it would make sense to have dev_pm_ops only defined when CONFIG_PM
is set to force all drivers stick to a common way of handling this.

Besides, currently, everybody who wants to keep the ifdeferry, needs to
define a macro for &my_dev_pm_ops or have two #ifdef..#endif blocks.

Either you do:

#ifdef CONFIG_PM
static int my_driver_suspend(struct device *dev)
{
	...

	return 0;
}
....

static const struct dev_pm_ops my_driver_pm_ops = {
	.suspend	= my_driver_suspend,
	...
};

#define DEV_PM_OPS	(&my_driver_pm_ops)
#else
#define DEV_PM_OPS	NULL
#endif

static struct platform_driver my_driver = {
	...
	.driver	= {
		.pm = DEV_PM_OPS
	},
};

or you do:

#ifdef CONFIG_PM
static int my_driver_suspend(struct device *dev)
{
	...

	return 0;
}
....

static const struct dev_pm_ops my_driver_pm_ops = {
	.suspend	= my_driver_suspend,
	...
};

#endif

static struct platform_driver my_driver = {
	...
	.driver	= {
#ifdef CONFIG_PM
		.pm = &my_driver_pm_ops,
#endif
	},
};

So, while this is a small thing which is easy to understand, it's still
yet another thing that all drivers have to remember to add. And when
everybody needs to remember that, I'd rather have it done
"automatically" by other means.

I mean, we already free .init.* sections after __init anyway, so what's
the problem in freeing another section ? I don't see it as obfuscation
at all. I see it as if the kernel is smart enough to free all unused
data by itself, without myself having to add ifdefs or freeing it by my
own.

On top of all that, today, we have driver with both ways of ifdefs plus
drivers with no ifdeferry at all, leaving dev_pm_ops floating around for
nothing.

IMHO, if things aren't uniform, we will have small problems, such as
this, proliferate because new drivers are based on other drivers,
generally.

-- 
balbi

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

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-05 19:54                     ` Felipe Balbi
  0 siblings, 0 replies; 50+ messages in thread
From: Felipe Balbi @ 2011-06-05 19:54 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Rafael J. Wysocki, Keshava Munegowda,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, gadiyar-l0cyMroinI0,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, khilman-l0cyMroinI0,
	b-cousson-l0cyMroinI0, paul-DWxLp4Yu+b8AvxtiuMwx3w

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

Hi,

On Sun, Jun 05, 2011 at 03:30:55PM -0400, Alan Stern wrote:
> > > > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > > > popping on most drivers recently ? To me it looks like driver.pm field
> > > > is always available even if PM is disabled, so what's the point ? Saving
> > > > a few bytes ?
> > > 
> > > Basically, yes (you may want to avoid defining the object this points to if
> > > CONFIG_PM is unset).
> > 
> > wouldn't it look nicer to have a specific section for dev_pm_ops which
> > gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
> > few drivers which don't have the ifdeferry around dev_pm_ops anyway.
> > 
> > So, something like:
> > 
> > #define __pm_ops	__section(.pm.ops)
> > 
> > static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> > 	.suspend	= my_driver_suspend,
> > 	.resume		= my_driver_resume,
> > 	[ blablabla ]
> > };
> > 
> > to simplify things, you could:
> > 
> > #define DEFINE_DEV_PM_OPS(_ops)		\
> > 	const struct dev_pm_ops _ops __pm_ops
> > 
> > that would mean changes to all linker scripts, though and a utility call
> > that only does anything ifndef CONFIG_PM to free the .pm.ops section.
> 
> In my opinion this would make programming harder, not easier.  It's

I tend to disagree with this statement, see below.

> very easy to understand "#ifdef" followed by "#endif"; people see them

very true... Still everybody has to put them in place.

> all the time.  The new tags you propose would force people to go
> searching through tons of source files to see what they mean, and then

only those who want to see "how things work" would be forced to do that,
other people would be allowed to "assume it's doing the right thing".

> readers would still have to figure out when these tags should be used
> or what advantage they might bring.

not really, if you add a macro which adds that correctly and during
review we only accept drivers using that particular macro, things
wouldn't go bad at all.

> It's a little like "typedef struct foo foo_t;" -- doing this forces

hey c'mon. Then you're saying that all __initdata, __devinitdata,
__initconst and all of those are "typedef struct foo foo_t" ;-)

> people to remember one extra piece of information that serves no real
> purpose except perhaps a minimal reduction in the amount of typing.  

and a guarantee that the unused data will be freed when it's really not
needed ;-)

> Since the limiting factor in kernel programming is human brainpower,
> not source file length, this is a bad tradeoff.  (Not to mention that

OTOH we are going through a big re-factor of the ARM port to reduce the
amount of code. Not that these few characters would change much but my
point is that amount of code also matters. So does uniformity, coding
style, etc...

> it also obscures an important fact: A foo_t is an extended structure
> rather than a single value.)

then it would make sense to have dev_pm_ops only defined when CONFIG_PM
is set to force all drivers stick to a common way of handling this.

Besides, currently, everybody who wants to keep the ifdeferry, needs to
define a macro for &my_dev_pm_ops or have two #ifdef..#endif blocks.

Either you do:

#ifdef CONFIG_PM
static int my_driver_suspend(struct device *dev)
{
	...

	return 0;
}
....

static const struct dev_pm_ops my_driver_pm_ops = {
	.suspend	= my_driver_suspend,
	...
};

#define DEV_PM_OPS	(&my_driver_pm_ops)
#else
#define DEV_PM_OPS	NULL
#endif

static struct platform_driver my_driver = {
	...
	.driver	= {
		.pm = DEV_PM_OPS
	},
};

or you do:

#ifdef CONFIG_PM
static int my_driver_suspend(struct device *dev)
{
	...

	return 0;
}
....

static const struct dev_pm_ops my_driver_pm_ops = {
	.suspend	= my_driver_suspend,
	...
};

#endif

static struct platform_driver my_driver = {
	...
	.driver	= {
#ifdef CONFIG_PM
		.pm = &my_driver_pm_ops,
#endif
	},
};

So, while this is a small thing which is easy to understand, it's still
yet another thing that all drivers have to remember to add. And when
everybody needs to remember that, I'd rather have it done
"automatically" by other means.

I mean, we already free .init.* sections after __init anyway, so what's
the problem in freeing another section ? I don't see it as obfuscation
at all. I see it as if the kernel is smart enough to free all unused
data by itself, without myself having to add ifdefs or freeing it by my
own.

On top of all that, today, we have driver with both ways of ifdefs plus
drivers with no ifdeferry at all, leaving dev_pm_ops floating around for
nothing.

IMHO, if things aren't uniform, we will have small problems, such as
this, proliferate because new drivers are based on other drivers,
generally.

-- 
balbi

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

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-06  9:45                     ` Mark Brown
  0 siblings, 0 replies; 50+ messages in thread
From: Mark Brown @ 2011-06-06  9:45 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Rafael J. Wysocki, Keshava Munegowda, linux-usb,
	linux-omap, linux-kernel, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

On Sun, Jun 05, 2011 at 03:30:55PM -0400, Alan Stern wrote:
> On Sun, 5 Jun 2011, Felipe Balbi wrote:

> > that would mean changes to all linker scripts, though and a utility call
> > that only does anything ifndef CONFIG_PM to free the .pm.ops section.

> In my opinion this would make programming harder, not easier.  It's
> very easy to understand "#ifdef" followed by "#endif"; people see them
> all the time.  The new tags you propose would force people to go
> searching through tons of source files to see what they mean, and then
> readers would still have to figure out when these tags should be used
> or what advantage they might bring.

The big advantage is that they make it much harder to introduce random
build breakage and they're an awful lot less fiddly to do - it used to
be not so bad when it was just the function pointers that needed to be
defined to NULL but now we need to faff around with both the functions
and the dev_pm_ops.

The annotation approach is already familiar from the init stuff so it
wouldn't be so hard for people to understand.

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-06  9:45                     ` Mark Brown
  0 siblings, 0 replies; 50+ messages in thread
From: Mark Brown @ 2011-06-06  9:45 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Rafael J. Wysocki, Keshava Munegowda,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, gadiyar-l0cyMroinI0,
	sameo-VuQAYsv1563Yd54FQh9/CA, parthab-PpE0FKYn9XJWk0Htik3J/w,
	tony-4v6yS6AI5VpBDgjK7y7TUQ, khilman-l0cyMroinI0,
	b-cousson-l0cyMroinI0, paul-DWxLp4Yu+b8AvxtiuMwx3w

On Sun, Jun 05, 2011 at 03:30:55PM -0400, Alan Stern wrote:
> On Sun, 5 Jun 2011, Felipe Balbi wrote:

> > that would mean changes to all linker scripts, though and a utility call
> > that only does anything ifndef CONFIG_PM to free the .pm.ops section.

> In my opinion this would make programming harder, not easier.  It's
> very easy to understand "#ifdef" followed by "#endif"; people see them
> all the time.  The new tags you propose would force people to go
> searching through tons of source files to see what they mean, and then
> readers would still have to figure out when these tags should be used
> or what advantage they might bring.

The big advantage is that they make it much harder to introduce random
build breakage and they're an awful lot less fiddly to do - it used to
be not so bad when it was just the function pointers that needed to be
defined to NULL but now we need to faff around with both the functions
and the dev_pm_ops.

The annotation approach is already familiar from the init stuff so it
wouldn't be so hard for people to understand.
--
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] 50+ messages in thread

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-06 16:06                       ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-06 16:06 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Rafael J. Wysocki, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

On Sun, 5 Jun 2011, Felipe Balbi wrote:

> Hi,
> 
> On Sun, Jun 05, 2011 at 03:30:55PM -0400, Alan Stern wrote:
> > > > > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > > > > popping on most drivers recently ? To me it looks like driver.pm field
> > > > > is always available even if PM is disabled, so what's the point ? Saving
> > > > > a few bytes ?
> > > > 
> > > > Basically, yes (you may want to avoid defining the object this points to if
> > > > CONFIG_PM is unset).
> > > 
> > > wouldn't it look nicer to have a specific section for dev_pm_ops which
> > > gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
> > > few drivers which don't have the ifdeferry around dev_pm_ops anyway.
> > > 
> > > So, something like:
> > > 
> > > #define __pm_ops	__section(.pm.ops)
> > > 
> > > static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> > > 	.suspend	= my_driver_suspend,
> > > 	.resume		= my_driver_resume,
> > > 	[ blablabla ]
> > > };
> > > 
> > > to simplify things, you could:
> > > 
> > > #define DEFINE_DEV_PM_OPS(_ops)		\
> > > 	const struct dev_pm_ops _ops __pm_ops
> > > 
> > > that would mean changes to all linker scripts, though and a utility call
> > > that only does anything ifndef CONFIG_PM to free the .pm.ops section.
> > 
> > In my opinion this would make programming harder, not easier.  It's
> 
> I tend to disagree with this statement, see below.
> 
> > very easy to understand "#ifdef" followed by "#endif"; people see them
> 
> very true... Still everybody has to put them in place.

True.  But with your suggestion, people have to remember to use 
__pm_ops and DEFINE_DEV_PM_OPS.

> > all the time.  The new tags you propose would force people to go
> > searching through tons of source files to see what they mean, and then
> 
> only those who want to see "how things work" would be forced to do that,
> other people would be allowed to "assume it's doing the right thing".

But what is the "right thing"?  Suppose you want to have conditional 
support for dev_pm_ops whenever CONFIG_PM is enabled and you _also_ 
want to have conditional support for runtime PM whenever 
CONFIG_PM_RUNTIME is enabled?

> > readers would still have to figure out when these tags should be used
> > or what advantage they might bring.
> 
> not really, if you add a macro which adds that correctly and during
> review we only accept drivers using that particular macro, things
> wouldn't go bad at all.
> 
> > It's a little like "typedef struct foo foo_t;" -- doing this forces
> 
> hey c'mon. Then you're saying that all __initdata, __devinitdata,
> __initconst and all of those are "typedef struct foo foo_t" ;-)

No.  Unlike foo_t, they don't obscure important information and they do 
provide a significant gain in simplicity.  On the other hand, they also 
provide a certain degree of confusion.  Remember all the difficulty we 
had with intialization code sections in the gadget framework.

> > people to remember one extra piece of information that serves no real
> > purpose except perhaps a minimal reduction in the amount of typing.  
> 
> and a guarantee that the unused data will be freed when it's really not
> needed ;-)

You can obtain that same guarantee by using #ifdef ... #endif.  Even 
better, you can guarantee that the unused data won't be present at all, 
as opposed to loaded and then freed.

> > Since the limiting factor in kernel programming is human brainpower,
> > not source file length, this is a bad tradeoff.  (Not to mention that
> 
> OTOH we are going through a big re-factor of the ARM port to reduce the
> amount of code. Not that these few characters would change much but my
> point is that amount of code also matters. So does uniformity, coding
> style, etc...
> 
> > it also obscures an important fact: A foo_t is an extended structure
> > rather than a single value.)
> 
> then it would make sense to have dev_pm_ops only defined when CONFIG_PM
> is set to force all drivers stick to a common way of handling this.
> 
> Besides, currently, everybody who wants to keep the ifdeferry, needs to
> define a macro for &my_dev_pm_ops or have two #ifdef..#endif blocks.
> 
> Either you do:
> 
> #ifdef CONFIG_PM
> static int my_driver_suspend(struct device *dev)
> {
> 	...
> 
> 	return 0;
> }
> ....
> 
> static const struct dev_pm_ops my_driver_pm_ops = {
> 	.suspend	= my_driver_suspend,
> 	...
> };
> 
> #define DEV_PM_OPS	(&my_driver_pm_ops)
> #else
> #define DEV_PM_OPS	NULL
> #endif
> 
> static struct platform_driver my_driver = {
> 	...
> 	.driver	= {
> 		.pm = DEV_PM_OPS
> 	},
> };
> 
> or you do:
> 
> #ifdef CONFIG_PM
> static int my_driver_suspend(struct device *dev)
> {
> 	...
> 
> 	return 0;
> }
> ....
> 
> static const struct dev_pm_ops my_driver_pm_ops = {
> 	.suspend	= my_driver_suspend,
> 	...
> };
> 
> #endif
> 
> static struct platform_driver my_driver = {
> 	...
> 	.driver	= {
> #ifdef CONFIG_PM
> 		.pm = &my_driver_pm_ops,
> #endif
> 	},
> };

Whereas your way people write:

static int __pm_ops my_driver_suspend(struct device *dev)
{
	...

	return 0;
}
....

static DEFINE_DEV_PM_OPS(my_driver_pm_ops) = {
	.suspend	= my_driver_suspend,
	...
};

static struct platform_driver my_driver = {
	...
	.driver	= {
		.pm = &my_driver_pm_ops,
	},
};

It doesn't seem like a good idea to keep the invalid pointer to 
my_driver_pm_ops, even though it should never get used.

An approach that might work better would be for the PM core to define a 
suitable macro:

#ifdef CONFIG_PM
	#define DEV_PM_OPS_REF(my_pm_ops)	&(my_pm_ops)
#else
	#define DEV_PM_OPS_REF(my_pm_ops)	NULL
#endif

Then people could write

static struct platform_driver my_driver = {
	...
	.driver	= {
		.pm = DEV_PM_OPS_REF(my_driver_pm_ops),
	},
};

without worrying about whether or not my_driver_pm_ops was defined.  
And only one #ifdef block would be needed.

> So, while this is a small thing which is easy to understand, it's still
> yet another thing that all drivers have to remember to add. And when
> everybody needs to remember that, I'd rather have it done
> "automatically" by other means.
> 
> I mean, we already free .init.* sections after __init anyway, so what's
> the problem in freeing another section ? I don't see it as obfuscation
> at all. I see it as if the kernel is smart enough to free all unused
> data by itself, without myself having to add ifdefs or freeing it by my
> own.
> 
> On top of all that, today, we have driver with both ways of ifdefs plus
> drivers with no ifdeferry at all, leaving dev_pm_ops floating around for
> nothing.
> 
> IMHO, if things aren't uniform, we will have small problems, such as
> this, proliferate because new drivers are based on other drivers,
> generally.

I have to agree that uniformity is to be desired.  And it's probably 
already way too late, because we can't prevent new drivers from being 
based on the existing drivers -- even if all the existing drivers get 
changed over (which seems unlikely).

Alan Stern


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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-06 16:06                       ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-06 16:06 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Rafael J. Wysocki, Keshava Munegowda, USB list,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Kernel development list,
	gadiyar-l0cyMroinI0, sameo-VuQAYsv1563Yd54FQh9/CA,
	parthab-PpE0FKYn9XJWk0Htik3J/w, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	khilman-l0cyMroinI0, b-cousson-l0cyMroinI0,
	paul-DWxLp4Yu+b8AvxtiuMwx3w

On Sun, 5 Jun 2011, Felipe Balbi wrote:

> Hi,
> 
> On Sun, Jun 05, 2011 at 03:30:55PM -0400, Alan Stern wrote:
> > > > > good point. BTW, do we need this #ifdef CONFIG_PM stuff which has been
> > > > > popping on most drivers recently ? To me it looks like driver.pm field
> > > > > is always available even if PM is disabled, so what's the point ? Saving
> > > > > a few bytes ?
> > > > 
> > > > Basically, yes (you may want to avoid defining the object this points to if
> > > > CONFIG_PM is unset).
> > > 
> > > wouldn't it look nicer to have a specific section for dev_pm_ops which
> > > gets automatically freed if CONFIG_PM isn't set ? I mean, there are a
> > > few drivers which don't have the ifdeferry around dev_pm_ops anyway.
> > > 
> > > So, something like:
> > > 
> > > #define __pm_ops	__section(.pm.ops)
> > > 
> > > static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> > > 	.suspend	= my_driver_suspend,
> > > 	.resume		= my_driver_resume,
> > > 	[ blablabla ]
> > > };
> > > 
> > > to simplify things, you could:
> > > 
> > > #define DEFINE_DEV_PM_OPS(_ops)		\
> > > 	const struct dev_pm_ops _ops __pm_ops
> > > 
> > > that would mean changes to all linker scripts, though and a utility call
> > > that only does anything ifndef CONFIG_PM to free the .pm.ops section.
> > 
> > In my opinion this would make programming harder, not easier.  It's
> 
> I tend to disagree with this statement, see below.
> 
> > very easy to understand "#ifdef" followed by "#endif"; people see them
> 
> very true... Still everybody has to put them in place.

True.  But with your suggestion, people have to remember to use 
__pm_ops and DEFINE_DEV_PM_OPS.

> > all the time.  The new tags you propose would force people to go
> > searching through tons of source files to see what they mean, and then
> 
> only those who want to see "how things work" would be forced to do that,
> other people would be allowed to "assume it's doing the right thing".

But what is the "right thing"?  Suppose you want to have conditional 
support for dev_pm_ops whenever CONFIG_PM is enabled and you _also_ 
want to have conditional support for runtime PM whenever 
CONFIG_PM_RUNTIME is enabled?

> > readers would still have to figure out when these tags should be used
> > or what advantage they might bring.
> 
> not really, if you add a macro which adds that correctly and during
> review we only accept drivers using that particular macro, things
> wouldn't go bad at all.
> 
> > It's a little like "typedef struct foo foo_t;" -- doing this forces
> 
> hey c'mon. Then you're saying that all __initdata, __devinitdata,
> __initconst and all of those are "typedef struct foo foo_t" ;-)

No.  Unlike foo_t, they don't obscure important information and they do 
provide a significant gain in simplicity.  On the other hand, they also 
provide a certain degree of confusion.  Remember all the difficulty we 
had with intialization code sections in the gadget framework.

> > people to remember one extra piece of information that serves no real
> > purpose except perhaps a minimal reduction in the amount of typing.  
> 
> and a guarantee that the unused data will be freed when it's really not
> needed ;-)

You can obtain that same guarantee by using #ifdef ... #endif.  Even 
better, you can guarantee that the unused data won't be present at all, 
as opposed to loaded and then freed.

> > Since the limiting factor in kernel programming is human brainpower,
> > not source file length, this is a bad tradeoff.  (Not to mention that
> 
> OTOH we are going through a big re-factor of the ARM port to reduce the
> amount of code. Not that these few characters would change much but my
> point is that amount of code also matters. So does uniformity, coding
> style, etc...
> 
> > it also obscures an important fact: A foo_t is an extended structure
> > rather than a single value.)
> 
> then it would make sense to have dev_pm_ops only defined when CONFIG_PM
> is set to force all drivers stick to a common way of handling this.
> 
> Besides, currently, everybody who wants to keep the ifdeferry, needs to
> define a macro for &my_dev_pm_ops or have two #ifdef..#endif blocks.
> 
> Either you do:
> 
> #ifdef CONFIG_PM
> static int my_driver_suspend(struct device *dev)
> {
> 	...
> 
> 	return 0;
> }
> ....
> 
> static const struct dev_pm_ops my_driver_pm_ops = {
> 	.suspend	= my_driver_suspend,
> 	...
> };
> 
> #define DEV_PM_OPS	(&my_driver_pm_ops)
> #else
> #define DEV_PM_OPS	NULL
> #endif
> 
> static struct platform_driver my_driver = {
> 	...
> 	.driver	= {
> 		.pm = DEV_PM_OPS
> 	},
> };
> 
> or you do:
> 
> #ifdef CONFIG_PM
> static int my_driver_suspend(struct device *dev)
> {
> 	...
> 
> 	return 0;
> }
> ....
> 
> static const struct dev_pm_ops my_driver_pm_ops = {
> 	.suspend	= my_driver_suspend,
> 	...
> };
> 
> #endif
> 
> static struct platform_driver my_driver = {
> 	...
> 	.driver	= {
> #ifdef CONFIG_PM
> 		.pm = &my_driver_pm_ops,
> #endif
> 	},
> };

Whereas your way people write:

static int __pm_ops my_driver_suspend(struct device *dev)
{
	...

	return 0;
}
....

static DEFINE_DEV_PM_OPS(my_driver_pm_ops) = {
	.suspend	= my_driver_suspend,
	...
};

static struct platform_driver my_driver = {
	...
	.driver	= {
		.pm = &my_driver_pm_ops,
	},
};

It doesn't seem like a good idea to keep the invalid pointer to 
my_driver_pm_ops, even though it should never get used.

An approach that might work better would be for the PM core to define a 
suitable macro:

#ifdef CONFIG_PM
	#define DEV_PM_OPS_REF(my_pm_ops)	&(my_pm_ops)
#else
	#define DEV_PM_OPS_REF(my_pm_ops)	NULL
#endif

Then people could write

static struct platform_driver my_driver = {
	...
	.driver	= {
		.pm = DEV_PM_OPS_REF(my_driver_pm_ops),
	},
};

without worrying about whether or not my_driver_pm_ops was defined.  
And only one #ifdef block would be needed.

> So, while this is a small thing which is easy to understand, it's still
> yet another thing that all drivers have to remember to add. And when
> everybody needs to remember that, I'd rather have it done
> "automatically" by other means.
> 
> I mean, we already free .init.* sections after __init anyway, so what's
> the problem in freeing another section ? I don't see it as obfuscation
> at all. I see it as if the kernel is smart enough to free all unused
> data by itself, without myself having to add ifdefs or freeing it by my
> own.
> 
> On top of all that, today, we have driver with both ways of ifdefs plus
> drivers with no ifdeferry at all, leaving dev_pm_ops floating around for
> nothing.
> 
> IMHO, if things aren't uniform, we will have small problems, such as
> this, proliferate because new drivers are based on other drivers,
> generally.

I have to agree that uniformity is to be desired.  And it's probably 
already way too late, because we can't prevent new drivers from being 
based on the existing drivers -- even if all the existing drivers get 
changed over (which seems unlikely).

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] 50+ messages in thread

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-06 16:06                       ` Alan Stern
  (?)
@ 2011-06-06 17:25                       ` Felipe Balbi
  2011-06-06 18:03                           ` Alan Stern
  -1 siblings, 1 reply; 50+ messages in thread
From: Felipe Balbi @ 2011-06-06 17:25 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Rafael J. Wysocki, Keshava Munegowda, USB list,
	linux-omap, Kernel development list, gadiyar, sameo, parthab,
	tony, khilman, b-cousson, paul

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

Hi,

On Mon, Jun 06, 2011 at 12:06:44PM -0400, Alan Stern wrote:
> > > > So, something like:
> > > > 
> > > > #define __pm_ops	__section(.pm.ops)
> > > > 
> > > > static const struct dev_pm_ops my_driver_pm_ops __pm_ops = {
> > > > 	.suspend	= my_driver_suspend,
> > > > 	.resume		= my_driver_resume,
> > > > 	[ blablabla ]
> > > > };
> > > > 
> > > > to simplify things, you could:
> > > > 
> > > > #define DEFINE_DEV_PM_OPS(_ops)		\
> > > > 	const struct dev_pm_ops _ops __pm_ops
> > > > 
> > > > that would mean changes to all linker scripts, though and a utility call
> > > > that only does anything ifndef CONFIG_PM to free the .pm.ops section.
> > > 
> > > In my opinion this would make programming harder, not easier.  It's
> > 
> > I tend to disagree with this statement, see below.
> > 
> > > very easy to understand "#ifdef" followed by "#endif"; people see them
> > 
> > very true... Still everybody has to put them in place.
> 
> True.  But with your suggestion, people have to remember to use 
> __pm_ops and DEFINE_DEV_PM_OPS.

Ok, I see your point here.

> > > all the time.  The new tags you propose would force people to go
> > > searching through tons of source files to see what they mean, and then
> > 
> > only those who want to see "how things work" would be forced to do that,
> > other people would be allowed to "assume it's doing the right thing".
> 
> But what is the "right thing"?  Suppose you want to have conditional 
> support for dev_pm_ops whenever CONFIG_PM is enabled and you _also_ 
> want to have conditional support for runtime PM whenever 
> CONFIG_PM_RUNTIME is enabled?

we don't have this today either. Currently everybody does #ifdef
CONFIG_PM, so either all the data is available, or none is and adding
another #ifdef CONFIG_PM_RUNTIME for the runtime_* friends, would just
look even uglier :-)

> > > readers would still have to figure out when these tags should be used
> > > or what advantage they might bring.
> > 
> > not really, if you add a macro which adds that correctly and during
> > review we only accept drivers using that particular macro, things
> > wouldn't go bad at all.
> > 
> > > It's a little like "typedef struct foo foo_t;" -- doing this forces
> > 
> > hey c'mon. Then you're saying that all __initdata, __devinitdata,
> > __initconst and all of those are "typedef struct foo foo_t" ;-)
> 
> No.  Unlike foo_t, they don't obscure important information and they do 
> provide a significant gain in simplicity.  On the other hand, they also 
> provide a certain degree of confusion.  Remember all the difficulty we 
> had with intialization code sections in the gadget framework.

this is fairly true, but only because the gadget framework isn't really
a framework. It's just an agreement that all UDCs will export a
particular function. It's a great infrastructure for the function
drivers, but not for UDCs, so I think this isn't a great example :-)

> > > people to remember one extra piece of information that serves no real
> > > purpose except perhaps a minimal reduction in the amount of typing.  
> > 
> > and a guarantee that the unused data will be freed when it's really not
> > needed ;-)
> 
> You can obtain that same guarantee by using #ifdef ... #endif.  Even 
> better, you can guarantee that the unused data won't be present at all, 
> as opposed to loaded and then freed.

I agree with you here, but I give you the same question as you gave me.
How will you have conditional on CONFIG_RUNTIME_PM and CONFIG_PM ? you'd
need two levels of ifdefs.

> > > Since the limiting factor in kernel programming is human brainpower,
> > > not source file length, this is a bad tradeoff.  (Not to mention that
> > 
> > OTOH we are going through a big re-factor of the ARM port to reduce the
> > amount of code. Not that these few characters would change much but my
> > point is that amount of code also matters. So does uniformity, coding
> > style, etc...
> > 
> > > it also obscures an important fact: A foo_t is an extended structure
> > > rather than a single value.)
> > 
> > then it would make sense to have dev_pm_ops only defined when CONFIG_PM
> > is set to force all drivers stick to a common way of handling this.
> > 
> > Besides, currently, everybody who wants to keep the ifdeferry, needs to
> > define a macro for &my_dev_pm_ops or have two #ifdef..#endif blocks.
> > 
> > Either you do:
> > 
> > #ifdef CONFIG_PM
> > static int my_driver_suspend(struct device *dev)
> > {
> > 	...
> > 
> > 	return 0;
> > }
> > ....
> > 
> > static const struct dev_pm_ops my_driver_pm_ops = {
> > 	.suspend	= my_driver_suspend,
> > 	...
> > };
> > 
> > #define DEV_PM_OPS	(&my_driver_pm_ops)
> > #else
> > #define DEV_PM_OPS	NULL
> > #endif
> > 
> > static struct platform_driver my_driver = {
> > 	...
> > 	.driver	= {
> > 		.pm = DEV_PM_OPS
> > 	},
> > };
> > 
> > or you do:
> > 
> > #ifdef CONFIG_PM
> > static int my_driver_suspend(struct device *dev)
> > {
> > 	...
> > 
> > 	return 0;
> > }
> > ....
> > 
> > static const struct dev_pm_ops my_driver_pm_ops = {
> > 	.suspend	= my_driver_suspend,
> > 	...
> > };
> > 
> > #endif
> > 
> > static struct platform_driver my_driver = {
> > 	...
> > 	.driver	= {
> > #ifdef CONFIG_PM
> > 		.pm = &my_driver_pm_ops,
> > #endif
> > 	},
> > };
> 
> Whereas your way people write:
> 
> static int __pm_ops my_driver_suspend(struct device *dev)
> {
> 	...
> 
> 	return 0;
> }
> ....
> 
> static DEFINE_DEV_PM_OPS(my_driver_pm_ops) = {
> 	.suspend	= my_driver_suspend,
> 	...
> };
> 
> static struct platform_driver my_driver = {
> 	...
> 	.driver	= {
> 		.pm = &my_driver_pm_ops,
> 	},
> };
> 
> It doesn't seem like a good idea to keep the invalid pointer to 
> my_driver_pm_ops, even though it should never get used.

true, I agree.

> An approach that might work better would be for the PM core to define a 
> suitable macro:
> 
> #ifdef CONFIG_PM
> 	#define DEV_PM_OPS_REF(my_pm_ops)	&(my_pm_ops)
> #else
> 	#define DEV_PM_OPS_REF(my_pm_ops)	NULL
> #endif
> 
> Then people could write
> 
> static struct platform_driver my_driver = {
> 	...
> 	.driver	= {
> 		.pm = DEV_PM_OPS_REF(my_driver_pm_ops),
> 	},
> };
> 
> without worrying about whether or not my_driver_pm_ops was defined.  
> And only one #ifdef block would be needed.

that'd be nice. Something similar to __exit_p() and __devexit_p()

> > So, while this is a small thing which is easy to understand, it's still
> > yet another thing that all drivers have to remember to add. And when
> > everybody needs to remember that, I'd rather have it done
> > "automatically" by other means.
> > 
> > I mean, we already free .init.* sections after __init anyway, so what's
> > the problem in freeing another section ? I don't see it as obfuscation
> > at all. I see it as if the kernel is smart enough to free all unused
> > data by itself, without myself having to add ifdefs or freeing it by my
> > own.
> > 
> > On top of all that, today, we have driver with both ways of ifdefs plus
> > drivers with no ifdeferry at all, leaving dev_pm_ops floating around for
> > nothing.
> > 
> > IMHO, if things aren't uniform, we will have small problems, such as
> > this, proliferate because new drivers are based on other drivers,
> > generally.
> 
> I have to agree that uniformity is to be desired.  And it's probably 
> already way too late, because we can't prevent new drivers from being 

I wouldn't call it late. Such small convertions can be done by simple
scripts, but when patches switching drivers over are rejected [1] then
we loose the opportunity to give good example to newcomers.

> based on the existing drivers -- even if all the existing drivers get 
> changed over (which seems unlikely).

Well, it might work out if pm core makes dev_pm_ops only available on
CONFIG_PM builds.

[1] http://marc.info/?l=linux-usb&m=129733927804315&w=2

-- 
balbi

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

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-06 17:25                       ` Felipe Balbi
@ 2011-06-06 18:03                           ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-06 18:03 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Rafael J. Wysocki, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

On Mon, 6 Jun 2011, Felipe Balbi wrote:

> > But what is the "right thing"?  Suppose you want to have conditional 
> > support for dev_pm_ops whenever CONFIG_PM is enabled and you _also_ 
> > want to have conditional support for runtime PM whenever 
> > CONFIG_PM_RUNTIME is enabled?
> 
> we don't have this today either. Currently everybody does #ifdef
> CONFIG_PM, so either all the data is available, or none is and adding
> another #ifdef CONFIG_PM_RUNTIME for the runtime_* friends, would just
> look even uglier :-)

Like in hcd-pci.c?  :-)

> > You can obtain that same guarantee by using #ifdef ... #endif.  Even 
> > better, you can guarantee that the unused data won't be present at all, 
> > as opposed to loaded and then freed.
> 
> I agree with you here, but I give you the same question as you gave me.
> How will you have conditional on CONFIG_RUNTIME_PM and CONFIG_PM ? you'd
> need two levels of ifdefs.

Well, you'd need more #ifdefs, no question about that.  Whether you 
need more _levels_ of #ifdefs is unclear.

> > #ifdef CONFIG_PM
> > 	#define DEV_PM_OPS_REF(my_pm_ops)	&(my_pm_ops)
> > #else
> > 	#define DEV_PM_OPS_REF(my_pm_ops)	NULL
> > #endif
> > 
> > Then people could write
> > 
> > static struct platform_driver my_driver = {
> > 	...
> > 	.driver	= {
> > 		.pm = DEV_PM_OPS_REF(my_driver_pm_ops),
> > 	},
> > };
> > 
> > without worrying about whether or not my_driver_pm_ops was defined.  
> > And only one #ifdef block would be needed.
> 
> that'd be nice. Something similar to __exit_p() and __devexit_p()

Right.  Maybe even call it __pm_ops_p().

In fact, rather than tying this specifically to dev_pm_ops, it would 
make sense to have a general-purpose memory section for code that won't 
be used, and an appropriate macro (such as "__unused") to specify that 
section attribute.  Then the PM core could do:

#ifdef CONFIG_PM
	#define __pm_ops
#else
	#define __pm_ops	__unused
#endif

and that would (I think) put less of a mental burden on people.

> Well, it might work out if pm core makes dev_pm_ops only available on
> CONFIG_PM builds.

Currently the .pm member is part of struct bus_type, struct
device_driver, and others whether CONFIG_PM is enabled or not.  I don't
know if removing it when CONFIG_PM is disabled would cause build
problems -- it might.

Alan Stern


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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-06 18:03                           ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-06 18:03 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Rafael J. Wysocki, Keshava Munegowda, USB list, linux-omap,
	Kernel development list, gadiyar, sameo, parthab, tony, khilman,
	b-cousson, paul

On Mon, 6 Jun 2011, Felipe Balbi wrote:

> > But what is the "right thing"?  Suppose you want to have conditional 
> > support for dev_pm_ops whenever CONFIG_PM is enabled and you _also_ 
> > want to have conditional support for runtime PM whenever 
> > CONFIG_PM_RUNTIME is enabled?
> 
> we don't have this today either. Currently everybody does #ifdef
> CONFIG_PM, so either all the data is available, or none is and adding
> another #ifdef CONFIG_PM_RUNTIME for the runtime_* friends, would just
> look even uglier :-)

Like in hcd-pci.c?  :-)

> > You can obtain that same guarantee by using #ifdef ... #endif.  Even 
> > better, you can guarantee that the unused data won't be present at all, 
> > as opposed to loaded and then freed.
> 
> I agree with you here, but I give you the same question as you gave me.
> How will you have conditional on CONFIG_RUNTIME_PM and CONFIG_PM ? you'd
> need two levels of ifdefs.

Well, you'd need more #ifdefs, no question about that.  Whether you 
need more _levels_ of #ifdefs is unclear.

> > #ifdef CONFIG_PM
> > 	#define DEV_PM_OPS_REF(my_pm_ops)	&(my_pm_ops)
> > #else
> > 	#define DEV_PM_OPS_REF(my_pm_ops)	NULL
> > #endif
> > 
> > Then people could write
> > 
> > static struct platform_driver my_driver = {
> > 	...
> > 	.driver	= {
> > 		.pm = DEV_PM_OPS_REF(my_driver_pm_ops),
> > 	},
> > };
> > 
> > without worrying about whether or not my_driver_pm_ops was defined.  
> > And only one #ifdef block would be needed.
> 
> that'd be nice. Something similar to __exit_p() and __devexit_p()

Right.  Maybe even call it __pm_ops_p().

In fact, rather than tying this specifically to dev_pm_ops, it would 
make sense to have a general-purpose memory section for code that won't 
be used, and an appropriate macro (such as "__unused") to specify that 
section attribute.  Then the PM core could do:

#ifdef CONFIG_PM
	#define __pm_ops
#else
	#define __pm_ops	__unused
#endif

and that would (I think) put less of a mental burden on people.

> Well, it might work out if pm core makes dev_pm_ops only available on
> CONFIG_PM builds.

Currently the .pm member is part of struct bus_type, struct
device_driver, and others whether CONFIG_PM is enabled or not.  I don't
know if removing it when CONFIG_PM is disabled would cause build
problems -- it might.

Alan Stern


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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-02  0:06           ` Kevin Hilman
  (?)
@ 2011-06-29 15:22           ` Munegowda, Keshava
  2011-06-29 16:37               ` Munegowda, Keshava
  -1 siblings, 1 reply; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-29 15:22 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
> Keshava Munegowda <keshava_mgowda@ti.com> writes:
>
>> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>>
>> The global suspend and resume functions for usbhs core driver
>> are implemented.These routine are called when the global suspend
>> and resume occurs. Before calling these functions, the
>> bus suspend and resume of ehci and ohci drivers are called
>> from runtime pm.
>>
>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>
> First, from what I can see, this is only a partial implementation of
> runtime PM.  What I mean is that the runtime PM methods are used only
> during the suspend path.  The rest of the time the USB host IP block is
> left enabled, even when nothing is connected.
>
> I tested this on my 3530/Overo board, and verified that indeed the
> usbhost powerdomain hits retention on suspend, but while idle, when
> nothing is connected, I would expect the driver could be clever enough
> to use runtime PM (probably using autosuspend timeouts) to disable the
> hardware as well.
>
>> ---
>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>> index 43de12a..32d19e2 100644
>> --- a/drivers/mfd/omap-usb-host.c
>> +++ b/drivers/mfd/omap-usb-host.c
>> @@ -146,6 +146,10 @@
>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>
>>
>> +/* USBHS state bits */
>> +#define OMAP_USBHS_INIT              0
>> +#define OMAP_USBHS_SUSPEND   4
>
> These additional state bits don't seem to be necessary.
>
> For suspend, just check 'pm_runtime_is_suspended()'
>
> The init flag is only used in the suspend/resume hooks, but the need for
> it is a side effect of not correctly using the runtime PM callbacks.
>
> Remember that the runtime PM get/put hooks have usage counting.  Only
> when the usage count transitions to/from zero is the actual
> hardware-level enable/disable (via omap_hwmod) being done.
>
> The current code is making the assumption that every call to get/put is
> going to result in an enable/disable of the hardware.
>
> Instead, all of the code that needs to be run only upon actual
> enable/disable of the hardware should be done in the driver's
> runtime_suspend/runtime_resume callbacks.  These are only called when
> the hardware actually changes state.
>
> Not knowing that much about the EHCI block, upon first glance, it looks
> like mmuch of what is done in usbhs_enable() should actually be done in
> the ->runtime_resume() callback, and similarily, much of what is done in
> usbhs_disable() should be done in the ->runtime_suspend() callback.

Kevin,
   do you mean driver->runtime_resume and driver->runtime_resume call backs.
are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-29 16:37               ` Munegowda, Keshava
  0 siblings, 0 replies; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-29 16:37 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

On Wed, Jun 29, 2011 at 8:52 PM, Munegowda, Keshava
<keshava_mgowda@ti.com> wrote:
> On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>> Keshava Munegowda <keshava_mgowda@ti.com> writes:
>>
>>> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>>>
>>> The global suspend and resume functions for usbhs core driver
>>> are implemented.These routine are called when the global suspend
>>> and resume occurs. Before calling these functions, the
>>> bus suspend and resume of ehci and ohci drivers are called
>>> from runtime pm.
>>>
>>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>>
>> First, from what I can see, this is only a partial implementation of
>> runtime PM.  What I mean is that the runtime PM methods are used only
>> during the suspend path.  The rest of the time the USB host IP block is
>> left enabled, even when nothing is connected.
>>
>> I tested this on my 3530/Overo board, and verified that indeed the
>> usbhost powerdomain hits retention on suspend, but while idle, when
>> nothing is connected, I would expect the driver could be clever enough
>> to use runtime PM (probably using autosuspend timeouts) to disable the
>> hardware as well.
>>
>>> ---
>>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>> index 43de12a..32d19e2 100644
>>> --- a/drivers/mfd/omap-usb-host.c
>>> +++ b/drivers/mfd/omap-usb-host.c
>>> @@ -146,6 +146,10 @@
>>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>>
>>>
>>> +/* USBHS state bits */
>>> +#define OMAP_USBHS_INIT              0
>>> +#define OMAP_USBHS_SUSPEND   4
>>
>> These additional state bits don't seem to be necessary.
>>
>> For suspend, just check 'pm_runtime_is_suspended()'
>>
>> The init flag is only used in the suspend/resume hooks, but the need for
>> it is a side effect of not correctly using the runtime PM callbacks.
>>
>> Remember that the runtime PM get/put hooks have usage counting.  Only
>> when the usage count transitions to/from zero is the actual
>> hardware-level enable/disable (via omap_hwmod) being done.
>>
>> The current code is making the assumption that every call to get/put is
>> going to result in an enable/disable of the hardware.
>>
>> Instead, all of the code that needs to be run only upon actual
>> enable/disable of the hardware should be done in the driver's
>> runtime_suspend/runtime_resume callbacks.  These are only called when
>> the hardware actually changes state.
>>
>> Not knowing that much about the EHCI block, upon first glance, it looks
>> like mmuch of what is done in usbhs_enable() should actually be done in
>> the ->runtime_resume() callback, and similarily, much of what is done in
>> usbhs_disable() should be done in the ->runtime_suspend() callback.
>
> Kevin,
>   do you mean driver->runtime_resume and driver->runtime_resume call backs.
> are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?

for usb host case , I am seeing that the pm_runtime_get_sync


static int rpm_resume(struct device *dev, int rpmflags)
{
  ............
 ..........
	if (dev->pwr_domain) {
		callback = dev->pwr_domain->ops.runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("dev->pwr_domain->ops.runtime_resume");
	}	
	else if (dev->type && dev->type->pm) {
		callback = dev->type->pm->runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("dev->type->pm->runtime_resume");
	}	
	else if (dev->class && dev->class->pm) {
		callback = dev->class->pm->runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("ev->class->pm->runtime_resume");
	}	
	else if (dev->bus && dev->bus->pm) {
		callback = dev->bus->pm->runtime_resume;
	if(!strcmp(dev_name(dev),"usbhs_omap"))
		 pr_err("dev->bus->pm->runtime_resume");
	}	
	else
		callback = NULL;
}


I am seeing that below if statement was hitting true:

	if (dev->pwr_domain) {
		callback = dev->pwr_domain->ops.runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("dev->pwr_domain->ops.runtime_resume");


due to this; the driver->runtime_resume was not getting called.

Any idea on why I am seeing only the dev->pwr_domain is set not
dev->bus && dev->bus->pm is hitting here?

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-29 16:37               ` Munegowda, Keshava
  0 siblings, 0 replies; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-29 16:37 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	gadiyar-l0cyMroinI0, sameo-VuQAYsv1563Yd54FQh9/CA,
	parthab-PpE0FKYn9XJWk0Htik3J/w, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	b-cousson-l0cyMroinI0, paul-DWxLp4Yu+b8AvxtiuMwx3w

On Wed, Jun 29, 2011 at 8:52 PM, Munegowda, Keshava
<keshava_mgowda-l0cyMroinI0@public.gmane.org> wrote:
> On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org> wrote:
>> Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org> writes:
>>
>>> From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>>
>>> The global suspend and resume functions for usbhs core driver
>>> are implemented.These routine are called when the global suspend
>>> and resume occurs. Before calling these functions, the
>>> bus suspend and resume of ehci and ohci drivers are called
>>> from runtime pm.
>>>
>>> Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>
>> First, from what I can see, this is only a partial implementation of
>> runtime PM.  What I mean is that the runtime PM methods are used only
>> during the suspend path.  The rest of the time the USB host IP block is
>> left enabled, even when nothing is connected.
>>
>> I tested this on my 3530/Overo board, and verified that indeed the
>> usbhost powerdomain hits retention on suspend, but while idle, when
>> nothing is connected, I would expect the driver could be clever enough
>> to use runtime PM (probably using autosuspend timeouts) to disable the
>> hardware as well.
>>
>>> ---
>>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>> index 43de12a..32d19e2 100644
>>> --- a/drivers/mfd/omap-usb-host.c
>>> +++ b/drivers/mfd/omap-usb-host.c
>>> @@ -146,6 +146,10 @@
>>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>>
>>>
>>> +/* USBHS state bits */
>>> +#define OMAP_USBHS_INIT              0
>>> +#define OMAP_USBHS_SUSPEND   4
>>
>> These additional state bits don't seem to be necessary.
>>
>> For suspend, just check 'pm_runtime_is_suspended()'
>>
>> The init flag is only used in the suspend/resume hooks, but the need for
>> it is a side effect of not correctly using the runtime PM callbacks.
>>
>> Remember that the runtime PM get/put hooks have usage counting.  Only
>> when the usage count transitions to/from zero is the actual
>> hardware-level enable/disable (via omap_hwmod) being done.
>>
>> The current code is making the assumption that every call to get/put is
>> going to result in an enable/disable of the hardware.
>>
>> Instead, all of the code that needs to be run only upon actual
>> enable/disable of the hardware should be done in the driver's
>> runtime_suspend/runtime_resume callbacks.  These are only called when
>> the hardware actually changes state.
>>
>> Not knowing that much about the EHCI block, upon first glance, it looks
>> like mmuch of what is done in usbhs_enable() should actually be done in
>> the ->runtime_resume() callback, and similarily, much of what is done in
>> usbhs_disable() should be done in the ->runtime_suspend() callback.
>
> Kevin,
>   do you mean driver->runtime_resume and driver->runtime_resume call backs.
> are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?

for usb host case , I am seeing that the pm_runtime_get_sync


static int rpm_resume(struct device *dev, int rpmflags)
{
  ............
 ..........
	if (dev->pwr_domain) {
		callback = dev->pwr_domain->ops.runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("dev->pwr_domain->ops.runtime_resume");
	}	
	else if (dev->type && dev->type->pm) {
		callback = dev->type->pm->runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("dev->type->pm->runtime_resume");
	}	
	else if (dev->class && dev->class->pm) {
		callback = dev->class->pm->runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("ev->class->pm->runtime_resume");
	}	
	else if (dev->bus && dev->bus->pm) {
		callback = dev->bus->pm->runtime_resume;
	if(!strcmp(dev_name(dev),"usbhs_omap"))
		 pr_err("dev->bus->pm->runtime_resume");
	}	
	else
		callback = NULL;
}


I am seeing that below if statement was hitting true:

	if (dev->pwr_domain) {
		callback = dev->pwr_domain->ops.runtime_resume;
		if(!strcmp(dev_name(dev),"usbhs_omap"))
			 pr_err("dev->pwr_domain->ops.runtime_resume");


due to this; the driver->runtime_resume was not getting called.

Any idea on why I am seeing only the dev->pwr_domain is set not
dev->bus && dev->bus->pm is hitting here?
--
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] 50+ messages in thread

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-29 16:37               ` Munegowda, Keshava
@ 2011-06-29 17:33                 ` Alan Stern
  -1 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-29 17:33 UTC (permalink / raw)
  To: Munegowda, Keshava
  Cc: Kevin Hilman, linux-usb, linux-omap, linux-kernel, balbi,
	gadiyar, sameo, parthab, tony, b-cousson, paul

On Wed, 29 Jun 2011, Munegowda, Keshava wrote:

> for usb host case , I am seeing that the pm_runtime_get_sync
> 
> 
> static int rpm_resume(struct device *dev, int rpmflags)
> {
>   ............
>  ..........
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> 	}	
> 	else if (dev->type && dev->type->pm) {
> 		callback = dev->type->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->type->pm->runtime_resume");
> 	}	
> 	else if (dev->class && dev->class->pm) {
> 		callback = dev->class->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("ev->class->pm->runtime_resume");
> 	}	
> 	else if (dev->bus && dev->bus->pm) {
> 		callback = dev->bus->pm->runtime_resume;
> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
> 		 pr_err("dev->bus->pm->runtime_resume");
> 	}	
> 	else
> 		callback = NULL;
> }
> 
> 
> I am seeing that below if statement was hitting true:
> 
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> 
> 
> due to this; the driver->runtime_resume was not getting called.
> 
> Any idea on why I am seeing only the dev->pwr_domain is set not
> dev->bus && dev->bus->pm is hitting here?

Because the PM domain takes precedence over the subsystem for PM 
callbacks.  If the subsystem routine should be called then the PM 
domain code has to call it.

Alan Stern


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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-29 17:33                 ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-29 17:33 UTC (permalink / raw)
  To: Munegowda, Keshava
  Cc: Kevin Hilman, linux-usb, linux-omap, linux-kernel, balbi,
	gadiyar, sameo, parthab, tony, b-cousson, paul

On Wed, 29 Jun 2011, Munegowda, Keshava wrote:

> for usb host case , I am seeing that the pm_runtime_get_sync
> 
> 
> static int rpm_resume(struct device *dev, int rpmflags)
> {
>   ............
>  ..........
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> 	}	
> 	else if (dev->type && dev->type->pm) {
> 		callback = dev->type->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->type->pm->runtime_resume");
> 	}	
> 	else if (dev->class && dev->class->pm) {
> 		callback = dev->class->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("ev->class->pm->runtime_resume");
> 	}	
> 	else if (dev->bus && dev->bus->pm) {
> 		callback = dev->bus->pm->runtime_resume;
> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
> 		 pr_err("dev->bus->pm->runtime_resume");
> 	}	
> 	else
> 		callback = NULL;
> }
> 
> 
> I am seeing that below if statement was hitting true:
> 
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> 
> 
> due to this; the driver->runtime_resume was not getting called.
> 
> Any idea on why I am seeing only the dev->pwr_domain is set not
> dev->bus && dev->bus->pm is hitting here?

Because the PM domain takes precedence over the subsystem for PM 
callbacks.  If the subsystem routine should be called then the PM 
domain code has to call it.

Alan Stern

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

* RE: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-29 17:33                 ` Alan Stern
  (?)
@ 2011-06-29 18:17                 ` Partha Basak
  2011-06-29 18:47                     ` Alan Stern
  -1 siblings, 1 reply; 50+ messages in thread
From: Partha Basak @ 2011-06-29 18:17 UTC (permalink / raw)
  To: Alan Stern, Keshava Munegowda
  Cc: Kevin Hilman, linux-usb, linux-omap, linux-kernel, Felipe Balbi,
	Anand Gadiyar, sameo, parthab, tony, Benoit Cousson, paul

>-----Original Message-----
>From: Alan Stern [mailto:stern@rowland.harvard.edu]
>Sent: Wednesday, June 29, 2011 11:03 PM
>To: Munegowda, Keshava
>Cc: Kevin Hilman; 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; b-
>cousson@ti.com; paul@pwsan.com
>Subject: Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci
>and ohci
>
>On Wed, 29 Jun 2011, Munegowda, Keshava wrote:
>
>> for usb host case , I am seeing that the pm_runtime_get_sync
>>
>>
>> static int rpm_resume(struct device *dev, int rpmflags)
>> {
>>   ............
>>  ..........
>> 	if (dev->pwr_domain) {
>> 		callback = dev->pwr_domain->ops.runtime_resume;
>> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
>> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
>> 	}
>> 	else if (dev->type && dev->type->pm) {
>> 		callback = dev->type->pm->runtime_resume;
>> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
>> 			 pr_err("dev->type->pm->runtime_resume");
>> 	}
>> 	else if (dev->class && dev->class->pm) {
>> 		callback = dev->class->pm->runtime_resume;
>> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
>> 			 pr_err("ev->class->pm->runtime_resume");
>> 	}
>> 	else if (dev->bus && dev->bus->pm) {
>> 		callback = dev->bus->pm->runtime_resume;
>> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
>> 		 pr_err("dev->bus->pm->runtime_resume");
>> 	}
>> 	else
>> 		callback = NULL;
>> }
>>
>>
>> I am seeing that below if statement was hitting true:
>>
>> 	if (dev->pwr_domain) {
>> 		callback = dev->pwr_domain->ops.runtime_resume;
>> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
>> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
>>
>>
>> due to this; the driver->runtime_resume was not getting called.
>>
>> Any idea on why I am seeing only the dev->pwr_domain is set not
>> dev->bus && dev->bus->pm is hitting here?
>
>Because the PM domain takes precedence over the subsystem for PM
>callbacks.  If the subsystem routine should be called then the PM
>domain code has to call it.

This is taken care of in the pm-domain code:
static int _od_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);

	omap_device_enable(pdev);

	return pm_generic_runtime_resume(dev);
}
pm_generic_runtime_resume will in turn call the driver call back.

int pm_generic_runtime_resume(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm :
NULL;
	int ret;

	ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;

	return ret;
}
>
>Alan Stern

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

* RE: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
  2011-06-29 18:17                 ` Partha Basak
@ 2011-06-29 18:47                     ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-29 18:47 UTC (permalink / raw)
  To: Partha Basak
  Cc: Keshava Munegowda, Kevin Hilman, linux-usb, linux-omap,
	linux-kernel, Felipe Balbi, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul

On Wed, 29 Jun 2011, Partha Basak wrote:

> >-----Original Message-----
> >From: Alan Stern [mailto:stern@rowland.harvard.edu]
> >Sent: Wednesday, June 29, 2011 11:03 PM
> >To: Munegowda, Keshava
> >Cc: Kevin Hilman; 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; b-
> >cousson@ti.com; paul@pwsan.com
> >Subject: Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci
> >and ohci
> >
> >On Wed, 29 Jun 2011, Munegowda, Keshava wrote:
> >
> >> for usb host case , I am seeing that the pm_runtime_get_sync
> >>
> >>
> >> static int rpm_resume(struct device *dev, int rpmflags)
> >> {
> >>   ............
> >>  ..........
> >> 	if (dev->pwr_domain) {
> >> 		callback = dev->pwr_domain->ops.runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> >> 	}
> >> 	else if (dev->type && dev->type->pm) {
> >> 		callback = dev->type->pm->runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("dev->type->pm->runtime_resume");
> >> 	}
> >> 	else if (dev->class && dev->class->pm) {
> >> 		callback = dev->class->pm->runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("ev->class->pm->runtime_resume");
> >> 	}
> >> 	else if (dev->bus && dev->bus->pm) {
> >> 		callback = dev->bus->pm->runtime_resume;
> >> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 		 pr_err("dev->bus->pm->runtime_resume");
> >> 	}
> >> 	else
> >> 		callback = NULL;
> >> }
> >>
> >>
> >> I am seeing that below if statement was hitting true:
> >>
> >> 	if (dev->pwr_domain) {
> >> 		callback = dev->pwr_domain->ops.runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> >>
> >>
> >> due to this; the driver->runtime_resume was not getting called.
> >>
> >> Any idea on why I am seeing only the dev->pwr_domain is set not
> >> dev->bus && dev->bus->pm is hitting here?
> >
> >Because the PM domain takes precedence over the subsystem for PM
> >callbacks.  If the subsystem routine should be called then the PM
> >domain code has to call it.
> 
> This is taken care of in the pm-domain code:
> static int _od_runtime_resume(struct device *dev)
> {
> 	struct platform_device *pdev = to_platform_device(dev);
> 
> 	omap_device_enable(pdev);
> 
> 	return pm_generic_runtime_resume(dev);
> }
> pm_generic_runtime_resume will in turn call the driver call back.
> 
> int pm_generic_runtime_resume(struct device *dev)
> {
> 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm :
> NULL;
> 	int ret;
> 
> 	ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
> 
> 	return ret;
> }

You appear to be contradicting what Keshava wrote: "due to this; the
driver->runtime_resume was not getting called."

You can't both be right.

Alan Stern



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

* RE: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-29 18:47                     ` Alan Stern
  0 siblings, 0 replies; 50+ messages in thread
From: Alan Stern @ 2011-06-29 18:47 UTC (permalink / raw)
  To: Partha Basak
  Cc: Keshava Munegowda, Kevin Hilman, linux-usb, linux-omap,
	linux-kernel, Felipe Balbi, Anand Gadiyar, sameo, parthab, tony,
	Benoit Cousson, paul

On Wed, 29 Jun 2011, Partha Basak wrote:

> >-----Original Message-----
> >From: Alan Stern [mailto:stern@rowland.harvard.edu]
> >Sent: Wednesday, June 29, 2011 11:03 PM
> >To: Munegowda, Keshava
> >Cc: Kevin Hilman; 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; b-
> >cousson@ti.com; paul@pwsan.com
> >Subject: Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci
> >and ohci
> >
> >On Wed, 29 Jun 2011, Munegowda, Keshava wrote:
> >
> >> for usb host case , I am seeing that the pm_runtime_get_sync
> >>
> >>
> >> static int rpm_resume(struct device *dev, int rpmflags)
> >> {
> >>   ............
> >>  ..........
> >> 	if (dev->pwr_domain) {
> >> 		callback = dev->pwr_domain->ops.runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> >> 	}
> >> 	else if (dev->type && dev->type->pm) {
> >> 		callback = dev->type->pm->runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("dev->type->pm->runtime_resume");
> >> 	}
> >> 	else if (dev->class && dev->class->pm) {
> >> 		callback = dev->class->pm->runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("ev->class->pm->runtime_resume");
> >> 	}
> >> 	else if (dev->bus && dev->bus->pm) {
> >> 		callback = dev->bus->pm->runtime_resume;
> >> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 		 pr_err("dev->bus->pm->runtime_resume");
> >> 	}
> >> 	else
> >> 		callback = NULL;
> >> }
> >>
> >>
> >> I am seeing that below if statement was hitting true:
> >>
> >> 	if (dev->pwr_domain) {
> >> 		callback = dev->pwr_domain->ops.runtime_resume;
> >> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> >> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> >>
> >>
> >> due to this; the driver->runtime_resume was not getting called.
> >>
> >> Any idea on why I am seeing only the dev->pwr_domain is set not
> >> dev->bus && dev->bus->pm is hitting here?
> >
> >Because the PM domain takes precedence over the subsystem for PM
> >callbacks.  If the subsystem routine should be called then the PM
> >domain code has to call it.
> 
> This is taken care of in the pm-domain code:
> static int _od_runtime_resume(struct device *dev)
> {
> 	struct platform_device *pdev = to_platform_device(dev);
> 
> 	omap_device_enable(pdev);
> 
> 	return pm_generic_runtime_resume(dev);
> }
> pm_generic_runtime_resume will in turn call the driver call back.
> 
> int pm_generic_runtime_resume(struct device *dev)
> {
> 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm :
> NULL;
> 	int ret;
> 
> 	ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : 0;
> 
> 	return ret;
> }

You appear to be contradicting what Keshava wrote: "due to this; the
driver->runtime_resume was not getting called."

You can't both be right.

Alan Stern



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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-29 19:20                 ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-29 19:20 UTC (permalink / raw)
  To: Munegowda, Keshava
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

"Munegowda, Keshava" <keshava_mgowda@ti.com> writes:

> On Wed, Jun 29, 2011 at 8:52 PM, Munegowda, Keshava
> <keshava_mgowda@ti.com> wrote:
>> On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>>> Keshava Munegowda <keshava_mgowda@ti.com> writes:
>>>
>>>> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>>>>
>>>> The global suspend and resume functions for usbhs core driver
>>>> are implemented.These routine are called when the global suspend
>>>> and resume occurs. Before calling these functions, the
>>>> bus suspend and resume of ehci and ohci drivers are called
>>>> from runtime pm.
>>>>
>>>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>>>
>>> First, from what I can see, this is only a partial implementation of
>>> runtime PM.  What I mean is that the runtime PM methods are used only
>>> during the suspend path.  The rest of the time the USB host IP block is
>>> left enabled, even when nothing is connected.
>>>
>>> I tested this on my 3530/Overo board, and verified that indeed the
>>> usbhost powerdomain hits retention on suspend, but while idle, when
>>> nothing is connected, I would expect the driver could be clever enough
>>> to use runtime PM (probably using autosuspend timeouts) to disable the
>>> hardware as well.
>>>
>>>> ---
>>>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>>> index 43de12a..32d19e2 100644
>>>> --- a/drivers/mfd/omap-usb-host.c
>>>> +++ b/drivers/mfd/omap-usb-host.c
>>>> @@ -146,6 +146,10 @@
>>>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>>>
>>>>
>>>> +/* USBHS state bits */
>>>> +#define OMAP_USBHS_INIT              0
>>>> +#define OMAP_USBHS_SUSPEND   4
>>>
>>> These additional state bits don't seem to be necessary.
>>>
>>> For suspend, just check 'pm_runtime_is_suspended()'
>>>
>>> The init flag is only used in the suspend/resume hooks, but the need for
>>> it is a side effect of not correctly using the runtime PM callbacks.
>>>
>>> Remember that the runtime PM get/put hooks have usage counting.  Only
>>> when the usage count transitions to/from zero is the actual
>>> hardware-level enable/disable (via omap_hwmod) being done.
>>>
>>> The current code is making the assumption that every call to get/put is
>>> going to result in an enable/disable of the hardware.
>>>
>>> Instead, all of the code that needs to be run only upon actual
>>> enable/disable of the hardware should be done in the driver's
>>> runtime_suspend/runtime_resume callbacks.  These are only called when
>>> the hardware actually changes state.
>>>
>>> Not knowing that much about the EHCI block, upon first glance, it looks
>>> like mmuch of what is done in usbhs_enable() should actually be done in
>>> the ->runtime_resume() callback, and similarily, much of what is done in
>>> usbhs_disable() should be done in the ->runtime_suspend() callback.
>>
>> Kevin,
>>   do you mean driver->runtime_resume and driver->runtime_resume call backs.
>> are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?
>
> for usb host case , I am seeing that the pm_runtime_get_sync
>
>
> static int rpm_resume(struct device *dev, int rpmflags)
> {
>   ............
>  ..........
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> 	}	
> 	else if (dev->type && dev->type->pm) {
> 		callback = dev->type->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->type->pm->runtime_resume");
> 	}	
> 	else if (dev->class && dev->class->pm) {
> 		callback = dev->class->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("ev->class->pm->runtime_resume");
> 	}	
> 	else if (dev->bus && dev->bus->pm) {
> 		callback = dev->bus->pm->runtime_resume;
> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
> 		 pr_err("dev->bus->pm->runtime_resume");
> 	}	
> 	else
> 		callback = NULL;
> }
>
>
> I am seeing that below if statement was hitting true:
>
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
>
>
> due to this; the driver->runtime_resume was not getting called.
>
> Any idea on why I am seeing only the dev->pwr_domain is set not
> dev->bus && dev->bus->pm is hitting here?

Because that's how it was designed. :)

On OMAP, for on-chip devices (omap_devices) we use PM domains
(pwr_domain) and not the subsystem (bus) to implment runtime PM, and as
Alan pointed out, PM domains have precedence over subsystem callbacks.

I'm curious why you determined the driver's runtime resume was not
getting called?

The PM domain callback will call your driver's runtime_resume (assuming
it exists.)

rpm_resume()
   dev->pwr_domain->ops.runtime_resume()
       omap_device_enable()
       pm_generic_runtime_resume()
          dev->driver->pm->runtime_resume()

Note that the PM domain implementation is done at the omap_device
level.  Specifically, see plat-omap/omap_device.c:_od_runtime_resume()

Kevin

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-29 19:20                 ` Kevin Hilman
  0 siblings, 0 replies; 50+ messages in thread
From: Kevin Hilman @ 2011-06-29 19:20 UTC (permalink / raw)
  To: Munegowda, Keshava
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	gadiyar-l0cyMroinI0, sameo-VuQAYsv1563Yd54FQh9/CA,
	parthab-PpE0FKYn9XJWk0Htik3J/w, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	b-cousson-l0cyMroinI0, paul-DWxLp4Yu+b8AvxtiuMwx3w

"Munegowda, Keshava" <keshava_mgowda-l0cyMroinI0@public.gmane.org> writes:

> On Wed, Jun 29, 2011 at 8:52 PM, Munegowda, Keshava
> <keshava_mgowda-l0cyMroinI0@public.gmane.org> wrote:
>> On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org> wrote:
>>> Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org> writes:
>>>
>>>> From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>>>
>>>> The global suspend and resume functions for usbhs core driver
>>>> are implemented.These routine are called when the global suspend
>>>> and resume occurs. Before calling these functions, the
>>>> bus suspend and resume of ehci and ohci drivers are called
>>>> from runtime pm.
>>>>
>>>> Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>>
>>> First, from what I can see, this is only a partial implementation of
>>> runtime PM.  What I mean is that the runtime PM methods are used only
>>> during the suspend path.  The rest of the time the USB host IP block is
>>> left enabled, even when nothing is connected.
>>>
>>> I tested this on my 3530/Overo board, and verified that indeed the
>>> usbhost powerdomain hits retention on suspend, but while idle, when
>>> nothing is connected, I would expect the driver could be clever enough
>>> to use runtime PM (probably using autosuspend timeouts) to disable the
>>> hardware as well.
>>>
>>>> ---
>>>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>>> index 43de12a..32d19e2 100644
>>>> --- a/drivers/mfd/omap-usb-host.c
>>>> +++ b/drivers/mfd/omap-usb-host.c
>>>> @@ -146,6 +146,10 @@
>>>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>>>
>>>>
>>>> +/* USBHS state bits */
>>>> +#define OMAP_USBHS_INIT              0
>>>> +#define OMAP_USBHS_SUSPEND   4
>>>
>>> These additional state bits don't seem to be necessary.
>>>
>>> For suspend, just check 'pm_runtime_is_suspended()'
>>>
>>> The init flag is only used in the suspend/resume hooks, but the need for
>>> it is a side effect of not correctly using the runtime PM callbacks.
>>>
>>> Remember that the runtime PM get/put hooks have usage counting.  Only
>>> when the usage count transitions to/from zero is the actual
>>> hardware-level enable/disable (via omap_hwmod) being done.
>>>
>>> The current code is making the assumption that every call to get/put is
>>> going to result in an enable/disable of the hardware.
>>>
>>> Instead, all of the code that needs to be run only upon actual
>>> enable/disable of the hardware should be done in the driver's
>>> runtime_suspend/runtime_resume callbacks.  These are only called when
>>> the hardware actually changes state.
>>>
>>> Not knowing that much about the EHCI block, upon first glance, it looks
>>> like mmuch of what is done in usbhs_enable() should actually be done in
>>> the ->runtime_resume() callback, and similarily, much of what is done in
>>> usbhs_disable() should be done in the ->runtime_suspend() callback.
>>
>> Kevin,
>>   do you mean driver->runtime_resume and driver->runtime_resume call backs.
>> are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?
>
> for usb host case , I am seeing that the pm_runtime_get_sync
>
>
> static int rpm_resume(struct device *dev, int rpmflags)
> {
>   ............
>  ..........
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
> 	}	
> 	else if (dev->type && dev->type->pm) {
> 		callback = dev->type->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->type->pm->runtime_resume");
> 	}	
> 	else if (dev->class && dev->class->pm) {
> 		callback = dev->class->pm->runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("ev->class->pm->runtime_resume");
> 	}	
> 	else if (dev->bus && dev->bus->pm) {
> 		callback = dev->bus->pm->runtime_resume;
> 	if(!strcmp(dev_name(dev),"usbhs_omap"))
> 		 pr_err("dev->bus->pm->runtime_resume");
> 	}	
> 	else
> 		callback = NULL;
> }
>
>
> I am seeing that below if statement was hitting true:
>
> 	if (dev->pwr_domain) {
> 		callback = dev->pwr_domain->ops.runtime_resume;
> 		if(!strcmp(dev_name(dev),"usbhs_omap"))
> 			 pr_err("dev->pwr_domain->ops.runtime_resume");
>
>
> due to this; the driver->runtime_resume was not getting called.
>
> Any idea on why I am seeing only the dev->pwr_domain is set not
> dev->bus && dev->bus->pm is hitting here?

Because that's how it was designed. :)

On OMAP, for on-chip devices (omap_devices) we use PM domains
(pwr_domain) and not the subsystem (bus) to implment runtime PM, and as
Alan pointed out, PM domains have precedence over subsystem callbacks.

I'm curious why you determined the driver's runtime resume was not
getting called?

The PM domain callback will call your driver's runtime_resume (assuming
it exists.)

rpm_resume()
   dev->pwr_domain->ops.runtime_resume()
       omap_device_enable()
       pm_generic_runtime_resume()
          dev->driver->pm->runtime_resume()

Note that the PM domain implementation is done at the omap_device
level.  Specifically, see plat-omap/omap_device.c:_od_runtime_resume()

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] 50+ messages in thread

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-30 12:40                   ` Munegowda, Keshava
  0 siblings, 0 replies; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-30 12:40 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-usb, linux-omap, linux-kernel, balbi, gadiyar, sameo,
	parthab, tony, b-cousson, paul

On Thu, Jun 30, 2011 at 12:50 AM, Kevin Hilman <khilman@ti.com> wrote:
> "Munegowda, Keshava" <keshava_mgowda@ti.com> writes:
>
>> On Wed, Jun 29, 2011 at 8:52 PM, Munegowda, Keshava
>> <keshava_mgowda@ti.com> wrote:
>>> On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman@ti.com> wrote:
>>>> Keshava Munegowda <keshava_mgowda@ti.com> writes:
>>>>
>>>>> From: Keshava Munegowda <Keshava_mgowda@ti.com>
>>>>>
>>>>> The global suspend and resume functions for usbhs core driver
>>>>> are implemented.These routine are called when the global suspend
>>>>> and resume occurs. Before calling these functions, the
>>>>> bus suspend and resume of ehci and ohci drivers are called
>>>>> from runtime pm.
>>>>>
>>>>> Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
>>>>
>>>> First, from what I can see, this is only a partial implementation of
>>>> runtime PM.  What I mean is that the runtime PM methods are used only
>>>> during the suspend path.  The rest of the time the USB host IP block is
>>>> left enabled, even when nothing is connected.
>>>>
>>>> I tested this on my 3530/Overo board, and verified that indeed the
>>>> usbhost powerdomain hits retention on suspend, but while idle, when
>>>> nothing is connected, I would expect the driver could be clever enough
>>>> to use runtime PM (probably using autosuspend timeouts) to disable the
>>>> hardware as well.
>>>>
>>>>> ---
>>>>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>>>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>>>> index 43de12a..32d19e2 100644
>>>>> --- a/drivers/mfd/omap-usb-host.c
>>>>> +++ b/drivers/mfd/omap-usb-host.c
>>>>> @@ -146,6 +146,10 @@
>>>>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>>>>
>>>>>
>>>>> +/* USBHS state bits */
>>>>> +#define OMAP_USBHS_INIT              0
>>>>> +#define OMAP_USBHS_SUSPEND   4
>>>>
>>>> These additional state bits don't seem to be necessary.
>>>>
>>>> For suspend, just check 'pm_runtime_is_suspended()'
>>>>
>>>> The init flag is only used in the suspend/resume hooks, but the need for
>>>> it is a side effect of not correctly using the runtime PM callbacks.
>>>>
>>>> Remember that the runtime PM get/put hooks have usage counting.  Only
>>>> when the usage count transitions to/from zero is the actual
>>>> hardware-level enable/disable (via omap_hwmod) being done.
>>>>
>>>> The current code is making the assumption that every call to get/put is
>>>> going to result in an enable/disable of the hardware.
>>>>
>>>> Instead, all of the code that needs to be run only upon actual
>>>> enable/disable of the hardware should be done in the driver's
>>>> runtime_suspend/runtime_resume callbacks.  These are only called when
>>>> the hardware actually changes state.
>>>>
>>>> Not knowing that much about the EHCI block, upon first glance, it looks
>>>> like mmuch of what is done in usbhs_enable() should actually be done in
>>>> the ->runtime_resume() callback, and similarily, much of what is done in
>>>> usbhs_disable() should be done in the ->runtime_suspend() callback.
>>>
>>> Kevin,
>>>   do you mean driver->runtime_resume and driver->runtime_resume call backs.
>>> are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?
>>
>> for usb host case , I am seeing that the pm_runtime_get_sync
>>
>>
>> static int rpm_resume(struct device *dev, int rpmflags)
>> {
>>   ............
>>  ..........
>>       if (dev->pwr_domain) {
>>               callback = dev->pwr_domain->ops.runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("dev->pwr_domain->ops.runtime_resume");
>>       }
>>       else if (dev->type && dev->type->pm) {
>>               callback = dev->type->pm->runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("dev->type->pm->runtime_resume");
>>       }
>>       else if (dev->class && dev->class->pm) {
>>               callback = dev->class->pm->runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("ev->class->pm->runtime_resume");
>>       }
>>       else if (dev->bus && dev->bus->pm) {
>>               callback = dev->bus->pm->runtime_resume;
>>       if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                pr_err("dev->bus->pm->runtime_resume");
>>       }
>>       else
>>               callback = NULL;
>> }
>>
>>
>> I am seeing that below if statement was hitting true:
>>
>>       if (dev->pwr_domain) {
>>               callback = dev->pwr_domain->ops.runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("dev->pwr_domain->ops.runtime_resume");
>>
>>
>> due to this; the driver->runtime_resume was not getting called.
>>
>> Any idea on why I am seeing only the dev->pwr_domain is set not
>> dev->bus && dev->bus->pm is hitting here?
>
> Because that's how it was designed. :)
>
> On OMAP, for on-chip devices (omap_devices) we use PM domains
> (pwr_domain) and not the subsystem (bus) to implment runtime PM, and as
> Alan pointed out, PM domains have precedence over subsystem callbacks.
>
> I'm curious why you determined the driver's runtime resume was not
> getting called?
>
> The PM domain callback will call your driver's runtime_resume (assuming
> it exists.)
>
> rpm_resume()
>   dev->pwr_domain->ops.runtime_resume()
>       omap_device_enable()
>       pm_generic_runtime_resume()
>          dev->driver->pm->runtime_resume()
>
> Note that the PM domain implementation is done at the omap_device
> level.  Specifically, see plat-omap/omap_device.c:_od_runtime_resume()
>
> Kevin

Thanks to partha and others

I was an rc issue; I migrated to latest kernel ; its working now.
driver runtime call backs are getting
called now. :-)

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

* Re: [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci
@ 2011-06-30 12:40                   ` Munegowda, Keshava
  0 siblings, 0 replies; 50+ messages in thread
From: Munegowda, Keshava @ 2011-06-30 12:40 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	gadiyar-l0cyMroinI0, sameo-VuQAYsv1563Yd54FQh9/CA,
	parthab-PpE0FKYn9XJWk0Htik3J/w, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	b-cousson-l0cyMroinI0, paul-DWxLp4Yu+b8AvxtiuMwx3w

On Thu, Jun 30, 2011 at 12:50 AM, Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org> wrote:
> "Munegowda, Keshava" <keshava_mgowda-l0cyMroinI0@public.gmane.org> writes:
>
>> On Wed, Jun 29, 2011 at 8:52 PM, Munegowda, Keshava
>> <keshava_mgowda-l0cyMroinI0@public.gmane.org> wrote:
>>> On Thu, Jun 2, 2011 at 5:36 AM, Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org> wrote:
>>>> Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org> writes:
>>>>
>>>>> From: Keshava Munegowda <Keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>>>>
>>>>> The global suspend and resume functions for usbhs core driver
>>>>> are implemented.These routine are called when the global suspend
>>>>> and resume occurs. Before calling these functions, the
>>>>> bus suspend and resume of ehci and ohci drivers are called
>>>>> from runtime pm.
>>>>>
>>>>> Signed-off-by: Keshava Munegowda <keshava_mgowda-l0cyMroinI0@public.gmane.org>
>>>>
>>>> First, from what I can see, this is only a partial implementation of
>>>> runtime PM.  What I mean is that the runtime PM methods are used only
>>>> during the suspend path.  The rest of the time the USB host IP block is
>>>> left enabled, even when nothing is connected.
>>>>
>>>> I tested this on my 3530/Overo board, and verified that indeed the
>>>> usbhost powerdomain hits retention on suspend, but while idle, when
>>>> nothing is connected, I would expect the driver could be clever enough
>>>> to use runtime PM (probably using autosuspend timeouts) to disable the
>>>> hardware as well.
>>>>
>>>>> ---
>>>>>  drivers/mfd/omap-usb-host.c |  103 +++++++++++++++++++++++++++++++++++++++++++
>>>>>  1 files changed, 103 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>>>>> index 43de12a..32d19e2 100644
>>>>> --- a/drivers/mfd/omap-usb-host.c
>>>>> +++ b/drivers/mfd/omap-usb-host.c
>>>>> @@ -146,6 +146,10 @@
>>>>>  #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
>>>>>
>>>>>
>>>>> +/* USBHS state bits */
>>>>> +#define OMAP_USBHS_INIT              0
>>>>> +#define OMAP_USBHS_SUSPEND   4
>>>>
>>>> These additional state bits don't seem to be necessary.
>>>>
>>>> For suspend, just check 'pm_runtime_is_suspended()'
>>>>
>>>> The init flag is only used in the suspend/resume hooks, but the need for
>>>> it is a side effect of not correctly using the runtime PM callbacks.
>>>>
>>>> Remember that the runtime PM get/put hooks have usage counting.  Only
>>>> when the usage count transitions to/from zero is the actual
>>>> hardware-level enable/disable (via omap_hwmod) being done.
>>>>
>>>> The current code is making the assumption that every call to get/put is
>>>> going to result in an enable/disable of the hardware.
>>>>
>>>> Instead, all of the code that needs to be run only upon actual
>>>> enable/disable of the hardware should be done in the driver's
>>>> runtime_suspend/runtime_resume callbacks.  These are only called when
>>>> the hardware actually changes state.
>>>>
>>>> Not knowing that much about the EHCI block, upon first glance, it looks
>>>> like mmuch of what is done in usbhs_enable() should actually be done in
>>>> the ->runtime_resume() callback, and similarily, much of what is done in
>>>> usbhs_disable() should be done in the ->runtime_suspend() callback.
>>>
>>> Kevin,
>>>   do you mean driver->runtime_resume and driver->runtime_resume call backs.
>>> are these call backs from pm_runtime_get_sync and pm_runtime_put_sync?
>>
>> for usb host case , I am seeing that the pm_runtime_get_sync
>>
>>
>> static int rpm_resume(struct device *dev, int rpmflags)
>> {
>>   ............
>>  ..........
>>       if (dev->pwr_domain) {
>>               callback = dev->pwr_domain->ops.runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("dev->pwr_domain->ops.runtime_resume");
>>       }
>>       else if (dev->type && dev->type->pm) {
>>               callback = dev->type->pm->runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("dev->type->pm->runtime_resume");
>>       }
>>       else if (dev->class && dev->class->pm) {
>>               callback = dev->class->pm->runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("ev->class->pm->runtime_resume");
>>       }
>>       else if (dev->bus && dev->bus->pm) {
>>               callback = dev->bus->pm->runtime_resume;
>>       if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                pr_err("dev->bus->pm->runtime_resume");
>>       }
>>       else
>>               callback = NULL;
>> }
>>
>>
>> I am seeing that below if statement was hitting true:
>>
>>       if (dev->pwr_domain) {
>>               callback = dev->pwr_domain->ops.runtime_resume;
>>               if(!strcmp(dev_name(dev),"usbhs_omap"))
>>                        pr_err("dev->pwr_domain->ops.runtime_resume");
>>
>>
>> due to this; the driver->runtime_resume was not getting called.
>>
>> Any idea on why I am seeing only the dev->pwr_domain is set not
>> dev->bus && dev->bus->pm is hitting here?
>
> Because that's how it was designed. :)
>
> On OMAP, for on-chip devices (omap_devices) we use PM domains
> (pwr_domain) and not the subsystem (bus) to implment runtime PM, and as
> Alan pointed out, PM domains have precedence over subsystem callbacks.
>
> I'm curious why you determined the driver's runtime resume was not
> getting called?
>
> The PM domain callback will call your driver's runtime_resume (assuming
> it exists.)
>
> rpm_resume()
>   dev->pwr_domain->ops.runtime_resume()
>       omap_device_enable()
>       pm_generic_runtime_resume()
>          dev->driver->pm->runtime_resume()
>
> Note that the PM domain implementation is done at the omap_device
> level.  Specifically, see plat-omap/omap_device.c:_od_runtime_resume()
>
> Kevin

Thanks to partha and others

I was an rc issue; I migrated to latest kernel ; its working now.
driver runtime call backs are getting
called now. :-)
--
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] 50+ messages in thread

end of thread, other threads:[~2011-06-30 12:40 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-01 13:27 [PATCH 0/4] arm: omap: usb: Hwmod and Runtime PM support for EHCI & OHCI Keshava Munegowda
2011-06-01 13:27 ` Keshava Munegowda
2011-06-01 13:27 ` [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4 Keshava Munegowda
2011-06-01 13:27   ` Keshava Munegowda
2011-06-01 13:27   ` [PATCH 2/4] arm: omap: usb: register hwmods of usbhs Keshava Munegowda
2011-06-01 13:27     ` Keshava Munegowda
2011-06-01 13:27     ` [PATCH 3/4] arm: omap: usb: device name change for the clk names " Keshava Munegowda
2011-06-01 13:27       ` Keshava Munegowda
2011-06-01 13:27       ` [PATCH 4/4] mfd: global Suspend and resume support of ehci and ohci Keshava Munegowda
2011-06-01 13:27         ` Keshava Munegowda
2011-06-01 13:31         ` Felipe Balbi
2011-06-01 13:38           ` Munegowda, Keshava
2011-06-01 13:54         ` Rafael J. Wysocki
2011-06-01 14:32           ` Felipe Balbi
2011-06-05 17:19             ` Rafael J. Wysocki
2011-06-05 18:50               ` Felipe Balbi
2011-06-05 19:30                 ` Alan Stern
2011-06-05 19:30                   ` Alan Stern
2011-06-05 19:54                   ` Felipe Balbi
2011-06-05 19:54                     ` Felipe Balbi
2011-06-06 16:06                     ` Alan Stern
2011-06-06 16:06                       ` Alan Stern
2011-06-06 17:25                       ` Felipe Balbi
2011-06-06 18:03                         ` Alan Stern
2011-06-06 18:03                           ` Alan Stern
2011-06-06  9:45                   ` Mark Brown
2011-06-06  9:45                     ` Mark Brown
2011-06-02  0:06         ` Kevin Hilman
2011-06-02  0:06           ` Kevin Hilman
2011-06-29 15:22           ` Munegowda, Keshava
2011-06-29 16:37             ` Munegowda, Keshava
2011-06-29 16:37               ` Munegowda, Keshava
2011-06-29 17:33               ` Alan Stern
2011-06-29 17:33                 ` Alan Stern
2011-06-29 18:17                 ` Partha Basak
2011-06-29 18:47                   ` Alan Stern
2011-06-29 18:47                     ` Alan Stern
2011-06-29 19:20               ` Kevin Hilman
2011-06-29 19:20                 ` Kevin Hilman
2011-06-30 12:40                 ` Munegowda, Keshava
2011-06-30 12:40                   ` Munegowda, Keshava
2011-06-01 20:05       ` [PATCH 3/4] arm: omap: usb: device name change for the clk names of usbhs Kevin Hilman
2011-06-01 20:05         ` Kevin Hilman
2011-06-01 20:01     ` [PATCH 2/4] arm: omap: usb: register hwmods " Kevin Hilman
2011-06-01 20:01       ` Kevin Hilman
2011-06-01 20:04     ` Kevin Hilman
2011-06-01 20:04       ` Kevin Hilman
2011-06-01 19:56   ` [PATCH 1/4] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4 Kevin Hilman
2011-06-01 19:56     ` Kevin Hilman
2011-06-02  6:55     ` Munegowda, Keshava

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.